Merge "[Large screen] Make slice deep linking to Settings show in 2-pane" into sc-v2-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index af7de00..8a69e04 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -308,6 +308,17 @@
                 android:value="true" />
         </activity>
 
+        <!-- Keep compatibility with old shortcuts. -->
+        <activity-alias
+            android:name="Settings$WifiSettings2Activity"
+            android:targetActivity="Settings$WifiSettingsActivity"
+            android:label="@string/wifi_settings"
+            android:icon="@drawable/ic_homepage_network"
+            android:exported="true">
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                       android:value="com.android.settings.wifi.WifiSettings" />
+        </activity-alias>
+
         <activity
             android:name="Settings$NetworkProviderSettingsActivity"
             android:label="@string/provider_internet_settings"
diff --git a/res/layout/fingerprint_enroll_find_sensor_base.xml b/res/layout/fingerprint_enroll_find_sensor_base.xml
index 62203f7..da7fc30 100644
--- a/res/layout/fingerprint_enroll_find_sensor_base.xml
+++ b/res/layout/fingerprint_enroll_find_sensor_base.xml
@@ -17,6 +17,7 @@
 
 <com.google.android.setupdesign.GlifLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/setup_wizard_layout"
     style="?attr/fingerprint_layout_theme"
     android:layout_width="match_parent"
@@ -40,5 +41,27 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"/>
 
+        <com.airbnb.lottie.LottieAnimationView
+            android:id="@+id/illustration_lottie"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scaleType="centerInside"
+            android:visibility="gone"
+            app:lottie_imageAssetsFolder="images"
+            app:lottie_autoPlay="true"
+            app:lottie_loop="true"
+            app:lottie_rawRes="@raw/fingerprint_edu_lottie"/>
+
+        <com.airbnb.lottie.LottieAnimationView
+            android:id="@+id/illustration_lottie_portrait"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scaleType="centerInside"
+            android:visibility="gone"
+            app:lottie_imageAssetsFolder="images"
+            app:lottie_autoPlay="true"
+            app:lottie_loop="true"
+            app:lottie_rawRes="@raw/fingerprint_edu_lottie_portrait"/>
+
     </LinearLayout>
 </com.google.android.setupdesign.GlifLayout>
diff --git a/res/raw/fingerprint_edu_lottie.json b/res/raw/fingerprint_edu_lottie.json
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/fingerprint_edu_lottie.json
diff --git a/res/raw/fingerprint_edu_lottie_portrait.json b/res/raw/fingerprint_edu_lottie_portrait.json
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/fingerprint_edu_lottie_portrait.json
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
index c3ad5de..974ec2c 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
@@ -63,13 +63,6 @@
 
         // Set a placeholder for home page.
         registerHomepagePlaceholderRule();
-        // Set subsettings rule.
-        registerTwoPanePairRule(mContext,
-                getComponentName(Settings.class),
-                getComponentName(SubSettings.class),
-                null /* secondaryIntentAction */,
-                true /* finishPrimaryWithSecondary */,
-                true /* finishSecondaryWithPrimary */);
     }
 
     /** Register a SplitPairRule for 2-pane. */
@@ -78,7 +71,8 @@
             ComponentName secondaryComponent,
             String secondaryIntentAction,
             boolean finishPrimaryWithSecondary,
-            boolean finishSecondaryWithPrimary) {
+            boolean finishSecondaryWithPrimary,
+            boolean clearTop) {
         final Set<SplitPairFilter> filters = new HashSet<>();
         filters.add(new SplitPairFilter(primaryComponent, secondaryComponent,
                 secondaryIntentAction));
@@ -86,13 +80,28 @@
         SplitController.getInstance().registerRule(new SplitPairRule(filters,
                 finishPrimaryWithSecondary,
                 finishSecondaryWithPrimary,
-                true /* clearTop */,
+                clearTop,
                 ActivityEmbeddingUtils.getMinCurrentScreenSplitWidthPx(context),
                 ActivityEmbeddingUtils.getMinSmallestScreenSplitWidthPx(context),
                 ActivityEmbeddingUtils.SPLIT_RATIO,
                 LayoutDirection.LOCALE));
     }
 
+    /** Register a SplitPairRule for SubSettings if the device supports 2-pane. */
+    public static void registerSubSettingsPairRuleIfNeeded(Context context, boolean clearTop) {
+        if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(context)) {
+            return;
+        }
+
+        registerTwoPanePairRule(context,
+                getComponentName(context, Settings.class),
+                getComponentName(context, SubSettings.class),
+                null /* secondaryIntentAction */,
+                true /* finishPrimaryWithSecondary */,
+                true /* finishSecondaryWithPrimary */,
+                clearTop);
+    }
+
     private void registerHomepagePlaceholderRule() {
         final Set<ActivityFilter> activityFilters = new HashSet<>();
         addActivityFilter(activityFilters, SettingsHomepageActivity.class);
@@ -126,6 +135,12 @@
 
     @NonNull
     private ComponentName getComponentName(Class<? extends Activity> activityClass) {
-        return new ComponentName(mContext.getPackageName(), activityClass.getName());
+        return getComponentName(mContext, activityClass);
+    }
+
+    @NonNull
+    private static ComponentName getComponentName(Context context,
+                Class<? extends Activity> activityClass) {
+        return new ComponentName(context.getPackageName(), activityClass.getName());
     }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
index 3cea962..64e066e 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
@@ -21,13 +21,14 @@
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.os.Bundle;
+import android.view.OrientationEventListener;
+import android.view.Surface;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.accessibility.AccessibilityManager;
 
 import androidx.annotation.Nullable;
 
-import com.airbnb.lottie.LottieAnimationView;
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.biometrics.BiometricEnrollBase;
@@ -35,6 +36,7 @@
 import com.android.settings.biometrics.BiometricUtils;
 import com.android.settings.password.ChooseLockSettingsHelper;
 
+import com.airbnb.lottie.LottieAnimationView;
 import com.google.android.setupcompat.template.FooterBarMixin;
 import com.google.android.setupcompat.template.FooterButton;
 
@@ -52,6 +54,10 @@
     private FingerprintEnrollSidecar mSidecar;
     private boolean mNextClicked;
     private boolean mCanAssumeUdfps;
+    private boolean mCanAssumeSidefps;
+
+    private OrientationEventListener mOrientationEventListener;
+    private int mPreviousRotation = 0;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -61,6 +67,7 @@
         final List<FingerprintSensorPropertiesInternal> props =
                 fingerprintManager.getSensorPropertiesInternal();
         mCanAssumeUdfps = props != null && props.size() == 1 && props.get(0).isAnyUdfpsType();
+        mCanAssumeSidefps = props != null && props.size() == 1 && props.get(0).isAnySidefpsType();
         setContentView(getContentView());
         mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class);
         mFooterBarMixin.setSecondaryButton(
@@ -72,6 +79,8 @@
                         .build()
         );
 
+        listenOrientationEvent();
+
         if (mCanAssumeUdfps) {
             setHeaderText(R.string.security_settings_udfps_enroll_find_sensor_title);
             setDescriptionText(R.string.security_settings_udfps_enroll_find_sensor_message);
@@ -90,6 +99,28 @@
                 lottieAnimationView.setAnimation(R.raw.udfps_edu_a11y_lottie);
             }
 
+        } else if (mCanAssumeSidefps) {
+            setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
+            setDescriptionText(R.string.security_settings_fingerprint_enroll_find_sensor_message);
+            final LottieAnimationView lottieAnimationView = findViewById(R.id.illustration_lottie);
+            final LottieAnimationView lottieAnimationViewPortrait =
+                    findViewById(R.id.illustration_lottie_portrait);
+            final int rotation = getApplicationContext().getDisplay().getRotation();
+            switch(rotation) {
+                case Surface.ROTATION_90:
+                    lottieAnimationView.setVisibility(View.GONE);
+                    lottieAnimationViewPortrait.setVisibility(View.VISIBLE);
+                    break;
+                case Surface.ROTATION_270:
+                    lottieAnimationView.setVisibility(View.GONE);
+                    lottieAnimationViewPortrait.setVisibility(View.VISIBLE);
+                    lottieAnimationViewPortrait.setRotation(180);
+                    break;
+                default:
+                    lottieAnimationView.setVisibility(View.VISIBLE);
+                    lottieAnimationViewPortrait.setVisibility(View.GONE);
+                    break;
+            }
         } else {
             setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
             setDescriptionText(R.string.security_settings_fingerprint_enroll_find_sensor_message);
@@ -220,6 +251,7 @@
 
     @Override
     protected void onDestroy() {
+        stopListenOrientationEvent();
         super.onDestroy();
         if (mAnimation != null) {
             mAnimation.stopAnimation();
@@ -297,4 +329,37 @@
     public int getMetricsCategory() {
         return SettingsEnums.FINGERPRINT_FIND_SENSOR;
     }
+
+    private void listenOrientationEvent() {
+        if (!mCanAssumeSidefps) {
+            // Do nothing if the device doesn't support SideFPS.
+            return;
+        }
+        mOrientationEventListener = new OrientationEventListener(this) {
+            @Override
+            public void onOrientationChanged(int orientation) {
+                final int currentRotation = getDisplay().getRotation();
+                if ((mPreviousRotation == Surface.ROTATION_90
+                        && currentRotation == Surface.ROTATION_270) || (
+                        mPreviousRotation == Surface.ROTATION_270
+                                && currentRotation == Surface.ROTATION_90)) {
+                    mPreviousRotation = currentRotation;
+                    recreate();
+                }
+            }
+        };
+        mOrientationEventListener.enable();
+        mPreviousRotation = getDisplay().getRotation();
+    }
+
+    private void stopListenOrientationEvent() {
+        if (!mCanAssumeSidefps) {
+            // Do nothing if the device doesn't support SideFPS.
+            return;
+        }
+        if (mOrientationEventListener != null) {
+            mOrientationEventListener.disable();
+        }
+        mOrientationEventListener = null;
+    }
 }
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index f8185db..951eb3c 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -60,6 +60,8 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
+import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
+import com.android.settings.activityembedding.ActivityEmbeddingUtils;
 import com.android.settings.dashboard.profileselector.ProfileSelectDialog;
 import com.android.settings.homepage.TopLevelSettings;
 import com.android.settings.overlay.FeatureFactory;
@@ -170,7 +172,20 @@
                 }
                 pref.setOnPreferenceClickListener(preference -> {
                     OnCancelListener listener = null;
-                    if (fragment instanceof TopLevelSettings) {
+                    if (fragment instanceof TopLevelSettings
+                            && ActivityEmbeddingUtils.isEmbeddingActivityEnabled(mContext)) {
+                        // Register the rule for injected apps.
+                        ActivityEmbeddingRulesController.registerTwoPanePairRule(mContext,
+                                new ComponentName(activity.getPackageName(),
+                                        com.android.settings.Settings.class.getName()),
+                                new ComponentName(tile.getPackageName(),
+                                        tile.getComponentName()),
+                                null /* secondaryIntentAction */,
+                                true /* finishPrimaryWithSecondary */,
+                                true /* finishSecondaryWithPrimary */,
+                                true /* clearTop */);
+
+                        // Highlight preference ui.
                         final TopLevelSettings topLevelSettings = (TopLevelSettings) fragment;
                         // Highlight the tile immediately whenever it's clicked
                         topLevelSettings.setHighlightPreferenceKey(key);
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index b3e3296..2bbc11e 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -248,13 +248,15 @@
                 targetComponentName,
                 targetIntent.getAction(),
                 true /* finishPrimaryWithSecondary */,
-                true /* finishSecondaryWithPrimary */);
+                true /* finishSecondaryWithPrimary */,
+                true /* clearTop*/);
         ActivityEmbeddingRulesController.registerTwoPanePairRule(this,
                 new ComponentName(Settings.class.getPackageName(), Settings.class.getName()),
                 targetComponentName,
                 targetIntent.getAction(),
                 true /* finishPrimaryWithSecondary */,
-                true /* finishSecondaryWithPrimary */);
+                true /* finishSecondaryWithPrimary */,
+                true /* clearTop*/);
         startActivity(targetIntent);
     }
 
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index 38b2baa..d3bfa02 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -36,6 +36,7 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
+import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
 import com.android.settings.activityembedding.ActivityEmbeddingUtils;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.dashboard.DashboardFragment;
@@ -98,6 +99,10 @@
 
     @Override
     public boolean onPreferenceTreeClick(Preference preference) {
+        // Register SplitPairRule for SubSettings.
+        ActivityEmbeddingRulesController.registerSubSettingsPairRuleIfNeeded(getContext(),
+                true /* clearTop*/);
+
         setHighlightPreferenceKey(preference.getKey());
         return super.onPreferenceTreeClick(preference);
     }
diff --git a/src/com/android/settings/search/SearchResultTrampoline.java b/src/com/android/settings/search/SearchResultTrampoline.java
index e930473..3414efe 100644
--- a/src/com/android/settings/search/SearchResultTrampoline.java
+++ b/src/com/android/settings/search/SearchResultTrampoline.java
@@ -25,6 +25,7 @@
 
 import com.android.settings.SettingsActivity;
 import com.android.settings.SubSettings;
+import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
 import com.android.settings.overlay.FeatureFactory;
 
 /**
@@ -53,6 +54,11 @@
         args.putInt(EXTRA_SHOW_FRAGMENT_TAB, tab);
         intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
 
+        // Register SplirPairRule for SubSettings, set clearTop false to prevent unexpected back
+        // navigation behavior.
+        ActivityEmbeddingRulesController.registerSubSettingsPairRuleIfNeeded(this /* context */,
+                false /* clearTop*/);
+
         // Reroute request to SubSetting.
         intent.setClass(this /* context */, SubSettings.class)
                 .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);