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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/customtabs/ActionButtonParams.java

Issue 1557803002: [Custom Tabs] Implement Bottombar (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplify APIs Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/customtabs/ActionButtonParams.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ActionButtonParams.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ActionButtonParams.java
index 9c959b26699ac70725974b8190411bdb876f964e..2d2a428ac63ecf5878000b5286654cbd5f7ea1af 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ActionButtonParams.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ActionButtonParams.java
@@ -5,7 +5,9 @@
package org.chromium.chrome.browser.customtabs;
import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
@@ -14,28 +16,42 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.customtabs.CustomTabsIntent;
import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
import org.chromium.base.Log;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.chrome.browser.widget.TintedDrawable;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
/**
- * Container for all parameters related to creating a custom action button.
+ * Container for all parameters related to creating a customizable button.
*/
-/* package */ class ActionButtonParams {
- private static final String TAG = "CustomTabs";
+class ActionButtonParams {
+ protected static final String TAG = "CustomTabs";
- private Bitmap mIcon;
- private String mDescription;
- private final PendingIntent mPendingIntent;
+ private int mId;
+ protected Bitmap mIcon;
+ protected String mDescription;
+ protected final PendingIntent mPendingIntent;
private boolean mShouldTint;
+ private boolean mOnToolbar;
- private ActionButtonParams(@NonNull Bitmap icon, @NonNull String description,
- @NonNull PendingIntent pendingIntent) {
+ private ActionButtonParams(int id, @NonNull Bitmap icon, @NonNull String description,
+ PendingIntent pendingIntent, boolean tinted, boolean onToolbar) {
+ mId = id;
mIcon = icon;
mDescription = description;
mPendingIntent = pendingIntent;
+ mShouldTint = tinted;
+ mOnToolbar = onToolbar;
}
/**
@@ -47,79 +63,161 @@ import org.chromium.chrome.browser.widget.TintedDrawable;
}
/**
- * Sets whether the action button icon should be tinted.
+ * @return Whether this button should be shown on the toolbar.
+ */
+ boolean showOnToolbar() {
+ return mOnToolbar;
+ }
+
+ /**
+ * @return The id associated with this button. Action button on the toolbar always uses
+ * {@link #TOOLBAR_ACTION_BUTTON_ID} as id.
*/
- void setTinted(boolean shouldTint) {
- mShouldTint = shouldTint;
+ int getId() {
+ return mId;
}
/**
- * @return The drawable for the action button. Will be a {@link TintedDrawable} if in the VIEW
- * intent the client required to tint it.
+ * @return The drawable for the customized button. If the button should be tinted, returns a
+ * {@link TintedDrawable}
*/
Drawable getIcon(Resources res) {
- Drawable drawable = null;
- if (mShouldTint) {
- drawable = TintedDrawable.constructTintedDrawable(res, mIcon);
- } else {
- drawable = new BitmapDrawable(res, mIcon);
- }
- return drawable;
+ if (mShouldTint) return TintedDrawable.constructTintedDrawable(res, mIcon);
+ else return new BitmapDrawable(res, mIcon);
}
/**
- * @return The content description for the custom action button.
+ * @return The content description for the customized button.
*/
String getDescription() {
return mDescription;
}
/**
- * @return The {@link PendingIntent} that will be sent when the user clicks the action button.
+ * @return The {@link PendingIntent} that will be sent when user clicks the customized button.
*/
PendingIntent getPendingIntent() {
return mPendingIntent;
}
/**
- * Parses an {@link ActionButtonParams} from an action button bundle sent by clients.
- * @param bundle The action button bundle specified by
- * {@link CustomTabsIntent#EXTRA_ACTION_BUTTON_BUNDLE}
- * @return The parsed {@link ActionButtonParams}. Return null if input is invalid.
+ * Converts the params to an {@link ImageButton} on the bottom bar.
+ * @param parent The parent that the inflated {@link ImageButton}.
+ * @return The inflated {@link ImageButton}. Returns null if this button is shown in toolbar.
*/
- static ActionButtonParams fromBundle(Context context, Bundle bundle) {
+ ImageButton toBottomBarButton(Context context, ViewGroup parent) {
+ if (mOnToolbar) return null;
+
+ ImageButton button = (ImageButton) LayoutInflater.from(context)
+ .inflate(R.layout.custom_tabs_bottombar_item, parent, false);
+ button.setImageBitmap(mIcon);
+ button.setContentDescription(mDescription);
+ if (mPendingIntent == null) {
+ button.setEnabled(false);
+ } else {
+ // TODO(ianwen): add UMA for botton clicking.
Yusuf 2016/01/06 06:51:14 button
Ian Wen 2016/01/06 10:50:59 Done.
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ try {
+ mPendingIntent.send();
+ } catch (CanceledException e) {
+ Log.e(TAG, "CanceledException while sending pending intent in custom tab");
+ }
+ }
+ });
+ }
+ return button;
+ }
+
+ /**
+ * Parses a list of {@link ActionButtonParams} from the intent sent by clients.
+ * @param intent The intent sent by the client.
+ * @return A list of parsed {@link ActionButtonParams}. Return an empty list if input is invalid
+ */
+ static List<ActionButtonParams> fromIntent(Context context, Intent intent) {
+ List<ActionButtonParams> result = new ArrayList<>(1);
Yusuf 2016/01/06 06:51:14 paramsList
Ian Wen 2016/01/06 10:50:59 Done.
+ if (intent == null) return result;
+
+ Bundle singleBundle = IntentUtils.safeGetBundleExtra(intent,
+ CustomTabsIntent.EXTRA_ACTION_BUTTON_BUNDLE);
+ ArrayList<Bundle> bundleList = IntentUtils.getParcelableArrayListExtra(intent,
+ CustomTabsIntent.EXTRA_ACTION_BUTTON_BUNDLE);
Yusuf 2016/01/06 06:51:14 wrong extra here
Ian Wen 2016/01/06 10:50:59 hmm this is intentional. The client now is able to
+ boolean tinted = IntentUtils.safeGetBooleanExtra(intent,
+ CustomTabsIntent.EXTRA_TINT_ACTION_BUTTON, false);
+ if (singleBundle != null) {
+ ActionButtonParams params = fromBundle(context, singleBundle, tinted);
+ result.add(params);
+ return result;
+ } else if (bundleList != null) {
+ Set<Integer> ids = new HashSet<>();
+ for (Bundle bundle : bundleList) {
+ ActionButtonParams params = fromBundle(context, bundle, tinted);
+ if (params == null) {
+ continue;
+ } else if (ids.contains(params.getId())) {
+ Log.e(TAG, "Bottom bar items contain duplicate id: " + params.getId());
+ continue;
+ }
+ ids.add(params.getId());
+ result.add(params);
+ }
+ return result;
+ }
+ return result;
+ }
+
+ /**
+ * Parses a ButtonParams out of a bundle. Note if an action button contains a bitmap that does
+ * not fit into toolbar, it will be pushed to bottom bar.
+ */
+ private static ActionButtonParams fromBundle(Context context, Bundle bundle, boolean tinted) {
if (bundle == null) return null;
- Bitmap bitmap = tryParseBitmapFromBundle(context, bundle);
- if (bitmap == null) return null;
+ int id = IntentUtils.safeGetInt(bundle, CustomTabsIntent.KEY_ID,
+ CustomTabsIntent.TOOLBAR_ACTION_BUTTON_ID);
Yusuf 2016/01/06 06:51:14 This will misbehave if the client doesn't add any
Ian Wen 2016/01/06 10:51:00 Right. In the old API no ID was not included so we
+
+ Bitmap bitmap = tryParseBitmapFromBundle(bundle);
+ if (bitmap == null) {
+ Log.e(TAG, "Invalid action button: bitmap not present in bundle!");
+ return null;
+ }
String description = tryParseDescriptionFromBundle(bundle);
if (TextUtils.isEmpty(description)) {
+ Log.e(TAG, "Invalid action button: content description not present in bundle!");
bitmap.recycle();
return null;
}
+ boolean onToolbar = id == CustomTabsIntent.TOOLBAR_ACTION_BUTTON_ID;
+ if (onToolbar && !checkCustomButtonIconWithinBounds(context, bitmap)) {
+ onToolbar = false;
+ Log.w(TAG, "Button's icon not suitable for toolbar, push it to bottom bar instead."
Yusuf 2016/01/06 06:51:14 s/push/putting
Ian Wen 2016/01/06 10:50:59 Done.
+ + "See: https://developer.android.com/reference/android/support/customtabs/"
+ + "CustomTabsIntent.html#KEY_ICON");
+ }
+
PendingIntent pi = IntentUtils.safeGetParcelable(bundle,
CustomTabsIntent.KEY_PENDING_INTENT);
- if (pi == null) return null;
- return new ActionButtonParams(bitmap, description, pi);
+ // PendingIntent is a must for buttons on the toolbar, but it's optional for bottombar.
+ if (onToolbar && pi == null) {
+ Log.w(TAG, "Invalid action button on toolbar: pending intent not present in bundle!");
+ bitmap.recycle();
+ return null;
+ }
+
+ return new ActionButtonParams(id, bitmap, description, pi, tinted, onToolbar);
}
/**
* @return The bitmap contained in the given {@link Bundle}. Will return null if input is
* invalid.
*/
- static Bitmap tryParseBitmapFromBundle(Context context, Bundle bundle) {
+ static Bitmap tryParseBitmapFromBundle(Bundle bundle) {
if (bundle == null) return null;
Bitmap bitmap = IntentUtils.safeGetParcelable(bundle, CustomTabsIntent.KEY_ICON);
if (bitmap == null) return null;
- if (!checkCustomButtonIconWithinBounds(context, bitmap)) {
- Log.w(TAG, "Action button's icon size not acceptable. Please refer to "
- + "https://developer.android.com/reference/android/support/customtabs/"
- + "CustomTabsIntent.html#KEY_ICON");
- bitmap.recycle();
- return null;
- }
return bitmap;
}

Powered by Google App Engine
This is Rietveld 408576698