Apply settings page transition
This change applies Shared X-Axis transition across settings pages. For
injected settings, the injected apps have to also apply the same
transition to take effect.
Fixes: 177479937
Test: robotests and navigate through settings pages
Change-Id: I6241860766f5969428faf9a5b3730a7614fdcd92
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 031fb8a..fd67aa8 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -77,6 +77,7 @@
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
+import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.Spannable;
@@ -109,6 +110,7 @@
import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.profileselector.ProfileFragmentBridge;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.password.ChooseLockSettingsHelper;
@@ -159,6 +161,9 @@
/** Whether or not app hibernation is enabled on the device **/
public static final String PROPERTY_APP_HIBERNATION_ENABLED = "app_hibernation_enabled";
+ /** Whether or not Settings Shared Axis transition is enabled */
+ public static final String SETTINGS_SHARED_AXIS_ENABLED = "settings_shared_axis_enabled";
+
/**
* Finds a matching activity for a preference's intent. If a matching
* activity is not found, it will remove the preference.
@@ -1196,4 +1201,12 @@
public static boolean isProviderModelEnabled(Context context) {
return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
}
+
+ public static boolean isPageTransitionEnabled(Context context) {
+ final boolean isSilkyHome = FeatureFlagUtils.isEnabled(context, FeatureFlags.SILKY_HOME);
+ final boolean isTransitionEnabled = Settings.Global.getInt(context.getContentResolver(),
+ SETTINGS_SHARED_AXIS_ENABLED, 0) == 1;
+
+ return isSilkyHome && isTransitionEnabled;
+ }
}
diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java
index cf3cd50..6215dc2 100644
--- a/src/com/android/settings/core/SettingsBaseActivity.java
+++ b/src/com/android/settings/core/SettingsBaseActivity.java
@@ -18,6 +18,7 @@
import android.annotation.LayoutRes;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -27,6 +28,7 @@
import android.content.res.TypedArray;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.FeatureFlagUtils;
@@ -43,8 +45,10 @@
import com.android.settings.R;
import com.android.settings.SubSettings;
+import com.android.settings.Utils;
import com.android.settings.dashboard.CategoryManager;
import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.transition.SettingsTransitionHelper;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -60,6 +64,7 @@
protected static final boolean DEBUG_TIMING = false;
private static final String TAG = "SettingsBaseActivity";
private static final String DATA_SCHEME_PKG = "package";
+ private static final int DEFAULT_REQUEST = -1;
// Serves as a temporary list of tiles to ignore until we heard back from the PM that they
// are disabled.
@@ -73,6 +78,13 @@
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
+ if (Utils.isPageTransitionEnabled(this)) {
+ // Enable Activity transitions
+ getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
+ SettingsTransitionHelper.applyForwardTransition(this);
+ SettingsTransitionHelper.applyBackwardTransition(this);
+ }
+
super.onCreate(savedInstanceState);
if (isLockTaskModePinned() && !isSettingsRunOnTop()) {
Log.w(TAG, "Devices lock task mode pinned.");
@@ -123,6 +135,57 @@
}
@Override
+ public void startActivity(Intent intent) {
+ if (!Utils.isPageTransitionEnabled(this)) {
+ super.startActivity(intent);
+ return;
+ }
+ super.startActivity(intent, getActivityOptionsBundle());
+ }
+
+ @Override
+ public void startActivity(Intent intent, @androidx.annotation.Nullable Bundle options) {
+ if (!Utils.isPageTransitionEnabled(this) || options != null) {
+ super.startActivity(intent, options);
+ return;
+ }
+ super.startActivity(intent, getActivityOptionsBundle());
+ }
+
+ @Override
+ public void startActivityForResult(Intent intent, int requestCode) {
+ // startActivity() will eventually calls startActivityForResult() with requestCode -1.
+ // Adding this condition to avoid multiple calls.
+ if (!Utils.isPageTransitionEnabled(this) || requestCode == DEFAULT_REQUEST) {
+ super.startActivityForResult(intent, requestCode);
+ return;
+ }
+ super.startActivityForResult(intent, requestCode, getActivityOptionsBundle());
+ }
+
+ @Override
+ public void startActivityForResult(Intent intent, int requestCode,
+ @androidx.annotation.Nullable Bundle options) {
+ if (!Utils.isPageTransitionEnabled(this) || requestCode == DEFAULT_REQUEST
+ || options != null) {
+ super.startActivityForResult(intent, requestCode, options);
+ return;
+ }
+ super.startActivityForResult(intent, requestCode, getActivityOptionsBundle());
+ }
+
+ @Override
+ public void startActivityForResultAsUser(Intent intent, int requestCode,
+ UserHandle userHandle) {
+ if (!Utils.isPageTransitionEnabled(this) || requestCode == DEFAULT_REQUEST) {
+ super.startActivityForResultAsUser(intent, requestCode, userHandle);
+ return;
+ }
+ super.startActivityForResultAsUser(intent, requestCode, getActivityOptionsBundle(),
+ userHandle);
+ }
+
+ @Override
protected void onResume() {
super.onResume();
final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
@@ -267,10 +330,16 @@
}
}
+ private Bundle getActivityOptionsBundle() {
+ final Toolbar toolbar = findViewById(R.id.action_bar);
+ return ActivityOptions.makeSceneTransitionAnimation(this, toolbar,
+ "shared_element_view").toBundle();
+ }
+
public interface CategoryListener {
/**
* @param categories the changed categories that have to be refreshed, or null to force
- * refreshing all.
+ * refreshing all.
*/
void onCategoriesChanged(@Nullable Set<String> categories);
}
diff --git a/src/com/android/settings/core/SubSettingLauncher.java b/src/com/android/settings/core/SubSettingLauncher.java
index 5d9a528..545fcda 100644
--- a/src/com/android/settings/core/SubSettingLauncher.java
+++ b/src/com/android/settings/core/SubSettingLauncher.java
@@ -17,18 +17,22 @@
package com.android.settings.core;
import android.annotation.StringRes;
+import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
-import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.widget.Toolbar;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
+import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
+import com.android.settings.Utils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class SubSettingLauncher {
@@ -183,7 +187,16 @@
resultListener.getActivity().startActivityForResultAsUser(intent, requestCode, userHandle);
}
- private void launchForResult(Fragment listener, Intent intent, int requestCode) {
+ @VisibleForTesting
+ void launchForResult(Fragment listener, Intent intent, int requestCode) {
+ if (Utils.isPageTransitionEnabled(mContext)) {
+ final Activity activity = listener.getActivity();
+ final Toolbar toolbar = activity.findViewById(R.id.action_bar);
+ final Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(activity, toolbar,
+ "shared_element_view").toBundle();
+ listener.startActivityForResult(intent, requestCode, bundle);
+ return;
+ }
listener.startActivityForResult(intent, requestCode);
}
@@ -192,6 +205,7 @@
intent.replaceExtras(mLaunchRequest.extras);
}
}
+
/**
* Simple container that has information about how to launch a subsetting.
*/
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 881e39c..cd980f3 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -18,11 +18,14 @@
import android.animation.LayoutTransition;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.app.settings.SettingsEnums;
+import android.content.Intent;
import android.os.Bundle;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.View;
+import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toolbar;
@@ -33,11 +36,13 @@
import androidx.fragment.app.FragmentTransaction;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.accounts.AvatarViewMixin;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.transition.SettingsTransitionHelper;
public class SettingsHomepageActivity extends FragmentActivity {
@@ -64,6 +69,12 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
+ if (Utils.isPageTransitionEnabled(this)) {
+ // Enable Activity transitions
+ getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
+ SettingsTransitionHelper.applyForwardTransition(this);
+ SettingsTransitionHelper.applyBackwardTransition(this);
+ }
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_homepage_container);
@@ -101,6 +112,16 @@
.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
}
+ @Override
+ public void startActivity(Intent intent) {
+ if (Utils.isPageTransitionEnabled(this)) {
+ final Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this).toBundle();
+ super.startActivity(intent, bundle);
+ return;
+ }
+ super.startActivity(intent);
+ }
+
private void showSuggestionFragment() {
final Class<? extends Fragment> fragment = FeatureFactory.getFactory(this)
.getSuggestionFeatureProvider(this).getContextualSuggestionFragment();