Start deep link page synchronously in SettingsActivity

- Use a synchronous API to make SettingsActivity start deep link intent
  in onCreate
- Change SettingsHomepageActivity from an alias to a real activity
- Clean up redundant codes

Fix: 206585572
Test: Manual, robotest build pass
Change-Id: Idf42c026f593bb5801a13cae250d1523030b7092
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index c216258..2b5f695 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -58,7 +58,6 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.settings.Settings.WifiSettingsActivity;
 import com.android.settings.activityembedding.ActivityEmbeddingUtils;
-import com.android.settings.activityembedding.SplitStateObserver;
 import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.core.OnActivityResultListener;
 import com.android.settings.core.SettingsBaseActivity;
@@ -248,16 +247,21 @@
 
     @Override
     protected void onCreate(Bundle savedState) {
-        super.onCreate(savedState);
-        Log.d(LOG_TAG, "Starting onCreate");
-
-        long startTime = System.currentTimeMillis();
-
         // Should happen before any call to getIntent()
         getMetaData();
         final Intent intent = getIntent();
 
-        registerSplitStateObserverForTwoPaneDeepLink();
+        if (shouldShowTwoPaneDeepLink(intent)) {
+            launchHomepageForTwoPaneDeepLink(intent);
+            finishAndRemoveTask();
+            super.onCreate(savedState);
+            return;
+        }
+
+        super.onCreate(savedState);
+        Log.d(LOG_TAG, "Starting onCreate");
+
+        long startTime = System.currentTimeMillis();
 
         final FeatureFactory factory = FeatureFactory.getFactory(this);
         mDashboardFeatureProvider = factory.getDashboardFeatureProvider(this);
@@ -362,30 +366,6 @@
         }
     }
 
-    private void registerSplitStateObserverForTwoPaneDeepLink() {
-        if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)) {
-            return;
-        }
-
-        final SplitStateObserver splitStateObserver = new SplitStateObserver(this /* activity*/,
-                true /* listenOnce */,
-                splitInfos -> {
-                    if (!splitInfos.isEmpty() || !SettingsActivity.this.isTaskRoot()) {
-                        // It's already in 2-pane or in a non-empty task, there is no need to go
-                        // 2-pane deep link flow.
-                        return;
-                    }
-
-                    if (shouldShowTwoPaneDeepLink(getIntent())) {
-                        launchHomepageForTwoPaneDeepLink(getIntent());
-                        finishAndRemoveTask();
-                        return;
-                    }
-                }
-            );
-        getLifecycle().addObserver(splitStateObserver);
-    }
-
     private boolean isSubSettings(Intent intent) {
         return this instanceof SubSettings ||
             intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);
@@ -435,6 +415,15 @@
     }
 
     private boolean shouldShowTwoPaneDeepLink(Intent intent) {
+        if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)) {
+            return false;
+        }
+
+        // If the activity is not the task root, it should not start trampoline for deep links.
+        if (!isTaskRoot()) {
+            return false;
+        }
+
         // Only starts trampoline for deep links. Should return false for all the cases that
         // Settings app starts SettingsActivity or SubSetting by itself.
         if (intent.getAction() == null) {
diff --git a/src/com/android/settings/SettingsInitialize.java b/src/com/android/settings/SettingsInitialize.java
index 376d916..ca13683 100644
--- a/src/com/android/settings/SettingsInitialize.java
+++ b/src/com/android/settings/SettingsInitialize.java
@@ -40,7 +40,7 @@
 import androidx.window.embedding.SplitController;
 
 import com.android.settings.Settings.CreateShortcutActivity;
-import com.android.settings.homepage.SettingsHomepageActivity;
+import com.android.settings.homepage.DeepLinkHomepageActivity;
 import com.android.settings.search.SearchStateReceiver;
 import com.android.settingslib.utils.ThreadUtils;
 
@@ -150,8 +150,8 @@
     }
 
     private void enableTwoPaneDeepLinkActivityIfNecessary(PackageManager pm, Context context) {
-        final ComponentName deepLinkHome = new ComponentName(Utils.SETTINGS_PACKAGE_NAME,
-                SettingsHomepageActivity.ALIAS_DEEP_LINK);
+        final ComponentName deepLinkHome = new ComponentName(context,
+                DeepLinkHomepageActivity.class);
         final ComponentName searchStateReceiver = new ComponentName(context,
                 SearchStateReceiver.class);
         final int enableState = SplitController.getInstance().isSplitSupported()
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingProvider.java b/src/com/android/settings/activityembedding/ActivityEmbeddingProvider.java
deleted file mode 100644
index 7645643..0000000
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingProvider.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2021 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.activityembedding;
-
-import android.app.Activity;
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.text.TextUtils;
-
-import com.android.settings.SettingsApplication;
-
-/**
- * A content provider for querying the state of activity embedding feature
- */
-public class ActivityEmbeddingProvider extends ContentProvider {
-
-    private static final String METHOD_IS_EMBEDDING_ACTIVITY_ENABLED = "isEmbeddingActivityEnabled";
-    private static final String METHOD_IS_IN_SETTINGS_TWO_PANE = "isInSettingsTwoPane";
-    private static final String EXTRA_ENABLED_STATE = "enabled_state";
-    private static final String EXTRA_TWO_PANE_STATE = "two_pane_state";
-
-    @Override
-    public boolean onCreate() {
-        return true;
-    }
-
-    @Override
-    public Bundle call(String method, String arg, Bundle extras) {
-        if (TextUtils.equals(method, METHOD_IS_EMBEDDING_ACTIVITY_ENABLED)) {
-            final Bundle bundle = new Bundle();
-            bundle.putBoolean(EXTRA_ENABLED_STATE,
-                    ActivityEmbeddingUtils.isEmbeddingActivityEnabled(getContext()));
-            return bundle;
-        } else if (TextUtils.equals(method, METHOD_IS_IN_SETTINGS_TWO_PANE)) {
-            final Activity homeActivity =
-                    ((SettingsApplication) getContext().getApplicationContext()).getHomeActivity();
-            final Bundle bundle = new Bundle();
-            bundle.putBoolean(EXTRA_TWO_PANE_STATE,
-                    homeActivity == null ? false
-                            : ActivityEmbeddingUtils.isTwoPaneResolution(homeActivity));
-            return bundle;
-        }
-        return null;
-    }
-
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
index 1540657..667c804 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
@@ -33,7 +33,7 @@
 
 import com.android.settings.Settings;
 import com.android.settings.SubSettings;
-import com.android.settings.Utils;
+import com.android.settings.homepage.DeepLinkHomepageActivity;
 import com.android.settings.homepage.SettingsHomepageActivity;
 import com.android.settings.homepage.SliceDeepLinkHomepageActivity;
 
@@ -101,7 +101,6 @@
             ComponentName secondaryComponent,
             String secondaryIntentAction,
             boolean clearTop) {
-
         registerTwoPanePairRule(
                 context,
                 getComponentName(context, Settings.class),
@@ -113,8 +112,7 @@
 
         registerTwoPanePairRule(
                 context,
-                new ComponentName(Utils.SETTINGS_PACKAGE_NAME,
-                        SettingsHomepageActivity.ALIAS_DEEP_LINK),
+                new ComponentName(context, DeepLinkHomepageActivity.class),
                 secondaryComponent,
                 secondaryIntentAction,
                 true /* finishPrimaryWithSecondary */,
@@ -156,9 +154,9 @@
     private void registerHomepagePlaceholderRule() {
         final Set<ActivityFilter> activityFilters = new HashSet<>();
         addActivityFilter(activityFilters, SettingsHomepageActivity.class);
+        addActivityFilter(activityFilters, DeepLinkHomepageActivity.class);
+        addActivityFilter(activityFilters, SliceDeepLinkHomepageActivity.class);
         addActivityFilter(activityFilters, Settings.class);
-        addActivityFilter(activityFilters, new ComponentName(Utils.SETTINGS_PACKAGE_NAME,
-                SettingsHomepageActivity.ALIAS_DEEP_LINK));
 
         final Intent intent = new Intent();
         intent.setComponent(getComponentName(Settings.NetworkDashboardActivity.class));
diff --git a/src/com/android/settings/activityembedding/SplitStateObserver.java b/src/com/android/settings/activityembedding/SplitStateObserver.java
deleted file mode 100644
index ba13c82..0000000
--- a/src/com/android/settings/activityembedding/SplitStateObserver.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2021 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.activityembedding;
-
-import static androidx.lifecycle.Lifecycle.Event.ON_START;
-import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
-
-import android.app.Activity;
-
-import androidx.annotation.NonNull;
-import androidx.core.content.ContextCompat;
-import androidx.core.util.Consumer;
-import androidx.lifecycle.LifecycleObserver;
-import androidx.lifecycle.OnLifecycleEvent;
-import androidx.window.embedding.SplitController;
-import androidx.window.embedding.SplitInfo;
-
-import java.util.List;
-
-/** A lifecycle-aware observer listens to active split state. */
-public class SplitStateObserver implements LifecycleObserver, Consumer<List<SplitInfo>> {
-
-    private final Activity mActivity;
-    private final boolean mListenOnce;
-    private final SplitStateListener mListener;
-    private final SplitController mSplitController;
-
-    public SplitStateObserver(@NonNull Activity activity, boolean listenOnce,
-            @NonNull SplitStateListener listener) {
-        mActivity = activity;
-        mListenOnce = listenOnce;
-        mListener = listener;
-        mSplitController = SplitController.getInstance();
-    }
-
-    /**
-     * Start lifecycle event.
-     */
-    @OnLifecycleEvent(ON_START)
-    public void onStart() {
-        mSplitController.addSplitListener(mActivity, ContextCompat.getMainExecutor(mActivity),
-                this);
-    }
-
-    /**
-     * Stop lifecycle event.
-     */
-    @OnLifecycleEvent(ON_STOP)
-    public void onStop() {
-        mSplitController.removeSplitListener(this);
-    }
-
-    @Override
-    public void accept(List<SplitInfo> splitInfos) {
-        if (mListenOnce) {
-            mSplitController.removeSplitListener(this);
-        }
-        mListener.onSplitInfoChanged(splitInfos);
-    }
-
-    /** This interface makes as class that it wants to listen to {@link SplitInfo} changes. */
-    public interface SplitStateListener {
-
-        /** Receive a set of split info change */
-        void onSplitInfoChanged(List<SplitInfo> splitInfos);
-    }
-}
diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java
index 304898f..464e459 100644
--- a/src/com/android/settings/core/SettingsBaseActivity.java
+++ b/src/com/android/settings/core/SettingsBaseActivity.java
@@ -74,6 +74,9 @@
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (isFinishing()) {
+            return;
+        }
         if (isLockTaskModePinned() && !isSettingsRunOnTop()) {
             Log.w(TAG, "Devices lock task mode pinned.");
             finish();
diff --git a/src/com/android/settings/homepage/DeepLinkHomepageActivity.java b/src/com/android/settings/homepage/DeepLinkHomepageActivity.java
new file mode 100644
index 0000000..59cfc3c
--- /dev/null
+++ b/src/com/android/settings/homepage/DeepLinkHomepageActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 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.homepage;
+
+/** Activity for other apps to launch Settings deep link page */
+public class DeepLinkHomepageActivity extends SettingsHomepageActivity {
+}
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 4e843fd..4609cec 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -44,7 +44,6 @@
 import com.android.settings.Settings;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsApplication;
-import com.android.settings.Utils;
 import com.android.settings.accounts.AvatarViewMixin;
 import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
 import com.android.settings.activityembedding.ActivityEmbeddingUtils;
@@ -72,9 +71,6 @@
     public static final String EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA =
             "settings_large_screen_deep_link_intent_data";
 
-    // An alias class name of SettingsHomepageActivity.
-    public static final String ALIAS_DEEP_LINK = "com.android.settings.DeepLinkHomepageActivity";
-
     private static final int DEFAULT_HIGHLIGHT_MENU_KEY = R.string.menu_key_network;
     private static final long HOMEPAGE_LOADING_TIMEOUT_MS = 300;
 
@@ -91,12 +87,12 @@
     }
 
     /**
-     *  Try to register a {@link HomepageLoadedListener}. If homepage is already loaded, the
-     *  listener will not be notified.
+     *  Try to add a {@link HomepageLoadedListener}. If homepage is already loaded, the listener
+     *  will not be notified.
      *
-     *  @return Whether the listener should be registered.
+     *  @return Whether the listener is added.
      */
-    public boolean registerHomepageLoadedListenerIfNeeded(HomepageLoadedListener listener) {
+    public boolean addHomepageLoadedListener(HomepageLoadedListener listener) {
         if (mHomepageView == null) {
             return false;
         } else {
@@ -245,6 +241,13 @@
             return;
         }
 
+        if (!(this instanceof DeepLinkHomepageActivity
+                || this instanceof SliceDeepLinkHomepageActivity)) {
+            Log.e(TAG, "Not a deep link component");
+            finish();
+            return;
+        }
+
         final String intentUriString = intent.getStringExtra(
                 EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI);
         if (TextUtils.isEmpty(intentUriString)) {
@@ -287,7 +290,7 @@
 
         // Set 2-pane pair rule for the deep link page.
         ActivityEmbeddingRulesController.registerTwoPanePairRule(this,
-                getDeepLinkComponent(),
+                new ComponentName(getApplicationContext(), getClass()),
                 targetComponentName,
                 targetIntent.getAction(),
                 true /* finishPrimaryWithSecondary */,
@@ -303,10 +306,6 @@
         startActivity(targetIntent);
     }
 
-    protected ComponentName getDeepLinkComponent() {
-        return new ComponentName(Utils.SETTINGS_PACKAGE_NAME, ALIAS_DEEP_LINK);
-    }
-
     private String getHighlightMenuKey() {
         final Intent intent = getIntent();
         if (intent != null && TextUtils.equals(intent.getAction(),
diff --git a/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java b/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java
index 2f83612..2ea8a83 100644
--- a/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java
+++ b/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java
@@ -16,12 +16,6 @@
 
 package com.android.settings.homepage;
 
-import android.content.ComponentName;
-
 /** Activity for Slices to launch Settings deep link page */
 public class SliceDeepLinkHomepageActivity extends SettingsHomepageActivity {
-    @Override
-    protected ComponentName getDeepLinkComponent() {
-        return new ComponentName(getApplicationContext(), getClass());
-    }
 }
diff --git a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
index bdf0886..4002500 100644
--- a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
+++ b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
@@ -203,7 +203,7 @@
             return;
         }
 
-        if (mHomepageActivity.registerHomepageLoadedListenerIfNeeded(this)) {
+        if (mHomepageActivity.addHomepageLoadedListener(this)) {
             return;
         }