Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.contextmenu; | 5 package org.chromium.chrome.browser.contextmenu; |
| 6 | 6 |
| 7 import android.app.Activity; | 7 import android.app.Activity; |
| 8 import android.content.Context; | 8 import android.content.ComponentName; |
| 9 import android.graphics.Bitmap; | 9 import android.graphics.Bitmap; |
| 10 import android.graphics.BitmapFactory; | 10 import android.graphics.BitmapFactory; |
| 11 import android.util.Pair; | 11 import android.util.Pair; |
| 12 import android.view.ContextMenu; | 12 import android.view.ContextMenu; |
| 13 import android.view.ContextMenu.ContextMenuInfo; | 13 import android.view.ContextMenu.ContextMenuInfo; |
| 14 import android.view.View; | 14 import android.view.View; |
| 15 import android.view.View.OnCreateContextMenuListener; | 15 import android.view.View.OnCreateContextMenuListener; |
| 16 | 16 |
| 17 import org.chromium.base.Callback; | 17 import org.chromium.base.Callback; |
| 18 import org.chromium.base.VisibleForTesting; | 18 import org.chromium.base.VisibleForTesting; |
| 19 import org.chromium.base.annotations.CalledByNative; | 19 import org.chromium.base.annotations.CalledByNative; |
| 20 import org.chromium.base.metrics.RecordHistogram; | 20 import org.chromium.base.metrics.RecordHistogram; |
| 21 import org.chromium.chrome.browser.ChromeFeatureList; | 21 import org.chromium.chrome.browser.ChromeFeatureList; |
| 22 import org.chromium.chrome.browser.share.ShareHelper; | 22 import org.chromium.chrome.browser.share.ShareHelper; |
| 23 import org.chromium.content.browser.ContentViewCore; | 23 import org.chromium.content.browser.ContentViewCore; |
| 24 import org.chromium.content_public.browser.WebContents; | 24 import org.chromium.content_public.browser.WebContents; |
| 25 import org.chromium.ui.base.WindowAndroid; | 25 import org.chromium.ui.base.WindowAndroid; |
| 26 import org.chromium.ui.base.WindowAndroid.OnCloseContextMenuListener; | 26 import org.chromium.ui.base.WindowAndroid.OnCloseContextMenuListener; |
| 27 | 27 |
| 28 import java.util.List; | 28 import java.util.List; |
| 29 | 29 |
| 30 /** | 30 /** |
| 31 * A helper class that handles generating context menus for {@link ContentViewCo re}s. | 31 * A helper class that handles generating context menus for {@link ContentViewCo re}s. |
| 32 */ | 32 */ |
| 33 public class ContextMenuHelper implements OnCreateContextMenuListener { | 33 public class ContextMenuHelper implements OnCreateContextMenuListener { |
| 34 private long mNativeContextMenuHelper; | 34 private long mNativeContextMenuHelper; |
| 35 | 35 |
| 36 private ContextMenuPopulator mPopulator; | 36 private ContextMenuPopulator mPopulator; |
| 37 private ContextMenuParams mCurrentContextMenuParams; | 37 private ContextMenuParams mCurrentContextMenuParams; |
| 38 private Context mContext; | 38 private Activity mActivity; |
|
Theresa
2017/03/30 15:12:45
Typically we recommend against caching the activit
JJ
2017/03/30 16:20:17
It works!
| |
| 39 private Callback<Integer> mCallback; | 39 private Callback<Integer> mCallback; |
| 40 private Runnable mOnMenuShown; | 40 private Runnable mOnMenuShown; |
| 41 private Runnable mOnMenuClosed; | 41 private Runnable mOnMenuClosed; |
| 42 private OnThumbnailReceivedListener mOnThumbnailReceivedListener; | 42 private OnThumbnailReceivedListener mOnThumbnailReceivedListener; |
| 43 private ComponentName mComponentName; | |
| 43 | 44 |
| 44 /** | 45 /** |
| 45 * This waits for a thumbnail to be retrieved by the native code. | 46 * This waits for a thumbnail to be retrieved by the native code. |
| 46 */ | 47 */ |
| 47 interface OnThumbnailReceivedListener { | 48 interface OnThumbnailReceivedListener { |
| 48 /** | 49 /** |
| 49 * When the thumbnail is received it will send the thumbnail via this me thod. This is | 50 * When the thumbnail is received it will send the thumbnail via this me thod. This is |
| 50 * activated after calling {@link #getThumbnail()}. | 51 * activated after calling {@link #getThumbnail()}. |
| 51 * @param bitmap The bitmap that is retrieved from native code. | 52 * @param bitmap The bitmap that is retrieved from native code. |
| 52 */ | 53 */ |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 * @param contentViewCore The {@link ContentViewCore} to show the menu to. | 87 * @param contentViewCore The {@link ContentViewCore} to show the menu to. |
| 87 * @param params The {@link ContextMenuParams} that indicate what m enu items to show. | 88 * @param params The {@link ContextMenuParams} that indicate what m enu items to show. |
| 88 */ | 89 */ |
| 89 @CalledByNative | 90 @CalledByNative |
| 90 private void showContextMenu(final ContentViewCore contentViewCore, ContextM enuParams params) { | 91 private void showContextMenu(final ContentViewCore contentViewCore, ContextM enuParams params) { |
| 91 if (params.isFile()) return; | 92 if (params.isFile()) return; |
| 92 View view = contentViewCore.getContainerView(); | 93 View view = contentViewCore.getContainerView(); |
| 93 final WindowAndroid windowAndroid = contentViewCore.getWindowAndroid(); | 94 final WindowAndroid windowAndroid = contentViewCore.getWindowAndroid(); |
| 94 | 95 |
| 95 if (view == null || view.getVisibility() != View.VISIBLE || view.getPare nt() == null | 96 if (view == null || view.getVisibility() != View.VISIBLE || view.getPare nt() == null |
| 96 || windowAndroid == null || windowAndroid.getContext().get() == null | 97 || windowAndroid == null || windowAndroid.getActivity().get() == null |
| 97 || mPopulator == null) { | 98 || mPopulator == null) { |
| 98 return; | 99 return; |
| 99 } | 100 } |
| 100 | 101 |
| 101 mCurrentContextMenuParams = params; | 102 mCurrentContextMenuParams = params; |
| 102 mContext = windowAndroid.getContext().get(); | 103 mActivity = windowAndroid.getActivity().get(); |
| 103 mCallback = new Callback<Integer>() { | 104 mCallback = new Callback<Integer>() { |
| 104 @Override | 105 @Override |
| 105 public void onResult(Integer result) { | 106 public void onResult(Integer result) { |
| 106 mPopulator.onItemSelected( | 107 mPopulator.onItemSelected( |
| 107 ContextMenuHelper.this, mCurrentContextMenuParams, resul t); | 108 ContextMenuHelper.this, mCurrentContextMenuParams, resul t); |
| 108 } | 109 } |
| 109 }; | 110 }; |
| 110 mOnMenuShown = new Runnable() { | 111 mOnMenuShown = new Runnable() { |
| 111 @Override | 112 @Override |
| 112 public void run() { | 113 public void run() { |
| 113 WebContents webContents = contentViewCore.getWebContents(); | 114 WebContents webContents = contentViewCore.getWebContents(); |
| 114 RecordHistogram.recordBooleanHistogram("ContextMenu.Shown", webC ontents != null); | 115 RecordHistogram.recordBooleanHistogram("ContextMenu.Shown", webC ontents != null); |
| 115 } | 116 } |
| 116 }; | 117 }; |
| 117 mOnMenuClosed = new Runnable() { | 118 mOnMenuClosed = new Runnable() { |
| 118 @Override | 119 @Override |
| 119 public void run() { | 120 public void run() { |
| 120 if (mNativeContextMenuHelper == 0) return; | 121 if (mNativeContextMenuHelper == 0) return; |
| 121 nativeOnContextMenuClosed(mNativeContextMenuHelper); | 122 nativeOnContextMenuClosed(mNativeContextMenuHelper); |
| 122 } | 123 } |
| 123 }; | 124 }; |
| 124 | 125 |
| 125 if (ChromeFeatureList.isEnabled(ChromeFeatureList.CUSTOM_CONTEXT_MENU)) { | 126 if (ChromeFeatureList.isEnabled(ChromeFeatureList.CUSTOM_CONTEXT_MENU)) { |
| 126 List<Pair<Integer, List<ContextMenuItem>>> items = | 127 List<Pair<Integer, List<ContextMenuItem>>> items = |
| 127 mPopulator.buildContextMenu(null, mContext, mCurrentContextM enuParams); | 128 mPopulator.buildContextMenu(null, mActivity, mCurrentContext MenuParams); |
| 128 | 129 |
| 129 ContextMenuUi menuUi = new TabularContextMenuUi(this); | 130 ContextMenuUi menuUi = new TabularContextMenuUi(this); |
| 130 menuUi.displayMenu(mContext, mCurrentContextMenuParams, items, mCall back, mOnMenuShown, | 131 menuUi.displayMenu(mActivity, mCurrentContextMenuParams, items, mCal lback, mOnMenuShown, |
| 131 mOnMenuClosed); | 132 mOnMenuClosed); |
| 132 return; | 133 return; |
| 133 } | 134 } |
| 134 | 135 |
| 135 // The Platform Context Menu requires the listener within this hepler si nce this helper and | 136 // The Platform Context Menu requires the listener within this hepler si nce this helper and |
| 136 // provides context menu for us to show. | 137 // provides context menu for us to show. |
| 137 view.setOnCreateContextMenuListener(this); | 138 view.setOnCreateContextMenuListener(this); |
| 138 if (view.showContextMenu()) { | 139 if (view.showContextMenu()) { |
| 139 mOnMenuShown.run(); | 140 mOnMenuShown.run(); |
| 140 windowAndroid.addContextMenuCloseListener(new OnCloseContextMenuList ener() { | 141 windowAndroid.addContextMenuCloseListener(new OnCloseContextMenuList ener() { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 if (mNativeContextMenuHelper == 0) return; | 173 if (mNativeContextMenuHelper == 0) return; |
| 173 nativeShareImage(mNativeContextMenuHelper); | 174 nativeShareImage(mNativeContextMenuHelper); |
| 174 } | 175 } |
| 175 | 176 |
| 176 @CalledByNative | 177 @CalledByNative |
| 177 private void onShareImageReceived( | 178 private void onShareImageReceived( |
| 178 WindowAndroid windowAndroid, byte[] jpegImageData) { | 179 WindowAndroid windowAndroid, byte[] jpegImageData) { |
| 179 Activity activity = windowAndroid.getActivity().get(); | 180 Activity activity = windowAndroid.getActivity().get(); |
| 180 if (activity == null) return; | 181 if (activity == null) return; |
| 181 | 182 |
| 182 ShareHelper.shareImage(activity, jpegImageData); | 183 ShareHelper.shareImage(activity, jpegImageData, mComponentName); |
| 184 // This needs to be reset to null after a share. This way the next time a user shares an | |
| 185 // image it won't share with the last shared item unless explicitly told . | |
|
Theresa
2017/03/30 15:12:45
nit: ...won't share with the last shared app...?
JJ
2017/03/30 16:20:17
Done.
| |
| 186 mComponentName = null; | |
| 183 } | 187 } |
| 184 | 188 |
| 185 /** | 189 /** |
| 190 * Share image triggered with the current context menu directly with a speci fic app. | |
| 191 * @param name The app to share the image directly with. | |
|
Theresa
2017/03/30 15:12:45
nit: The {@link ComponentName} of the app to share
JJ
2017/03/30 16:20:17
Done.
| |
| 192 */ | |
| 193 public void shareImageDirectly(ComponentName name) { | |
| 194 mComponentName = name; | |
| 195 shareImage(); | |
| 196 } | |
| 197 | |
| 198 /** | |
| 186 * Gets the thumbnail of the current image that triggered the context menu. | 199 * Gets the thumbnail of the current image that triggered the context menu. |
| 187 */ | 200 */ |
| 188 public void getThumbnail() { | 201 public void getThumbnail() { |
| 189 if (mNativeContextMenuHelper == 0) return; | 202 if (mNativeContextMenuHelper == 0) return; |
| 190 nativeRetrieveHeaderThumbnail(mNativeContextMenuHelper); | 203 nativeRetrieveHeaderThumbnail(mNativeContextMenuHelper); |
| 191 } | 204 } |
| 192 | 205 |
| 193 @CalledByNative | 206 @CalledByNative |
| 194 private void onHeaderThumbnailReceived(WindowAndroid windowAndroid, byte[] j pegImageData) { | 207 private void onHeaderThumbnailReceived(WindowAndroid windowAndroid, byte[] j pegImageData) { |
| 195 Bitmap bitmap = BitmapFactory.decodeByteArray(jpegImageData, 0, jpegImag eData.length); | 208 Bitmap bitmap = BitmapFactory.decodeByteArray(jpegImageData, 0, jpegImag eData.length); |
| 196 if (mOnThumbnailReceivedListener != null) { | 209 if (mOnThumbnailReceivedListener != null) { |
| 197 mOnThumbnailReceivedListener.onThumbnailReceived(bitmap); | 210 mOnThumbnailReceivedListener.onThumbnailReceived(bitmap); |
| 198 } | 211 } |
| 199 } | 212 } |
| 200 | 213 |
| 201 @Override | 214 @Override |
| 202 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo me nuInfo) { | 215 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo me nuInfo) { |
| 203 List<Pair<Integer, List<ContextMenuItem>>> items = | 216 List<Pair<Integer, List<ContextMenuItem>>> items = |
| 204 mPopulator.buildContextMenu(menu, v.getContext(), mCurrentContex tMenuParams); | 217 mPopulator.buildContextMenu(menu, v.getContext(), mCurrentContex tMenuParams); |
| 205 ContextMenuUi menuUi = new PlatformContextMenuUi(menu); | 218 ContextMenuUi menuUi = new PlatformContextMenuUi(menu); |
| 206 menuUi.displayMenu( | 219 menuUi.displayMenu(mActivity, mCurrentContextMenuParams, items, mCallbac k, mOnMenuShown, |
| 207 mContext, mCurrentContextMenuParams, items, mCallback, mOnMenuSh own, mOnMenuClosed); | 220 mOnMenuClosed); |
| 208 } | 221 } |
| 209 | 222 |
| 210 /** | 223 /** |
| 211 * Sets the listener for retrieving a thumbnail when calling {@link #getThum bnail()}. | 224 * Sets the listener for retrieving a thumbnail when calling {@link #getThum bnail()}. |
| 212 * @param listener The listener that will be called once a thumbnail is retr ieved. | 225 * @param listener The listener that will be called once a thumbnail is retr ieved. |
| 213 */ | 226 */ |
| 214 public void setOnThumbnailReceivedListener(OnThumbnailReceivedListener liste ner) { | 227 public void setOnThumbnailReceivedListener(OnThumbnailReceivedListener liste ner) { |
| 215 mOnThumbnailReceivedListener = listener; | 228 mOnThumbnailReceivedListener = listener; |
| 216 } | 229 } |
| 217 | 230 |
| 218 /** | 231 /** |
| 219 * @return The {@link ContextMenuPopulator} responsible for populating the c ontext menu. | 232 * @return The {@link ContextMenuPopulator} responsible for populating the c ontext menu. |
| 220 */ | 233 */ |
| 221 @VisibleForTesting | 234 @VisibleForTesting |
| 222 public ContextMenuPopulator getPopulator() { | 235 public ContextMenuPopulator getPopulator() { |
| 223 return mPopulator; | 236 return mPopulator; |
| 224 } | 237 } |
| 225 | 238 |
| 226 private native void nativeOnStartDownload( | 239 private native void nativeOnStartDownload( |
| 227 long nativeContextMenuHelper, boolean isLink, boolean isDataReductio nProxyEnabled); | 240 long nativeContextMenuHelper, boolean isLink, boolean isDataReductio nProxyEnabled); |
| 228 private native void nativeSearchForImage(long nativeContextMenuHelper); | 241 private native void nativeSearchForImage(long nativeContextMenuHelper); |
| 229 private native void nativeShareImage(long nativeContextMenuHelper); | 242 private native void nativeShareImage(long nativeContextMenuHelper); |
| 230 private native void nativeOnContextMenuClosed(long nativeContextMenuHelper); | 243 private native void nativeOnContextMenuClosed(long nativeContextMenuHelper); |
| 231 private native void nativeRetrieveHeaderThumbnail(long nativeContextMenuHelp er); | 244 private native void nativeRetrieveHeaderThumbnail(long nativeContextMenuHelp er); |
| 232 } | 245 } |
| OLD | NEW |