Bug 1329145 - Part 2: To apply custom animation if any draft
authorJulian_Chu <walkingice0204@gmail.com>
Wed, 25 Jan 2017 19:07:21 +0800
changeset 469532 0118aafb57323ac3335d2b3b682be18a2c87987e
parent 467102 faff293235365ef19dfb0d221e992123fe37c94d
child 469533 7f5845146485a05113326e755b37a15165eddce1
push id43756
push userbmo:walkingice0204@gmail.com
push dateThu, 02 Feb 2017 08:43:17 +0000
bugs1329145
milestone53.0a1
Bug 1329145 - Part 2: To apply custom animation if any 3rd party app could specify its own custom-exit-animation when launching CustomTabsActivity. For that case, to call `overridePendingTransition` in method finish(). MozReview-Commit-ID: CivYpP2jvXp
mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
mobile/android/base/java/org/mozilla/gecko/customtabs/IntentUtil.java
mobile/android/base/moz.build
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
@@ -39,16 +39,19 @@ public class CustomTabsActivity extends 
 
     private ActionBar actionBar;
     private int tabId = -1;
     private boolean useDomainTitle = true;
 
     private int toolbarColor;
     private String toolbarTitle;
 
+    // A state to indicate whether this activity is finishing with customize animation
+    private boolean usingCustomAnimation = false;
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         if (savedInstanceState != null) {
             toolbarColor = savedInstanceState.getInt(SAVED_TOOLBAR_COLOR, NO_COLOR);
             toolbarTitle = savedInstanceState.getString(SAVED_TOOLBAR_TITLE, AppConstants.MOZ_APP_BASENAME);
         } else {
@@ -98,16 +101,42 @@ public class CustomTabsActivity extends 
         if (ColorUtil.getReadableTextColor(toolbarColor) == Color.BLACK) {
             setTheme(R.style.Theme_AppCompat_Light_NoActionBar);
         } else {
             setTheme(R.style.Theme_AppCompat_NoActionBar);
         }
 
     }
 
+    // Bug 1329145: 3rd party app could specify customized exit-animation to this activity.
+    // Activity.overridePendingTransition will invoke getPackageName to retrieve that animation resource.
+    // In that case, to return different package name to get customized animation resource.
+    @Override
+    public String getPackageName() {
+        if (usingCustomAnimation) {
+            // Use its package name to retrieve animation resource
+            return IntentUtil.getAnimationPackageName(getIntent());
+        } else {
+            return super.getPackageName();
+        }
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+
+        // When 3rd party app launch this Activity, it could also specify custom exit-animation.
+        if (IntentUtil.hasExitAnimation(getIntent())) {
+            usingCustomAnimation = true;
+            overridePendingTransition(IntentUtil.getEnterAnimationRes(getIntent()),
+                    IntentUtil.getExitAnimationRes(getIntent()));
+            usingCustomAnimation = false;
+        }
+    }
+
     @Override
     public void onDestroy() {
         super.onDestroy();
         Tabs.unregisterOnTabsChangedListener(this);
     }
 
     @Override
     public int getLayout() {
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/IntentUtil.java
@@ -0,0 +1,96 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.customtabs;
+
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.customtabs.CustomTabsIntent;
+
+/**
+ * A utility class for CustomTabsActivity to extract information from intent.
+ * For example, this class helps to extract exit-animation resource id.
+ */
+class IntentUtil {
+
+    public static final int NO_ANIMATION_RESOURCE = -1;
+
+    // Hidden constant values from ActivityOptions.java
+    private static final String PREFIX = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+            ? "android:activity."
+            : "android:";
+    private static final String KEY_PACKAGE_NAME = PREFIX + "packageName";
+    private static final String KEY_ANIM_ENTER_RES_ID = PREFIX + "animEnterRes";
+    private static final String KEY_ANIM_EXIT_RES_ID = PREFIX + "animExitRes";
+
+    /**
+     * To get package name of 3rd-party-app from an intent.
+     * If the app defined extra exit-animation to use, it should also provide its package name
+     * to get correct animation resource.
+     *
+     * @param intent which to launch a Custom-Tabs-Activity
+     * @return package name, if the intent defined extra exit-animation bundle. Otherwise, null.
+     */
+    static String getAnimationPackageName(@NonNull Intent intent) {
+        final Bundle bundle = getAnimationBundle(intent);
+        return (bundle == null) ? null : bundle.getString(KEY_PACKAGE_NAME);
+    }
+
+    /**
+     * To check whether the intent has necessary information to apply customize exit-animation.
+     *
+     * @param intent which to launch a Custom-Tabs-Activity
+     * @return true, if the intent has necessary information.
+     */
+    static boolean hasExitAnimation(@NonNull Intent intent) {
+        final Bundle bundle = getAnimationBundle(intent);
+        return (bundle != null)
+                && (getAnimationPackageName(intent) != null)
+                && (getEnterAnimationRes(intent) != NO_ANIMATION_RESOURCE)
+                && (getExitAnimationRes(intent) != NO_ANIMATION_RESOURCE);
+    }
+
+    /**
+     * To get enter-animation resource id of 3rd-party-app from an intent.
+     * If the app defined extra exit-animation to use, it should also provide its animation resource
+     * id.
+     *
+     * @param intent which to launch a Custom-Tabs-Activity
+     * @return animation resource id if any; otherwise, NO_ANIMATION_RESOURCE;
+     */
+    static int getEnterAnimationRes(@NonNull Intent intent) {
+        final Bundle bundle = getAnimationBundle(intent);
+        return (bundle == null)
+                ? NO_ANIMATION_RESOURCE
+                : bundle.getInt(KEY_ANIM_ENTER_RES_ID, NO_ANIMATION_RESOURCE);
+    }
+
+    /**
+     * To get exit-animation resource id of 3rd-party-app from an intent.
+     * If the app defined extra exit-animation to use, it should also provide its animation resource
+     * id.
+     *
+     * @param intent which to launch a Custom-Tabs-Activity
+     * @return animation resource id if any; otherwise, NO_ANIMATION_RESOURCE.
+     */
+    static int getExitAnimationRes(@NonNull Intent intent) {
+        final Bundle bundle = getAnimationBundle(intent);
+        return (bundle == null)
+                ? NO_ANIMATION_RESOURCE
+                : bundle.getInt(KEY_ANIM_EXIT_RES_ID, NO_ANIMATION_RESOURCE);
+    }
+
+    /**
+     * To extract extra exit-animation bundle from an intent.
+     *
+     * @param intent which to launch a Custom-Tabs-Activity
+     * @return bundle for extra exit-animation, if any. Otherwise, null.
+     */
+    private static Bundle getAnimationBundle(@NonNull Intent intent) {
+        return intent.getBundleExtra(CustomTabsIntent.EXTRA_EXIT_ANIMATION_BUNDLE);
+    }
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -352,16 +352,17 @@ gbjar.sources += ['java/org/mozilla/geck
     'BootReceiver.java',
     'BrowserApp.java',
     'BrowserLocaleManager.java',
     'cleanup/FileCleanupController.java',
     'cleanup/FileCleanupService.java',
     'CustomEditText.java',
     'customtabs/CustomTabsActivity.java',
     'customtabs/GeckoCustomTabsService.java',
+    'customtabs/IntentUtil.java',
     'DataReportingNotification.java',
     'db/AbstractPerProfileDatabaseProvider.java',
     'db/AbstractTransactionalProvider.java',
     'db/BaseTable.java',
     'db/BrowserDatabaseHelper.java',
     'db/BrowserDB.java',
     'db/BrowserProvider.java',
     'db/DBUtils.java',