Skip to content

Commit 340e261

Browse files
committed
Showing default activity in activity chooser view only if enough space.
1. While a default target is very convenient, having two targets for the widget on a phone takes too much space and the apps do not have room to add other essential affordances to the action bar. Making the default activity show only of the screen is large enough - the action bar accommodates at least four targets i.e. 500dip. 2. Fixed a bug where changing the backing model of an ActivityChooserView when the view is not shown did not remove the observer for the old model, hence the View can get into a state where it responds to changes of two models while presenting only one. Also in such a case the view would leak since the singleton model will keep a handle to it. 3. Updated the documentation of share action provider to explain how a a developer can change the backing history file and refresh the UI based on the historical data in that file. bug:6447692 Change-Id: Id5c9e54cd5df322ded8574ba028cb680e628243b
1 parent b05b158 commit 340e261

File tree

6 files changed

+74
-10
lines changed

6 files changed

+74
-10
lines changed

core/java/android/widget/ActivityChooserModel.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,16 @@ private void pruneHistoricalRecordsForPackageLocked(String packageName) {
760760
}
761761
}
762762

763+
/**
764+
* Gets whether the given observer is already registered.
765+
*
766+
* @param observer The observer.
767+
* @return True if already registered.
768+
*/
769+
public boolean isRegisteredObserver(DataSetObserver observer) {
770+
return mObservers.contains(observer);
771+
}
772+
763773
/**
764774
* Represents a record in the history.
765775
*/

core/java/android/widget/ActivityChooserView.java

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020

2121
import android.content.Context;
2222
import android.content.Intent;
23+
import android.content.pm.ActivityInfo;
2324
import android.content.pm.PackageManager;
2425
import android.content.pm.ResolveInfo;
26+
import android.content.res.Configuration;
2527
import android.content.res.Resources;
2628
import android.content.res.TypedArray;
2729
import android.database.DataSetObserver;
@@ -173,6 +175,11 @@ public void onGlobalLayout() {
173175
*/
174176
private int mDefaultActionButtonContentDescription;
175177

178+
/**
179+
* Whether this view has a default activity affordance.
180+
*/
181+
private boolean mHasDefaultActivity;
182+
176183
/**
177184
* Create a new instance.
178185
*
@@ -245,6 +252,8 @@ public void onChanged() {
245252
Resources resources = context.getResources();
246253
mListPopupMaxWidth = Math.max(resources.getDisplayMetrics().widthPixels / 2,
247254
resources.getDimensionPixelSize(com.android.internal.R.dimen.config_prefDialogWidth));
255+
256+
updateHasDefaultActivity();
248257
}
249258

250259
/**
@@ -258,6 +267,21 @@ public void setActivityChooserModel(ActivityChooserModel dataModel) {
258267
}
259268
}
260269

270+
@Override
271+
protected void onConfigurationChanged(Configuration newConfig) {
272+
Configuration oldConfig = mContext.getResources().getConfiguration();
273+
final int changed = oldConfig.diff(newConfig);
274+
if ((changed & ActivityInfo.CONFIG_SCREEN_SIZE) != 0
275+
|| (changed & ActivityInfo.CONFIG_ORIENTATION) != 0) {
276+
updateHasDefaultActivity();
277+
}
278+
}
279+
280+
private void updateHasDefaultActivity() {
281+
mHasDefaultActivity = mContext.getResources().getBoolean(
282+
R.bool.activity_chooser_view_has_default_activity);
283+
}
284+
261285
/**
262286
* Sets the background for the button that expands the activity
263287
* overflow list.
@@ -383,7 +407,8 @@ public boolean isShowingPopup() {
383407
protected void onAttachedToWindow() {
384408
super.onAttachedToWindow();
385409
ActivityChooserModel dataModel = mAdapter.getDataModel();
386-
if (dataModel != null) {
410+
if (dataModel != null
411+
&& !dataModel.isRegisteredObserver(mModelDataSetOberver)) {
387412
dataModel.registerObserver(mModelDataSetOberver);
388413
}
389414
mIsAttachedToWindow = true;
@@ -393,7 +418,8 @@ protected void onAttachedToWindow() {
393418
protected void onDetachedFromWindow() {
394419
super.onDetachedFromWindow();
395420
ActivityChooserModel dataModel = mAdapter.getDataModel();
396-
if (dataModel != null) {
421+
if (dataModel != null
422+
&& dataModel.isRegisteredObserver(mModelDataSetOberver)) {
397423
dataModel.unregisterObserver(mModelDataSetOberver);
398424
}
399425
ViewTreeObserver viewTreeObserver = getViewTreeObserver();
@@ -496,7 +522,7 @@ private void updateAppearance() {
496522
// Default activity button.
497523
final int activityCount = mAdapter.getActivityCount();
498524
final int historySize = mAdapter.getHistorySize();
499-
if (activityCount > 0 && historySize > 0) {
525+
if (mHasDefaultActivity && activityCount > 0 && historySize > 0) {
500526
mDefaultActivityButton.setVisibility(VISIBLE);
501527
ResolveInfo activity = mAdapter.getDefaultActivity();
502528
PackageManager packageManager = mContext.getPackageManager();
@@ -512,9 +538,9 @@ private void updateAppearance() {
512538
}
513539
// Activity chooser content.
514540
if (mDefaultActivityButton.getVisibility() == VISIBLE) {
515-
mActivityChooserContent.setBackgroundDrawable(mActivityChooserContentBackground);
541+
mActivityChooserContent.setBackground(mActivityChooserContentBackground);
516542
} else {
517-
mActivityChooserContent.setBackgroundDrawable(null);
543+
mActivityChooserContent.setBackground(null);
518544
}
519545
}
520546

@@ -577,7 +603,7 @@ public void onClick(View view) {
577603
// OnLongClickListener#onLongClick
578604
@Override
579605
public boolean onLongClick(View view) {
580-
if (view == mDefaultActivityButton) {
606+
if (mHasDefaultActivity && view == mDefaultActivityButton) {
581607
if (mAdapter.getCount() > 0) {
582608
mIsSelectingDefaultActivity = true;
583609
showPopupUnchecked(mInitialActivityCount);
@@ -630,14 +656,16 @@ private class ActivityChooserViewAdapter extends BaseAdapter {
630656

631657
public void setDataModel(ActivityChooserModel dataModel) {
632658
ActivityChooserModel oldDataModel = mAdapter.getDataModel();
633-
if (oldDataModel != null && isShown()) {
659+
if (oldDataModel != null) {
634660
oldDataModel.unregisterObserver(mModelDataSetOberver);
635661
}
636662
mDataModel = dataModel;
637-
if (dataModel != null && isShown()) {
663+
if (dataModel != null) {
638664
dataModel.registerObserver(mModelDataSetOberver);
665+
notifyDataSetChanged();
666+
} else {
667+
notifyDataSetInvalidated();
639668
}
640-
notifyDataSetChanged();
641669
}
642670

643671
@Override

core/java/android/widget/ShareActionProvider.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
* <code>
4545
* // In Activity#onCreateOptionsMenu
4646
* public boolean onCreateOptionsMenu(Menu menu) {
47+
* getManuInflater().inflate(R.menu.my_menu, menu);
4748
* // Get the menu item.
4849
* MenuItem menuItem = menu.findItem(R.id.my_menu_item);
4950
* // Get the provider and hold onto it to set/change the share intent.
@@ -239,7 +240,11 @@ public void onPrepareSubMenu(SubMenu subMenu) {
239240
* <p>
240241
* <strong>Note:</strong> The history file name can be set any time, however
241242
* only the action views created by {@link #onCreateActionView()} after setting
242-
* the file name will be backed by the provided file.
243+
* the file name will be backed by the provided file. Hence, if you are using
244+
* a share action provider on a menu item and want to change the history file
245+
* based on the type of the currently selected item, you need to call
246+
* {@link android.app.Activity#invalidateOptionsMenu()} to force the system
247+
* to recreate the menu UI.
243248
* <p>
244249
*
245250
* @param shareHistoryFile The share history file name.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Copyright (C) 2012 The Android Open Source Project
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
17+
<resources>
18+
<bool name="activity_chooser_view_has_default_activity">true</bool>
19+
</resources>

core/res/res/values/bools.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@
2222
<bool name="show_ongoing_ime_switcher">true</bool>
2323
<bool name="action_bar_expanded_action_views_exclusive">true</bool>
2424
<bool name="target_honeycomb_needs_options_menu">true</bool>
25+
<bool name="activity_chooser_view_has_default_activity">false</bool>
2526
</resources>

core/res/res/values/public.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,7 @@
13761376
<java-symbol type="bool" name="config_wifi_dual_band_support" />
13771377
<java-symbol type="bool" name="config_wimaxEnabled" />
13781378
<java-symbol type="bool" name="show_ongoing_ime_switcher" />
1379+
<java-symbol type="bool" name="activity_chooser_view_has_default_activity" />
13791380
<java-symbol type="color" name="config_defaultNotificationColor" />
13801381
<java-symbol type="drawable" name="ic_notification_ime_default" />
13811382
<java-symbol type="drawable" name="stat_notify_car_mode" />

0 commit comments

Comments
 (0)