| Index: chrome/android/java_staging/src/org/chromium/chrome/browser/hosted/HostedIntentDataProvider.java
|
| diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/hosted/HostedIntentDataProvider.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/hosted/HostedIntentDataProvider.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a3587e59f4f2eebfca7ad3ff00fe0933ab6df8c9
|
| --- /dev/null
|
| +++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/hosted/HostedIntentDataProvider.java
|
| @@ -0,0 +1,245 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.chrome.browser.hosted;
|
| +
|
| +import android.app.Activity;
|
| +import android.app.PendingIntent;
|
| +import android.app.PendingIntent.CanceledException;
|
| +import android.content.Context;
|
| +import android.content.Intent;
|
| +import android.graphics.Bitmap;
|
| +import android.graphics.Color;
|
| +import android.net.Uri;
|
| +import android.os.Bundle;
|
| +import android.text.TextUtils;
|
| +import android.util.Pair;
|
| +
|
| +import com.google.android.apps.chrome.R;
|
| +
|
| +import org.chromium.base.Log;
|
| +
|
| +import java.util.ArrayList;
|
| +import java.util.List;
|
| +
|
| +/**
|
| + * A model class that parses intent from third-party apps and provides results to
|
| + * {@link HostedActivity}.
|
| + */
|
| +public class HostedIntentDataProvider {
|
| + private static final String TAG = "HostedIntentDataProvider";
|
| +
|
| + /**
|
| + * Extra used to match the session. Its value is a long returned by
|
| + * {@link IBrowserConnectionService#newSession}.
|
| + */
|
| + public static final String EXTRA_HOSTED_SESSION_ID = "hosted:session_id";
|
| +
|
| + /**
|
| + * Extra that changes the background color for the omnibox. colorRes is an int that specifies a
|
| + * color
|
| + */
|
| + public static final String EXTRA_HOSTED_TOOLBAR_COLOR = "hosted:toolbar_color";
|
| +
|
| + /**
|
| + * Bundle used for the action button parameters.
|
| + */
|
| + public static final String EXTRA_HOSTED_ACTION_BUTTON_BUNDLE = "hosted:action_button_bundle";
|
| +
|
| + /**
|
| + * Key that specifies the Bitmap to be used as the image source for the action button.
|
| + */
|
| + public static final String KEY_HOSTED_ICON = "hosted:icon";
|
| +
|
| + /**
|
| + * Key that specifies the PendingIntent to launch when the action button or menu item was
|
| + * clicked. Chrome will be calling {@link PendingIntent#send()} on clicks after adding the url
|
| + * as data. The client app can call {@link Intent#getDataString()} to get the url.
|
| + */
|
| + public static final String KEY_HOSTED_PENDING_INTENT = "hosted:pending_intent";
|
| +
|
| + /**
|
| + * Use an {@code ArrayList<Bundle>} for specifying menu related params. There should be a
|
| + * separate Bundle for each custom menu item.
|
| + */
|
| + public static final String EXTRA_HOSTED_MENU_ITEMS = "hosted:menu_items";
|
| +
|
| + /**
|
| + * Key for the title of a menu item.
|
| + */
|
| + public static final String KEY_HOSTED_MENU_TITLE = "hosted:menu_title";
|
| +
|
| + /**
|
| + * Bundle constructed out of ActivityOptions that Chrome will be running when it finishes
|
| + * HostedActivity. A similar ActivityOptions for starting Chrome should be constructed and
|
| + * given to the startActivity() call that launches Chrome.
|
| + */
|
| + public static final String EXTRA_HOSTED_EXIT_ANIMATION_BUNDLE = "hosted:exit_animation_bundle";
|
| +
|
| + /**
|
| + * An invalid session ID, used when none is provided in the intent.
|
| + */
|
| + public static final long INVALID_SESSION_ID = -1;
|
| +
|
| + private static final String BUNDLE_PACKAGE_NAME = "android:packageName";
|
| + private static final String BUNDLE_ENTER_ANIMATION_RESOURCE = "android:animEnterRes";
|
| + private static final String BUNDLE_EXIT_ANIMATION_RESOURCE = "android:animExitRes";
|
| + private final long mSessionId;
|
| + private int mToolbarColor;
|
| + private Bitmap mIcon;
|
| + private PendingIntent mActionButtonPendingIntent;
|
| + private List<Pair<String, PendingIntent>> mMenuEntries = new ArrayList<>();
|
| + private Bundle mAnimationBundle;
|
| +
|
| + /**
|
| + * Constructs a {@link HostedIntentDataProvider}.
|
| + */
|
| + public HostedIntentDataProvider(Intent intent, Context context) {
|
| + if (intent == null) assert false;
|
| +
|
| + mSessionId = intent.getLongExtra(EXTRA_HOSTED_SESSION_ID, INVALID_SESSION_ID);
|
| + retrieveToolbarColor(intent, context);
|
| + Bundle actionButtonBundle = intent.getBundleExtra(EXTRA_HOSTED_ACTION_BUTTON_BUNDLE);
|
| + if (actionButtonBundle != null) {
|
| + mIcon = (Bitmap) actionButtonBundle.getParcelable(KEY_HOSTED_ICON);
|
| + mActionButtonPendingIntent = (PendingIntent) actionButtonBundle.getParcelable(
|
| + KEY_HOSTED_PENDING_INTENT);
|
| + }
|
| + List<Bundle> menuItems = intent.getParcelableArrayListExtra(EXTRA_HOSTED_MENU_ITEMS);
|
| + if (menuItems != null) {
|
| + for (Bundle bundle : menuItems) {
|
| + String title = bundle.getString(KEY_HOSTED_MENU_TITLE);
|
| + PendingIntent pendingIntent = bundle.getParcelable(KEY_HOSTED_PENDING_INTENT);
|
| + if (TextUtils.isEmpty(title) || pendingIntent == null) continue;
|
| + mMenuEntries.add(new Pair<String, PendingIntent>(title, pendingIntent));
|
| + }
|
| + }
|
| + mAnimationBundle = intent.getBundleExtra(EXTRA_HOSTED_EXIT_ANIMATION_BUNDLE);
|
| + }
|
| +
|
| + /**
|
| + * Processes the color passed from the client app and updates {@link #mToolbarColor}.
|
| + */
|
| + private void retrieveToolbarColor(Intent intent, Context context) {
|
| + int color = intent.getIntExtra(EXTRA_HOSTED_TOOLBAR_COLOR,
|
| + context.getResources().getColor(R.color.default_primary_color));
|
| + int defaultColor = context.getResources().getColor(R.color.default_primary_color);
|
| +
|
| + if (color == Color.TRANSPARENT) color = defaultColor;
|
| +
|
| + // Ignore any transparency value.
|
| + color |= 0xFF000000;
|
| +
|
| + mToolbarColor = color;
|
| + }
|
| +
|
| + /**
|
| + * @return The session ID specified in the intent. Will be
|
| + * INVALID_SESSION_ID if it is not set in the intent.
|
| + */
|
| + public long getSessionId() {
|
| + return mSessionId;
|
| + }
|
| +
|
| + /**
|
| + * @return The toolbar color specified in the intent. Will return the color of
|
| + * default_primary_color, if not set in the intent.
|
| + */
|
| + public int getToolbarColor() {
|
| + return mToolbarColor;
|
| + }
|
| +
|
| + /**
|
| + * @return Whether the client app has provided sufficient info for the toolbar to show the
|
| + * action button.
|
| + */
|
| + public boolean shouldShowActionButton() {
|
| + return mIcon != null && mActionButtonPendingIntent != null;
|
| + }
|
| +
|
| + /**
|
| + * @return The icon used for the action button. Will be null if not set in the intent.
|
| + */
|
| + public Bitmap getActionButtonIcon() {
|
| + return mIcon;
|
| + }
|
| +
|
| + /**
|
| + * @return Titles of menu items that were passed from client app via intent.
|
| + */
|
| + public List<String> getMenuTitles() {
|
| + ArrayList<String> list = new ArrayList<>();
|
| + for (Pair<String, PendingIntent> pair : mMenuEntries) {
|
| + list.add(pair.first);
|
| + }
|
| + return list;
|
| + }
|
| +
|
| + /**
|
| + * Triggers the client-defined action when the user clicks a custom menu item.
|
| + * @param menuIndex The index that the menu item is shown in the result of
|
| + * {@link #getMenuTitles()}
|
| + */
|
| + public void clickMenuItemWithUrl(Context context, int menuIndex, String url) {
|
| + Intent addedIntent = new Intent();
|
| + addedIntent.setData(Uri.parse(url));
|
| + try {
|
| + PendingIntent pendingIntent = mMenuEntries.get(menuIndex).second;
|
| + pendingIntent.send(context, 0, addedIntent);
|
| + } catch (CanceledException e) {
|
| + Log.e(TAG, "Hosted chrome failed to send pending intent.");
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @return Whether chrome should animate when it finishes. We show animations only if the client
|
| + * app has supplied the correct animation resources via intent extra.
|
| + */
|
| + public boolean shouldAnimateOnFinish() {
|
| + return mAnimationBundle != null && getClientPackageName() != null;
|
| + }
|
| +
|
| + /**
|
| + * @return The package name of the client app. This is used for a workaround in order to
|
| + * retrieve the client's animation resources.
|
| + */
|
| + public String getClientPackageName() {
|
| + if (mAnimationBundle == null) return null;
|
| + return mAnimationBundle.getString(BUNDLE_PACKAGE_NAME);
|
| + }
|
| +
|
| + /**
|
| + * @return The resource id for enter animation, which is used in
|
| + * {@link Activity#overridePendingTransition(int, int)}.
|
| + */
|
| + public int getAnimationEnterRes() {
|
| + return shouldAnimateOnFinish() ? mAnimationBundle.getInt(BUNDLE_ENTER_ANIMATION_RESOURCE)
|
| + : 0;
|
| + }
|
| +
|
| + /**
|
| + * @return The resource id for exit animation, which is used in
|
| + * {@link Activity#overridePendingTransition(int, int)}.
|
| + */
|
| + public int getAnimationExitRes() {
|
| + return shouldAnimateOnFinish() ? mAnimationBundle.getInt(BUNDLE_EXIT_ANIMATION_RESOURCE)
|
| + : 0;
|
| + }
|
| +
|
| + /**
|
| + * Send the pending intent for the current action button with the given url as data.
|
| + * @param context The context to use for sending the {@link PendingIntent}.
|
| + * @param url The url to attach as additional data to the {@link PendingIntent}.
|
| + */
|
| + public void sendButtonPendingIntentWithUrl(Context context, String url) {
|
| + assert mActionButtonPendingIntent != null;
|
| + Intent addedIntent = new Intent();
|
| + addedIntent.setData(Uri.parse(url));
|
| + try {
|
| + mActionButtonPendingIntent.send(context, 0, addedIntent);
|
| + } catch (CanceledException e) {
|
| + Log.e(TAG, "CanceledException while sending pending intent in hosted mode");
|
| + }
|
| + }
|
| +}
|
|
|