summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/prompts/IntentChooserPrompt.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/base/java/org/mozilla/gecko/prompts/IntentChooserPrompt.java')
-rw-r--r--mobile/android/base/java/org/mozilla/gecko/prompts/IntentChooserPrompt.java158
1 files changed, 158 insertions, 0 deletions
diff --git a/mobile/android/base/java/org/mozilla/gecko/prompts/IntentChooserPrompt.java b/mobile/android/base/java/org/mozilla/gecko/prompts/IntentChooserPrompt.java
new file mode 100644
index 000000000..502f1156d
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/prompts/IntentChooserPrompt.java
@@ -0,0 +1,158 @@
+/* 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.prompts;
+
+import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.util.ThreadUtils;
+import org.mozilla.gecko.widget.GeckoActionProvider;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.widget.ListView;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Shows a prompt letting the user pick from a list of intent handlers for a set of Intents or
+ * for a GeckoActionProvider. Basic usage:
+ * IntentChooserPrompt prompt = new IntentChooserPrompt(context, new Intent[] {
+ * ... // some intents
+ * });
+ * prompt.show("Title", context, new IntentHandler() {
+ * public void onIntentSelected(Intent intent, int position) { }
+ * public void onCancelled() { }
+ * });
+ **/
+public class IntentChooserPrompt {
+ private static final String LOGTAG = "GeckoIntentChooser";
+
+ private final ArrayList<PromptListItem> mItems;
+
+ public IntentChooserPrompt(Context context, Intent[] intents) {
+ mItems = getItems(context, intents);
+ }
+
+ public IntentChooserPrompt(Context context, GeckoActionProvider provider) {
+ mItems = getItems(context, provider);
+ }
+
+ /* If an IntentHandler is passed in, will asynchronously call the handler when the dialog is closed
+ * Otherwise, will return the Intent that was chosen by the user. Must be called on the UI thread.
+ */
+ public void show(final String title, final Context context, final IntentHandler handler) {
+ ThreadUtils.assertOnUiThread();
+
+ if (mItems.isEmpty()) {
+ Log.i(LOGTAG, "No activities for the intent chooser!");
+ handler.onCancelled();
+ return;
+ }
+
+ // If there's only one item in the intent list, just return it
+ if (mItems.size() == 1) {
+ handler.onIntentSelected(mItems.get(0).getIntent(), 0);
+ return;
+ }
+
+ final Prompt prompt = new Prompt(context, new Prompt.PromptCallback() {
+ @Override
+ public void onPromptFinished(String promptServiceResult) {
+ if (handler == null) {
+ return;
+ }
+
+ int itemId = -1;
+ try {
+ itemId = new JSONObject(promptServiceResult).getInt("button");
+ } catch (JSONException e) {
+ Log.e(LOGTAG, "result from promptservice was invalid: ", e);
+ }
+
+ if (itemId == -1) {
+ handler.onCancelled();
+ } else {
+ handler.onIntentSelected(mItems.get(itemId).getIntent(), itemId);
+ }
+ }
+ });
+
+ PromptListItem[] arrays = new PromptListItem[mItems.size()];
+ mItems.toArray(arrays);
+ prompt.show(title, "", arrays, ListView.CHOICE_MODE_NONE);
+
+ return;
+ }
+
+ // Whether or not any activities were found. Useful for checking if you should try a different Intent set
+ public boolean hasActivities(Context context) {
+ return mItems.isEmpty();
+ }
+
+ // Gets a list of PromptListItems for an Intent array
+ private ArrayList<PromptListItem> getItems(final Context context, Intent[] intents) {
+ final ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
+
+ // If we have intents, use them to build the initial list
+ for (final Intent intent : intents) {
+ items.addAll(getItemsForIntent(context, intent));
+ }
+
+ return items;
+ }
+
+ // Gets a list of PromptListItems for a GeckoActionProvider
+ private ArrayList<PromptListItem> getItems(final Context context, final GeckoActionProvider provider) {
+ final ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
+
+ // Add any intents from the provider.
+ final PackageManager packageManager = context.getPackageManager();
+ final ArrayList<ResolveInfo> infos = provider.getSortedActivities();
+
+ for (final ResolveInfo info : infos) {
+ items.add(getItemForResolveInfo(info, packageManager, provider.getIntent()));
+ }
+
+ return items;
+ }
+
+ private PromptListItem getItemForResolveInfo(ResolveInfo info, PackageManager pm, Intent intent) {
+ PromptListItem item = new PromptListItem(info.loadLabel(pm).toString());
+ item.setIcon(info.loadIcon(pm));
+
+ Intent i = new Intent(intent);
+ // These intents should be implicit.
+ i.setComponent(new ComponentName(info.activityInfo.applicationInfo.packageName,
+ info.activityInfo.name));
+ item.setIntent(new Intent(i));
+
+ return item;
+ }
+
+ private ArrayList<PromptListItem> getItemsForIntent(Context context, Intent intent) {
+ ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> lri = pm.queryIntentActivityOptions(GeckoAppShell.getGeckoInterface().getActivity().getComponentName(), null, intent, 0);
+
+ // If we didn't find any activities, just return the empty list
+ if (lri == null) {
+ return items;
+ }
+
+ // Otherwise, convert the ResolveInfo. Note we don't currently check for duplicates here.
+ for (ResolveInfo ri : lri) {
+ items.add(getItemForResolveInfo(ri, pm, intent));
+ }
+
+ return items;
+ }
+}