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
3 // found in the LICENSE file.
5 package org.chromium.chrome.browser;
7 import android.app.ActivityManager;
8 import android.content.Context;
9 import android.content.Intent;
10 import android.graphics.Bitmap;
11 import android.text.TextUtils;
12 import android.util.Base64;
13 import android.util.Log;
15 import org.chromium.base.CalledByNative;
16 import org.chromium.content_public.common.ScreenOrientationConstants;
18 import java.io.ByteArrayOutputStream;
19 import java.util.UUID;
22 * This is a helper class to create shortcuts on the Android home screen.
24 public class ShortcutHelper {
25 public static final String EXTRA_ICON = "org.chromium.chrome.browser.webapp_icon";
26 public static final String EXTRA_ID = "org.chromium.chrome.browser.webapp_id";
27 public static final String EXTRA_MAC = "org.chromium.chrome.browser.webapp_mac";
28 public static final String EXTRA_TITLE = "org.chromium.chrome.browser.webapp_title";
29 public static final String EXTRA_URL = "org.chromium.chrome.browser.webapp_url";
30 public static final String EXTRA_ORIENTATION = ScreenOrientationConstants.EXTRA_ORIENTATION;
32 private static String sFullScreenAction;
35 * Sets the class name used when launching the shortcuts.
36 * @param fullScreenAction Class name of the fullscreen Activity.
38 public static void setFullScreenAction(String fullScreenAction) {
39 sFullScreenAction = fullScreenAction;
43 * Callback to be passed to the initialized() method.
45 public interface OnInitialized {
46 public void onInitialized(String title);
49 private final Context mAppContext;
50 private final Tab mTab;
52 private OnInitialized mCallback;
53 private boolean mIsInitialized;
54 private long mNativeShortcutHelper;
56 public ShortcutHelper(Context appContext, Tab tab) {
57 mAppContext = appContext;
62 * Gets all the information required to initialize the UI, the passed
63 * callback will be run when those information will be available.
64 * @param callback Callback to be run when initialized.
66 public void initialize(OnInitialized callback) {
68 mNativeShortcutHelper = nativeInitialize(mTab.getNativePtr());
72 * Returns whether the object is initialized.
74 public boolean isInitialized() {
75 return mIsInitialized;
79 * Puts the object in a state where it is safe to be destroyed.
81 public void tearDown() {
82 nativeTearDown(mNativeShortcutHelper);
84 // Make sure the callback isn't run if the tear down happens before
85 // onInitialized() is called.
87 mNativeShortcutHelper = 0;
91 private void onInitialized(String title) {
92 mIsInitialized = true;
94 if (mCallback != null) {
95 mCallback.onInitialized(title);
100 * Adds a shortcut for the current Tab.
101 * @param userRequestedTitle Updated title for the shortcut.
103 public void addShortcut(String userRequestedTitle) {
104 if (TextUtils.isEmpty(sFullScreenAction)) {
105 Log.e("ShortcutHelper", "ShortcutHelper is uninitialized. Aborting.");
108 ActivityManager am = (ActivityManager) mAppContext.getSystemService(
109 Context.ACTIVITY_SERVICE);
110 nativeAddShortcut(mNativeShortcutHelper, userRequestedTitle, am.getLauncherLargeIconSize());
112 // The C++ instance is no longer owned by the Java object.
114 mNativeShortcutHelper = 0;
118 * Called when we have to fire an Intent to add a shortcut to the homescreen.
119 * If the webpage indicated that it was capable of functioning as a webapp, it is added as a
120 * shortcut to a webapp Activity rather than as a general bookmark. User is sent to the
121 * homescreen as soon as the shortcut is created.
123 @SuppressWarnings("unused")
125 private static void addShortcut(Context context, String url, String title, Bitmap icon,
126 int red, int green, int blue, boolean isWebappCapable, int orientation) {
127 assert sFullScreenAction != null;
129 Intent shortcutIntent;
130 if (isWebappCapable) {
131 // Encode the icon as a base64 string (Launcher drops Bitmaps in the Intent).
132 String encodedIcon = "";
134 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
135 icon.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
136 byte[] byteArray = byteArrayOutputStream.toByteArray();
137 encodedIcon = Base64.encodeToString(byteArray, Base64.DEFAULT);
140 // Add the shortcut as a launcher icon for a full-screen Activity.
141 shortcutIntent = new Intent();
142 shortcutIntent.setAction(sFullScreenAction);
143 shortcutIntent.putExtra(EXTRA_ICON, encodedIcon);
144 shortcutIntent.putExtra(EXTRA_ID, UUID.randomUUID().toString());
145 shortcutIntent.putExtra(EXTRA_TITLE, title);
146 shortcutIntent.putExtra(EXTRA_URL, url);
147 shortcutIntent.putExtra(EXTRA_ORIENTATION, orientation);
149 // The only reason we convert to a String here is because Android inexplicably eats a
150 // byte[] when adding the shortcut -- the Bundle received by the launched Activity even
151 // lacks the key for the extra.
152 byte[] mac = WebappAuthenticator.getMacForUrl(context, url);
153 String encodedMac = Base64.encodeToString(mac, Base64.DEFAULT);
154 shortcutIntent.putExtra(EXTRA_MAC, encodedMac);
156 // Add the shortcut as a launcher icon to open in the browser Activity.
157 shortcutIntent = BookmarkUtils.createShortcutIntent(context, url);
160 shortcutIntent.setPackage(context.getPackageName());
161 context.sendBroadcast(BookmarkUtils.createAddToHomeIntent(context, shortcutIntent, title,
162 icon, red, green, blue));
164 // User is sent to the homescreen as soon as the shortcut is created.
165 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
166 homeIntent.addCategory(Intent.CATEGORY_HOME);
167 homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
168 context.startActivity(homeIntent);
171 private native long nativeInitialize(long tabAndroidPtr);
172 private native void nativeAddShortcut(long nativeShortcutHelper, String userRequestedTitle,
173 int launcherLargeIconSize);
174 private native void nativeTearDown(long nativeShortcutHelper);