Skip to content

Commit 823f074

Browse files
committed
Fix bug 5300621 - Share menu disappears in gallery
ActionProviders (or action views) unfortunately had no way to report that they had opened a sub-UI that would affect menu visibility listeners used to hide action bars when not in use. This caused the Gallery UI to hide its action bar when the share popup was open. Add hidden API (to be made public later) to ActionProvider that can be used to inform the menu system that a sub UI has opened or closed. Account for this in menu visibility callbacks. Fix ShareActionProvider to use this when its popup windows open and close. Fix a regression where submenus were not properly reporting visibility changes. Change-Id: Ia6f45fb463ad106105c40d01f141c2e5c8b96f78
1 parent a80599f commit 823f074

7 files changed

Lines changed: 90 additions & 5 deletions

File tree

core/java/android/view/ActionProvider.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
* @see MenuItem#getActionProvider()
5959
*/
6060
public abstract class ActionProvider {
61+
private SubUiVisibilityListener mSubUiVisibilityListener;
6162

6263
/**
6364
* Creates a new instance.
@@ -138,4 +139,31 @@ public boolean hasSubMenu() {
138139
*/
139140
public void onPrepareSubMenu(SubMenu subMenu) {
140141
}
142+
143+
/**
144+
* Notify the system that the visibility of an action view's sub-UI such as
145+
* an anchored popup has changed. This will affect how other system
146+
* visibility notifications occur.
147+
*
148+
* @hide Pending future API approval
149+
*/
150+
public void subUiVisibilityChanged(boolean isVisible) {
151+
if (mSubUiVisibilityListener != null) {
152+
mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible);
153+
}
154+
}
155+
156+
/**
157+
* @hide Internal use only
158+
*/
159+
public void setSubUiVisibilityListener(SubUiVisibilityListener listener) {
160+
mSubUiVisibilityListener = listener;
161+
}
162+
163+
/**
164+
* @hide Internal use only
165+
*/
166+
public interface SubUiVisibilityListener {
167+
public void onSubUiVisibilityChanged(boolean isVisible);
168+
}
141169
}

core/java/android/widget/ActivityChooserView.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package android.widget;
1818

19+
import com.android.internal.R;
20+
1921
import android.content.Context;
2022
import android.content.Intent;
2123
import android.content.pm.PackageManager;
@@ -25,15 +27,14 @@
2527
import android.database.DataSetObserver;
2628
import android.graphics.drawable.Drawable;
2729
import android.util.AttributeSet;
30+
import android.view.ActionProvider;
2831
import android.view.LayoutInflater;
2932
import android.view.View;
3033
import android.view.ViewGroup;
3134
import android.view.ViewTreeObserver;
3235
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
3336
import android.widget.ActivityChooserModel.ActivityChooserModelClient;
3437

35-
import com.android.internal.R;
36-
3738
/**
3839
* This class is a view for choosing an activity for handling a given {@link Intent}.
3940
* <p>
@@ -104,6 +105,11 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
104105
*/
105106
private final int mListPopupMaxWidth;
106107

108+
/**
109+
* The ActionProvider hosting this view, if applicable.
110+
*/
111+
ActionProvider mProvider;
112+
107113
/**
108114
* Observer for the model data.
109115
*/
@@ -129,6 +135,9 @@ public void onGlobalLayout() {
129135
getListPopupWindow().dismiss();
130136
} else {
131137
getListPopupWindow().show();
138+
if (mProvider != null) {
139+
mProvider.subUiVisibilityChanged(true);
140+
}
132141
}
133142
}
134143
}
@@ -259,6 +268,14 @@ public void setExpandActivityOverflowButtonDrawable(Drawable drawable) {
259268
mExpandActivityOverflowButtonImage.setImageDrawable(drawable);
260269
}
261270

271+
/**
272+
* Set the provider hosting this view, if applicable.
273+
* @hide Internal use only
274+
*/
275+
public void setProvider(ActionProvider provider) {
276+
mProvider = provider;
277+
}
278+
262279
/**
263280
* Shows the popup window with activities.
264281
*
@@ -307,6 +324,9 @@ private void showPopupUnchecked(int maxActivityCount) {
307324
final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth);
308325
popupWindow.setContentWidth(contentWidth);
309326
popupWindow.show();
327+
if (mProvider != null) {
328+
mProvider.subUiVisibilityChanged(true);
329+
}
310330
}
311331
}
312332

@@ -525,6 +545,9 @@ public boolean onLongClick(View view) {
525545
// PopUpWindow.OnDismissListener#onDismiss
526546
public void onDismiss() {
527547
notifyOnDismissListener();
548+
if (mProvider != null) {
549+
mProvider.subUiVisibilityChanged(false);
550+
}
528551
}
529552

530553
private void notifyOnDismissListener() {

core/java/android/widget/PopupMenu.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
157157
* @hide
158158
*/
159159
public boolean onOpenSubMenu(MenuBuilder subMenu) {
160+
if (subMenu == null) return false;
161+
160162
if (!subMenu.hasVisibleItems()) {
161163
return true;
162164
}

core/java/android/widget/ShareActionProvider.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ public View onCreateActionView() {
169169
mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
170170
Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId);
171171
activityChooserView.setExpandActivityOverflowButtonDrawable(drawable);
172+
activityChooserView.setProvider(this);
172173

173174
return activityChooserView;
174175
}

core/java/com/android/internal/view/menu/ActionMenuPresenter.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import android.os.Parcel;
2525
import android.os.Parcelable;
2626
import android.util.SparseBooleanArray;
27+
import android.view.ActionProvider;
2728
import android.view.MenuItem;
2829
import android.view.SoundEffectConstants;
2930
import android.view.View;
@@ -40,7 +41,8 @@
4041
/**
4142
* MenuPresenter for building action menus as seen in the action bar and action modes.
4243
*/
43-
public class ActionMenuPresenter extends BaseMenuPresenter {
44+
public class ActionMenuPresenter extends BaseMenuPresenter
45+
implements ActionProvider.SubUiVisibilityListener {
4446
private static final String TAG = "ActionMenuPresenter";
4547

4648
private View mOverflowButton;
@@ -187,6 +189,17 @@ public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
187189
public void updateMenuView(boolean cleared) {
188190
super.updateMenuView(cleared);
189191

192+
if (mMenu != null) {
193+
final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems();
194+
final int count = actionItems.size();
195+
for (int i = 0; i < count; i++) {
196+
final ActionProvider provider = actionItems.get(i).getActionProvider();
197+
if (provider != null) {
198+
provider.setSubUiVisibilityListener(this);
199+
}
200+
}
201+
}
202+
190203
final boolean hasOverflow = mReserveOverflow && mMenu != null &&
191204
mMenu.getNonActionItems().size() > 0;
192205
if (hasOverflow) {
@@ -483,6 +496,16 @@ public void onRestoreInstanceState(Parcelable state) {
483496
}
484497
}
485498

499+
@Override
500+
public void onSubUiVisibilityChanged(boolean isVisible) {
501+
if (isVisible) {
502+
// Not a submenu, but treat it like one.
503+
super.onSubMenuSelected(null);
504+
} else {
505+
mMenu.close(false);
506+
}
507+
}
508+
486509
private static class SavedState implements Parcelable {
487510
public int openSubMenuId;
488511

@@ -590,7 +613,6 @@ public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) {
590613
@Override
591614
public void onDismiss() {
592615
super.onDismiss();
593-
mSubMenu.close();
594616
mActionButtonPopup = null;
595617
mOpenSubMenuId = 0;
596618
}
@@ -600,12 +622,17 @@ private class PopupPresenterCallback implements MenuPresenter.Callback {
600622

601623
@Override
602624
public boolean onOpenSubMenu(MenuBuilder subMenu) {
625+
if (subMenu == null) return false;
626+
603627
mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
604628
return false;
605629
}
606630

607631
@Override
608632
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
633+
if (menu instanceof SubMenuBuilder) {
634+
((SubMenuBuilder) menu).getRootMenu().close(false);
635+
}
609636
}
610637
}
611638

core/java/com/android/internal/view/menu/IconMenuPresenter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@ public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
187187

188188
@Override
189189
public boolean onOpenSubMenu(MenuBuilder subMenu) {
190-
mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
190+
if (subMenu != null) {
191+
mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
192+
}
191193
return false;
192194
}
193195

policy/src/com/android/internal/policy/impl/PhoneWindow.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3470,6 +3470,8 @@ public void onMenuModeChange(MenuBuilder menu) {
34703470
}
34713471

34723472
public boolean onOpenSubMenu(MenuBuilder subMenu) {
3473+
if (subMenu == null) return false;
3474+
34733475
// Set a simple callback for the submenu
34743476
subMenu.setCallback(this);
34753477

0 commit comments

Comments
 (0)