OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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.browseractions; | 5 package org.chromium.chrome.browser.browseractions; |
6 | 6 |
7 import android.app.Activity; | 7 import android.app.Activity; |
8 import android.app.NotificationManager; | |
9 import android.app.PendingIntent; | 8 import android.app.PendingIntent; |
10 import android.app.PendingIntent.CanceledException; | 9 import android.app.PendingIntent.CanceledException; |
11 import android.content.ClipData; | 10 import android.content.ClipData; |
12 import android.content.ClipboardManager; | 11 import android.content.ClipboardManager; |
13 import android.content.Context; | 12 import android.content.Context; |
14 import android.content.Intent; | 13 import android.content.Intent; |
15 import android.content.SharedPreferences; | |
16 import android.net.Uri; | 14 import android.net.Uri; |
17 import android.provider.Browser; | 15 import android.provider.Browser; |
18 | 16 |
19 import org.chromium.base.ApplicationStatus; | 17 import org.chromium.base.ApplicationStatus; |
20 import org.chromium.base.ContextUtils; | |
21 import org.chromium.base.Log; | 18 import org.chromium.base.Log; |
22 import org.chromium.base.VisibleForTesting; | 19 import org.chromium.base.VisibleForTesting; |
23 import org.chromium.chrome.R; | 20 import org.chromium.chrome.R; |
24 import org.chromium.chrome.browser.ChromeTabbedActivity; | 21 import org.chromium.chrome.browser.ChromeTabbedActivity; |
25 import org.chromium.chrome.browser.IntentHandler; | 22 import org.chromium.chrome.browser.IntentHandler; |
| 23 import org.chromium.chrome.browser.browseractions.BrowserActionsTabCreatorManage
r.BrowserActionsTabCreator; |
26 import org.chromium.chrome.browser.document.ChromeLauncherActivity; | 24 import org.chromium.chrome.browser.document.ChromeLauncherActivity; |
27 import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; | |
28 import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; | |
29 import org.chromium.chrome.browser.notifications.NotificationConstants; | |
30 import org.chromium.chrome.browser.notifications.NotificationUmaTracker; | |
31 import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; | |
32 import org.chromium.chrome.browser.share.ShareHelper; | 25 import org.chromium.chrome.browser.share.ShareHelper; |
33 import org.chromium.chrome.browser.share.ShareParams; | 26 import org.chromium.chrome.browser.share.ShareParams; |
34 import org.chromium.chrome.browser.tab.Tab; | 27 import org.chromium.chrome.browser.tab.Tab; |
35 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; | 28 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
36 import org.chromium.chrome.browser.util.IntentUtils; | 29 import org.chromium.chrome.browser.util.IntentUtils; |
37 import org.chromium.content_public.browser.LoadUrlParams; | 30 import org.chromium.content_public.browser.LoadUrlParams; |
38 import org.chromium.content_public.common.Referrer; | 31 import org.chromium.content_public.common.Referrer; |
39 import org.chromium.ui.widget.Toast; | 32 import org.chromium.ui.widget.Toast; |
40 | 33 |
41 import java.lang.ref.WeakReference; | 34 import java.lang.ref.WeakReference; |
42 | 35 |
43 /** | 36 /** |
44 * A delegate responsible for taking actions based on browser action context men
u selections. | 37 * A delegate responsible for taking actions based on browser action context men
u selections. |
45 */ | 38 */ |
46 public class BrowserActionsContextMenuItemDelegate { | 39 public class BrowserActionsContextMenuItemDelegate { |
47 private static final String TAG = "BrowserActionsItem"; | 40 private static final String TAG = "BrowserActionsItem"; |
48 /** | |
49 * Action to request open ChromeTabbedActivity in tab switcher mode. | |
50 */ | |
51 public static final String ACTION_BROWSER_ACTIONS_OPEN_IN_BACKGROUND = | |
52 "org.chromium.chrome.browser.browseractions.browser_action_open_in_b
ackground"; | |
53 | |
54 public static final String PREF_HAS_BROWSER_ACTIONS_NOTIFICATION = | |
55 "org.chromium.chrome.browser.browseractions.HAS_BROWSER_ACTIONS_NOTI
FICATION"; | |
56 | |
57 /** | |
58 * Extra that indicates whether to show a Tab for single url or the tab swit
cher for | |
59 * multiple urls. | |
60 */ | |
61 public static final String EXTRA_IS_SINGLE_URL = | |
62 "org.chromium.chrome.browser.browseractions.is_single_url"; | |
63 | 41 |
64 private final Activity mActivity; | 42 private final Activity mActivity; |
65 private final NotificationManager mNotificationManager; | |
66 private final SharedPreferences mSharedPreferences; | |
67 private final String mSourcePackageName; | 43 private final String mSourcePackageName; |
68 | 44 private final BrowserActionsTabCreatorManager mTabCreatorManager; |
69 private Intent mNotificationIntent; | |
70 | 45 |
71 /** | 46 /** |
72 * Builds a {@link BrowserActionsContextMenuItemDelegate} instance. | 47 * Builds a {@link BrowserActionsContextMenuItemDelegate} instance. |
73 * @param activity The activity displays the context menu. | 48 * @param activity The activity displays the context menu. |
74 * @param sourcePackageName The package name of the app which requests the B
rowser Actions. | 49 * @param sourcePackageName The package name of the app which requests the B
rowser Actions. |
75 */ | 50 */ |
76 public BrowserActionsContextMenuItemDelegate(Activity activity, String sourc
ePackageName) { | 51 public BrowserActionsContextMenuItemDelegate(Activity activity, String sourc
ePackageName) { |
77 mActivity = activity; | 52 mActivity = activity; |
78 mNotificationManager = | |
79 (NotificationManager) activity.getSystemService(Context.NOTIFICA
TION_SERVICE); | |
80 mSharedPreferences = ContextUtils.getAppSharedPreferences(); | |
81 mSourcePackageName = sourcePackageName; | 53 mSourcePackageName = sourcePackageName; |
82 } | 54 mTabCreatorManager = new BrowserActionsTabCreatorManager(); |
83 | |
84 @VisibleForTesting | |
85 Intent getNotificationIntent() { | |
86 return mNotificationIntent; | |
87 } | |
88 | |
89 private void sendBrowserActionsNotification(int tabId) { | |
90 ChromeNotificationBuilder builder = createNotificationBuilder(tabId); | |
91 mNotificationManager.notify( | |
92 NotificationConstants.NOTIFICATION_ID_BROWSER_ACTIONS, builder.b
uild()); | |
93 mSharedPreferences.edit().putBoolean(PREF_HAS_BROWSER_ACTIONS_NOTIFICATI
ON, true).apply(); | |
94 NotificationUmaTracker.getInstance().onNotificationShown( | |
95 NotificationUmaTracker.BROWSER_ACTIONS, ChannelDefinitions.CHANN
EL_ID_BROWSER); | |
96 } | |
97 | |
98 private ChromeNotificationBuilder createNotificationBuilder(int tabId) { | |
99 ChromeNotificationBuilder builder = | |
100 NotificationBuilderFactory | |
101 .createChromeNotificationBuilder( | |
102 true /* preferCompat */, ChannelDefinitions.CHAN
NEL_ID_BROWSER) | |
103 .setSmallIcon(R.drawable.infobar_chrome) | |
104 .setLocalOnly(true) | |
105 .setAutoCancel(true) | |
106 .setContentText( | |
107 mActivity.getString(R.string.browser_actions_not
ification_text)); | |
108 int titleResId = hasBrowserActionsNotification() | |
109 ? R.string.browser_actions_multi_links_open_notification_title | |
110 : R.string.browser_actions_single_link_open_notification_title; | |
111 builder.setContentTitle(mActivity.getString(titleResId)); | |
112 mNotificationIntent = buildNotificationIntent(tabId); | |
113 PendingIntent notifyPendingIntent = PendingIntent.getActivity( | |
114 mActivity, 0, mNotificationIntent, PendingIntent.FLAG_UPDATE_CUR
RENT); | |
115 builder.setContentIntent(notifyPendingIntent); | |
116 return builder; | |
117 } | |
118 | |
119 private Intent buildNotificationIntent(int tabId) { | |
120 boolean multipleUrls = hasBrowserActionsNotification(); | |
121 if (!multipleUrls && tabId != Tab.INVALID_TAB_ID) { | |
122 return Tab.createBringTabToFrontIntent(tabId); | |
123 } | |
124 Intent intent = new Intent(mActivity, ChromeLauncherActivity.class); | |
125 intent.setAction(ACTION_BROWSER_ACTIONS_OPEN_IN_BACKGROUND); | |
126 intent.putExtra(EXTRA_IS_SINGLE_URL, !multipleUrls); | |
127 return intent; | |
128 } | |
129 | |
130 boolean hasBrowserActionsNotification() { | |
131 return mSharedPreferences.getBoolean(PREF_HAS_BROWSER_ACTIONS_NOTIFICATI
ON, false); | |
132 } | 55 } |
133 | 56 |
134 private int openTabInBackground(String linkUrl) { | 57 private int openTabInBackground(String linkUrl) { |
135 int tabId = Tab.INVALID_TAB_ID; | |
136 Referrer referrer = IntentHandler.constructValidReferrerForAuthority(mSo
urcePackageName); | 58 Referrer referrer = IntentHandler.constructValidReferrerForAuthority(mSo
urcePackageName); |
137 LoadUrlParams loadUrlParams = new LoadUrlParams(linkUrl); | 59 LoadUrlParams loadUrlParams = new LoadUrlParams(linkUrl); |
138 loadUrlParams.setReferrer(referrer); | 60 loadUrlParams.setReferrer(referrer); |
139 for (WeakReference<Activity> ref : ApplicationStatus.getRunningActivitie
s()) { | 61 for (WeakReference<Activity> ref : ApplicationStatus.getRunningActivitie
s()) { |
140 if (!(ref.get() instanceof ChromeTabbedActivity)) continue; | 62 if (!(ref.get() instanceof ChromeTabbedActivity)) continue; |
141 | 63 |
142 ChromeTabbedActivity activity = (ChromeTabbedActivity) ref.get(); | 64 ChromeTabbedActivity activity = (ChromeTabbedActivity) ref.get(); |
143 if (activity == null) continue; | 65 if (activity == null) continue; |
144 if (activity.getTabModelSelector() != null) { | 66 if (activity.getTabModelSelector() != null) { |
145 Tab tab = activity.getTabModelSelector().openNewTab( | 67 Tab tab = activity.getTabModelSelector().openNewTab( |
146 loadUrlParams, TabLaunchType.FROM_BROWSER_ACTIONS, null,
false); | 68 loadUrlParams, TabLaunchType.FROM_BROWSER_ACTIONS, null,
false); |
147 assert tab != null; | 69 assert tab != null; |
148 tabId = tab.getId(); | 70 return tab.getId(); |
149 } | 71 } |
150 } | 72 } |
151 return tabId; | 73 BrowserActionsTabModelSelector selector = |
| 74 BrowserActionsTabModelSelector.getInstance(mActivity, mTabCreato
rManager); |
| 75 if (!selector.isActiveState()) { |
| 76 selector.initializeSelector(); |
| 77 ((BrowserActionsTabCreator) mTabCreatorManager.getTabCreator(false)) |
| 78 .setTabModel(selector.getCurrentModel()); |
| 79 selector.loadState(true); |
| 80 selector.restoreTabs(false); |
| 81 } |
| 82 selector.openNewTab(loadUrlParams, TabLaunchType.FROM_BROWSER_ACTIONS, n
ull, false); |
| 83 return Tab.INVALID_TAB_ID; |
| 84 } |
| 85 |
| 86 @VisibleForTesting |
| 87 BrowserActionsTabCreatorManager getTabCreatorManager() { |
| 88 return mTabCreatorManager; |
152 } | 89 } |
153 | 90 |
154 /** | 91 /** |
155 * Called when the {@code text} should be saved to the clipboard. | 92 * Called when the {@code text} should be saved to the clipboard. |
156 * @param text The text to save to the clipboard. | 93 * @param text The text to save to the clipboard. |
157 */ | 94 */ |
158 public void onSaveToClipboard(String text) { | 95 public void onSaveToClipboard(String text) { |
159 ClipboardManager clipboardManager = | 96 ClipboardManager clipboardManager = |
160 (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_
SERVICE); | 97 (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_
SERVICE); |
161 ClipData data = ClipData.newPlainText("url", text); | 98 ClipData data = ClipData.newPlainText("url", text); |
(...skipping 14 matching lines...) Expand all Loading... |
176 IntentHandler.addTrustedIntentExtras(intent); | 113 IntentHandler.addTrustedIntentExtras(intent); |
177 IntentHandler.setTabLaunchType(intent, TabLaunchType.FROM_EXTERNAL_APP); | 114 IntentHandler.setTabLaunchType(intent, TabLaunchType.FROM_EXTERNAL_APP); |
178 IntentUtils.safeStartActivity(mActivity, intent); | 115 IntentUtils.safeStartActivity(mActivity, intent); |
179 } | 116 } |
180 | 117 |
181 /** | 118 /** |
182 * Called when the {@code linkUrl} should be opened in Chrome in the backgro
und. | 119 * Called when the {@code linkUrl} should be opened in Chrome in the backgro
und. |
183 * @param linkUrl The url to open. | 120 * @param linkUrl The url to open. |
184 */ | 121 */ |
185 public void onOpenInBackground(String linkUrl) { | 122 public void onOpenInBackground(String linkUrl) { |
| 123 BrowserActionsService.sendIntent( |
| 124 BrowserActionsService.ACTION_TAB_CREATION_START, Tab.INVALID_TAB
_ID); |
| 125 |
186 int tabId = openTabInBackground(linkUrl); | 126 int tabId = openTabInBackground(linkUrl); |
187 if (tabId != Tab.INVALID_TAB_ID) { | 127 if (tabId != Tab.INVALID_TAB_ID) { |
188 sendBrowserActionsNotification(tabId); | 128 BrowserActionsService.sendIntent( |
189 Toast.makeText(mActivity, R.string.browser_actions_open_in_backgroun
d_toast_message, | 129 BrowserActionsService.ACTION_TAB_CREATION_UPDATE, Tab.INVALI
D_TAB_ID); |
190 Toast.LENGTH_SHORT) | |
191 .show(); | |
192 } else { | |
193 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl)); | |
194 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
195 intent.setClass(mActivity, ChromeLauncherActivity.class); | |
196 intent.putExtra(ChromeLauncherActivity.EXTRA_IS_ALLOWED_TO_RETURN_TO
_PARENT, false); | |
197 IntentUtils.safeStartActivity(mActivity, intent); | |
198 } | 130 } |
| 131 Toast.makeText(mActivity, R.string.browser_actions_open_in_background_to
ast_message, |
| 132 Toast.LENGTH_SHORT) |
| 133 .show(); |
199 } | 134 } |
200 | 135 |
201 /** | 136 /** |
202 * Called when a custom item of Browser action menu is selected. | 137 * Called when a custom item of Browser action menu is selected. |
203 * @param action The PendingIntent action to be launched. | 138 * @param action The PendingIntent action to be launched. |
204 */ | 139 */ |
205 public void onCustomItemSelected(PendingIntent action) { | 140 public void onCustomItemSelected(PendingIntent action) { |
206 try { | 141 try { |
207 action.send(); | 142 action.send(); |
208 } catch (CanceledException e) { | 143 } catch (CanceledException e) { |
(...skipping 14 matching lines...) Expand all Loading... |
223 */ | 158 */ |
224 public void share(Boolean shareDirectly, String linkUrl) { | 159 public void share(Boolean shareDirectly, String linkUrl) { |
225 ShareParams params = new ShareParams.Builder(mActivity, linkUrl, linkUrl
) | 160 ShareParams params = new ShareParams.Builder(mActivity, linkUrl, linkUrl
) |
226 .setShareDirectly(shareDirectly) | 161 .setShareDirectly(shareDirectly) |
227 .setSaveLastUsed(!shareDirectly) | 162 .setSaveLastUsed(!shareDirectly) |
228 .setSourcePackageName(mSourcePackageName) | 163 .setSourcePackageName(mSourcePackageName) |
229 .setIsExternalUrl(true) | 164 .setIsExternalUrl(true) |
230 .build(); | 165 .build(); |
231 ShareHelper.share(params); | 166 ShareHelper.share(params); |
232 } | 167 } |
233 | |
234 /** | |
235 * Cancel Browser Actions notification. | |
236 */ | |
237 public static void cancelBrowserActionsNotification() { | |
238 NotificationManager notificationManager = | |
239 (NotificationManager) ContextUtils.getApplicationContext().getSy
stemService( | |
240 Context.NOTIFICATION_SERVICE); | |
241 notificationManager.cancel(NotificationConstants.NOTIFICATION_ID_BROWSER
_ACTIONS); | |
242 ContextUtils.getAppSharedPreferences() | |
243 .edit() | |
244 .putBoolean( | |
245 BrowserActionsContextMenuItemDelegate.PREF_HAS_BROWSER_A
CTIONS_NOTIFICATION, | |
246 false) | |
247 .apply(); | |
248 } | |
249 | |
250 /** | |
251 * Checks whether Chrome should display tab switcher via Browser Actions Int
ent. | |
252 * @param intent The intent to open the Chrome. | |
253 * @param isOverviewVisible Whether tab switcher is shown. | |
254 */ | |
255 public static boolean toggleOverviewByBrowserActions(Intent intent, boolean
isOverviewVisible) { | |
256 boolean fromBrowserActions = isStartedByBrowserActions(intent); | |
257 boolean isSingleUrl = IntentUtils.safeGetBooleanExtra( | |
258 intent, BrowserActionsContextMenuItemDelegate.EXTRA_IS_SINGLE_UR
L, false); | |
259 if (fromBrowserActions) { | |
260 return isSingleUrl == isOverviewVisible; | |
261 } | |
262 return false; | |
263 } | |
264 | |
265 private static boolean isStartedByBrowserActions(Intent intent) { | |
266 if (BrowserActionsContextMenuItemDelegate.ACTION_BROWSER_ACTIONS_OPEN_IN
_BACKGROUND.equals( | |
267 intent.getAction())) { | |
268 return true; | |
269 } | |
270 return false; | |
271 } | |
272 } | 168 } |
OLD | NEW |