mobile/android/base/widget/GeckoActionProvider.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 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 package org.mozilla.gecko.widget;
michael@0 7
michael@0 8 import org.mozilla.gecko.GeckoAppShell;
michael@0 9 import org.mozilla.gecko.Telemetry;
michael@0 10 import org.mozilla.gecko.TelemetryContract;
michael@0 11 import org.mozilla.gecko.menu.MenuItemActionView;
michael@0 12 import org.mozilla.gecko.util.ThreadUtils;
michael@0 13
michael@0 14 import android.content.Context;
michael@0 15 import android.content.Intent;
michael@0 16 import android.content.pm.PackageManager;
michael@0 17 import android.content.pm.ResolveInfo;
michael@0 18 import android.graphics.drawable.Drawable;
michael@0 19 import android.view.MenuItem;
michael@0 20 import android.view.MenuItem.OnMenuItemClickListener;
michael@0 21 import android.view.SubMenu;
michael@0 22 import android.view.View;
michael@0 23 import android.view.View.OnClickListener;
michael@0 24 import android.text.TextUtils;
michael@0 25
michael@0 26 import java.util.ArrayList;
michael@0 27 import java.util.HashMap;
michael@0 28
michael@0 29 public class GeckoActionProvider {
michael@0 30 private static int MAX_HISTORY_SIZE = 2;
michael@0 31
michael@0 32 /**
michael@0 33 * A listener to know when a target was selected.
michael@0 34 * When setting a provider, the activity can listen to this,
michael@0 35 * to close the menu.
michael@0 36 */
michael@0 37 public interface OnTargetSelectedListener {
michael@0 38 public void onTargetSelected();
michael@0 39 }
michael@0 40
michael@0 41 private final Context mContext;
michael@0 42
michael@0 43 public final static String DEFAULT_MIME_TYPE = "text/plain";
michael@0 44
michael@0 45 public static final String DEFAULT_HISTORY_FILE_NAME = "history.xml";
michael@0 46
michael@0 47 // History file.
michael@0 48 private String mHistoryFileName = DEFAULT_HISTORY_FILE_NAME;
michael@0 49
michael@0 50 private OnTargetSelectedListener mOnTargetListener;
michael@0 51
michael@0 52 private final Callbacks mCallbacks = new Callbacks();
michael@0 53
michael@0 54 private static HashMap<String, GeckoActionProvider> mProviders = new HashMap<String, GeckoActionProvider>();
michael@0 55
michael@0 56 private static String getFilenameFromMimeType(String mimeType) {
michael@0 57 String[] mime = mimeType.split("/");
michael@0 58
michael@0 59 // All text mimetypes use the default provider
michael@0 60 if ("text".equals(mime[0])) {
michael@0 61 return DEFAULT_HISTORY_FILE_NAME;
michael@0 62 }
michael@0 63
michael@0 64 return "history-" + mime[0] + ".xml";
michael@0 65 }
michael@0 66
michael@0 67 // Gets the action provider for a particular mimetype
michael@0 68 public static GeckoActionProvider getForType(String mimeType, Context context) {
michael@0 69 if (!mProviders.keySet().contains(mimeType)) {
michael@0 70 GeckoActionProvider provider = new GeckoActionProvider(context);
michael@0 71
michael@0 72 // For empty types, we just return a default provider
michael@0 73 if (TextUtils.isEmpty(mimeType)) {
michael@0 74 return provider;
michael@0 75 }
michael@0 76
michael@0 77 provider.setHistoryFileName(getFilenameFromMimeType(mimeType));
michael@0 78 mProviders.put(mimeType, provider);
michael@0 79 }
michael@0 80 return mProviders.get(mimeType);
michael@0 81 }
michael@0 82
michael@0 83 public GeckoActionProvider(Context context) {
michael@0 84 mContext = context;
michael@0 85 }
michael@0 86
michael@0 87 public View onCreateActionView() {
michael@0 88 // Create the view and set its data model.
michael@0 89 ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
michael@0 90 MenuItemActionView view = new MenuItemActionView(mContext, null);
michael@0 91 view.addActionButtonClickListener(mCallbacks);
michael@0 92
michael@0 93 final PackageManager packageManager = mContext.getPackageManager();
michael@0 94 int historySize = dataModel.getDistinctActivityCountInHistory();
michael@0 95 if (historySize > MAX_HISTORY_SIZE) {
michael@0 96 historySize = MAX_HISTORY_SIZE;
michael@0 97 }
michael@0 98
michael@0 99 // Historical data is dependent on past selection of activities.
michael@0 100 // Activity count is determined by the number of activities that can handle
michael@0 101 // the particular intent. When no intent is set, the activity count is 0,
michael@0 102 // while the history count can be a valid number.
michael@0 103 if (historySize > dataModel.getActivityCount()) {
michael@0 104 return view;
michael@0 105 }
michael@0 106
michael@0 107 for (int i = 0; i < historySize; i++) {
michael@0 108 view.addActionButton(dataModel.getActivity(i).loadIcon(packageManager));
michael@0 109 }
michael@0 110
michael@0 111 return view;
michael@0 112 }
michael@0 113
michael@0 114 public View getView() {
michael@0 115 return onCreateActionView();
michael@0 116 }
michael@0 117
michael@0 118 public boolean hasSubMenu() {
michael@0 119 return true;
michael@0 120 }
michael@0 121
michael@0 122 public void onPrepareSubMenu(SubMenu subMenu) {
michael@0 123 // Clear since the order of items may change.
michael@0 124 subMenu.clear();
michael@0 125
michael@0 126 ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
michael@0 127 PackageManager packageManager = mContext.getPackageManager();
michael@0 128
michael@0 129 // Populate the sub-menu with a sub set of the activities.
michael@0 130 final int count = dataModel.getActivityCount();
michael@0 131 for (int i = 0; i < count; i++) {
michael@0 132 ResolveInfo activity = dataModel.getActivity(i);
michael@0 133 subMenu.add(0, i, i, activity.loadLabel(packageManager))
michael@0 134 .setIcon(activity.loadIcon(packageManager))
michael@0 135 .setOnMenuItemClickListener(mCallbacks);
michael@0 136 }
michael@0 137 }
michael@0 138
michael@0 139 public void setHistoryFileName(String historyFile) {
michael@0 140 mHistoryFileName = historyFile;
michael@0 141 }
michael@0 142
michael@0 143 public Intent getIntent() {
michael@0 144 ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
michael@0 145 return dataModel.getIntent();
michael@0 146 }
michael@0 147
michael@0 148 public void setIntent(Intent intent) {
michael@0 149 ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
michael@0 150 dataModel.setIntent(intent);
michael@0 151
michael@0 152 // Inform the target listener to refresh it's UI, if needed.
michael@0 153 if (mOnTargetListener != null) {
michael@0 154 mOnTargetListener.onTargetSelected();
michael@0 155 }
michael@0 156 }
michael@0 157
michael@0 158 public void setOnTargetSelectedListener(OnTargetSelectedListener listener) {
michael@0 159 mOnTargetListener = listener;
michael@0 160 }
michael@0 161
michael@0 162 public ArrayList<ResolveInfo> getSortedActivites() {
michael@0 163 ArrayList<ResolveInfo> infos = new ArrayList<ResolveInfo>();
michael@0 164
michael@0 165 ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
michael@0 166 PackageManager packageManager = mContext.getPackageManager();
michael@0 167
michael@0 168 // Populate the sub-menu with a sub set of the activities.
michael@0 169 final int count = dataModel.getActivityCount();
michael@0 170 for (int i = 0; i < count; i++) {
michael@0 171 infos.add(dataModel.getActivity(i));
michael@0 172 }
michael@0 173 return infos;
michael@0 174 }
michael@0 175
michael@0 176 public void chooseActivity(int position) {
michael@0 177 mCallbacks.chooseActivity(position);
michael@0 178 }
michael@0 179
michael@0 180 /**
michael@0 181 * Listener for handling default activity / menu item clicks.
michael@0 182 */
michael@0 183 private class Callbacks implements OnMenuItemClickListener,
michael@0 184 OnClickListener {
michael@0 185 private void chooseActivity(int index) {
michael@0 186 final ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
michael@0 187 final Intent launchIntent = dataModel.chooseActivity(index);
michael@0 188 if (launchIntent != null) {
michael@0 189 // This may cause a download to happen. Make sure we're on the background thread.
michael@0 190 ThreadUtils.postToBackgroundThread(new Runnable() {
michael@0 191 @Override
michael@0 192 public void run() {
michael@0 193 // Share image downloads the image before sharing it.
michael@0 194 String type = launchIntent.getType();
michael@0 195 if (Intent.ACTION_SEND.equals(launchIntent.getAction()) && type != null && type.startsWith("image/")) {
michael@0 196 GeckoAppShell.downloadImageForIntent(launchIntent);
michael@0 197 }
michael@0 198
michael@0 199 launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
michael@0 200 mContext.startActivity(launchIntent);
michael@0 201 }
michael@0 202 });
michael@0 203 }
michael@0 204
michael@0 205 if (mOnTargetListener != null) {
michael@0 206 mOnTargetListener.onTargetSelected();
michael@0 207 }
michael@0 208 }
michael@0 209
michael@0 210 @Override
michael@0 211 public boolean onMenuItemClick(MenuItem item) {
michael@0 212 chooseActivity(item.getItemId());
michael@0 213
michael@0 214 // Context: Sharing via chrome mainmenu list (no explicit session is active)
michael@0 215 Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST);
michael@0 216 return true;
michael@0 217 }
michael@0 218
michael@0 219 @Override
michael@0 220 public void onClick(View view) {
michael@0 221 Integer index = (Integer) view.getTag();
michael@0 222 chooseActivity(index);
michael@0 223
michael@0 224 // Context: Sharing via chrome mainmenu and content contextmenu quickshare (no explicit session is active)
michael@0 225 Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.BUTTON);
michael@0 226 }
michael@0 227 }
michael@0 228 }

mercurial