diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 2b2a1b82490..48837401ba5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2737,10 +2737,18 @@ - - - - + + + + @@ -2770,9 +2778,15 @@ android:theme="@style/GlifTheme.Light" android:taskAffinity="com.android.settings.root" /> - - - + + + - + android:viewportWidth="960" + android:viewportHeight="960" + android:tint="?android:attr/colorAccent"> + diff --git a/res/layout-land/confirm_lock_pattern_base.xml b/res/layout-land/confirm_lock_pattern_base.xml index 99617698e80..01f028e1684 100644 --- a/res/layout-land/confirm_lock_pattern_base.xml +++ b/res/layout-land/confirm_lock_pattern_base.xml @@ -71,8 +71,8 @@ diff --git a/res/layout-land/confirm_lock_pattern_normal_base.xml b/res/layout-land/confirm_lock_pattern_normal_base.xml index 812aecdb2a1..4bb4818fde2 100644 --- a/res/layout-land/confirm_lock_pattern_normal_base.xml +++ b/res/layout-land/confirm_lock_pattern_normal_base.xml @@ -45,8 +45,8 @@ diff --git a/res/layout/private_space_advancing_screen.xml b/res/layout/private_space_advancing_screen.xml deleted file mode 100644 index b3bb26c72f8..00000000000 --- a/res/layout/private_space_advancing_screen.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - diff --git a/res/layout/private_space_confirm_deletion.xml b/res/layout/private_space_confirm_deletion.xml index 31418e1d149..62940a3fe78 100644 --- a/res/layout/private_space_confirm_deletion.xml +++ b/res/layout/private_space_confirm_deletion.xml @@ -25,6 +25,6 @@ android:icon="@drawable/ic_delete_accent" app:sudUsePartnerHeavyTheme="true" app:sudIllustrationType="default" - app:sudDescriptionText = "@string/private_space_confirm_deletion_summary" + app:sudDescriptionText = "@string/private_space_few_moments_text" app:sucHeaderText="@string/private_space_confirm_deletion_header"> \ No newline at end of file diff --git a/res/layout/private_space_create_screen.xml b/res/layout/private_space_create_screen.xml new file mode 100644 index 00000000000..d98aba8ee58 --- /dev/null +++ b/res/layout/private_space_create_screen.xml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/res/navigation/privatespace_main_context_nav.xml b/res/navigation/privatespace_main_context_nav.xml index b027d87e556..0de5d9132ad 100644 --- a/res/navigation/privatespace_main_context_nav.xml +++ b/res/navigation/privatespace_main_context_nav.xml @@ -23,14 +23,14 @@ android:name="com.android.settings.privatespace.PrivateSpaceEducation" android:label="fragment_ps_education"> + android:id="@+id/action_education_to_create" + app:destination="@id/ps_create_fragment"/> - + + app:destination="@id/ps_create_fragment"/> Delete Deleting private space\u2026 - - This will take a few moments Private space deleted @@ -1332,14 +1330,10 @@ Learn more about private space https://support.google.com/android?p=private_space - + + This will take a few moments + Setting up private space\u2026 - - Notifications from private space apps are hidden when it\u2019s locked - - Explore private space settings to hide private space and set up automatic locking - - Required apps are already installed in your private space Couldn\u2019t set up a private space @@ -1396,6 +1390,10 @@ Suggested content related to your activity in private space apps Got it + + Lock + + Hide You can add up to %d fingerprints diff --git a/res/xml/private_space_hide_locked.xml b/res/xml/private_space_hide_locked.xml index 4c83e842a0e..d157685df16 100644 --- a/res/xml/private_space_hide_locked.xml +++ b/res/xml/private_space_hide_locked.xml @@ -19,7 +19,7 @@ android:title="@string/private_space_hide_page_title"> diff --git a/res/xml/private_space_settings.xml b/res/xml/private_space_settings.xml index b1233b9d797..197ba3efb8f 100644 --- a/res/xml/private_space_settings.xml +++ b/res/xml/private_space_settings.xml @@ -23,7 +23,7 @@ settings:searchable="false"> @@ -34,7 +34,14 @@ settings:searchable="false" /> + android:title="@string/private_space_category_lock"> + + - + + + > HEADER_ILLUSTRATION_PAIRS = - ImmutableList.of( - new Pair(R.string.private_space_notifications_hidden_title, - R.raw.private_space_notifications_illustration), - new Pair(R.string.private_space_apps_installed_title, - R.raw.private_space_unlock_to_share_illustration), - new Pair(R.string.private_space_explore_settings_title, - R.raw.private_space_placeholder_illustration)); - - private Runnable mUpdateScreenResources = - new Runnable() { - @Override - public void run() { - if (getActivity() != null) { - if (++mScreenTitleIndex < HEADER_ILLUSTRATION_PAIRS.size()) { - startFadeOutAnimation(); - sHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS); - } else if (PrivateSpaceMaintainer.getInstance(getActivity()) - .doesPrivateSpaceExist()) { - mMetricsFeatureProvider.action( - getContext(), - SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_SPACE_CREATED, - true); - if (isConnectedToInternet()) { - NavHostFragment.findNavController(AutoAdvanceSetupFragment.this) - .navigate(R.id.action_account_intro_fragment); - } else { - NavHostFragment.findNavController(AutoAdvanceSetupFragment.this) - .navigate(R.id.action_set_lock_fragment); - } - } else { - mMetricsFeatureProvider.action( - getContext(), - SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_SPACE_CREATED, - false); - showPrivateSpaceErrorScreen(); - } - } - } - }; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - if (android.os.Flags.allowPrivateProfile() - && android.multiuser.Flags.enablePrivateSpaceFeatures()) { - super.onCreate(savedInstanceState); - } - } - - @Override - public View onCreateView( - LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - if (savedInstanceState == null) { - if (PrivateSpaceMaintainer.getInstance(getActivity()).createPrivateSpace()) { - Log.i(TAG, "Private Space created"); - } - } else { - mScreenTitleIndex = savedInstanceState.getInt(TITLE_INDEX); - if (mScreenTitleIndex >= HEADER_ILLUSTRATION_PAIRS.size()) { - return super.onCreateView(inflater, container, savedInstanceState); - } - } - mRootView = - (GlifLayout) - inflater.inflate(R.layout.private_space_advancing_screen, container, false); - mRootView.getHeaderTextView().setMaxLines(HEADER_TEXT_MAX_LINES); - mRootView.getHeaderTextView().setBreakStrategy(BREAK_STRATEGY_SIMPLE); - mRootView.getHeaderTextView().setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE); - updateHeaderAndIllustration(); - OnBackPressedCallback callback = - new OnBackPressedCallback(true /* enabled by default */) { - @Override - public void handleOnBackPressed() { - // Handle the back button event. We intentionally don't want to allow back - // button to work in this screen during the setup flow. - } - }; - requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); - return mRootView; - } - - @Override - public void onSaveInstanceState(@NotNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(TITLE_INDEX, mScreenTitleIndex); - } - - @Override - public void onDestroy() { - sHandler.removeCallbacks(mUpdateScreenResources); - super.onDestroy(); - } - - @Override - public void onResume() { - sHandler.postDelayed(mUpdateScreenResources, DELAY_BETWEEN_SCREENS); - super.onResume(); - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.PRIVATE_SPACE_SETUP_SPACE_CREATION; - } - - private void showPrivateSpaceErrorScreen() { - NavHostFragment.findNavController(AutoAdvanceSetupFragment.this) - .navigate(R.id.action_advance_profile_error); - } - - private void updateHeaderAndIllustration() { - mRootView.setHeaderText(HEADER_ILLUSTRATION_PAIRS.get(mScreenTitleIndex).first); - LottieAnimationView animationView = mRootView.findViewById(R.id.lottie_animation); - animationView.setAnimation(HEADER_ILLUSTRATION_PAIRS.get(mScreenTitleIndex).second); - animationView.playAnimation(); - startFadeInAnimation(); - } - - private void startFadeInAnimation() { - ValueAnimator textView = ObjectAnimator.ofFloat( - mRootView.getHeaderTextView(), View.ALPHA, 0f, 1f); - ValueAnimator lottieView = ObjectAnimator.ofFloat( - mRootView.findViewById(R.id.lottie_animation), View.ALPHA, 0, 1f); - AnimatorSet fadeIn = new AnimatorSet(); - fadeIn.playTogether(textView, lottieView); - fadeIn.setDuration(ANIMATION_DURATION_MILLIS).start(); - } - - private void startFadeOutAnimation() { - AnimatorSet fadeOut = new AnimatorSet(); - ValueAnimator textView = ObjectAnimator.ofFloat( - mRootView.getHeaderTextView(), View.ALPHA, 1f, 0f); - ValueAnimator lottieView = ObjectAnimator.ofFloat( - mRootView.findViewById(R.id.lottie_animation), View.ALPHA, 1f, 0f); - fadeOut.playTogether(textView, lottieView); - fadeOut.setDuration(ANIMATION_DURATION_MILLIS).start(); - fadeOut.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - updateHeaderAndIllustration(); - } - }); - } - - /** Returns true if device has an active internet connection, false otherwise. */ - private boolean isConnectedToInternet() { - ConnectivityManager cm = - (ConnectivityManager) - getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); - return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); - } -} diff --git a/src/com/android/settings/privatespace/HidePrivateSpaceSettings.java b/src/com/android/settings/privatespace/HidePrivateSpaceSettings.java index c41267f3b69..64f27144280 100644 --- a/src/com/android/settings/privatespace/HidePrivateSpaceSettings.java +++ b/src/com/android/settings/privatespace/HidePrivateSpaceSettings.java @@ -21,9 +21,12 @@ import android.os.Bundle; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.widget.IllustrationPreference; -public class HidePrivateSpaceSettings extends DashboardFragment{ +public class HidePrivateSpaceSettings extends DashboardFragment { private static final String TAG = "HidePrivateSpaceSettings"; + private static final String PRIVATE_SPACE_HIDE_ILLUSTRATION_KEY = + "private_space_hide_illustration"; @Override public void onCreate(Bundle icicle) { @@ -41,6 +44,14 @@ public class HidePrivateSpaceSettings extends DashboardFragment{ } } + @Override + public void onResume() { + super.onResume(); + final IllustrationPreference illustrationPreference = + getPreferenceScreen().findPreference(PRIVATE_SPACE_HIDE_ILLUSTRATION_KEY); + illustrationPreference.applyDynamicColor(); + } + @Override public int getMetricsCategory() { return SettingsEnums.PRIVATE_SPACE_SETTINGS; diff --git a/src/com/android/settings/privatespace/PrivateProfileContextHelperActivity.java b/src/com/android/settings/privatespace/PrivateProfileContextHelperActivity.java index 416b2dd7105..ef33d11f012 100644 --- a/src/com/android/settings/privatespace/PrivateProfileContextHelperActivity.java +++ b/src/com/android/settings/privatespace/PrivateProfileContextHelperActivity.java @@ -96,13 +96,24 @@ public class PrivateProfileContextHelperActivity extends FragmentActivity { } private void onAccountAdded(@Nullable ActivityResult result) { - if (result != null && result.getResultCode() == RESULT_OK) { + if (result == null) { + Log.i(TAG, "private space account login result null"); + setResult(RESULT_CANCELED); + finish(); + return; + } + final int resultCode = result.getResultCode(); + if (resultCode == RESULT_OK) { Log.i(TAG, "private space account login success"); - setResult(RESULT_OK); + } else if (resultCode == RESULT_FIRST_USER) { + Log.i(TAG, "private space account login skipped"); } else { Log.i(TAG, "private space account login failed"); - setResult(RESULT_CANCELED); } + setResult( + resultCode == RESULT_OK || resultCode == RESULT_FIRST_USER + ? RESULT_OK + : RESULT_CANCELED); finish(); } diff --git a/src/com/android/settings/privatespace/PrivateSpaceBroadcastReceiver.java b/src/com/android/settings/privatespace/PrivateSpaceBroadcastReceiver.java index 4c59ab9e9a1..fe65ab64369 100644 --- a/src/com/android/settings/privatespace/PrivateSpaceBroadcastReceiver.java +++ b/src/com/android/settings/privatespace/PrivateSpaceBroadcastReceiver.java @@ -33,7 +33,7 @@ public class PrivateSpaceBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if (android.multiuser.Flags.enablePrivateSpaceFeatures() && android.multiuser.Flags.blockPrivateSpaceCreation()) { - Log.d("Here", "Intent: " + intent.getAction()); + Log.d(TAG, "Received Intent: " + intent.getAction()); PrivateSpaceMaintainer privateSpaceMaintainer = PrivateSpaceMaintainer.getInstance(context); // Disable the PrivateSpaceAuthenticationActivity when diff --git a/src/com/android/settings/privatespace/PrivateSpaceCreationFragment.java b/src/com/android/settings/privatespace/PrivateSpaceCreationFragment.java new file mode 100644 index 00000000000..1e0c65e0844 --- /dev/null +++ b/src/com/android/settings/privatespace/PrivateSpaceCreationFragment.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.privatespace; + +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.activity.OnBackPressedCallback; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.navigation.fragment.NavHostFragment; + +import com.android.settings.R; +import com.android.settings.core.InstrumentedFragment; + +import com.google.android.setupdesign.GlifLayout; + +/** Fragment to a show loading screen and create private profile during private space setup flow */ +public class PrivateSpaceCreationFragment extends InstrumentedFragment { + private static final String TAG = "PrivateSpaceCreateFrag"; + private static final int PRIVATE_SPACE_CREATE_POST_DELAY_MS = 1000; + private static final Handler sHandler = new Handler(Looper.getMainLooper()); + private Runnable mRunnable = + () -> { + createPrivateSpace(); + }; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + if (android.os.Flags.allowPrivateProfile() + && android.multiuser.Flags.enablePrivateSpaceFeatures()) { + super.onCreate(savedInstanceState); + } + } + + @NonNull + @Override + public View onCreateView( + @NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + GlifLayout rootView = + (GlifLayout) + inflater.inflate(R.layout.private_space_create_screen, container, false); + OnBackPressedCallback callback = + new OnBackPressedCallback(true /* enabled by default */) { + @Override + public void handleOnBackPressed() { + // Handle the back button event. We intentionally don't want to allow back + // button to work in this screen during the setup flow. + } + }; + requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); + return rootView; + } + + @Override + public void onResume() { + super.onResume(); + // Ensures screen visibility to user by introducing a 1-second delay before creating private + // space. + sHandler.postDelayed(mRunnable, PRIVATE_SPACE_CREATE_POST_DELAY_MS); + } + + @Override + public void onDestroy() { + sHandler.removeCallbacks(mRunnable); + super.onDestroy(); + } + + private void createPrivateSpace() { + if (PrivateSpaceMaintainer.getInstance(getActivity()).createPrivateSpace()) { + Log.i(TAG, "Private Space created"); + mMetricsFeatureProvider.action( + getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_SPACE_CREATED, true); + if (isConnectedToInternet()) { + NavHostFragment.findNavController(PrivateSpaceCreationFragment.this) + .navigate(R.id.action_account_intro_fragment); + } else { + NavHostFragment.findNavController(PrivateSpaceCreationFragment.this) + .navigate(R.id.action_set_lock_fragment); + } + } else { + mMetricsFeatureProvider.action( + getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_SPACE_CREATED, false); + showPrivateSpaceErrorScreen(); + } + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.PRIVATE_SPACE_SETUP_SPACE_CREATION; + } + + private void showPrivateSpaceErrorScreen() { + NavHostFragment.findNavController(PrivateSpaceCreationFragment.this) + .navigate(R.id.action_create_profile_error); + } + + /** Returns true if device has an active internet connection, false otherwise. */ + private boolean isConnectedToInternet() { + ConnectivityManager cm = + (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); + } +} diff --git a/src/com/android/settings/privatespace/PrivateSpaceDashboardFragment.java b/src/com/android/settings/privatespace/PrivateSpaceDashboardFragment.java index f539a8b86c6..4e904d32bf9 100644 --- a/src/com/android/settings/privatespace/PrivateSpaceDashboardFragment.java +++ b/src/com/android/settings/privatespace/PrivateSpaceDashboardFragment.java @@ -26,10 +26,12 @@ import android.widget.Toast; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.widget.IllustrationPreference; /** Fragment representing the Private Space dashboard in Settings. */ public class PrivateSpaceDashboardFragment extends DashboardFragment { private static final String TAG = "PSDashboardFragment"; + private static final String PRIVATE_SPACE_ILLUSTRATION_KEY = "private_space_illustration"; @Override public void onCreate(Bundle icicle) { @@ -60,6 +62,14 @@ public class PrivateSpaceDashboardFragment extends DashboardFragment { } } + @Override + public void onResume() { + super.onResume(); + final IllustrationPreference illustrationPreference = + getPreferenceScreen().findPreference(PRIVATE_SPACE_ILLUSTRATION_KEY); + illustrationPreference.applyDynamicColor(); + } + @Override protected int getPreferenceScreenResId() { return R.xml.private_space_settings; diff --git a/src/com/android/settings/privatespace/PrivateSpaceEducation.java b/src/com/android/settings/privatespace/PrivateSpaceEducation.java index a21aac3c82d..dfaf8b9cfa7 100644 --- a/src/com/android/settings/privatespace/PrivateSpaceEducation.java +++ b/src/com/android/settings/privatespace/PrivateSpaceEducation.java @@ -31,7 +31,9 @@ import androidx.navigation.fragment.NavHostFragment; import com.android.settings.R; import com.android.settings.core.InstrumentedFragment; +import com.android.settingslib.widget.LottieColorUtils; +import com.airbnb.lottie.LottieAnimationView; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupdesign.GlifLayout; @@ -69,6 +71,8 @@ public class PrivateSpaceEducation extends InstrumentedFragment { .setButtonType(FooterButton.ButtonType.CANCEL) .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Secondary) .build()); + LottieAnimationView lottieAnimationView = rootView.findViewById(R.id.lottie_animation); + LottieColorUtils.applyDynamicColors(getContext(), lottieAnimationView); TextView infoTextView = rootView.findViewById(R.id.learn_more); Pattern pattern = Pattern.compile(infoTextView.getText().toString()); @@ -91,7 +95,7 @@ public class PrivateSpaceEducation extends InstrumentedFragment { getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_START); Log.i(TAG, "Starting private space setup"); NavHostFragment.findNavController(PrivateSpaceEducation.this) - .navigate(R.id.action_education_to_auto_advance); + .navigate(R.id.action_education_to_create); }; } diff --git a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java index 2ca22d1d478..e219c078bce 100644 --- a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java +++ b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java @@ -83,7 +83,7 @@ public class PrivateSpaceMaintainer { * *

This method should be used by the Private Space Setup Flow ONLY. */ - @VisibleForTesting + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public final synchronized boolean createPrivateSpace() { if (!Flags.allowPrivateProfile() || !android.multiuser.Flags.enablePrivateSpaceFeatures()) { diff --git a/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java b/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java index 11f4bcb74e3..286f860ba52 100644 --- a/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java +++ b/src/com/android/settings/privatespace/PrivateSpaceSetLockFragment.java @@ -34,7 +34,9 @@ import androidx.navigation.fragment.NavHostFragment; import com.android.settings.R; import com.android.settings.core.InstrumentedFragment; +import com.android.settingslib.widget.LottieColorUtils; +import com.airbnb.lottie.LottieAnimationView; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupdesign.GlifLayout; @@ -82,6 +84,8 @@ public class PrivateSpaceSetLockFragment extends InstrumentedFragment { } }; requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); + LottieAnimationView lottieAnimationView = rootView.findViewById(R.id.lottie_animation); + LottieColorUtils.applyDynamicColors(getContext(), lottieAnimationView); return rootView; } diff --git a/src/com/android/settings/privatespace/SetupSuccessFragment.java b/src/com/android/settings/privatespace/SetupSuccessFragment.java index 90be48ea9a4..647bc62087d 100644 --- a/src/com/android/settings/privatespace/SetupSuccessFragment.java +++ b/src/com/android/settings/privatespace/SetupSuccessFragment.java @@ -17,6 +17,7 @@ package com.android.settings.privatespace; import android.app.Activity; +import android.app.ActivityManager; import android.app.settings.SettingsEnums; import android.content.Intent; import android.content.pm.PackageManager; @@ -34,11 +35,15 @@ import androidx.annotation.Nullable; import com.android.settings.R; import com.android.settings.core.InstrumentedFragment; +import com.android.settingslib.widget.LottieColorUtils; +import com.airbnb.lottie.LottieAnimationView; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupdesign.GlifLayout; +import java.util.List; + /** Fragment for the final screen shown on successful completion of private space setup. */ public class SetupSuccessFragment extends InstrumentedFragment { private static final String TAG = "SetupSuccessFragment"; @@ -72,6 +77,8 @@ public class SetupSuccessFragment extends InstrumentedFragment { } }; requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); + LottieAnimationView lottieAnimationView = rootView.findViewById(R.id.lottie_animation); + LottieColorUtils.applyDynamicColors(getContext(), lottieAnimationView); return rootView; } @@ -103,7 +110,7 @@ public class SetupSuccessFragment extends InstrumentedFragment { accessPrivateSpaceToast(); startActivity(allAppsIntent); Log.i(TAG, "Private space setup complete"); - activity.finish(); + deleteAllTaskAndFinish(activity); } }; } @@ -118,4 +125,12 @@ public class SetupSuccessFragment extends InstrumentedFragment { drawable) .show(); } + + private void deleteAllTaskAndFinish(Activity activity) { + ActivityManager activityManager = activity.getSystemService(ActivityManager.class); + List tasks = activityManager.getAppTasks(); + for (var task : tasks) { + task.finishAndRemoveTask(); + } + } } diff --git a/tests/robotests/src/com/android/settings/gestures/BackGestureIndicatorViewTest.java b/tests/robotests/src/com/android/settings/gestures/BackGestureIndicatorViewTest.java index 527ea44edec..793aaab1d86 100644 --- a/tests/robotests/src/com/android/settings/gestures/BackGestureIndicatorViewTest.java +++ b/tests/robotests/src/com/android/settings/gestures/BackGestureIndicatorViewTest.java @@ -21,20 +21,25 @@ import static org.junit.Assert.assertEquals; import android.content.Context; import android.widget.ImageView; +import androidx.test.core.app.ApplicationProvider; + import com.android.settings.R; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.LooperMode; +import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricTestRunner.class) -@LooperMode(LooperMode.Mode.LEGACY) public class BackGestureIndicatorViewTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + private Context mContext; private BackGestureIndicatorDrawable mLeftDrawable; @@ -44,9 +49,7 @@ public class BackGestureIndicatorViewTest { @Before public void setUp() { - MockitoAnnotations.initMocks(this); - - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mView = new BackGestureIndicatorView(mContext); mLeftDrawable = (BackGestureIndicatorDrawable) ((ImageView) mView.findViewById( @@ -59,6 +62,7 @@ public class BackGestureIndicatorViewTest { public void testSetIndicatoreWidth() { mView.setIndicatorWidth(25, true); mView.setIndicatorWidth(52, false); + ShadowLooper.idleMainLooper(); assertEquals(25, mLeftDrawable.getWidth()); assertEquals(52, mRightDrawable.getWidth()); diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/AbnormalRingerConditionControllerBaseTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/AbnormalRingerConditionControllerBaseTest.java index b75240c9809..4834127efa7 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/AbnormalRingerConditionControllerBaseTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/AbnormalRingerConditionControllerBaseTest.java @@ -23,21 +23,26 @@ import android.content.Context; import android.content.Intent; import android.media.AudioManager; +import androidx.test.core.app.ApplicationProvider; + import com.android.settings.homepage.contextualcards.ContextualCard; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.LooperMode; +import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricTestRunner.class) -@LooperMode(LooperMode.Mode.LEGACY) public class AbnormalRingerConditionControllerBaseTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock private ConditionManager mConditionManager; @@ -46,8 +51,7 @@ public class AbnormalRingerConditionControllerBaseTest { @Before public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mCondition = new TestCondition(mContext, mConditionManager); } @@ -60,9 +64,13 @@ public class AbnormalRingerConditionControllerBaseTest { mCondition.startMonitoringStateChange(); mContext.sendBroadcast(broadcast1); + ShadowLooper.idleMainLooper(); + verify(mConditionManager, never()).onConditionChanged(); mContext.sendBroadcast(broadcast2); + ShadowLooper.idleMainLooper(); + verify(mConditionManager).onConditionChanged(); } diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java index c8637c8f108..0fc915f601f 100644 --- a/tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/localepicker/LocaleDialogFragmentTest.java @@ -38,22 +38,26 @@ import com.android.internal.app.LocaleStore; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import org.robolectric.annotation.LooperMode; +import org.robolectric.shadows.ShadowLooper; import java.util.Locale; @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowAlertDialogCompat.class}) -@LooperMode(LooperMode.Mode.LEGACY) public class LocaleDialogFragmentTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock private OnBackInvokedDispatcher mOnBackInvokedDispatcher; @@ -62,8 +66,6 @@ public class LocaleDialogFragmentTest { @Before public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mActivity = Robolectric.setupActivity(FragmentActivity.class); mDialogFragment = LocaleDialogFragment.newInstance(); LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(Locale.ENGLISH); @@ -75,6 +77,7 @@ public class LocaleDialogFragmentTest { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(mDialogFragment, null); fragmentTransaction.commit(); + ShadowLooper.idleMainLooper(); } @Test diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java index e51f9a3f742..10115399cfd 100644 --- a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java +++ b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java @@ -57,6 +57,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import androidx.test.core.app.ApplicationProvider; import com.android.internal.app.LocaleStore; import com.android.settings.R; @@ -72,12 +73,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import org.robolectric.annotation.LooperMode; +import org.robolectric.shadows.ShadowLooper; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; @@ -90,9 +91,11 @@ import java.util.Locale; ShadowActivityManager.class, com.android.settings.testutils.shadow.ShadowFragment.class, }) -@LooperMode(LooperMode.Mode.LEGACY) public class LocaleListEditorTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + private static final String ARG_DIALOG_TYPE = "arg_dialog_type"; private static final String TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT = "dialog_confirm_system_default"; private static final String TAG_DIALOG_NOT_AVAILABLE = "dialog_not_available_locale"; @@ -147,8 +150,8 @@ public class LocaleListEditorTest { @Before public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); + Context context = ApplicationProvider.getApplicationContext(); + mContext = spy(context); mLocaleListEditor = spy(new LocaleListEditor()); when(mLocaleListEditor.getContext()).thenReturn(mContext); mActivity = spy(Robolectric.buildActivity(FragmentActivity.class).get()); @@ -156,11 +159,11 @@ public class LocaleListEditorTest { when(mLocaleListEditor.getNotificationController()).thenReturn( mNotificationController); ReflectionHelpers.setField(mLocaleListEditor, "mEmptyTextView", - new TextView(RuntimeEnvironment.application)); + new TextView(context)); ReflectionHelpers.setField(mLocaleListEditor, "mRestrictionsManager", - RuntimeEnvironment.application.getSystemService(Context.RESTRICTIONS_SERVICE)); + context.getSystemService(Context.RESTRICTIONS_SERVICE)); ReflectionHelpers.setField(mLocaleListEditor, "mUserManager", - RuntimeEnvironment.application.getSystemService(Context.USER_SERVICE)); + context.getSystemService(Context.USER_SERVICE)); ReflectionHelpers.setField(mLocaleListEditor, "mAdapter", mAdapter); ReflectionHelpers.setField(mLocaleListEditor, "mAddLanguage", mAddLanguage); ReflectionHelpers.setField(mLocaleListEditor, "mFragmentManager", mFragmentManager); @@ -283,6 +286,7 @@ public class LocaleListEditorTest { // click the remove button dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); + ShadowLooper.idleMainLooper(); assertThat(dialog.isShowing()).isFalse();