diff --git a/mobile/android/base/BrowserApp.java b/mobile/android/base/BrowserApp.java index 38f8e7bf8a1a..b890d0203fd2 100644 --- a/mobile/android/base/BrowserApp.java +++ b/mobile/android/base/BrowserApp.java @@ -20,7 +20,6 @@ import org.mozilla.gecko.util.HardwareUtils; import org.mozilla.gecko.util.ThreadUtils; import org.mozilla.gecko.util.UiAsyncTask; import org.mozilla.gecko.widget.AboutHome; -import org.mozilla.gecko.widget.GeckoActionProvider; import org.json.JSONArray; import org.json.JSONException; @@ -1427,19 +1426,6 @@ abstract public class BrowserApp extends GeckoApp mAddonMenuItemsCache.clear(); } - // Action providers are available only ICS+. - if (Build.VERSION.SDK_INT >= 14) { - MenuItem share = mMenu.findItem(R.id.share); - GeckoActionProvider provider = new GeckoActionProvider(this); - provider.setOnTargetSelectedListener(new GeckoActionProvider.OnTargetSelectedListener() { - @Override - public void onTargetSelected() { - closeOptionsMenu(); - } - }); - share.setActionProvider(provider); - } - return true; } @@ -1530,16 +1516,6 @@ abstract public class BrowserApp extends GeckoApp share.setEnabled(!(scheme.equals("about") || scheme.equals("chrome") || scheme.equals("file") || scheme.equals("resource"))); - // Action providers are available only ICS+. - if (Build.VERSION.SDK_INT >= 14) { - GeckoActionProvider provider = (GeckoActionProvider) share.getActionProvider(); - if (provider != null) { - Intent shareIntent = GeckoAppShell.getShareIntent(this, url, - "text/plain", tab.getDisplayTitle()); - provider.setIntent(shareIntent); - } - } - // Disable save as PDF for about:home and xul pages saveAsPDF.setEnabled(!(tab.getURL().equals("about:home") || tab.getContentType().equals("application/vnd.mozilla.xul+xml"))); diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java index 9c951007ce46..358a3b9b8a02 100644 --- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -1104,38 +1104,6 @@ public class GeckoAppShell return u.buildUpon().scheme(lower).build(); } - /** - * Given a URI, a MIME type, and a title, - * produce a share intent which can be used to query all activities - * than can open the specified URI. - * - * @param context a Context instance. - * @param targetURI the string spec of the URI to open. - * @param mimeType an optional MIME type string. - * @param title the title to use in ACTION_SEND intents. - * @return an Intent, or null if none could be - * produced. - */ - static Intent getShareIntent(final Context context, - final String targetURI, - final String mimeType, - final String title) { - Intent shareIntent = getIntentForActionString(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_TEXT, targetURI); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, title); - - // Note that EXTRA_TITLE is intended to be used for share dialog - // titles. Common usage (e.g., Pocket) suggests that it's sometimes - // interpreted as an alternate to EXTRA_SUBJECT, so we include it. - shareIntent.putExtra(Intent.EXTRA_TITLE, title); - - if (mimeType != null && mimeType.length() > 0) { - shareIntent.setType(mimeType); - } - - return shareIntent; - } - /** * Given a URI, a MIME type, an Android intent "action", and a title, * produce an intent which can be used to start an activity to open @@ -1157,7 +1125,19 @@ public class GeckoAppShell final String title) { if (action.equalsIgnoreCase(Intent.ACTION_SEND)) { - Intent shareIntent = getShareIntent(context, targetURI, mimeType, title); + Intent shareIntent = getIntentForActionString(action); + shareIntent.putExtra(Intent.EXTRA_TEXT, targetURI); + shareIntent.putExtra(Intent.EXTRA_SUBJECT, title); + + // Note that EXTRA_TITLE is intended to be used for share dialog + // titles. Common usage (e.g., Pocket) suggests that it's sometimes + // interpreted as an alternate to EXTRA_SUBJECT, so we include it. + shareIntent.putExtra(Intent.EXTRA_TITLE, title); + + if (mimeType != null && mimeType.length() > 0) { + shareIntent.setType(mimeType); + } + return Intent.createChooser(shareIntent, context.getResources().getString(R.string.share_title)); } diff --git a/mobile/android/base/GeckoViewsFactory.java b/mobile/android/base/GeckoViewsFactory.java index a2db19112ab4..be136174d9a2 100644 --- a/mobile/android/base/GeckoViewsFactory.java +++ b/mobile/android/base/GeckoViewsFactory.java @@ -5,7 +5,6 @@ package org.mozilla.gecko; import org.mozilla.gecko.gfx.LayerView; -import org.mozilla.gecko.menu.MenuItemActionBar; import org.mozilla.gecko.menu.MenuItemDefault; import org.mozilla.gecko.widget.AboutHomeView; import org.mozilla.gecko.widget.AddonsSection; @@ -64,7 +63,6 @@ public final class GeckoViewsFactory implements LayoutInflater.Factory { mFactoryMap.put("ForwardButton", ForwardButton.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("GeckoApp$MainLayout", GeckoApp.MainLayout.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("LinkTextView", LinkTextView.class.getConstructor(arg1Class, arg2Class)); - mFactoryMap.put("MenuItemActionBar", MenuItemActionBar.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("MenuItemDefault", MenuItemDefault.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("FindInPageBar", FindInPageBar.class.getConstructor(arg1Class, arg2Class)); mFactoryMap.put("IconTabWidget", IconTabWidget.class.getConstructor(arg1Class, arg2Class)); diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 609633ba92cf..722f3d958f59 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -218,20 +218,17 @@ FENNEC_JAVA_FILES = \ menu/GeckoMenuItem.java \ menu/GeckoSubMenu.java \ menu/MenuItemActionBar.java \ - menu/MenuItemActionView.java \ menu/MenuItemDefault.java \ menu/MenuPanel.java \ menu/MenuPopup.java \ widget/AboutHome.java \ widget/AboutHomeView.java \ widget/AboutHomeSection.java \ - widget/ActivityChooserModel.java \ widget/AddonsSection.java \ widget/DateTimePicker.java \ widget/Divider.java \ widget/FaviconView.java \ widget/GeckoPopupMenu.java \ - widget/GeckoActionProvider.java \ widget/IconTabWidget.java \ widget/LastTabsSection.java \ widget/LinkTextView.java \ @@ -442,7 +439,6 @@ RES_LAYOUT = \ res/layout/launch_app_list.xml \ res/layout/launch_app_listitem.xml \ res/layout/menu_action_bar.xml \ - res/layout/menu_item_action_view.xml \ res/layout/menu_popup.xml \ res/layout/notification_icon_text.xml \ res/layout/notification_progress.xml \ @@ -1041,7 +1037,6 @@ MOZ_ANDROID_DRAWABLES += \ mobile/android/base/resources/drawable/awesomebar_tab_indicator.xml \ mobile/android/base/resources/drawable/awesomebar_tab_selected.xml \ mobile/android/base/resources/drawable/awesomebar_tab_unselected.xml \ - mobile/android/base/resources/drawable/divider_vertical.xml \ mobile/android/base/resources/drawable/favicon_bg.xml \ mobile/android/base/resources/drawable/handle_end_level.xml \ mobile/android/base/resources/drawable/handle_start_level.xml \ diff --git a/mobile/android/base/menu/GeckoMenu.java b/mobile/android/base/menu/GeckoMenu.java index fbf6be875fd4..03a2e7976090 100644 --- a/mobile/android/base/menu/GeckoMenu.java +++ b/mobile/android/base/menu/GeckoMenu.java @@ -232,23 +232,10 @@ public class GeckoMenu extends ListView @Override public void clear() { - for (GeckoMenuItem menuItem : mItems) { - if (menuItem.hasSubMenu()) { - SubMenu subMenu = menuItem.getSubMenu(); - subMenu.clear(); - } - } - - mAdapter.clear(); - - mItems.clear(); - mActionItems.clear(); } @Override public void close() { - if (mMenuPresenter != null) - mMenuPresenter.closeMenu(); } @Override @@ -568,11 +555,6 @@ public class GeckoMenu extends ListView notifyDataSetChanged(); } - public void clear() { - mItems.clear(); - notifyDataSetChanged(); - } - public GeckoMenuItem getMenuItem(int id) { for (GeckoMenuItem item : mItems) { if (item.getItemId() == id) diff --git a/mobile/android/base/menu/GeckoMenuItem.java b/mobile/android/base/menu/GeckoMenuItem.java index c0db61a7be5a..02b18bef70cf 100644 --- a/mobile/android/base/menu/GeckoMenuItem.java +++ b/mobile/android/base/menu/GeckoMenuItem.java @@ -4,12 +4,9 @@ package org.mozilla.gecko.menu; -import org.mozilla.gecko.widget.GeckoActionProvider; - import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; -import android.os.Build; import android.view.ActionProvider; import android.view.ContextMenu; import android.view.LayoutInflater; @@ -56,7 +53,6 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener { private boolean mEnabled; private Drawable mIcon; private int mIconRes; - private ActionProvider mActionProvider; private GeckoMenu mMenu; private GeckoSubMenu mSubMenu; private MenuItem.OnMenuItemClickListener mMenuItemClickListener; @@ -95,17 +91,11 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener { @Override public ActionProvider getActionProvider() { - return mActionProvider; + return null; } @Override public View getActionView() { - if (mActionProvider != null && mActionProvider instanceof GeckoActionProvider) { - final View view = ((GeckoActionProvider) mActionProvider).getView(this); - view.setOnClickListener(this); - return view; - } - return null; } @@ -142,10 +132,6 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener { } public View getLayout() { - if (mActionProvider != null) { - return getActionView(); - } - return mLayout.getView(); } @@ -170,10 +156,6 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener { @Override public SubMenu getSubMenu() { - if (mActionProvider != null) { - mActionProvider.onPrepareSubMenu(mSubMenu); - } - return mSubMenu; } @@ -189,10 +171,6 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener { @Override public boolean hasSubMenu() { - if (mActionProvider != null) { - return mActionProvider.hasSubMenu(); - } - return (mSubMenu != null); } @@ -223,8 +201,6 @@ public class GeckoMenuItem implements MenuItem, View.OnClickListener { @Override public MenuItem setActionProvider(ActionProvider actionProvider) { - mActionProvider = actionProvider; - mSubMenu = new GeckoSubMenu(mContext, null); return this; } diff --git a/mobile/android/base/menu/MenuItemActionView.java b/mobile/android/base/menu/MenuItemActionView.java deleted file mode 100644 index b6e91748010d..000000000000 --- a/mobile/android/base/menu/MenuItemActionView.java +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.menu; - -import org.mozilla.gecko.R; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.ImageButton; - -public class MenuItemActionView extends LinearLayout - implements GeckoMenuItem.Layout { - private static final String LOGTAG = "GeckoMenuItemActionView"; - - private MenuItemDefault mMenuItem; - private ImageButton mActionButton; - - public MenuItemActionView(Context context, AttributeSet attrs) { - super(context, attrs); - - Resources res = context.getResources(); - int width = res.getDimensionPixelSize(R.dimen.menu_item_row_width); - int height = res.getDimensionPixelSize(R.dimen.menu_item_row_height); - setMinimumWidth(width); - setMinimumHeight(height); - - setShowDividers(SHOW_DIVIDER_MIDDLE); - setDividerDrawable(res.getDrawable(R.drawable.divider_vertical)); - setDividerPadding((int) (8 * res.getDisplayMetrics().density)); - - LayoutInflater.from(context).inflate(R.layout.menu_item_action_view, this); - mMenuItem = (MenuItemDefault) findViewById(R.id.menu_item); - mActionButton = (ImageButton) findViewById(R.id.action_button); - - mMenuItem.setBackgroundResource(R.drawable.action_bar_button); - } - - @Override - public View getView() { - return this; - } - - @Override - public void setIcon(Drawable icon) { - mMenuItem.setIcon(icon); - } - - @Override - public void setIcon(int icon) { - mMenuItem.setIcon(icon); - } - - @Override - public void setTitle(CharSequence title) { - mMenuItem.setTitle(title); - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - mMenuItem.setEnabled(enabled); - - if (mActionButton != null) { - mActionButton.setEnabled(enabled); - mActionButton.setAlpha(enabled ? 255 : 99); - } - } - - @Override - public void setCheckable(boolean checkable) { - } - - @Override - public void setChecked(boolean checked) { - } - - @Override - public void setSubMenuIndicator(boolean hasSubMenu) { - } - - public void setActionButtonClickListener(View.OnClickListener listener) { - mActionButton.setOnClickListener(listener); - } - - public void setActionButton(Drawable drawable) { - mActionButton.setImageDrawable(drawable); - } -} diff --git a/mobile/android/base/resources/drawable/divider_vertical.xml b/mobile/android/base/resources/drawable/divider_vertical.xml deleted file mode 100644 index 90296c634a04..000000000000 --- a/mobile/android/base/resources/drawable/divider_vertical.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - diff --git a/mobile/android/base/resources/layout/menu_item_action_view.xml b/mobile/android/base/resources/layout/menu_item_action_view.xml deleted file mode 100644 index 363743cd3072..000000000000 --- a/mobile/android/base/resources/layout/menu_item_action_view.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - diff --git a/mobile/android/base/resources/values/dimens.xml b/mobile/android/base/resources/values/dimens.xml index 53a2c848c894..754b01ec0b13 100644 --- a/mobile/android/base/resources/values/dimens.xml +++ b/mobile/android/base/resources/values/dimens.xml @@ -38,7 +38,6 @@ 400dp 6dp - 80dp 21dp 18dp 44dp diff --git a/mobile/android/base/widget/ActivityChooserModel.java b/mobile/android/base/widget/ActivityChooserModel.java deleted file mode 100644 index 96e1f3669769..000000000000 --- a/mobile/android/base/widget/ActivityChooserModel.java +++ /dev/null @@ -1,1147 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Mozilla: Changing the package. - */ -//package android.widget; -package org.mozilla.gecko.widget; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.database.DataSetObservable; -import android.os.AsyncTask; -import android.text.TextUtils; -import android.util.Log; -import android.util.Xml; - -/** - * Mozilla: Unused import. - */ -//import com.android.internal.content.PackageMonitor; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - *

- * This class represents a data model for choosing a component for handing a - * given {@link Intent}. The model is responsible for querying the system for - * activities that can handle the given intent and order found activities - * based on historical data of previous choices. The historical data is stored - * in an application private file. If a client does not want to have persistent - * choice history the file can be omitted, thus the activities will be ordered - * based on historical usage for the current session. - *

- *

- * For each backing history file there is a singleton instance of this class. Thus, - * several clients that specify the same history file will share the same model. Note - * that if multiple clients are sharing the same model they should implement semantically - * equivalent functionality since setting the model intent will change the found - * activities and they may be inconsistent with the functionality of some of the clients. - * For example, choosing a share activity can be implemented by a single backing - * model and two different views for performing the selection. If however, one of the - * views is used for sharing but the other for importing, for example, then each - * view should be backed by a separate model. - *

- *

- * The way clients interact with this class is as follows: - *

- *

- *

- * 
- *  // Get a model and set it to a couple of clients with semantically similar function.
- *  ActivityChooserModel dataModel =
- *      ActivityChooserModel.get(context, "task_specific_history_file_name.xml");
- *
- *  ActivityChooserModelClient modelClient1 = getActivityChooserModelClient1();
- *  modelClient1.setActivityChooserModel(dataModel);
- *
- *  ActivityChooserModelClient modelClient2 = getActivityChooserModelClient2();
- *  modelClient2.setActivityChooserModel(dataModel);
- *
- *  // Set an intent to choose a an activity for.
- *  dataModel.setIntent(intent);
- * 
- * 
- * 

- *

- * Note: This class is thread safe. - *

- * - * @hide - */ -public class ActivityChooserModel extends DataSetObservable { - - /** - * Client that utilizes an {@link ActivityChooserModel}. - */ - public interface ActivityChooserModelClient { - - /** - * Sets the {@link ActivityChooserModel}. - * - * @param dataModel The model. - */ - public void setActivityChooserModel(ActivityChooserModel dataModel); - } - - /** - * Defines a sorter that is responsible for sorting the activities - * based on the provided historical choices and an intent. - */ - public interface ActivitySorter { - - /** - * Sorts the activities in descending order of relevance - * based on previous history and an intent. - * - * @param intent The {@link Intent}. - * @param activities Activities to be sorted. - * @param historicalRecords Historical records. - */ - // 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 activities, - List historicalRecords); - } - - /** - * Listener for choosing an activity. - */ - public interface OnChooseActivityListener { - - /** - * Called when an activity has been chosen. The client can decide whether - * an activity can be chosen and if so the caller of - * {@link ActivityChooserModel#chooseActivity(int)} will receive and {@link Intent} - * for launching it. - *

- * Note: Modifying the intent is not permitted and - * any changes to the latter will be ignored. - *

- * - * @param host The listener's host model. - * @param intent The intent for launching the chosen activity. - * @return Whether the intent is handled and should not be delivered to clients. - * - * @see ActivityChooserModel#chooseActivity(int) - */ - public boolean onChooseActivity(ActivityChooserModel host, Intent intent); - } - - /** - * Flag for selecting debug mode. - */ - private static final boolean DEBUG = false; - - /** - * Tag used for logging. - */ - private static final String LOG_TAG = ActivityChooserModel.class.getSimpleName(); - - /** - * The root tag in the history file. - */ - private static final String TAG_HISTORICAL_RECORDS = "historical-records"; - - /** - * The tag for a record in the history file. - */ - private static final String TAG_HISTORICAL_RECORD = "historical-record"; - - /** - * Attribute for the activity. - */ - private static final String ATTRIBUTE_ACTIVITY = "activity"; - - /** - * Attribute for the choice time. - */ - private static final String ATTRIBUTE_TIME = "time"; - - /** - * Attribute for the choice weight. - */ - private static final String ATTRIBUTE_WEIGHT = "weight"; - - /** - * The default name of the choice history file. - */ - public static final String DEFAULT_HISTORY_FILE_NAME = - "activity_choser_model_history.xml"; - - /** - * The default maximal length of the choice history. - */ - public static final int DEFAULT_HISTORY_MAX_LENGTH = 50; - - /** - * The amount with which to inflate a chosen activity when set as default. - */ - private static final int DEFAULT_ACTIVITY_INFLATION = 5; - - /** - * Default weight for a choice record. - */ - private static final float DEFAULT_HISTORICAL_RECORD_WEIGHT = 1.0f; - - /** - * The extension of the history file. - */ - private static final String HISTORY_FILE_EXTENSION = ".xml"; - - /** - * An invalid item index. - */ - private static final int INVALID_INDEX = -1; - - /** - * Lock to guard the model registry. - */ - private static final Object sRegistryLock = new Object(); - - /** - * This the registry for data models. - */ - private static final Map sDataModelRegistry = - new HashMap(); - - /** - * Lock for synchronizing on this instance. - */ - private final Object mInstanceLock = new Object(); - - /** - * List of activities that can handle the current intent. - */ - private final List mActivities = new ArrayList(); - - /** - * List with historical choice records. - */ - private final List mHistoricalRecords = new ArrayList(); - - /** - * Monitor for added and removed packages. - */ - /** - * Mozilla: Not needed for the application. - */ - //private final PackageMonitor mPackageMonitor = new DataModelPackageMonitor(); - - /** - * Context for accessing resources. - */ - private final Context mContext; - - /** - * The name of the history file that backs this model. - */ - private final String mHistoryFileName; - - /** - * The intent for which a activity is being chosen. - */ - private Intent mIntent; - - /** - * The sorter for ordering activities based on intent and past choices. - */ - private ActivitySorter mActivitySorter = new DefaultSorter(); - - /** - * The maximal length of the choice history. - */ - private int mHistoryMaxSize = DEFAULT_HISTORY_MAX_LENGTH; - - /** - * Flag whether choice history can be read. In general many clients can - * share the same data model and {@link #readHistoricalDataIfNeeded()} may be called - * by arbitrary of them any number of times. Therefore, this class guarantees - * that the very first read succeeds and subsequent reads can be performed - * only after a call to {@link #persistHistoricalDataIfNeeded()} followed by change - * of the share records. - */ - private boolean mCanReadHistoricalData = true; - - /** - * Flag whether the choice history was read. This is used to enforce that - * before calling {@link #persistHistoricalDataIfNeeded()} a call to - * {@link #persistHistoricalDataIfNeeded()} has been made. This aims to avoid a - * scenario in which a choice history file exits, it is not read yet and - * it is overwritten. Note that always all historical records are read in - * full and the file is rewritten. This is necessary since we need to - * purge old records that are outside of the sliding window of past choices. - */ - private boolean mReadShareHistoryCalled = false; - - /** - * Flag whether the choice records have changed. In general many clients can - * share the same data model and {@link #persistHistoricalDataIfNeeded()} may be called - * by arbitrary of them any number of times. Therefore, this class guarantees - * that choice history will be persisted only if it has changed. - */ - private boolean mHistoricalRecordsChanged = true; - - /** - * Flag whether to reload the activities for the current intent. - */ - private boolean mReloadActivities = false; - - /** - * Policy for controlling how the model handles chosen activities. - */ - private OnChooseActivityListener mActivityChoserModelPolicy; - - /** - * Gets the data model backed by the contents of the provided file with historical data. - * Note that only one data model is backed by a given file, thus multiple calls with - * the same file name will return the same model instance. If no such instance is present - * it is created. - *

- * Note: To use the default historical data file clients should explicitly - * pass as file name {@link #DEFAULT_HISTORY_FILE_NAME}. If no persistence of the choice - * history is desired clients should pass null for the file name. In such - * case a new model is returned for each invocation. - *

- * - *

- * Always use difference historical data files for semantically different actions. - * For example, sharing is different from importing. - *

- * - * @param context Context for loading resources. - * @param historyFileName File name with choice history, null - * if the model should not be backed by a file. In this case the activities - * will be ordered only by data from the current session. - * - * @return The model. - */ - public static ActivityChooserModel get(Context context, String historyFileName) { - synchronized (sRegistryLock) { - ActivityChooserModel dataModel = sDataModelRegistry.get(historyFileName); - if (dataModel == null) { - dataModel = new ActivityChooserModel(context, historyFileName); - sDataModelRegistry.put(historyFileName, dataModel); - } - return dataModel; - } - } - - /** - * Creates a new instance. - * - * @param context Context for loading resources. - * @param historyFileName The history XML file. - */ - private ActivityChooserModel(Context context, String historyFileName) { - mContext = context.getApplicationContext(); - if (!TextUtils.isEmpty(historyFileName) - && !historyFileName.endsWith(HISTORY_FILE_EXTENSION)) { - mHistoryFileName = historyFileName + HISTORY_FILE_EXTENSION; - } else { - mHistoryFileName = historyFileName; - } - - /** - * Mozilla: Not needed for the application. - */ - //mPackageMonitor.register(mContext, null, true); - } - - /** - * Sets an intent for which to choose a activity. - *

- * Note: Clients must set only semantically similar - * intents for each data model. - *

- * - * @param intent The intent. - */ - public void setIntent(Intent intent) { - synchronized (mInstanceLock) { - if (mIntent == intent) { - return; - } - mIntent = intent; - mReloadActivities = true; - ensureConsistentState(); - } - } - - /** - * Gets the intent for which a activity is being chosen. - * - * @return The intent. - */ - public Intent getIntent() { - synchronized (mInstanceLock) { - return mIntent; - } - } - - /** - * Gets the number of activities that can handle the intent. - * - * @return The activity count. - * - * @see #setIntent(Intent) - */ - public int getActivityCount() { - synchronized (mInstanceLock) { - ensureConsistentState(); - return mActivities.size(); - } - } - - /** - * Gets an activity at a given index. - * - * @return The activity. - * - * @see ActivityResolveInfo - * @see #setIntent(Intent) - */ - public ResolveInfo getActivity(int index) { - synchronized (mInstanceLock) { - ensureConsistentState(); - return mActivities.get(index).resolveInfo; - } - } - - /** - * Gets the index of a the given activity. - * - * @param activity The activity index. - * - * @return The index if found, -1 otherwise. - */ - public int getActivityIndex(ResolveInfo activity) { - synchronized (mInstanceLock) { - ensureConsistentState(); - List activities = mActivities; - final int activityCount = activities.size(); - for (int i = 0; i < activityCount; i++) { - ActivityResolveInfo currentActivity = activities.get(i); - if (currentActivity.resolveInfo == activity) { - return i; - } - } - return INVALID_INDEX; - } - } - - /** - * Chooses a activity to handle the current intent. This will result in - * adding a historical record for that action and construct intent with - * its component name set such that it can be immediately started by the - * client. - *

- * Note: By calling this method the client guarantees - * that the returned intent will be started. This intent is returned to - * the client solely to let additional customization before the start. - *

- * - * @return An {@link Intent} for launching the activity or null if the - * policy has consumed the intent or there is not current intent - * set via {@link #setIntent(Intent)}. - * - * @see HistoricalRecord - * @see OnChooseActivityListener - */ - public Intent chooseActivity(int index) { - synchronized (mInstanceLock) { - if (mIntent == null) { - return null; - } - - ensureConsistentState(); - - ActivityResolveInfo chosenActivity = mActivities.get(index); - - ComponentName chosenName = new ComponentName( - chosenActivity.resolveInfo.activityInfo.packageName, - chosenActivity.resolveInfo.activityInfo.name); - - Intent choiceIntent = new Intent(mIntent); - choiceIntent.setComponent(chosenName); - - if (mActivityChoserModelPolicy != null) { - // Do not allow the policy to change the intent. - Intent choiceIntentCopy = new Intent(choiceIntent); - final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this, - choiceIntentCopy); - if (handled) { - return null; - } - } - - HistoricalRecord historicalRecord = new HistoricalRecord(chosenName, - System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT); - addHisoricalRecord(historicalRecord); - - return choiceIntent; - } - } - - /** - * Sets the listener for choosing an activity. - * - * @param listener The listener. - */ - public void setOnChooseActivityListener(OnChooseActivityListener listener) { - synchronized (mInstanceLock) { - mActivityChoserModelPolicy = listener; - } - } - - /** - * Gets the default activity, The default activity is defined as the one - * with highest rank i.e. the first one in the list of activities that can - * handle the intent. - * - * @return The default activity, null id not activities. - * - * @see #getActivity(int) - */ - public ResolveInfo getDefaultActivity() { - synchronized (mInstanceLock) { - ensureConsistentState(); - if (!mActivities.isEmpty()) { - return mActivities.get(0).resolveInfo; - } - } - return null; - } - - /** - * Sets the default activity. The default activity is set by adding a - * historical record with weight high enough that this activity will - * become the highest ranked. Such a strategy guarantees that the default - * will eventually change if not used. Also the weight of the record for - * setting a default is inflated with a constant amount to guarantee that - * it will stay as default for awhile. - * - * @param index The index of the activity to set as default. - */ - public void setDefaultActivity(int index) { - synchronized (mInstanceLock) { - ensureConsistentState(); - - ActivityResolveInfo newDefaultActivity = mActivities.get(index); - ActivityResolveInfo oldDefaultActivity = mActivities.get(0); - - final float weight; - if (oldDefaultActivity != null) { - // Add a record with weight enough to boost the chosen at the top. - weight = oldDefaultActivity.weight - newDefaultActivity.weight - + DEFAULT_ACTIVITY_INFLATION; - } else { - weight = DEFAULT_HISTORICAL_RECORD_WEIGHT; - } - - ComponentName defaultName = new ComponentName( - newDefaultActivity.resolveInfo.activityInfo.packageName, - newDefaultActivity.resolveInfo.activityInfo.name); - HistoricalRecord historicalRecord = new HistoricalRecord(defaultName, - System.currentTimeMillis(), weight); - addHisoricalRecord(historicalRecord); - } - } - - /** - * Persists the history data to the backing file if the latter - * was provided. Calling this method before a call to {@link #readHistoricalDataIfNeeded()} - * throws an exception. Calling this method more than one without choosing an - * activity has not effect. - * - * @throws IllegalStateException If this method is called before a call to - * {@link #readHistoricalDataIfNeeded()}. - */ - private void persistHistoricalDataIfNeeded() { - if (!mReadShareHistoryCalled) { - throw new IllegalStateException("No preceding call to #readHistoricalData"); - } - if (!mHistoricalRecordsChanged) { - return; - } - mHistoricalRecordsChanged = false; - if (!TextUtils.isEmpty(mHistoryFileName)) { - new PersistHistoryAsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, - new ArrayList(mHistoricalRecords), mHistoryFileName); - } - } - - /** - * Sets the sorter for ordering activities based on historical data and an intent. - * - * @param activitySorter The sorter. - * - * @see ActivitySorter - */ - public void setActivitySorter(ActivitySorter activitySorter) { - synchronized (mInstanceLock) { - if (mActivitySorter == activitySorter) { - return; - } - mActivitySorter = activitySorter; - if (sortActivitiesIfNeeded()) { - notifyChanged(); - } - } - } - - /** - * Sets the maximal size of the historical data. Defaults to - * {@link #DEFAULT_HISTORY_MAX_LENGTH} - *

- * Note: Setting this property will immediately - * enforce the specified max history size by dropping enough old - * historical records to enforce the desired size. Thus, any - * records that exceed the history size will be discarded and - * irreversibly lost. - *

- * - * @param historyMaxSize The max history size. - */ - public void setHistoryMaxSize(int historyMaxSize) { - synchronized (mInstanceLock) { - if (mHistoryMaxSize == historyMaxSize) { - return; - } - mHistoryMaxSize = historyMaxSize; - pruneExcessiveHistoricalRecordsIfNeeded(); - if (sortActivitiesIfNeeded()) { - notifyChanged(); - } - } - } - - /** - * Gets the history max size. - * - * @return The history max size. - */ - public int getHistoryMaxSize() { - synchronized (mInstanceLock) { - return mHistoryMaxSize; - } - } - - /** - * Gets the history size. - * - * @return The history size. - */ - public int getHistorySize() { - synchronized (mInstanceLock) { - ensureConsistentState(); - return mHistoricalRecords.size(); - } - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - - /** - * Mozilla: Not needed for the application. - */ - //mPackageMonitor.unregister(); - } - - /** - * Ensures the model is in a consistent state which is the - * activities for the current intent have been loaded, the - * most recent history has been read, and the activities - * are sorted. - */ - private void ensureConsistentState() { - boolean stateChanged = loadActivitiesIfNeeded(); - stateChanged |= readHistoricalDataIfNeeded(); - pruneExcessiveHistoricalRecordsIfNeeded(); - if (stateChanged) { - sortActivitiesIfNeeded(); - notifyChanged(); - } - } - - /** - * Sorts the activities if necessary which is if there is a - * sorter, there are some activities to sort, and there is some - * historical data. - * - * @return Whether sorting was performed. - */ - private boolean sortActivitiesIfNeeded() { - if (mActivitySorter != null && mIntent != null - && !mActivities.isEmpty() && !mHistoricalRecords.isEmpty()) { - mActivitySorter.sort(mIntent, mActivities, - Collections.unmodifiableList(mHistoricalRecords)); - return true; - } - return false; - } - - /** - * Loads the activities for the current intent if needed which is - * if they are not already loaded for the current intent. - * - * @return Whether loading was performed. - */ - private boolean loadActivitiesIfNeeded() { - if (mReloadActivities && mIntent != null) { - mReloadActivities = false; - mActivities.clear(); - List resolveInfos = mContext.getPackageManager() - .queryIntentActivities(mIntent, 0); - final int resolveInfoCount = resolveInfos.size(); - for (int i = 0; i < resolveInfoCount; i++) { - ResolveInfo resolveInfo = resolveInfos.get(i); - mActivities.add(new ActivityResolveInfo(resolveInfo)); - } - return true; - } - return false; - } - - /** - * Reads the historical data if necessary which is it has - * changed, there is a history file, and there is not persist - * in progress. - * - * @return Whether reading was performed. - */ - private boolean readHistoricalDataIfNeeded() { - if (mCanReadHistoricalData && mHistoricalRecordsChanged && - !TextUtils.isEmpty(mHistoryFileName)) { - mCanReadHistoricalData = false; - mReadShareHistoryCalled = true; - readHistoricalDataImpl(); - return true; - } - return false; - } - - /** - * Adds a historical record. - * - * @param historicalRecord The record to add. - * @return True if the record was added. - */ - private boolean addHisoricalRecord(HistoricalRecord historicalRecord) { - final boolean added = mHistoricalRecords.add(historicalRecord); - if (added) { - mHistoricalRecordsChanged = true; - pruneExcessiveHistoricalRecordsIfNeeded(); - persistHistoricalDataIfNeeded(); - sortActivitiesIfNeeded(); - notifyChanged(); - } - return added; - } - - /** - * Prunes older excessive records to guarantee maxHistorySize. - */ - private void pruneExcessiveHistoricalRecordsIfNeeded() { - final int pruneCount = mHistoricalRecords.size() - mHistoryMaxSize; - if (pruneCount <= 0) { - return; - } - mHistoricalRecordsChanged = true; - for (int i = 0; i < pruneCount; i++) { - HistoricalRecord prunedRecord = mHistoricalRecords.remove(0); - if (DEBUG) { - Log.i(LOG_TAG, "Pruned: " + prunedRecord); - } - } - } - - /** - * Represents a record in the history. - */ - public final static class HistoricalRecord { - - /** - * The activity name. - */ - public final ComponentName activity; - - /** - * The choice time. - */ - public final long time; - - /** - * The record weight. - */ - public final float weight; - - /** - * Creates a new instance. - * - * @param activityName The activity component name flattened to string. - * @param time The time the activity was chosen. - * @param weight The weight of the record. - */ - public HistoricalRecord(String activityName, long time, float weight) { - this(ComponentName.unflattenFromString(activityName), time, weight); - } - - /** - * Creates a new instance. - * - * @param activityName The activity name. - * @param time The time the activity was chosen. - * @param weight The weight of the record. - */ - public HistoricalRecord(ComponentName activityName, long time, float weight) { - this.activity = activityName; - this.time = time; - this.weight = weight; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((activity == null) ? 0 : activity.hashCode()); - result = prime * result + (int) (time ^ (time >>> 32)); - result = prime * result + Float.floatToIntBits(weight); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - HistoricalRecord other = (HistoricalRecord) obj; - if (activity == null) { - if (other.activity != null) { - return false; - } - } else if (!activity.equals(other.activity)) { - return false; - } - if (time != other.time) { - return false; - } - if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("["); - builder.append("; activity:").append(activity); - builder.append("; time:").append(time); - builder.append("; weight:").append(new BigDecimal(weight)); - builder.append("]"); - return builder.toString(); - } - } - - /** - * Represents an activity. - */ - public final class ActivityResolveInfo implements Comparable { - - /** - * The {@link ResolveInfo} of the activity. - */ - public final ResolveInfo resolveInfo; - - /** - * Weight of the activity. Useful for sorting. - */ - public float weight; - - /** - * Creates a new instance. - * - * @param resolveInfo activity {@link ResolveInfo}. - */ - public ActivityResolveInfo(ResolveInfo resolveInfo) { - this.resolveInfo = resolveInfo; - } - - @Override - public int hashCode() { - return 31 + Float.floatToIntBits(weight); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ActivityResolveInfo other = (ActivityResolveInfo) obj; - if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { - return false; - } - return true; - } - - public int compareTo(ActivityResolveInfo another) { - return Float.floatToIntBits(another.weight) - Float.floatToIntBits(weight); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("["); - builder.append("resolveInfo:").append(resolveInfo.toString()); - builder.append("; weight:").append(new BigDecimal(weight)); - builder.append("]"); - return builder.toString(); - } - } - - /** - * Default activity sorter implementation. - */ - private final class DefaultSorter implements ActivitySorter { - private static final float WEIGHT_DECAY_COEFFICIENT = 0.95f; - - private final Map mPackageNameToActivityMap = - new HashMap(); - - public void sort(Intent intent, List activities, - List historicalRecords) { - Map packageNameToActivityMap = - mPackageNameToActivityMap; - packageNameToActivityMap.clear(); - - final int activityCount = activities.size(); - for (int i = 0; i < activityCount; i++) { - ActivityResolveInfo activity = activities.get(i); - activity.weight = 0.0f; - String packageName = activity.resolveInfo.activityInfo.packageName; - packageNameToActivityMap.put(packageName, activity); - } - - final int lastShareIndex = historicalRecords.size() - 1; - float nextRecordWeight = 1; - for (int i = lastShareIndex; i >= 0; i--) { - HistoricalRecord historicalRecord = historicalRecords.get(i); - String packageName = historicalRecord.activity.getPackageName(); - ActivityResolveInfo activity = packageNameToActivityMap.get(packageName); - if (activity != null) { - activity.weight += historicalRecord.weight * nextRecordWeight; - nextRecordWeight = nextRecordWeight * WEIGHT_DECAY_COEFFICIENT; - } - } - - Collections.sort(activities); - - if (DEBUG) { - for (int i = 0; i < activityCount; i++) { - Log.i(LOG_TAG, "Sorted: " + activities.get(i)); - } - } - } - } - - /** - * Command for reading the historical records from a file off the UI thread. - */ - private void readHistoricalDataImpl() { - FileInputStream fis = null; - try { - fis = mContext.openFileInput(mHistoryFileName); - } catch (FileNotFoundException fnfe) { - if (DEBUG) { - Log.i(LOG_TAG, "Could not open historical records file: " + mHistoryFileName); - } - return; - } - try { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(fis, null); - - int type = XmlPullParser.START_DOCUMENT; - while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { - type = parser.next(); - } - - if (!TAG_HISTORICAL_RECORDS.equals(parser.getName())) { - throw new XmlPullParserException("Share records file does not start with " - + TAG_HISTORICAL_RECORDS + " tag."); - } - - List historicalRecords = mHistoricalRecords; - historicalRecords.clear(); - - while (true) { - type = parser.next(); - if (type == XmlPullParser.END_DOCUMENT) { - break; - } - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - String nodeName = parser.getName(); - if (!TAG_HISTORICAL_RECORD.equals(nodeName)) { - throw new XmlPullParserException("Share records file not well-formed."); - } - - String activity = parser.getAttributeValue(null, ATTRIBUTE_ACTIVITY); - final long time = - Long.parseLong(parser.getAttributeValue(null, ATTRIBUTE_TIME)); - final float weight = - Float.parseFloat(parser.getAttributeValue(null, ATTRIBUTE_WEIGHT)); - HistoricalRecord readRecord = new HistoricalRecord(activity, time, weight); - historicalRecords.add(readRecord); - - if (DEBUG) { - Log.i(LOG_TAG, "Read " + readRecord.toString()); - } - } - - if (DEBUG) { - Log.i(LOG_TAG, "Read " + historicalRecords.size() + " historical records."); - } - } catch (XmlPullParserException xppe) { - Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, xppe); - } catch (IOException ioe) { - Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, ioe); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException ioe) { - /* ignore */ - } - } - } - } - - /** - * Command for persisting the historical records to a file off the UI thread. - */ - private final class PersistHistoryAsyncTask extends AsyncTask { - - @Override - @SuppressWarnings("unchecked") - public Void doInBackground(Object... args) { - List historicalRecords = (List) args[0]; - String hostoryFileName = (String) args[1]; - - FileOutputStream fos = null; - - try { - fos = mContext.openFileOutput(hostoryFileName, Context.MODE_PRIVATE); - } catch (FileNotFoundException fnfe) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + hostoryFileName, fnfe); - return null; - } - - XmlSerializer serializer = Xml.newSerializer(); - - try { - serializer.setOutput(fos, null); - serializer.startDocument("UTF-8", true); - serializer.startTag(null, TAG_HISTORICAL_RECORDS); - - final int recordCount = historicalRecords.size(); - for (int i = 0; i < recordCount; i++) { - HistoricalRecord record = historicalRecords.remove(0); - serializer.startTag(null, TAG_HISTORICAL_RECORD); - serializer.attribute(null, ATTRIBUTE_ACTIVITY, - record.activity.flattenToString()); - serializer.attribute(null, ATTRIBUTE_TIME, String.valueOf(record.time)); - serializer.attribute(null, ATTRIBUTE_WEIGHT, String.valueOf(record.weight)); - serializer.endTag(null, TAG_HISTORICAL_RECORD); - if (DEBUG) { - Log.i(LOG_TAG, "Wrote " + record.toString()); - } - } - - serializer.endTag(null, TAG_HISTORICAL_RECORDS); - serializer.endDocument(); - - if (DEBUG) { - Log.i(LOG_TAG, "Wrote " + recordCount + " historical records."); - } - } catch (IllegalArgumentException iae) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, iae); - } catch (IllegalStateException ise) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ise); - } catch (IOException ioe) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ioe); - } finally { - mCanReadHistoricalData = true; - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - /* ignore */ - } - } - } - return null; - } - } - - /** - * Keeps in sync the historical records and activities with the installed applications. - */ - /** - * Mozilla: Not needed for the application. - */ - /* - private final class DataModelPackageMonitor extends PackageMonitor { - - @Override - public void onSomePackagesChanged() { - mReloadActivities = true; - } - } - */ -} - diff --git a/mobile/android/base/widget/GeckoActionProvider.java b/mobile/android/base/widget/GeckoActionProvider.java deleted file mode 100644 index f700e63bc385..000000000000 --- a/mobile/android/base/widget/GeckoActionProvider.java +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.widget; - -import org.mozilla.gecko.menu.MenuItemActionView; - -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.view.ActionProvider; -import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; -import android.view.SubMenu; -import android.view.View; -import android.view.View.OnClickListener; - -public class GeckoActionProvider extends ActionProvider { - - /** - * A listener to know when a target was selected. - * When setting a provider, the activity can listen to this, - * to close the menu. - */ - public interface OnTargetSelectedListener { - public void onTargetSelected(); - } - - private final Context mContext; - - public static final String DEFAULT_HISTORY_FILE_NAME = "history.xml"; - - // History file. - private String mHistoryFileName = DEFAULT_HISTORY_FILE_NAME; - - private OnTargetSelectedListener mOnTargetListener; - - private final Callbacks mCallbacks = new Callbacks(); - - public GeckoActionProvider(Context context) { - super(context); - mContext = context; - } - - @Override - public View onCreateActionView() { - // Create the view and set its data model. - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName); - MenuItemActionView view = new MenuItemActionView(mContext, null); - view.setActionButtonClickListener(mCallbacks); - - PackageManager packageManager = mContext.getPackageManager(); - ResolveInfo defaultActivity = dataModel.getDefaultActivity(); - view.setActionButton(defaultActivity == null ? null : defaultActivity.loadIcon(packageManager)); - - return view; - } - - @Override - public View onCreateActionView(MenuItem item) { - MenuItemActionView view = (MenuItemActionView) onCreateActionView(); - view.setId(item.getItemId()); - view.setTitle(item.getTitle()); - view.setIcon(item.getIcon()); - view.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE); - view.setEnabled(item.isEnabled()); - return view; - } - - public View getView(MenuItem item) { - return onCreateActionView(item); - } - - @Override - public boolean hasSubMenu() { - return true; - } - - @Override - public void onPrepareSubMenu(SubMenu subMenu) { - // Clear since the order of items may change. - subMenu.clear(); - - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName); - PackageManager packageManager = mContext.getPackageManager(); - - // Populate the sub-menu with a sub set of the activities. - for (int i = 0; i < dataModel.getActivityCount(); i++) { - ResolveInfo activity = dataModel.getActivity(i); - subMenu.add(0, i, i, activity.loadLabel(packageManager)) - .setIcon(activity.loadIcon(packageManager)) - .setOnMenuItemClickListener(mCallbacks); - } - } - - public void setHistoryFileName(String historyFile) { - mHistoryFileName = historyFile; - } - - public void setIntent(Intent intent) { - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName); - dataModel.setIntent(intent); - } - - public void setOnTargetSelectedListener(OnTargetSelectedListener listener) { - mOnTargetListener = listener; - } - - /** - * Listener for handling default activity / menu item clicks. - */ - private class Callbacks implements OnMenuItemClickListener, - OnClickListener { - private void chooseActivity(int index) { - if (mOnTargetListener != null) - mOnTargetListener.onTargetSelected(); - - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName); - Intent launchIntent = dataModel.chooseActivity(index); - if (launchIntent != null) { - launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - mContext.startActivity(launchIntent); - } - } - - @Override - public boolean onMenuItemClick(MenuItem item) { - chooseActivity(item.getItemId()); - return true; - } - - @Override - public void onClick(View view) { - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName); - chooseActivity(dataModel.getActivityIndex(dataModel.getDefaultActivity())); - } - } -} -