Merge "Apply settings page transition" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-04-28 13:41:04 +00:00
committed by Android (Google) Code Review
7 changed files with 143 additions and 5 deletions

View File

@@ -77,6 +77,7 @@ import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data; import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Profile; import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.RawContacts;
import android.provider.Settings;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.Spannable; import android.text.Spannable;
@@ -109,6 +110,7 @@ import androidx.preference.PreferenceGroup;
import com.android.internal.app.UnlaunchableAppActivity; import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils; 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.ProfileFragmentBridge;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
@@ -159,6 +161,9 @@ public final class Utils extends com.android.settingslib.Utils {
/** Whether or not app hibernation is enabled on the device **/ /** Whether or not app hibernation is enabled on the device **/
public static final String PROPERTY_APP_HIBERNATION_ENABLED = "app_hibernation_enabled"; 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 * Finds a matching activity for a preference's intent. If a matching
* activity is not found, it will remove the preference. * activity is not found, it will remove the preference.
@@ -1196,4 +1201,12 @@ public final class Utils extends com.android.settingslib.Utils {
public static boolean isProviderModelEnabled(Context context) { public static boolean isProviderModelEnabled(Context context) {
return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL); 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;
}
} }

View File

@@ -18,6 +18,7 @@ package com.android.settings.core;
import android.annotation.LayoutRes; import android.annotation.LayoutRes;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
@@ -27,6 +28,7 @@ import android.content.pm.PackageManager;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.FeatureFlagUtils; import android.util.FeatureFlagUtils;
@@ -43,8 +45,10 @@ import androidx.fragment.app.FragmentActivity;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SubSettings; import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.dashboard.CategoryManager; import com.android.settings.dashboard.CategoryManager;
import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.Tile;
import com.android.settingslib.transition.SettingsTransitionHelper;
import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.resources.TextAppearanceConfig; import com.google.android.material.resources.TextAppearanceConfig;
@@ -61,6 +65,7 @@ public class SettingsBaseActivity extends FragmentActivity {
protected static final boolean DEBUG_TIMING = false; protected static final boolean DEBUG_TIMING = false;
private static final String TAG = "SettingsBaseActivity"; private static final String TAG = "SettingsBaseActivity";
private static final String DATA_SCHEME_PKG = "package"; 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 // Serves as a temporary list of tiles to ignore until we heard back from the PM that they
// are disabled. // are disabled.
@@ -74,6 +79,13 @@ public class SettingsBaseActivity extends FragmentActivity {
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { 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); super.onCreate(savedInstanceState);
if (isLockTaskModePinned() && !isSettingsRunOnTop()) { if (isLockTaskModePinned() && !isSettingsRunOnTop()) {
Log.w(TAG, "Devices lock task mode pinned."); Log.w(TAG, "Devices lock task mode pinned.");
@@ -124,6 +136,57 @@ public class SettingsBaseActivity extends FragmentActivity {
return true; return true;
} }
@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 @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
@@ -269,10 +332,16 @@ public class SettingsBaseActivity extends FragmentActivity {
} }
} }
private Bundle getActivityOptionsBundle() {
final Toolbar toolbar = findViewById(R.id.action_bar);
return ActivityOptions.makeSceneTransitionAnimation(this, toolbar,
"shared_element_view").toBundle();
}
public interface CategoryListener { public interface CategoryListener {
/** /**
* @param categories the changed categories that have to be refreshed, or null to force * @param categories the changed categories that have to be refreshed, or null to force
* refreshing all. * refreshing all.
*/ */
void onCategoriesChanged(@Nullable Set<String> categories); void onCategoriesChanged(@Nullable Set<String> categories);
} }

View File

@@ -17,18 +17,22 @@
package com.android.settings.core; package com.android.settings.core;
import android.annotation.StringRes; import android.annotation.StringRes;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.text.TextUtils; import android.text.TextUtils;
import android.widget.Toolbar;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings; import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class SubSettingLauncher { public class SubSettingLauncher {
@@ -183,7 +187,16 @@ public class SubSettingLauncher {
resultListener.getActivity().startActivityForResultAsUser(intent, requestCode, userHandle); 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); listener.startActivityForResult(intent, requestCode);
} }
@@ -192,6 +205,7 @@ public class SubSettingLauncher {
intent.replaceExtras(mLaunchRequest.extras); intent.replaceExtras(mLaunchRequest.extras);
} }
} }
/** /**
* Simple container that has information about how to launch a subsetting. * Simple container that has information about how to launch a subsetting.
*/ */

View File

@@ -18,11 +18,14 @@ package com.android.settings.homepage;
import android.animation.LayoutTransition; import android.animation.LayoutTransition;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.util.FeatureFlagUtils; import android.util.FeatureFlagUtils;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.Window;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Toolbar; import android.widget.Toolbar;
@@ -33,11 +36,13 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.accounts.AvatarViewMixin; import com.android.settings.accounts.AvatarViewMixin;
import com.android.settings.core.FeatureFlags; import com.android.settings.core.FeatureFlags;
import com.android.settings.core.HideNonSystemOverlayMixin; import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.homepage.contextualcards.ContextualCardsFragment; import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.transition.SettingsTransitionHelper;
public class SettingsHomepageActivity extends FragmentActivity { public class SettingsHomepageActivity extends FragmentActivity {
@@ -64,6 +69,12 @@ public class SettingsHomepageActivity extends FragmentActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { 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); super.onCreate(savedInstanceState);
setContentView(R.layout.settings_homepage_container); setContentView(R.layout.settings_homepage_container);
@@ -101,6 +112,16 @@ public class SettingsHomepageActivity extends FragmentActivity {
.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING); .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() { private void showSuggestionFragment() {
final Class<? extends Fragment> fragment = FeatureFactory.getFactory(this) final Class<? extends Fragment> fragment = FeatureFactory.getFactory(this)
.getSuggestionFeatureProvider(this).getContextualSuggestionFragment(); .getSuggestionFeatureProvider(this).getContextualSuggestionFragment();

View File

@@ -28,12 +28,14 @@ import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import org.junit.Before; import org.junit.Before;
@@ -42,10 +44,12 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowUtils.class)
public class SubSettingLauncherTest { public class SubSettingLauncherTest {
@Mock @Mock
@@ -109,10 +113,13 @@ public class SubSettingLauncherTest {
@Test @Test
public void launch_hasRequestListener_shouldStartActivityForResult() { public void launch_hasRequestListener_shouldStartActivityForResult() {
ShadowUtils.setIsPageTransitionEnabled(true);
final int requestCode = 123123; final int requestCode = 123123;
when(mFragment.getActivity()).thenReturn(mActivity); when(mFragment.getActivity()).thenReturn(mActivity);
final SubSettingLauncher launcher = spy(new SubSettingLauncher(mContext)); final SubSettingLauncher launcher = spy(new SubSettingLauncher(mContext));
doNothing().when(launcher).launchForResult(any(Fragment.class), any(Intent.class),
anyInt());
launcher.setTitleText("123") launcher.setTitleText("123")
.setDestination(SubSettingLauncherTest.class.getName()) .setDestination(SubSettingLauncherTest.class.getName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -120,7 +127,8 @@ public class SubSettingLauncherTest {
.setResultListener(mFragment, requestCode) .setResultListener(mFragment, requestCode)
.launch(); .launch();
verify(mFragment).startActivityForResult(any(Intent.class), eq(requestCode)); verify(launcher)
.launchForResult(eq(mFragment), any(Intent.class), eq(requestCode));
} }
@Test @Test

View File

@@ -39,6 +39,7 @@ import com.android.settings.core.HideNonSystemOverlayMixin;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl; import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest; import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -58,12 +59,13 @@ import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowUserManager.class, @Config(shadows = {ShadowUserManager.class,
SettingsHomepageActivityTest.ShadowSuggestionFeatureProviderImpl.class}) SettingsHomepageActivityTest.ShadowSuggestionFeatureProviderImpl.class, ShadowUtils.class})
public class SettingsHomepageActivityTest { public class SettingsHomepageActivityTest {
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
ShadowUtils.setIsPageTransitionEnabled(false);
} }
@Test @Test

View File

@@ -47,6 +47,7 @@ public class ShadowUtils {
private static boolean sIsVoiceCapable; private static boolean sIsVoiceCapable;
private static ArraySet<String> sResultLinks = new ArraySet<>(); private static ArraySet<String> sResultLinks = new ArraySet<>();
private static boolean sIsBatteryPresent; private static boolean sIsBatteryPresent;
private static boolean sIsPageTransitionEnabled;
@Implementation @Implementation
protected static int enforceSameOwner(Context context, int userId) { protected static int enforceSameOwner(Context context, int userId) {
@@ -69,6 +70,7 @@ public class ShadowUtils {
sIsVoiceCapable = false; sIsVoiceCapable = false;
sResultLinks = new ArraySet<>(); sResultLinks = new ArraySet<>();
sIsBatteryPresent = true; sIsBatteryPresent = true;
sIsPageTransitionEnabled = true;
} }
public static void setIsDemoUser(boolean isDemoUser) { public static void setIsDemoUser(boolean isDemoUser) {
@@ -166,4 +168,13 @@ public class ShadowUtils {
public static void setIsBatteryPresent(boolean isBatteryPresent) { public static void setIsBatteryPresent(boolean isBatteryPresent) {
sIsBatteryPresent = isBatteryPresent; sIsBatteryPresent = isBatteryPresent;
} }
@Implementation
protected static boolean isPageTransitionEnabled(Context context) {
return sIsPageTransitionEnabled;
}
public static void setIsPageTransitionEnabled(boolean isPageTransitionEnabled) {
sIsPageTransitionEnabled = isPageTransitionEnabled;
}
} }