mobile/android/base/prompts/IntentChooserPrompt.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 package org.mozilla.gecko.prompts;
michael@0 6
michael@0 7 import org.mozilla.gecko.GeckoAppShell;
michael@0 8 import org.mozilla.gecko.util.ThreadUtils;
michael@0 9 import org.mozilla.gecko.widget.GeckoActionProvider;
michael@0 10
michael@0 11 import android.app.Activity;
michael@0 12 import android.content.ComponentName;
michael@0 13 import android.content.Context;
michael@0 14 import android.content.Intent;
michael@0 15 import android.content.pm.PackageManager;
michael@0 16 import android.content.pm.ResolveInfo;
michael@0 17 import android.widget.ListView;
michael@0 18 import android.util.Log;
michael@0 19
michael@0 20 import org.json.JSONException;
michael@0 21 import org.json.JSONObject;
michael@0 22
michael@0 23 import java.util.ArrayList;
michael@0 24 import java.util.List;
michael@0 25
michael@0 26 /**
michael@0 27 * Shows a prompt letting the user pick from a list of intent handlers for a set of Intents or
michael@0 28 * for a GeckoActionProvider. Basic usage:
michael@0 29 * IntentChooserPrompt prompt = new IntentChooserPrompt(context, new Intent[] {
michael@0 30 * ... // some intents
michael@0 31 * });
michael@0 32 * prompt.show("Title", context, new IntentHandler() {
michael@0 33 * public void onIntentSelected(Intent intent, int position) { }
michael@0 34 * public void onCancelled() { }
michael@0 35 * });
michael@0 36 **/
michael@0 37 public class IntentChooserPrompt {
michael@0 38 private static final String LOGTAG = "GeckoIntentChooser";
michael@0 39
michael@0 40 private final ArrayList<PromptListItem> mItems;
michael@0 41
michael@0 42 public IntentChooserPrompt(Context context, Intent[] intents) {
michael@0 43 mItems = getItems(context, intents);
michael@0 44 }
michael@0 45
michael@0 46 public IntentChooserPrompt(Context context, GeckoActionProvider provider) {
michael@0 47 mItems = getItems(context, provider);
michael@0 48 }
michael@0 49
michael@0 50 /* If an IntentHandler is passed in, will asynchronously call the handler when the dialog is closed
michael@0 51 * Otherwise, will return the Intent that was chosen by the user. Must be called on the UI thread.
michael@0 52 */
michael@0 53 public void show(final String title, final Context context, final IntentHandler handler) {
michael@0 54 ThreadUtils.assertOnUiThread();
michael@0 55
michael@0 56 if (mItems.isEmpty()) {
michael@0 57 Log.i(LOGTAG, "No activities for the intent chooser!");
michael@0 58 handler.onCancelled();
michael@0 59 return;
michael@0 60 }
michael@0 61
michael@0 62 // If there's only one item in the intent list, just return it
michael@0 63 if (mItems.size() == 1) {
michael@0 64 handler.onIntentSelected(mItems.get(0).getIntent(), 0);
michael@0 65 return;
michael@0 66 }
michael@0 67
michael@0 68 final Prompt prompt = new Prompt(context, new Prompt.PromptCallback() {
michael@0 69 @Override
michael@0 70 public void onPromptFinished(String promptServiceResult) {
michael@0 71 if (handler == null) {
michael@0 72 return;
michael@0 73 }
michael@0 74
michael@0 75 int itemId = -1;
michael@0 76 try {
michael@0 77 itemId = new JSONObject(promptServiceResult).getInt("button");
michael@0 78 } catch (JSONException e) {
michael@0 79 Log.e(LOGTAG, "result from promptservice was invalid: ", e);
michael@0 80 }
michael@0 81
michael@0 82 if (itemId == -1) {
michael@0 83 handler.onCancelled();
michael@0 84 } else {
michael@0 85 handler.onIntentSelected(mItems.get(itemId).getIntent(), itemId);
michael@0 86 }
michael@0 87 }
michael@0 88 });
michael@0 89
michael@0 90 PromptListItem[] arrays = new PromptListItem[mItems.size()];
michael@0 91 mItems.toArray(arrays);
michael@0 92 prompt.show(title, "", arrays, ListView.CHOICE_MODE_NONE);
michael@0 93
michael@0 94 return;
michael@0 95 }
michael@0 96
michael@0 97 // Whether or not any activities were found. Useful for checking if you should try a different Intent set
michael@0 98 public boolean hasActivities(Context context) {
michael@0 99 return mItems.isEmpty();
michael@0 100 }
michael@0 101
michael@0 102 // Gets a list of PromptListItems for an Intent array
michael@0 103 private ArrayList<PromptListItem> getItems(final Context context, Intent[] intents) {
michael@0 104 final ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
michael@0 105
michael@0 106 // If we have intents, use them to build the initial list
michael@0 107 for (final Intent intent : intents) {
michael@0 108 items.addAll(getItemsForIntent(context, intent));
michael@0 109 }
michael@0 110
michael@0 111 return items;
michael@0 112 }
michael@0 113
michael@0 114 // Gets a list of PromptListItems for a GeckoActionProvider
michael@0 115 private ArrayList<PromptListItem> getItems(final Context context, final GeckoActionProvider provider) {
michael@0 116 final ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
michael@0 117
michael@0 118 // Add any intents from the provider.
michael@0 119 final PackageManager packageManager = context.getPackageManager();
michael@0 120 final ArrayList<ResolveInfo> infos = provider.getSortedActivites();
michael@0 121
michael@0 122 for (final ResolveInfo info : infos) {
michael@0 123 items.add(getItemForResolveInfo(info, packageManager, provider.getIntent()));
michael@0 124 }
michael@0 125
michael@0 126 return items;
michael@0 127 }
michael@0 128
michael@0 129 private PromptListItem getItemForResolveInfo(ResolveInfo info, PackageManager pm, Intent intent) {
michael@0 130 PromptListItem item = new PromptListItem(info.loadLabel(pm).toString());
michael@0 131 item.setIcon(info.loadIcon(pm));
michael@0 132
michael@0 133 Intent i = new Intent(intent);
michael@0 134 // These intents should be implicit.
michael@0 135 i.setComponent(new ComponentName(info.activityInfo.applicationInfo.packageName,
michael@0 136 info.activityInfo.name));
michael@0 137 item.setIntent(new Intent(i));
michael@0 138
michael@0 139 return item;
michael@0 140 }
michael@0 141
michael@0 142 private ArrayList<PromptListItem> getItemsForIntent(Context context, Intent intent) {
michael@0 143 ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
michael@0 144 PackageManager pm = context.getPackageManager();
michael@0 145 List<ResolveInfo> lri = pm.queryIntentActivityOptions(GeckoAppShell.getGeckoInterface().getActivity().getComponentName(), null, intent, 0);
michael@0 146
michael@0 147 // If we didn't find any activities, just return the empty list
michael@0 148 if (lri == null) {
michael@0 149 return items;
michael@0 150 }
michael@0 151
michael@0 152 // Otherwise, convert the ResolveInfo. Note we don't currently check for duplicates here.
michael@0 153 for (ResolveInfo ri : lri) {
michael@0 154 items.add(getItemForResolveInfo(ri, pm, intent));
michael@0 155 }
michael@0 156
michael@0 157 return items;
michael@0 158 }
michael@0 159 }

mercurial