Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java

Issue 2689993002: Refactor the INSTALL_SHORTCUT broadcast code into ChromeShortcutManager (Closed)
Patch Set: Make some changes according to review comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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; 5 package org.chromium.chrome.browser;
6 6
7 import android.annotation.SuppressLint;
8 import android.app.ActivityManager; 7 import android.app.ActivityManager;
9 import android.content.Context; 8 import android.content.Context;
10 import android.content.Intent; 9 import android.content.Intent;
11 import android.content.pm.ApplicationInfo; 10 import android.content.pm.ApplicationInfo;
12 import android.content.pm.PackageInfo; 11 import android.content.pm.PackageInfo;
13 import android.content.pm.PackageManager; 12 import android.content.pm.PackageManager;
14 import android.content.pm.PackageManager.NameNotFoundException; 13 import android.content.pm.PackageManager.NameNotFoundException;
15 import android.content.pm.ResolveInfo;
16 import android.graphics.Bitmap; 14 import android.graphics.Bitmap;
17 import android.graphics.BitmapFactory; 15 import android.graphics.BitmapFactory;
18 import android.graphics.Canvas; 16 import android.graphics.Canvas;
19 import android.graphics.Color; 17 import android.graphics.Color;
20 import android.graphics.Paint; 18 import android.graphics.Paint;
21 import android.graphics.Rect; 19 import android.graphics.Rect;
22 import android.graphics.drawable.BitmapDrawable; 20 import android.graphics.drawable.BitmapDrawable;
23 import android.graphics.drawable.Drawable; 21 import android.graphics.drawable.Drawable;
24 import android.net.Uri; 22 import android.net.Uri;
25 import android.os.AsyncTask; 23 import android.os.AsyncTask;
26 import android.support.annotation.NonNull; 24 import android.support.annotation.NonNull;
27 import android.text.TextUtils; 25 import android.text.TextUtils;
28 import android.util.Base64; 26 import android.util.Base64;
29 27
30 import org.chromium.base.ApiCompatibilityUtils; 28 import org.chromium.base.ApiCompatibilityUtils;
31 import org.chromium.base.ContextUtils; 29 import org.chromium.base.ContextUtils;
32 import org.chromium.base.Log; 30 import org.chromium.base.Log;
33 import org.chromium.base.ThreadUtils; 31 import org.chromium.base.ThreadUtils;
34 import org.chromium.base.VisibleForTesting; 32 import org.chromium.base.VisibleForTesting;
35 import org.chromium.base.annotations.CalledByNative; 33 import org.chromium.base.annotations.CalledByNative;
36 import org.chromium.blink_public.platform.WebDisplayMode; 34 import org.chromium.blink_public.platform.WebDisplayMode;
37 import org.chromium.chrome.R; 35 import org.chromium.chrome.R;
36 import org.chromium.chrome.browser.webapps.ChromeShortcutManager;
38 import org.chromium.chrome.browser.webapps.ChromeWebApkHost; 37 import org.chromium.chrome.browser.webapps.ChromeWebApkHost;
39 import org.chromium.chrome.browser.webapps.WebApkInfo; 38 import org.chromium.chrome.browser.webapps.WebApkInfo;
40 import org.chromium.chrome.browser.webapps.WebappActivity; 39 import org.chromium.chrome.browser.webapps.WebappActivity;
41 import org.chromium.chrome.browser.webapps.WebappAuthenticator; 40 import org.chromium.chrome.browser.webapps.WebappAuthenticator;
42 import org.chromium.chrome.browser.webapps.WebappDataStorage; 41 import org.chromium.chrome.browser.webapps.WebappDataStorage;
43 import org.chromium.chrome.browser.webapps.WebappLauncherActivity; 42 import org.chromium.chrome.browser.webapps.WebappLauncherActivity;
44 import org.chromium.chrome.browser.webapps.WebappRegistry; 43 import org.chromium.chrome.browser.webapps.WebappRegistry;
45 import org.chromium.chrome.browser.widget.RoundedIconGenerator; 44 import org.chromium.chrome.browser.widget.RoundedIconGenerator;
46 import org.chromium.content_public.common.ScreenOrientationConstants; 45 import org.chromium.content_public.common.ScreenOrientationConstants;
47 import org.chromium.ui.widget.Toast; 46 import org.chromium.ui.widget.Toast;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 83
85 // When a new field is added to the intent, this version should be increment ed so that it will 84 // When a new field is added to the intent, this version should be increment ed so that it will
86 // be correctly populated into the WebappRegistry/WebappDataStorage. 85 // be correctly populated into the WebappRegistry/WebappDataStorage.
87 public static final int WEBAPP_SHORTCUT_VERSION = 2; 86 public static final int WEBAPP_SHORTCUT_VERSION = 2;
88 87
89 // This value is equal to kInvalidOrMissingColor in the C++ content::Manifes t struct. 88 // This value is equal to kInvalidOrMissingColor in the C++ content::Manifes t struct.
90 public static final long MANIFEST_COLOR_INVALID_OR_MISSING = ((long) Integer .MAX_VALUE) + 1; 89 public static final long MANIFEST_COLOR_INVALID_OR_MISSING = ((long) Integer .MAX_VALUE) + 1;
91 90
92 private static final String TAG = "ShortcutHelper"; 91 private static final String TAG = "ShortcutHelper";
93 92
94 // There is no public string defining this intent so if Home changes the val ue, we
95 // have to update this string.
96 private static final String INSTALL_SHORTCUT = "com.android.launcher.action. INSTALL_SHORTCUT";
97
98 // The activity class used for launching a WebApk. 93 // The activity class used for launching a WebApk.
99 private static final String WEBAPK_MAIN_ACTIVITY = "org.chromium.webapk.shel l_apk.MainActivity"; 94 private static final String WEBAPK_MAIN_ACTIVITY = "org.chromium.webapk.shel l_apk.MainActivity";
100 95
101 // These sizes are from the Material spec for icons: 96 // These sizes are from the Material spec for icons:
102 // https://www.google.com/design/spec/style/icons.html#icons-product-icons 97 // https://www.google.com/design/spec/style/icons.html#icons-product-icons
103 private static final float MAX_INNER_SIZE_RATIO = 1.25f; 98 private static final float MAX_INNER_SIZE_RATIO = 1.25f;
104 private static final float ICON_PADDING_RATIO = 2.0f / 44.0f; 99 private static final float ICON_PADDING_RATIO = 2.0f / 44.0f;
105 private static final float ICON_CORNER_RADIUS_RATIO = 1.0f / 16.0f; 100 private static final float ICON_CORNER_RADIUS_RATIO = 1.0f / 16.0f;
106 private static final float GENERATED_ICON_PADDING_RATIO = 1.0f / 12.0f; 101 private static final float GENERATED_ICON_PADDING_RATIO = 1.0f / 12.0f;
107 private static final float GENERATED_ICON_FONT_SIZE_RATIO = 1.0f / 3.0f; 102 private static final float GENERATED_ICON_FONT_SIZE_RATIO = 1.0f / 3.0f;
108 103
109 /** Broadcasts Intents out Android for adding the shortcut. */ 104 /** Request Android to add a shortcut to the home screen. */
110 public static class Delegate { 105 public static class Delegate {
111 /** 106 /**
112 * Broadcasts an intent to all interested BroadcastReceivers. 107 * Request Android to add a shortcut to the home screen
113 * @param context The Context to use. 108 * @param title Title of the shortcut.
114 * @param intent The intent to broadcast. 109 * @param icon Image that represents the shortcut.
110 * @param intent Intent to fire when the shortcut is activated.
115 */ 111 */
116 public void sendBroadcast(Context context, Intent intent) { 112 public void addShortcutToHomescreen(String title, Bitmap icon, Intent sh ortcutIntent) {
117 context.sendBroadcast(intent); 113 ChromeShortcutManager.getInstance().addShortcutToHomeScreen(
114 title, icon, shortcutIntent);
118 } 115 }
119 116
120 /** 117 /**
121 * Returns the name of the fullscreen Activity to use when launching sho rtcuts. 118 * Returns the name of the fullscreen Activity to use when launching sho rtcuts.
122 */ 119 */
123 public String getFullscreenAction() { 120 public String getFullscreenAction() {
124 return WebappLauncherActivity.ACTION_START_WEBAPP; 121 return WebappLauncherActivity.ACTION_START_WEBAPP;
125 } 122 }
126 } 123 }
127 124
(...skipping 16 matching lines...) Expand all
144 @CalledByNative 141 @CalledByNative
145 private static void addWebapp(final String id, final String url, final Strin g scopeUrl, 142 private static void addWebapp(final String id, final String url, final Strin g scopeUrl,
146 final String userTitle, final String name, final String shortName, f inal String iconUrl, 143 final String userTitle, final String name, final String shortName, f inal String iconUrl,
147 final Bitmap icon, final int displayMode, final int orientation, fin al int source, 144 final Bitmap icon, final int displayMode, final int orientation, fin al int source,
148 final long themeColor, final long backgroundColor, final long callba ckPointer) { 145 final long themeColor, final long backgroundColor, final long callba ckPointer) {
149 new AsyncTask<Void, Void, Intent>() { 146 new AsyncTask<Void, Void, Intent>() {
150 @Override 147 @Override
151 protected Intent doInBackground(Void... args0) { 148 protected Intent doInBackground(Void... args0) {
152 // Encoding {@link icon} as a string and computing the mac are e xpensive. 149 // Encoding {@link icon} as a string and computing the mac are e xpensive.
153 150
154 Context context = ContextUtils.getApplicationContext(); 151 Context context = ContextUtils.getApplicationContext();
dominickn 2017/02/14 03:04:21 Remove the context variable, and call setPackage()
Marti Wong 2017/02/14 04:37:51 Seems it's more straightforward that the shortcutI
155 String nonEmptyScopeUrl = 152 String nonEmptyScopeUrl =
156 TextUtils.isEmpty(scopeUrl) ? getScopeFromUrl(url) : sco peUrl; 153 TextUtils.isEmpty(scopeUrl) ? getScopeFromUrl(url) : sco peUrl;
157 Intent shortcutIntent = createWebappShortcutIntent(id, 154 Intent shortcutIntent = createWebappShortcutIntent(id,
158 sDelegate.getFullscreenAction(), url, nonEmptyScopeUrl, name, shortName, 155 sDelegate.getFullscreenAction(), url, nonEmptyScopeUrl, name, shortName,
159 icon, WEBAPP_SHORTCUT_VERSION, displayMode, orientation, themeColor, 156 icon, WEBAPP_SHORTCUT_VERSION, displayMode, orientation, themeColor,
160 backgroundColor, iconUrl.isEmpty()); 157 backgroundColor, iconUrl.isEmpty());
161 shortcutIntent.putExtra(EXTRA_MAC, getEncodedMac(context, url)); 158 shortcutIntent.putExtra(EXTRA_MAC, getEncodedMac(context, url));
162 shortcutIntent.putExtra(EXTRA_SOURCE, source); 159 shortcutIntent.putExtra(EXTRA_SOURCE, source);
163 shortcutIntent.setPackage(context.getPackageName()); 160 shortcutIntent.setPackage(context.getPackageName());
164 return shortcutIntent; 161 return shortcutIntent;
165 } 162 }
166 @Override 163 @Override
167 protected void onPostExecute(final Intent resultIntent) { 164 protected void onPostExecute(final Intent resultIntent) {
168 Context context = ContextUtils.getApplicationContext(); 165 Context context = ContextUtils.getApplicationContext();
dominickn 2017/02/14 03:04:21 This variable is no longer used: remove.
Marti Wong 2017/02/14 04:37:51 Done. thanks!
169 sDelegate.sendBroadcast( 166 sDelegate.addShortcutToHomescreen(userTitle, icon, resultIntent) ;
170 context, createAddToHomeIntent(userTitle, icon, resultIn tent));
171 167
172 // Store the webapp data so that it is accessible without the in tent. Once this 168 // Store the webapp data so that it is accessible without the in tent. Once this
173 // process is complete, call back to native code to start the sp lash image 169 // process is complete, call back to native code to start the sp lash image
174 // download. 170 // download.
175 WebappRegistry.getInstance().register( 171 WebappRegistry.getInstance().register(
176 id, new WebappRegistry.FetchWebappDataStorageCallback() { 172 id, new WebappRegistry.FetchWebappDataStorageCallback() {
177 @Override 173 @Override
178 public void onWebappDataStorageRetrieved(WebappDataS torage storage) { 174 public void onWebappDataStorageRetrieved(WebappDataS torage storage) {
179 storage.updateFromShortcutIntent(resultIntent); 175 storage.updateFromShortcutIntent(resultIntent);
180 nativeOnWebappDataStored(callbackPointer); 176 nativeOnWebappDataStored(callbackPointer);
181 } 177 }
182 }); 178 });
183 179 if (ChromeShortcutManager.getInstance().shouldShowAddedToHomescr eenToast()) {
184 showAddedToHomescreenToast(userTitle); 180 showAddedToHomescreenToast(userTitle);
181 }
185 } 182 }
186 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 183 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
187 } 184 }
188 185
189 public static void addWebApkShortcut(Context context, String packageName) { 186 public static void addWebApkShortcut(Context context, String packageName) {
190 PackageManager pm = context.getPackageManager(); 187 PackageManager pm = context.getPackageManager();
191 try { 188 try {
192 ApplicationInfo appInfo = pm.getApplicationInfo( 189 ApplicationInfo appInfo = pm.getApplicationInfo(
193 packageName, PackageManager.GET_META_DATA); 190 packageName, PackageManager.GET_META_DATA);
194 String shortcutTitle = pm.getApplicationLabel(appInfo).toString(); 191 String shortcutTitle = pm.getApplicationLabel(appInfo).toString();
195 Bitmap shortcutIcon = ((BitmapDrawable) pm.getApplicationIcon(packag eName)).getBitmap(); 192 Bitmap shortcutIcon = ((BitmapDrawable) pm.getApplicationIcon(packag eName)).getBitmap();
196 193
197 Bitmap bitmap = createHomeScreenIconFromWebIcon(shortcutIcon); 194 Bitmap bitmap = createHomeScreenIconFromWebIcon(shortcutIcon);
198 Intent i = new Intent(); 195 Intent i = new Intent();
199 i.setClassName(packageName, WEBAPK_MAIN_ACTIVITY); 196 i.setClassName(packageName, WEBAPK_MAIN_ACTIVITY);
200 i.addCategory(Intent.CATEGORY_LAUNCHER); 197 i.addCategory(Intent.CATEGORY_LAUNCHER);
201 context.sendBroadcast(createAddToHomeIntent(shortcutTitle, bitmap, i )); 198 context.sendBroadcast(
199 ChromeShortcutManager.createAddToHomeIntent(shortcutTitle, b itmap, i));
202 } catch (NameNotFoundException e) { 200 } catch (NameNotFoundException e) {
203 e.printStackTrace(); 201 e.printStackTrace();
204 } 202 }
205 } 203 }
206 204
207 /** 205 /**
208 * Adds home screen shortcut which opens in the browser Activity. 206 * Adds home screen shortcut which opens in the browser Activity.
209 */ 207 */
210 @SuppressWarnings("unused") 208 @SuppressWarnings("unused")
211 @CalledByNative 209 @CalledByNative
212 private static void addShortcut(String url, String userTitle, Bitmap icon, i nt source) { 210 private static void addShortcut(
211 String id, String url, String userTitle, Bitmap icon, int source) {
213 Context context = ContextUtils.getApplicationContext(); 212 Context context = ContextUtils.getApplicationContext();
dominickn 2017/02/14 03:04:21 Remove context from here, and call setPackage() in
Marti Wong 2017/02/14 04:37:51 will keep getPackageName() below. So this context
214 final Intent shortcutIntent = createShortcutIntent(url); 213 final Intent shortcutIntent = createShortcutIntent(url);
214 shortcutIntent.putExtra(EXTRA_ID, id);
215 shortcutIntent.putExtra(EXTRA_SOURCE, source); 215 shortcutIntent.putExtra(EXTRA_SOURCE, source);
216 shortcutIntent.setPackage(context.getPackageName()); 216 shortcutIntent.setPackage(context.getPackageName());
217 sDelegate.sendBroadcast( 217 sDelegate.addShortcutToHomescreen(userTitle, icon, shortcutIntent);
218 context, createAddToHomeIntent(userTitle, icon, shortcutIntent)) ; 218 if (ChromeShortcutManager.getInstance().shouldShowAddedToHomescreenToast ()) {
219 showAddedToHomescreenToast(userTitle); 219 showAddedToHomescreenToast(userTitle);
220 }
220 } 221 }
221 222
222 /** 223 /**
223 * Show toast to alert user that the shortcut was added to the home screen. 224 * Show toast to alert user that the shortcut was added to the home screen.
224 */ 225 */
225 private static void showAddedToHomescreenToast(final String title) { 226 private static void showAddedToHomescreenToast(final String title) {
226 Context applicationContext = ContextUtils.getApplicationContext(); 227 Context applicationContext = ContextUtils.getApplicationContext();
227 String toastText = applicationContext.getString(R.string.added_to_homesc reen, title); 228 String toastText = applicationContext.getString(R.string.added_to_homesc reen, title);
228 showToast(toastText); 229 showToast(toastText);
229 } 230 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 267
267 @Override 268 @Override
268 protected void onPostExecute(String encodedImage) { 269 protected void onPostExecute(String encodedImage) {
269 storage.updateSplashScreenImage(encodedImage); 270 storage.updateSplashScreenImage(encodedImage);
270 } 271 }
271 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 272 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
272 } 273 }
273 } 274 }
274 275
275 /** 276 /**
276 * Creates an intent that will add a shortcut to the home screen.
277 * @param title Title of the shortcut.
278 * @param icon Image that represents the shortcut.
279 * @param shortcutIntent Intent to fire when the shortcut is activated.
280 * @return Intent for the shortcut.
281 */
282 public static Intent createAddToHomeIntent(String title, Bitmap icon,
283 Intent shortcutIntent) {
284 Intent i = new Intent(INSTALL_SHORTCUT);
285 i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
286 i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
287 i.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon);
288 return i;
289 }
Marti Wong 2017/02/14 04:37:50 Moved to ChromeShortcutManager
290
291 /**
292 * Creates a shortcut to launch a web app on the home screen. 277 * Creates a shortcut to launch a web app on the home screen.
293 * @param id Id of the web app. 278 * @param id Id of the web app.
294 * @param action Intent action to open a full screen activity. 279 * @param action Intent action to open a full screen activity.
295 * @param url Url of the web app. 280 * @param url Url of the web app.
296 * @param scope Url scope of the web app. 281 * @param scope Url scope of the web app.
297 * @param name Name of the web app. 282 * @param name Name of the web app.
298 * @param shortName Short name of the web app. 283 * @param shortName Short name of the web app.
299 * @param icon Icon of the web app. 284 * @param icon Icon of the web app.
300 * @param version Version number of the shortcut. 285 * @param version Version number of the shortcut.
301 * @param displayMode Display mode of the web app. 286 * @param displayMode Display mode of the web app.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 339 Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
355 shortcutIntent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true); 340 shortcutIntent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true);
356 return shortcutIntent; 341 return shortcutIntent;
357 } 342 }
358 343
359 /** 344 /**
360 * Utility method to check if a shortcut can be added to the home screen. 345 * Utility method to check if a shortcut can be added to the home screen.
361 * @param context Context used to get the package manager. 346 * @param context Context used to get the package manager.
362 * @return if a shortcut can be added to the home screen under the current p rofile. 347 * @return if a shortcut can be added to the home screen under the current p rofile.
363 */ 348 */
364 // TODO(crbug.com/635567): Fix this properly.
365 @SuppressLint("WrongConstant")
366 public static boolean isAddToHomeIntentSupported(Context context) { 349 public static boolean isAddToHomeIntentSupported(Context context) {
367 PackageManager pm = context.getPackageManager(); 350 return ChromeShortcutManager.getInstance().canAddShortcutToHomescreen();
368 Intent i = new Intent(INSTALL_SHORTCUT);
369 List<ResolveInfo> receivers = pm.queryBroadcastReceivers(
370 i, PackageManager.GET_INTENT_FILTERS);
371 return !receivers.isEmpty();
372 } 351 }
373 352
374 /** 353 /**
375 * Returns whether the given icon matches the size requirements to be used o n the home screen. 354 * Returns whether the given icon matches the size requirements to be used o n the home screen.
376 * @param width Icon width, in pixels. 355 * @param width Icon width, in pixels.
377 * @param height Icon height, in pixels. 356 * @param height Icon height, in pixels.
378 * @return whether the given icon matches the size requirements to be used o n the home screen. 357 * @return whether the given icon matches the size requirements to be used o n the home screen.
379 */ 358 */
380 @CalledByNative 359 @CalledByNative
381 public static boolean isIconLargeEnoughForLauncher(int width, int height) { 360 public static boolean isIconLargeEnoughForLauncher(int width, int height) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 for (int i = 0; i < list.size(); i++) { 679 for (int i = 0; i < list.size(); i++) {
701 array[i] = list.get(i); 680 array[i] = list.get(i);
702 } 681 }
703 return array; 682 return array;
704 } 683 }
705 684
706 private static native void nativeOnWebappDataStored(long callbackPointer); 685 private static native void nativeOnWebappDataStored(long callbackPointer);
707 private static native void nativeOnWebApksRetrieved(long callbackPointer, St ring[] shortNames, 686 private static native void nativeOnWebApksRetrieved(long callbackPointer, St ring[] shortNames,
708 String[] packageName, int[] shellApkVersions, int[] versionCodes); 687 String[] packageName, int[] shellApkVersions, int[] versionCodes);
709 } 688 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698