diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/backup/BackupAgent.java | 11 | ||||
| -rw-r--r-- | core/java/android/os/storage/StorageVolume.java | 5 | ||||
| -rw-r--r-- | core/java/android/provider/ContactsContract.java | 23 | ||||
| -rw-r--r-- | core/java/android/view/ActionProvider.java | 4 | ||||
| -rw-r--r-- | core/java/android/webkit/WebView.java | 55 | ||||
| -rw-r--r-- | core/java/android/widget/ActivityChooserModel.java | 63 | ||||
| -rw-r--r-- | core/java/android/widget/ActivityChooserView.java | 311 | ||||
| -rw-r--r-- | core/java/android/widget/CalendarView.java | 1 | ||||
| -rw-r--r-- | core/java/android/widget/ShareActionProvider.java | 101 |
9 files changed, 314 insertions, 260 deletions
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index dce0a97..436fdf8 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -28,6 +28,7 @@ import android.os.RemoteException; import android.util.Log; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.util.HashSet; import java.util.LinkedList; @@ -533,6 +534,16 @@ public abstract class BackupAgent extends ContextWrapper { Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex); throw ex; } finally { + // Send the EOD marker indicating that there is no more data + // forthcoming from this agent. + try { + FileOutputStream out = new FileOutputStream(data.getFileDescriptor()); + byte[] buf = new byte[4]; + out.write(buf); + } catch (IOException e) { + Log.e(TAG, "Unable to finalize backup stream!"); + } + Binder.restoreCallingIdentity(ident); try { callbackBinder.opComplete(token); diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index 60900e1..2c4b863 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -172,7 +172,10 @@ public class StorageVolume implements Parcelable { @Override public String toString() { - return mPath; + return "StorageVolume [mAllowMassStorage=" + mAllowMassStorage + ", mDescription=" + + mDescription + ", mEmulated=" + mEmulated + ", mMaxFileSize=" + mMaxFileSize + + ", mMtpReserveSpace=" + mMtpReserveSpace + ", mPath=" + mPath + ", mRemovable=" + + mRemovable + ", mStorageId=" + mStorageId + "]"; } public static final Parcelable.Creator<StorageVolume> CREATOR = diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 62c8231..0dd9a4d 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -17,6 +17,7 @@ package android.provider; import android.accounts.Account; +import android.app.Activity; import android.content.ContentProviderClient; import android.content.ContentProviderOperation; import android.content.ContentResolver; @@ -6411,6 +6412,28 @@ public final class ContactsContract { public static final String NOTES = "notes"; /** + * The Activity action to open the group in the source app (e.g. + * {@link Intent#ACTION_VIEW}). Can be NULL if the group does not have a dedicated viewer. + * This is used in conjunction with {@link #ACTION_URI}: In order to show an "Open in + * (sourceapp)"-button, both of these fields must be set + * <p> + * Type: TEXT + */ + public static final String ACTION = "action"; + + + /** + * Uri to open the group in the source app. + * Can be NULL if the group does not have a dedicated viewer. + * This is used in conjunction with {@link #ACTION}: In order to show an "Open in + * (sourceapp)"-button, both of these fields must be set + * <p> + * Type: TEXT + */ + public static final String ACTION_URI = "action_uri"; + + + /** * The ID of this group if it is a System Group, i.e. a group that has a special meaning * to the sync adapter, null otherwise. * <P>Type: TEXT</P> diff --git a/core/java/android/view/ActionProvider.java b/core/java/android/view/ActionProvider.java index 47f7358..5601dc5 100644 --- a/core/java/android/view/ActionProvider.java +++ b/core/java/android/view/ActionProvider.java @@ -28,7 +28,9 @@ import android.content.Context; * {@link android.app.ActionBar} as a substitute for the menu item when the item is * displayed as an action item. Also the provider is responsible for performing a * default action if a menu item placed on the overflow menu of the ActionBar is - * selected and none of the menu item callbacks has handled the selection. + * selected and none of the menu item callbacks has handled the selection. For this + * case the provider can also optionally provide a sub-menu for accomplishing the + * task at hand. * </p> * <p> * There are two ways for using an action provider for creating and handling of action views: diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 7ba86a5..3ae10fe 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -9089,6 +9089,52 @@ public class WebView extends AbsoluteLayout } } + /** + * Begin collecting per-tile profiling data + * + * @hide only used by profiling tests + */ + public void tileProfilingStart() { + nativeTileProfilingStart(); + } + /** + * Return per-tile profiling data + * + * @hide only used by profiling tests + */ + public float tileProfilingStop() { + return nativeTileProfilingStop(); + } + + /** @hide only used by profiling tests */ + public void tileProfilingClear() { + nativeTileProfilingClear(); + } + /** @hide only used by profiling tests */ + public int tileProfilingNumFrames() { + return nativeTileProfilingNumFrames(); + } + /** @hide only used by profiling tests */ + public int tileProfilingNumTilesInFrame(int frame) { + return nativeTileProfilingNumTilesInFrame(frame); + } + /** @hide only used by profiling tests */ + public int tileProfilingGetX(int frame, int tile) { + return nativeTileProfilingGetX(frame, tile); + } + /** @hide only used by profiling tests */ + public int tileProfilingGetY(int frame, int tile) { + return nativeTileProfilingGetY(frame, tile); + } + /** @hide only used by profiling tests */ + public boolean tileProfilingGetReady(int frame, int tile) { + return nativeTileProfilingGetReady(frame, tile); + } + /** @hide only used by profiling tests */ + public int tileProfilingGetLevel(int frame, int tile) { + return nativeTileProfilingGetLevel(frame, tile); + } + private native int nativeCacheHitFramePointer(); private native boolean nativeCacheHitIsPlugin(); private native Rect nativeCacheHitNodeBounds(); @@ -9211,6 +9257,15 @@ public class WebView extends AbsoluteLayout private native void nativeStopGL(); private native Rect nativeSubtractLayers(Rect content); private native int nativeTextGeneration(); + private native void nativeTileProfilingStart(); + private native float nativeTileProfilingStop(); + private native void nativeTileProfilingClear(); + private native int nativeTileProfilingNumFrames(); + private native int nativeTileProfilingNumTilesInFrame(int frame); + private native int nativeTileProfilingGetX(int frame, int tile); + private native int nativeTileProfilingGetY(int frame, int tile); + private native boolean nativeTileProfilingGetReady(int frame, int tile); + private native int nativeTileProfilingGetLevel(int frame, int tile); // Never call this version except by updateCachedTextfield(String) - // we always want to pass in our generation number. private native void nativeUpdateCachedTextfield(String updatedText, diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java index 83f80ff..32c44d8 100644 --- a/core/java/android/widget/ActivityChooserModel.java +++ b/core/java/android/widget/ActivityChooserModel.java @@ -126,7 +126,7 @@ public class ActivityChooserModel extends DataSetObservable { */ // This cannot be done by a simple comparator since an Activity weight // is computed from history. Note that Activity implements Comparable. - public void sort(Intent intent, List<Activity> activities, + public void sort(Intent intent, List<ActivityResolveInfo> activities, List<HistoricalRecord> historicalRecords); } @@ -215,7 +215,7 @@ public class ActivityChooserModel extends DataSetObservable { /** * List of activities that can handle the current intent. */ - private final List<Activity> mActivitys = new ArrayList<Activity>(); + private final List<ActivityResolveInfo> mActivites = new ArrayList<ActivityResolveInfo>(); /** * List with historical choice records. @@ -311,9 +311,6 @@ public class ActivityChooserModel extends DataSetObservable { * @return The model. */ public static ActivityChooserModel get(Context context, String historyFileName) { - if (historyFileName == null) { - return new ActivityChooserModel(context, historyFileName); - } synchronized (sRegistryLock) { ActivityChooserModel dataModel = sDataModelRegistry.get(historyFileName); if (dataModel == null) { @@ -380,7 +377,7 @@ public class ActivityChooserModel extends DataSetObservable { */ public int getActivityCount() { synchronized (mInstanceLock) { - return mActivitys.size(); + return mActivites.size(); } } @@ -389,12 +386,12 @@ public class ActivityChooserModel extends DataSetObservable { * * @return The activity. * - * @see Activity + * @see ActivityResolveInfo * @see #setIntent(Intent) */ public ResolveInfo getActivity(int index) { synchronized (mInstanceLock) { - return mActivitys.get(index).resolveInfo; + return mActivites.get(index).resolveInfo; } } @@ -406,10 +403,10 @@ public class ActivityChooserModel extends DataSetObservable { * @return The index if found, -1 otherwise. */ public int getActivityIndex(ResolveInfo activity) { - List<Activity> activities = mActivitys; + List<ActivityResolveInfo> activities = mActivites; final int activityCount = activities.size(); for (int i = 0; i < activityCount; i++) { - Activity currentActivity = activities.get(i); + ActivityResolveInfo currentActivity = activities.get(i); if (currentActivity.resolveInfo == activity) { return i; } @@ -433,8 +430,8 @@ public class ActivityChooserModel extends DataSetObservable { * @see HistoricalRecord */ public Intent chooseActivity(int index) { - Activity chosenActivity = mActivitys.get(index); - Activity defaultActivity = mActivitys.get(0); + ActivityResolveInfo chosenActivity = mActivites.get(index); + ActivityResolveInfo defaultActivity = mActivites.get(0); ComponentName chosenName = new ComponentName( chosenActivity.resolveInfo.activityInfo.packageName, @@ -460,8 +457,8 @@ public class ActivityChooserModel extends DataSetObservable { */ public ResolveInfo getDefaultActivity() { synchronized (mInstanceLock) { - if (!mActivitys.isEmpty()) { - return mActivitys.get(0).resolveInfo; + if (!mActivites.isEmpty()) { + return mActivites.get(0).resolveInfo; } } return null; @@ -478,8 +475,8 @@ public class ActivityChooserModel extends DataSetObservable { * @param index The index of the activity to set as default. */ public void setDefaultActivity(int index) { - Activity newDefaultActivity = mActivitys.get(index); - Activity oldDefaultActivity = mActivitys.get(0); + ActivityResolveInfo newDefaultActivity = mActivites.get(index); + ActivityResolveInfo oldDefaultActivity = mActivites.get(0); final float weight; if (oldDefaultActivity != null) { @@ -572,8 +569,8 @@ public class ActivityChooserModel extends DataSetObservable { */ private void sortActivities() { synchronized (mInstanceLock) { - if (mActivitySorter != null && !mActivitys.isEmpty()) { - mActivitySorter.sort(mIntent, mActivitys, + if (mActivitySorter != null && !mActivites.isEmpty()) { + mActivitySorter.sort(mIntent, mActivites, Collections.unmodifiableList(mHistoricalRecords)); notifyChanged(); } @@ -661,14 +658,14 @@ public class ActivityChooserModel extends DataSetObservable { * Loads the activities. */ private void loadActivitiesLocked() { - mActivitys.clear(); + mActivites.clear(); if (mIntent != null) { List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentActivities(mIntent, 0); final int resolveInfoCount = resolveInfos.size(); for (int i = 0; i < resolveInfoCount; i++) { ResolveInfo resolveInfo = resolveInfos.get(i); - mActivitys.add(new Activity(resolveInfo)); + mActivites.add(new ActivityResolveInfo(resolveInfo)); } sortActivities(); } else { @@ -797,7 +794,7 @@ public class ActivityChooserModel extends DataSetObservable { /** * Represents an activity. */ - public final class Activity implements Comparable<Activity> { + public final class ActivityResolveInfo implements Comparable<ActivityResolveInfo> { /** * The {@link ResolveInfo} of the activity. @@ -814,7 +811,7 @@ public class ActivityChooserModel extends DataSetObservable { * * @param resolveInfo activity {@link ResolveInfo}. */ - public Activity(ResolveInfo resolveInfo) { + public ActivityResolveInfo(ResolveInfo resolveInfo) { this.resolveInfo = resolveInfo; } @@ -834,14 +831,14 @@ public class ActivityChooserModel extends DataSetObservable { if (getClass() != obj.getClass()) { return false; } - Activity other = (Activity) obj; + ActivityResolveInfo other = (ActivityResolveInfo) obj; if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { return false; } return true; } - public int compareTo(Activity another) { + public int compareTo(ActivityResolveInfo another) { return Float.floatToIntBits(another.weight) - Float.floatToIntBits(weight); } @@ -862,18 +859,18 @@ public class ActivityChooserModel extends DataSetObservable { private final class DefaultSorter implements ActivitySorter { private static final float WEIGHT_DECAY_COEFFICIENT = 0.95f; - private final Map<String, Activity> mPackageNameToActivityMap = - new HashMap<String, Activity>(); + private final Map<String, ActivityResolveInfo> mPackageNameToActivityMap = + new HashMap<String, ActivityResolveInfo>(); - public void sort(Intent intent, List<Activity> activities, + public void sort(Intent intent, List<ActivityResolveInfo> activities, List<HistoricalRecord> historicalRecords) { - Map<String, Activity> packageNameToActivityMap = + Map<String, ActivityResolveInfo> packageNameToActivityMap = mPackageNameToActivityMap; packageNameToActivityMap.clear(); final int activityCount = activities.size(); for (int i = 0; i < activityCount; i++) { - Activity activity = activities.get(i); + ActivityResolveInfo activity = activities.get(i); activity.weight = 0.0f; String packageName = activity.resolveInfo.activityInfo.packageName; packageNameToActivityMap.put(packageName, activity); @@ -884,9 +881,11 @@ public class ActivityChooserModel extends DataSetObservable { for (int i = lastShareIndex; i >= 0; i--) { HistoricalRecord historicalRecord = historicalRecords.get(i); String packageName = historicalRecord.activity.getPackageName(); - Activity activity = packageNameToActivityMap.get(packageName); - activity.weight += historicalRecord.weight * nextRecordWeight; - nextRecordWeight = nextRecordWeight * WEIGHT_DECAY_COEFFICIENT; + ActivityResolveInfo activity = packageNameToActivityMap.get(packageName); + if (activity != null) { + activity.weight += historicalRecord.weight * nextRecordWeight; + nextRecordWeight = nextRecordWeight * WEIGHT_DECAY_COEFFICIENT; + } } Collections.sort(activities); diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java index 2fe8162..f500b39 100644 --- a/core/java/android/widget/ActivityChooserView.java +++ b/core/java/android/widget/ActivityChooserView.java @@ -16,10 +16,7 @@ package android.widget; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -27,12 +24,20 @@ import android.content.res.TypedArray; import android.database.DataSetObserver; import android.graphics.Canvas; import android.graphics.drawable.Drawable; -import android.os.Debug; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ActivityChooserModel; import android.widget.ActivityChooserModel.ActivityChooserModelClient; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListPopupWindow; +import android.widget.PopupWindow; +import android.widget.TextView; import com.android.internal.R; @@ -56,11 +61,6 @@ import com.android.internal.R; * </li> * </ul> * </p> - * </p> - * This view is backed by a {@link ActivityChooserModel}. Calling {@link #showPopup()} - * while this view is attached to the view hierarchy will show a popup with - * activities while if the view is not attached it will show a dialog. - * </p> * * @hide */ @@ -92,29 +92,21 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod private final ImageButton mDefaultActionButton; /** - * The header for handlers list. + * Observer for the model data. */ - private final View mListHeaderView; + private final DataSetObserver mModelDataSetOberver = new DataSetObserver() { - /** - * The footer for handlers list. - */ - private final View mListFooterView; - - /** - * The title of the header view. - */ - private TextView mListHeaderViewTitle; - - /** - * The title for expanding the activities list. - */ - private final String mListHeaderViewTitleSelectDefault; - - /** - * The title if no activity exist. - */ - private final String mListHeaderViewTitleNoActivities; + @Override + public void onChanged() { + super.onChanged(); + mAdapter.notifyDataSetChanged(); + } + @Override + public void onInvalidated() { + super.onInvalidated(); + mAdapter.notifyDataSetInvalidated(); + } + }; /** * Popup window for showing the activity overflow list. @@ -122,11 +114,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod private ListPopupWindow mListPopupWindow; /** - * Alert dialog for showing the activity overflow list. - */ - private AlertDialog mAlertDialog; - - /** * Listener for the dismissal of the popup/alert. */ private PopupWindow.OnDismissListener mOnDismissListener; @@ -147,16 +134,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod private boolean mIsAttachedToWindow; /** - * Flag whether this view is showing an alert dialog. - */ - private boolean mIsShowingAlertDialog; - - /** - * Flag whether this view is showing a popup window. - */ - private boolean mIsShowingPopuWindow; - - /** * Create a new instance. * * @param context The application environment. @@ -195,8 +172,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable( R.styleable.ActivityChooserView_expandActivityOverflowButtonDrawable); - LayoutInflater inflater = (LayoutInflater) context.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater inflater = LayoutInflater.from(mContext); inflater.inflate(R.layout.activity_chooser_view, this, true); mCallbacks = new Callbacks(); @@ -211,15 +187,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod mExpandActivityOverflowButton.setOnClickListener(mCallbacks); mExpandActivityOverflowButton.setBackgroundDrawable(expandActivityOverflowButtonDrawable); - mListHeaderView = inflater.inflate(R.layout.activity_chooser_list_header, null); - mListFooterView = inflater.inflate(R.layout.activity_chooser_list_footer, null); - - mListHeaderViewTitle = (TextView) mListHeaderView.findViewById(R.id.title); - mListHeaderViewTitleSelectDefault = context.getString( - R.string.activity_chooser_view_select_default); - mListHeaderViewTitleNoActivities = context.getString( - R.string.activity_chooser_view_no_activities); - mAdapter = new ActivityChooserViewAdapter(); mAdapter.registerDataSetObserver(new DataSetObserver() { @Override @@ -262,7 +229,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod * @return True if the popup was shown, false if already showing. */ public boolean showPopup() { - if (isShowingPopup()) { + if (isShowingPopup() || !mIsAttachedToWindow) { return false; } mIsSelectingDefaultActivity = false; @@ -276,38 +243,29 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod * @param maxActivityCount The max number of activities to display. */ private void showPopupUnchecked(int maxActivityCount) { - mAdapter.setMaxActivityCount(maxActivityCount); - if (mIsSelectingDefaultActivity) { - if (mAdapter.getActivityCount() > 0) { - mListHeaderViewTitle.setText(mListHeaderViewTitleSelectDefault); - } else { - mListHeaderViewTitle.setText(mListHeaderViewTitleNoActivities); - } - mAdapter.setHeaderView(mListHeaderView); - } else { - mAdapter.setHeaderView(null); + if (mAdapter.getDataModel() == null) { + throw new IllegalStateException("No data model. Did you call #setDataModel?"); } - if (mAdapter.getActivityCount() > maxActivityCount + 1) { - mAdapter.setFooterView(mListFooterView); + mAdapter.setMaxActivityCount(maxActivityCount); + + final int activityCount = mAdapter.getActivityCount(); + if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED + && activityCount > maxActivityCount + 1) { + mAdapter.setShowFooterView(true); } else { - mAdapter.setFooterView(null); + mAdapter.setShowFooterView(false); } - if (!mIsAttachedToWindow || mIsShowingAlertDialog) { - AlertDialog alertDialog = getAlertDilalog(); - if (!alertDialog.isShowing()) { - alertDialog.setCustomTitle(this); - alertDialog.show(); - mIsShowingAlertDialog = true; - } - } else { - ListPopupWindow popupWindow = getListPopupWindow(); - if (!popupWindow.isShowing()) { - popupWindow.setContentWidth(mAdapter.measureContentWidth()); - popupWindow.show(); - mIsShowingPopuWindow = true; + ListPopupWindow popupWindow = getListPopupWindow(); + if (!popupWindow.isShowing()) { + if (mIsSelectingDefaultActivity) { + mAdapter.setShowDefaultActivity(true); + } else { + mAdapter.setShowDefaultActivity(false); } + popupWindow.setContentWidth(mAdapter.measureContentWidth()); + popupWindow.show(); } } @@ -317,12 +275,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod * @return True if dismissed, false if already dismissed. */ public boolean dismissPopup() { - if (!isShowingPopup()) { - return false; - } - if (mIsShowingAlertDialog) { - getAlertDilalog().dismiss(); - } else if (mIsShowingPopuWindow) { + if (isShowingPopup()) { getListPopupWindow().dismiss(); } return true; @@ -334,12 +287,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod * @return True if the popup is shown. */ public boolean isShowingPopup() { - if (mIsShowingAlertDialog) { - return getAlertDilalog().isShowing(); - } else if (mIsShowingPopuWindow) { - return getListPopupWindow().isShowing(); - } - return false; + return getListPopupWindow().isShowing(); } @Override @@ -347,6 +295,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod super.onAttachedToWindow(); ActivityChooserModel dataModel = mAdapter.getDataModel(); if (dataModel != null) { + dataModel.registerObserver(mModelDataSetOberver); dataModel.readHistoricalData(); } mIsAttachedToWindow = true; @@ -357,6 +306,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod super.onDetachedFromWindow(); ActivityChooserModel dataModel = mAdapter.getDataModel(); if (dataModel != null) { + dataModel.unregisterObserver(mModelDataSetOberver); dataModel.persistHistoricalData(); } mIsAttachedToWindow = false; @@ -371,13 +321,11 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - mActivityChooserContent.layout(left, top, right, bottom); - if (mIsShowingPopuWindow) { - if (isShown()) { - showPopupUnchecked(mAdapter.getMaxActivityCount()); - } else { - dismissPopup(); - } + mActivityChooserContent.layout(0, 0, right - left, bottom - top); + if (getListPopupWindow().isShowing()) { + showPopupUnchecked(mAdapter.getMaxActivityCount()); + } else { + dismissPopup(); } } @@ -429,22 +377,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod } /** - * Gets the alert dialog which is lazily initialized. - * - * @return The popup. - */ - private AlertDialog getAlertDilalog() { - if (mAlertDialog == null) { - Builder builder = new Builder(getContext()); - builder.setAdapter(mAdapter, null); - mAlertDialog = builder.create(); - mAlertDialog.getListView().setOnItemClickListener(mCallbacks); - mAlertDialog.setOnDismissListener(mCallbacks); - } - return mAlertDialog; - } - - /** * Updates the buttons state. */ private void updateButtons() { @@ -469,24 +401,23 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod * Interface implementation to avoid publishing them in the APIs. */ private class Callbacks implements AdapterView.OnItemClickListener, - View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener, - DialogInterface.OnDismissListener { + View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener { // AdapterView#OnItemClickListener public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ActivityChooserViewAdapter adapter = (ActivityChooserViewAdapter) parent.getAdapter(); final int itemViewType = adapter.getItemViewType(position); switch (itemViewType) { - case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_HEADER: { - /* do nothing */ - } break; case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_FOOTER: { showPopupUnchecked(ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED); } break; case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_ACTIVITY: { dismissPopup(); if (mIsSelectingDefaultActivity) { - mAdapter.getDataModel().setDefaultActivity(position); + // The item at position zero is the default already. + if (position > 0) { + mAdapter.getDataModel().setDefaultActivity(position); + } } else { // The first item in the model is default action => adjust index Intent launchIntent = mAdapter.getDataModel().chooseActivity(position + 1); @@ -530,16 +461,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod // PopUpWindow.OnDismissListener#onDismiss public void onDismiss() { - mIsShowingPopuWindow = false; - notifyOnDismissListener(); - } - - // DialogInterface.OnDismissListener#onDismiss - @Override - public void onDismiss(DialogInterface dialog) { - mIsShowingAlertDialog = false; - AlertDialog alertDialog = (AlertDialog) dialog; - alertDialog.setCustomTitle(null); notifyOnDismissListener(); } @@ -559,59 +480,35 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod public static final int MAX_ACTIVITY_COUNT_DEFAULT = 4; - private static final int ITEM_VIEW_TYPE_HEADER = 0; + private static final int ITEM_VIEW_TYPE_ACTIVITY = 0; - private static final int ITEM_VIEW_TYPE_ACTIVITY = 1; - - private static final int ITEM_VIEW_TYPE_FOOTER = 2; + private static final int ITEM_VIEW_TYPE_FOOTER = 1; private static final int ITEM_VIEW_TYPE_COUNT = 3; - private final DataSetObserver mDataSetOberver = new DataSetObserver() { - - @Override - public void onChanged() { - super.onChanged(); - notifyDataSetChanged(); - } - @Override - public void onInvalidated() { - super.onInvalidated(); - notifyDataSetInvalidated(); - } - }; - private ActivityChooserModel mDataModel; private int mMaxActivityCount = MAX_ACTIVITY_COUNT_DEFAULT; - private ResolveInfo mDefaultActivity; + private boolean mShowDefaultActivity; - private View mHeaderView; - - private View mFooterView; + private boolean mShowFooterView; public void setDataModel(ActivityChooserModel dataModel) { + ActivityChooserModel oldDataModel = mAdapter.getDataModel(); + if (oldDataModel != null && isShown()) { + oldDataModel.unregisterObserver(mModelDataSetOberver); + } mDataModel = dataModel; - mDataModel.registerObserver(mDataSetOberver); - notifyDataSetChanged(); - } - - @Override - public void notifyDataSetChanged() { - if (mDataModel.getActivityCount() > 0) { - mDefaultActivity = mDataModel.getDefaultActivity(); - } else { - mDefaultActivity = null; + if (dataModel != null && isShown()) { + dataModel.registerObserver(mModelDataSetOberver); } - super.notifyDataSetChanged(); + notifyDataSetChanged(); } @Override public int getItemViewType(int position) { - if (mHeaderView != null && position == 0) { - return ITEM_VIEW_TYPE_HEADER; - } else if (mFooterView != null && position == getCount() - 1) { + if (mShowFooterView && position == getCount() - 1) { return ITEM_VIEW_TYPE_FOOTER; } else { return ITEM_VIEW_TYPE_ACTIVITY; @@ -626,14 +523,11 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod public int getCount() { int count = 0; int activityCount = mDataModel.getActivityCount(); - if (activityCount > 0) { + if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) { activityCount--; } count = Math.min(activityCount, mMaxActivityCount); - if (mHeaderView != null) { - count++; - } - if (mFooterView != null) { + if (mShowFooterView) { count++; } return count; @@ -642,16 +536,13 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod public Object getItem(int position) { final int itemViewType = getItemViewType(position); switch (itemViewType) { - case ITEM_VIEW_TYPE_HEADER: - return mHeaderView; case ITEM_VIEW_TYPE_FOOTER: - return mFooterView; + return null; case ITEM_VIEW_TYPE_ACTIVITY: - int targetIndex = (mHeaderView == null) ? position : position - 1; - if (mDefaultActivity != null) { - targetIndex++; + if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) { + position++; } - return mDataModel.getActivity(targetIndex); + return mDataModel.getActivity(position); default: throw new IllegalArgumentException(); } @@ -661,27 +552,19 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod return position; } - @Override - public boolean isEnabled(int position) { - final int itemViewType = getItemViewType(position); - switch (itemViewType) { - case ITEM_VIEW_TYPE_HEADER: - return false; - case ITEM_VIEW_TYPE_FOOTER: - case ITEM_VIEW_TYPE_ACTIVITY: - return true; - default: - throw new IllegalArgumentException(); - } - } - public View getView(int position, View convertView, ViewGroup parent) { final int itemViewType = getItemViewType(position); switch (itemViewType) { - case ITEM_VIEW_TYPE_HEADER: - return mHeaderView; case ITEM_VIEW_TYPE_FOOTER: - return mFooterView; + if (convertView == null || convertView.getId() != ITEM_VIEW_TYPE_FOOTER) { + convertView = LayoutInflater.from(getContext()).inflate( + R.layout.activity_chooser_view_list_item, parent, false); + convertView.setId(ITEM_VIEW_TYPE_FOOTER); + TextView titleView = (TextView) convertView.findViewById(R.id.title); + titleView.setText(mContext.getString( + R.string.activity_chooser_view_see_all)); + } + return convertView; case ITEM_VIEW_TYPE_ACTIVITY: if (convertView == null || convertView.getId() != R.id.list_item) { convertView = LayoutInflater.from(getContext()).inflate( @@ -695,6 +578,12 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod // Set the title. TextView titleView = (TextView) convertView.findViewById(R.id.title); titleView.setText(activity.loadLabel(packageManager)); + // Highlight the default. + if (mShowDefaultActivity && position == 0) { + convertView.setActivated(true); + } else { + convertView.setActivated(false); + } return convertView; default: throw new IllegalArgumentException(); @@ -702,7 +591,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod } public int measureContentWidth() { - // The user may have specified some of the target not to be show but we + // The user may have specified some of the target not to be shown but we // want to measure all of them since after expansion they should fit. final int oldMaxActivityCount = mMaxActivityCount; mMaxActivityCount = MAX_ACTIVITY_COUNT_UNLIMITED; @@ -733,19 +622,12 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod } public ResolveInfo getDefaultActivity() { - return mDefaultActivity; - } - - public void setHeaderView(View headerView) { - if (mHeaderView != headerView) { - mHeaderView = headerView; - notifyDataSetChanged(); - } + return mDataModel.getDefaultActivity(); } - public void setFooterView(View footerView) { - if (mFooterView != footerView) { - mFooterView = footerView; + public void setShowFooterView(boolean showFooterView) { + if (mShowFooterView != showFooterView) { + mShowFooterView = showFooterView; notifyDataSetChanged(); } } @@ -761,5 +643,12 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod public ActivityChooserModel getDataModel() { return mDataModel; } + + public void setShowDefaultActivity(boolean showDefaultActivity) { + if (mShowDefaultActivity != showDefaultActivity) { + mShowDefaultActivity = showDefaultActivity; + notifyDataSetChanged(); + } + } } } diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java index 3b16994..1b713c3 100644 --- a/core/java/android/widget/CalendarView.java +++ b/core/java/android/widget/CalendarView.java @@ -375,6 +375,7 @@ public class CalendarView extends FrameLayout { com.android.internal.R.styleable.TextAppearance); mDateTextSize = dateTextAppearance.getDimensionPixelSize( R.styleable.TextAppearance_textSize, DEFAULT_DATE_TEXT_SIZE); + dateTextAppearance.recycle(); int weekDayTextAppearanceResId = attributesArray.getResourceId( R.styleable.CalendarView_weekDayTextAppearance, diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java index f48261d..2e0cc62 100644 --- a/core/java/android/widget/ShareActionProvider.java +++ b/core/java/android/widget/ShareActionProvider.java @@ -16,21 +16,25 @@ package android.widget; -import com.android.internal.R; - import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.util.TypedValue; import android.view.ActionProvider; +import android.view.Menu; import android.view.MenuItem; +import android.view.MenuItem.OnMenuItemClickListener; import android.view.SubMenu; import android.view.View; +import com.android.internal.R; + /** * This is a provider for a share action. It is responsible for creating views - * that enable data sharing and also to perform a default action for showing - * a share dialog. + * that enable data sharing and also to show a sub menu with sharing activities + * if the hosting item is placed on the overflow menu. * <p> * Here is how to use the action provider with custom backing file in a {@link MenuItem}: * </p> @@ -48,15 +52,13 @@ import android.view.View; * // {@link ActionProvider#onCreateActionView()} which uses the backing file name. Omit this * // line if using the default share history file is desired. * mShareActionProvider.setShareHistoryFileName("custom_share_history.xml"); - * // Get the action view and hold onto it to set the share intent. - * mActionView = menuItem.getActionView(); * . . . * } * * // Somewhere in the application. * public void doShare(Intent shareIntent) { * // When you want to share set the share intent. - * mShareActionProvider.setShareIntent(mActionView, shareIntent); + * mShareActionProvider.setShareIntent(shareIntent); * } * </pre> * </code> @@ -71,11 +73,34 @@ import android.view.View; public class ShareActionProvider extends ActionProvider { /** + * The default for the maximal number of activities shown in the sub-menu. + */ + private static final int DEFAULT_INITIAL_ACTIVITY_COUNT = 4; + + /** + * The the maximum number activities shown in the sub-menu. + */ + private int mMaxShownActivityCount = DEFAULT_INITIAL_ACTIVITY_COUNT; + + /** + * Listener for handling menu item clicks. + */ + private final ShareMenuItemOnMenuItemClickListener mOnMenuItemClickListener = + new ShareMenuItemOnMenuItemClickListener(); + + /** * The default name for storing share history. */ public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml"; + /** + * Context for accessing resources. + */ private final Context mContext; + + /** + * The name of the file with share history data. + */ private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME; /** @@ -93,24 +118,59 @@ public class ShareActionProvider extends ActionProvider { */ @Override public View onCreateActionView() { + // Create the view and set its data model. ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); ActivityChooserView activityChooserView = new ActivityChooserView(mContext); activityChooserView.setActivityChooserModel(dataModel); + + // Lookup and set the expand action icon. TypedValue outTypedValue = new TypedValue(); mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true); Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId); activityChooserView.setExpandActivityOverflowButtonDrawable(drawable); + return activityChooserView; } + /** + * {@inheritDoc} + */ @Override public boolean hasSubMenu() { return true; } + /** + * {@inheritDoc} + */ @Override public void onPrepareSubMenu(SubMenu subMenu) { - // TODO Implement me + // Clear since the order of items may change. + subMenu.clear(); + + ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); + PackageManager packageManager = mContext.getPackageManager(); + + final int expandedActivityCount = dataModel.getActivityCount(); + final int collapsedActivityCount = Math.min(expandedActivityCount, mMaxShownActivityCount); + + // Populate the sub-menu with a sub set of the activities. + for (int i = 0; i < collapsedActivityCount; i++) { + ResolveInfo activity = dataModel.getActivity(i); + subMenu.add(0, i, i, activity.loadLabel(packageManager)) + .setIcon(activity.loadIcon(packageManager)) + .setOnMenuItemClickListener(mOnMenuItemClickListener); + } + + // Add a sub-menu for showing all activities as a list item. + SubMenu expandedSubMenu = subMenu.addSubMenu(Menu.NONE, collapsedActivityCount, + collapsedActivityCount, mContext.getString(R.string.activity_chooser_view_see_all)); + for (int i = 0; i < expandedActivityCount; i++) { + ResolveInfo activity = dataModel.getActivity(i); + expandedSubMenu.add(0, i, i, activity.loadLabel(packageManager)) + .setIcon(activity.loadIcon(packageManager)) + .setOnMenuItemClickListener(mOnMenuItemClickListener); + } } /** @@ -145,18 +205,29 @@ public class ShareActionProvider extends ActionProvider { * </code> * </p> * - * @param actionView An action view created by {@link #onCreateActionView()}. * @param shareIntent The share intent. * * @see Intent#ACTION_SEND * @see Intent#ACTION_SEND_MULTIPLE */ - public void setShareIntent(View actionView, Intent shareIntent) { - if (actionView instanceof ActivityChooserView) { - ActivityChooserView activityChooserView = (ActivityChooserView) actionView; - activityChooserView.getDataModel().setIntent(shareIntent); - } else { - throw new IllegalArgumentException("actionView not instance of ActivityChooserView"); + public void setShareIntent(Intent shareIntent) { + ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, + mShareHistoryFileName); + dataModel.setIntent(shareIntent); + } + + /** + * Reusable listener for handling share item clicks. + */ + private class ShareMenuItemOnMenuItemClickListener implements OnMenuItemClickListener { + @Override + public boolean onMenuItemClick(MenuItem item) { + ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, + mShareHistoryFileName); + final int itemId = item.getItemId(); + Intent launchIntent = dataModel.chooseActivity(itemId); + mContext.startActivity(launchIntent); + return true; } } } |
