Merge "Fix wallpaper preview flash of WallpaperSectionController" into sc-v2-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 72d721d..21c1288 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -10,6 +10,7 @@
        android:protectionLevel="signature"/>
 
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+  <uses-permission android:name="android.permission.LAUNCH_TWO_PANE_SETTINGS_DEEP_LINK" />
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
   <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
diff --git a/res/layout/fragment_image_preview.xml b/res/layout/fragment_image_preview.xml
index 46b4b88..de8df17 100644
--- a/res/layout/fragment_image_preview.xml
+++ b/res/layout/fragment_image_preview.xml
@@ -21,6 +21,15 @@
     android:layout_height="match_parent"
     android:background="?android:colorBackground">
 
+    <!-- Preview header (toolbar + status bar) is used to solve preview with full screen animated
+         to non-full screen cases. -->
+    <FrameLayout
+        android:id="@+id/preview_header"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="?android:attr/actionBarSize">
+    </FrameLayout>
+
     <FrameLayout
         android:id="@+id/separated_tabs_container"
         android:layout_width="match_parent"
diff --git a/res/layout/fragment_live_preview.xml b/res/layout/fragment_live_preview.xml
index dc8273c..462329b 100644
--- a/res/layout/fragment_live_preview.xml
+++ b/res/layout/fragment_live_preview.xml
@@ -21,6 +21,15 @@
     android:layout_height="match_parent"
     android:background="?android:colorBackground">
 
+    <!-- Preview header (toolbar + status bar) is used to solve preview with full screen animated
+         to non-full screen cases. -->
+    <FrameLayout
+        android:id="@+id/preview_header"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="?android:attr/actionBarSize">
+    </FrameLayout>
+
     <FrameLayout
         android:id="@+id/separated_tabs_container"
         android:layout_width="match_parent"
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index e91262c..c381330 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -56,9 +56,9 @@
     <string name="wallpaper_disabled_by_administrator_message" msgid="1551430406714747884">"Jou toesteladministrateur het die stel van \'n muurpapier gedeaktiveer"</string>
     <string name="wallpaper_set_successfully_message" msgid="2958998799111688578">"Muurpapier is suksesvol gestel"</string>
     <string name="wallpapers_unavailable_offline_message" msgid="8136405438621689532">"Jy moet \'n internetverbinding hê om muurpapiere te bekyk. Koppel en probeer weer."</string>
-    <string name="currently_set_home_wallpaper_thumbnail" msgid="4022381436821898917">"Kleinkiekie van die muurpapier wat tans op die tuisskerm gestel is"</string>
-    <string name="currently_set_lock_wallpaper_thumbnail" msgid="2094209303934569997">"Kleinkiekie van die muurpapier wat tans op die sluitskerm gestel is"</string>
-    <string name="currently_set_wallpaper_thumbnail" msgid="8651887838745545107">"Kleinkiekie van die muurpapier wat tans gestel is"</string>
+    <string name="currently_set_home_wallpaper_thumbnail" msgid="4022381436821898917">"Miniprent van die muurpapier wat tans op die tuisskerm gestel is"</string>
+    <string name="currently_set_lock_wallpaper_thumbnail" msgid="2094209303934569997">"Miniprent van die muurpapier wat tans op die sluitskerm gestel is"</string>
+    <string name="currently_set_wallpaper_thumbnail" msgid="8651887838745545107">"Miniprent van die muurpapier wat tans gestel is"</string>
     <string name="wallpaper_thumbnail" msgid="569931475923605974">"Muurpapierkleinkiekie"</string>
     <string name="explore_home_screen" msgid="8756346794535765482">"Verken tuisskermmuurpapier"</string>
     <string name="explore_lock_screen" msgid="268938342103703665">"Verken sluitskermmuurpapier"</string>
diff --git a/src/com/android/wallpaper/model/CurrentWallpaperInfoVN.java b/src/com/android/wallpaper/model/CurrentWallpaperInfoVN.java
index cc2677a..3522dc5 100755
--- a/src/com/android/wallpaper/model/CurrentWallpaperInfoVN.java
+++ b/src/com/android/wallpaper/model/CurrentWallpaperInfoVN.java
@@ -18,8 +18,6 @@
 import android.app.Activity;
 import android.content.Context;
 import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.StringRes;
@@ -31,7 +29,6 @@
 import com.android.wallpaper.compat.WallpaperManagerCompat.WallpaperLocation;
 import com.android.wallpaper.module.InjectorProvider;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -140,23 +137,10 @@
      * Constructs and returns an Asset instance representing the currently-set wallpaper asset.
      */
     private Asset createCurrentWallpaperAssetVN(Context context) {
-        WallpaperManagerCompat wallpaperManagerCompat = InjectorProvider.getInjector()
-                .getWallpaperManagerCompat(context);
-
-        ParcelFileDescriptor systemWallpaperFile = wallpaperManagerCompat.getWallpaperFile(
-                WallpaperManagerCompat.FLAG_SYSTEM);
-
         // Whether the wallpaper this object represents is the default built-in wallpaper.
         boolean isSystemBuiltIn = mWallpaperManagerFlag == WallpaperManagerCompat.FLAG_SYSTEM
-                && systemWallpaperFile == null;
-
-        if (systemWallpaperFile != null) {
-            try {
-                systemWallpaperFile.close();
-            } catch (IOException e) {
-                Log.e(TAG, "Unable to close system wallpaper ParcelFileDescriptor", e);
-            }
-        }
+                && !InjectorProvider.getInjector().getWallpaperStatusChecker()
+                .isHomeStaticWallpaperSet(context);
 
         return (isSystemBuiltIn)
                 ? new BuiltInWallpaperAsset(context)
diff --git a/src/com/android/wallpaper/module/BaseWallpaperInjector.java b/src/com/android/wallpaper/module/BaseWallpaperInjector.java
index 0dc5578..ea429a6 100755
--- a/src/com/android/wallpaper/module/BaseWallpaperInjector.java
+++ b/src/com/android/wallpaper/module/BaseWallpaperInjector.java
@@ -33,6 +33,7 @@
     private WallpaperRefresher mWallpaperRefresher;
     private Requester mRequester;
     private WallpaperManagerCompat mWallpaperManagerCompat;
+    private WallpaperStatusChecker mWallpaperStatusChecker;
     private CurrentWallpaperInfoFactory mCurrentWallpaperFactory;
     private NetworkStatusNotifier mNetworkStatusNotifier;
     private AlarmManagerWrapper mAlarmManagerWrapper;
@@ -101,6 +102,14 @@
     }
 
     @Override
+    public WallpaperStatusChecker getWallpaperStatusChecker() {
+        if (mWallpaperStatusChecker == null) {
+            mWallpaperStatusChecker = new DefaultWallpaperStatusChecker();
+        }
+        return mWallpaperStatusChecker;
+    }
+
+    @Override
     public synchronized CurrentWallpaperInfoFactory getCurrentWallpaperFactory(Context context) {
         if (mCurrentWallpaperFactory == null) {
             mCurrentWallpaperFactory =
diff --git a/src/com/android/wallpaper/module/DefaultWallpaperPersister.java b/src/com/android/wallpaper/module/DefaultWallpaperPersister.java
index abe1728..9148b9f 100755
--- a/src/com/android/wallpaper/module/DefaultWallpaperPersister.java
+++ b/src/com/android/wallpaper/module/DefaultWallpaperPersister.java
@@ -656,8 +656,9 @@
             }
 
 
-            boolean wasLockWallpaperSet = LockWallpaperStatusChecker.isLockWallpaperSet(
-                    mAppContext);
+            boolean wasLockWallpaperSet =
+                    InjectorProvider.getInjector().getWallpaperStatusChecker().isLockWallpaperSet(
+                            mAppContext);
 
             boolean allowBackup = mWallpaper.getBackupPermission() == WallpaperInfo.BACKUP_ALLOWED;
             final int wallpaperId;
diff --git a/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java b/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java
index d85e04e..246b017 100755
--- a/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java
+++ b/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java
@@ -49,6 +49,7 @@
     private final Context mAppContext;
     private final WallpaperPreferences mWallpaperPreferences;
     private final WallpaperManager mWallpaperManager;
+    private final WallpaperStatusChecker mWallpaperStatusChecker;
 
     /**
      * @param context The application's context.
@@ -58,6 +59,7 @@
 
         Injector injector = InjectorProvider.getInjector();
         mWallpaperPreferences = injector.getPreferences(mAppContext);
+        mWallpaperStatusChecker = injector.getWallpaperStatusChecker();
 
         // Retrieve WallpaperManager using Context#getSystemService instead of
         // WallpaperManager#getInstance so it can be mocked out in test.
@@ -98,8 +100,8 @@
                 setFallbackHomeScreenWallpaperMetadata();
             }
 
-            boolean isLockScreenWallpaperCurrentlySet = LockWallpaperStatusChecker
-                    .isLockWallpaperSet(mAppContext);
+            boolean isLockScreenWallpaperCurrentlySet = mWallpaperStatusChecker.isLockWallpaperSet(
+                    mAppContext);
 
             if (!BuildCompat.isAtLeastN() || !isLockScreenWallpaperCurrentlySet) {
                 // Return only home metadata if pre-N device or lock screen wallpaper is not explicitly set.
@@ -226,7 +228,7 @@
 
         private long getCurrentLockWallpaperHashCode() {
             if (mCurrentLockWallpaperHashCode == 0
-                    && LockWallpaperStatusChecker.isLockWallpaperSet(mAppContext)) {
+                    && mWallpaperStatusChecker.isLockWallpaperSet(mAppContext)) {
                 Bitmap wallpaperBitmap = getLockWallpaperBitmap();
                 mCurrentLockWallpaperHashCode = BitmapUtils.generateHashCode(wallpaperBitmap);
             }
diff --git a/src/com/android/wallpaper/module/DefaultWallpaperStatusChecker.java b/src/com/android/wallpaper/module/DefaultWallpaperStatusChecker.java
new file mode 100644
index 0000000..372ff7f
--- /dev/null
+++ b/src/com/android/wallpaper/module/DefaultWallpaperStatusChecker.java
@@ -0,0 +1,58 @@
+/*
+ * 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.wallpaper.module;
+
+import static android.app.WallpaperManager.FLAG_LOCK;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import com.android.wallpaper.compat.WallpaperManagerCompat;
+
+import java.io.IOException;
+
+/**
+ * Default implementation of {@link WallpaperStatusChecker}.
+ */
+public final class DefaultWallpaperStatusChecker implements WallpaperStatusChecker {
+
+    private static final String TAG = "DefaultWallpaperStatusChecker";
+
+    @Override
+    public boolean isHomeStaticWallpaperSet(Context context) {
+        ParcelFileDescriptor systemWallpaperFile =
+                InjectorProvider.getInjector().getWallpaperManagerCompat(context).getWallpaperFile(
+                        WallpaperManagerCompat.FLAG_SYSTEM);
+        boolean isStaticWallpaperSet = systemWallpaperFile != null;
+
+        if (systemWallpaperFile != null) {
+            try {
+                systemWallpaperFile.close();
+            } catch (IOException e) {
+                Log.e(TAG, "Unable to close system wallpaper ParcelFileDescriptor", e);
+            }
+        }
+
+        return isStaticWallpaperSet;
+    }
+
+    @Override
+    public boolean isLockWallpaperSet(Context context) {
+        return WallpaperManager.getInstance(context).getWallpaperId(FLAG_LOCK) > 0;
+    }
+}
diff --git a/src/com/android/wallpaper/module/Injector.java b/src/com/android/wallpaper/module/Injector.java
index 1c40e93..919d1ba 100755
--- a/src/com/android/wallpaper/module/Injector.java
+++ b/src/com/android/wallpaper/module/Injector.java
@@ -62,6 +62,8 @@
 
     WallpaperManagerCompat getWallpaperManagerCompat(Context context);
 
+    WallpaperStatusChecker getWallpaperStatusChecker();
+
     WallpaperPersister getWallpaperPersister(Context context);
 
     WallpaperPreferences getPreferences(Context context);
diff --git a/src/com/android/wallpaper/module/LargeScreenTwoPanesChecker.kt b/src/com/android/wallpaper/module/LargeScreenTwoPanesChecker.kt
new file mode 100644
index 0000000..4a36049
--- /dev/null
+++ b/src/com/android/wallpaper/module/LargeScreenTwoPanesChecker.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.wallpaper.module
+
+import android.content.Context
+import android.content.Intent
+import android.content.Intent.ACTION_SET_WALLPAPER
+import android.content.pm.PackageManager.MATCH_DEFAULT_ONLY
+import android.provider.Settings.*
+
+/**
+ * Utility class to check the support of two panes integration (trampoline)
+ */
+class LargeScreenTwoPanesChecker : TwoPanesChecker {
+    companion object {
+        private const val TAG = "LargeScreenTwoPanesChecker"
+        private const val VALUE_HIGHLIGHT_MENU = "top_level_wallpaper"
+    }
+
+    override fun isTwoPanesEnabled(context: Context): Boolean {
+        val pm = context.packageManager
+        val intent = getTwoPanesIntent(context)
+
+        val resolveInfo = pm.resolveActivity(intent, MATCH_DEFAULT_ONLY)?.activityInfo?.enabled
+        return resolveInfo != null
+    }
+
+    override fun getTwoPanesIntent(context: Context): Intent {
+        val intentUri = Intent(ACTION_SET_WALLPAPER)
+                .setPackage(context.packageName).toUri(Intent.URI_INTENT_SCHEME)
+
+        return Intent(ACTION_SETTINGS_LARGE_SCREEN_DEEP_LINK).apply {
+            putExtra(EXTRA_SETTINGS_LARGE_SCREEN_HIGHLIGHT_MENU_KEY, VALUE_HIGHLIGHT_MENU)
+            putExtra(EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_URI, intentUri)
+        };
+    }
+}
diff --git a/src/com/android/wallpaper/module/LockWallpaperStatusChecker.java b/src/com/android/wallpaper/module/LockWallpaperStatusChecker.java
deleted file mode 100755
index 2ae93b0..0000000
--- a/src/com/android/wallpaper/module/LockWallpaperStatusChecker.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2017 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.wallpaper.module;
-
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import com.android.wallpaper.compat.BuildCompat;
-import com.android.wallpaper.compat.WallpaperManagerCompat;
-
-import java.io.IOException;
-
-/**
- * Checks whether an explicit lock wallpaper is set to the device (i.e., independently shown under
- * the keyguard and separate from the wallpaper shown under the user's launcher).
- */
-public class LockWallpaperStatusChecker {
-
-    private static final String TAG = "LockWPStatusChecker";
-
-    /**
-     * Returns whether a lock screen wallpaper is independently set to the device.
-     */
-    public static boolean isLockWallpaperSet(Context context) {
-        // Lock screen wallpapers are not supported until Android N.
-        if (!BuildCompat.isAtLeastN()) {
-            return false;
-        }
-
-        WallpaperManagerCompat wallpaperManagerCompat = InjectorProvider.getInjector()
-                .getWallpaperManagerCompat(context);
-        ParcelFileDescriptor parcelFd =
-                wallpaperManagerCompat.getWallpaperFile(WallpaperManagerCompat.FLAG_LOCK);
-        boolean isSet = parcelFd != null;
-        if (isSet) {
-            try {
-                // Close the ParcelFileDescriptor if it's not null to avoid a resource leak.
-                parcelFd.close();
-            } catch (IOException e) {
-                Log.e(TAG, "IO exception when closing the lock screen wallpaper file descriptor.");
-            }
-        }
-        return isSet;
-    }
-}
diff --git a/src/com/android/wallpaper/module/TwoPanesChecker.kt b/src/com/android/wallpaper/module/TwoPanesChecker.kt
new file mode 100644
index 0000000..c43a366
--- /dev/null
+++ b/src/com/android/wallpaper/module/TwoPanesChecker.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.wallpaper.module
+
+import android.content.Context
+import android.content.Intent
+
+/**
+ * Checks if the device is supporting two panes' features
+ */
+interface TwoPanesChecker {
+    /**
+     * Checks if the device is supporting two-panes landscape
+     *
+     * @param context the Activity's context
+     * @return `true` if supported, `false` otherwise.
+     */
+    fun isTwoPanesEnabled(context: Context): Boolean
+
+    /**
+     * Gets the intent to start two-panes landscape Activity
+     *
+     * @param context the Activity's context
+     * @return [Intent] to start two panels
+     */
+    fun getTwoPanesIntent(context: Context): Intent?
+}
\ No newline at end of file
diff --git a/src/com/android/wallpaper/module/WallpaperSetter.java b/src/com/android/wallpaper/module/WallpaperSetter.java
index 4cdc8bc..428ff86 100644
--- a/src/com/android/wallpaper/module/WallpaperSetter.java
+++ b/src/com/android/wallpaper/module/WallpaperSetter.java
@@ -1,5 +1,7 @@
 package com.android.wallpaper.module;
 
+import static android.app.WallpaperManager.FLAG_LOCK;
+
 import android.app.Activity;
 import android.app.ProgressDialog;
 import android.app.WallpaperColors;
@@ -22,7 +24,6 @@
 
 import com.android.wallpaper.R;
 import com.android.wallpaper.asset.Asset;
-import com.android.wallpaper.asset.BuiltInWallpaperAsset;
 import com.android.wallpaper.model.LiveWallpaperInfo;
 import com.android.wallpaper.model.WallpaperInfo;
 import com.android.wallpaper.module.UserEventLogger.WallpaperSetFailureReason;
@@ -205,7 +206,7 @@
                     activity.getWindow().getDecorView().getRootView().getWindowToken(),
                     0.5f /* xOffset */, 0.0f /* yOffset */);
             if (destination == WallpaperPersister.DEST_BOTH) {
-                wallpaperManager.clear(WallpaperManager.FLAG_LOCK);
+                wallpaperManager.clear(FLAG_LOCK);
             }
             mPreferences.storeLatestHomeWallpaper(wallpaper.getWallpaperId(), wallpaper,
                     colors != null ? colors :
@@ -284,8 +285,6 @@
      */
     public void requestDestination(Activity activity, FragmentManager fragmentManager,
             @StringRes int titleResId, Listener listener, boolean isLiveWallpaper) {
-        CurrentWallpaperInfoFactory factory = InjectorProvider.getInjector()
-                .getCurrentWallpaperFactory(activity);
         saveAndLockScreenOrientationIfNeeded(activity);
         Listener listenerWrapper = new Listener() {
             @Override
@@ -305,28 +304,34 @@
                 }
             }
         };
-        factory.createCurrentWallpaperInfos((homeWallpaper, lockWallpaper, presentationMode) -> {
-            SetWallpaperDialogFragment setWallpaperDialog = new SetWallpaperDialogFragment();
-            setWallpaperDialog.setTitleResId(titleResId);
-            setWallpaperDialog.setListener(listenerWrapper);
-            boolean isBuiltIn = homeWallpaper.getAsset(activity) instanceof BuiltInWallpaperAsset;
-            if ((homeWallpaper instanceof LiveWallpaperInfo || isBuiltIn)
-                    && lockWallpaper == null) {
-                if (isLiveWallpaper) {
-                    // If lock wallpaper is live and we're setting a live wallpaper, we can only
-                    // set it to both, so bypass the dialog.
-                    listener.onSet(WallpaperPersister.DEST_BOTH);
-                    restoreScreenOrientationIfNeeded(activity);
-                    return;
-                }
-                // if the lock wallpaper is a live wallpaper, we cannot set a home-only static one
-                setWallpaperDialog.setHomeOptionAvailable(false);
-            }
+
+        WallpaperStatusChecker wallpaperStatusChecker =
+                InjectorProvider.getInjector().getWallpaperStatusChecker();
+        boolean isLiveWallpaperSet =
+                WallpaperManager.getInstance(activity).getWallpaperInfo() != null;
+        // Alternative of ag/15567276
+        boolean isBuiltIn = !isLiveWallpaperSet
+                && !wallpaperStatusChecker.isHomeStaticWallpaperSet(activity);
+
+        SetWallpaperDialogFragment setWallpaperDialog = new SetWallpaperDialogFragment();
+        setWallpaperDialog.setTitleResId(titleResId);
+        setWallpaperDialog.setListener(listenerWrapper);
+        if ((isLiveWallpaperSet || isBuiltIn)
+                && !wallpaperStatusChecker.isLockWallpaperSet(activity)) {
             if (isLiveWallpaper) {
-                setWallpaperDialog.setLockOptionAvailable(false);
+                // If lock wallpaper is live and we're setting a live wallpaper, we can only
+                // set it to both, so bypass the dialog.
+                listener.onSet(WallpaperPersister.DEST_BOTH);
+                restoreScreenOrientationIfNeeded(activity);
+                return;
             }
-            setWallpaperDialog.show(fragmentManager, TAG_SET_WALLPAPER_DIALOG_FRAGMENT);
-        }, true); // Force refresh as the wallpaper may have been set while this fragment was paused
+            // if the lock wallpaper is a live wallpaper, we cannot set a home-only static one
+            setWallpaperDialog.setHomeOptionAvailable(false);
+        }
+        if (isLiveWallpaper) {
+            setWallpaperDialog.setLockOptionAvailable(false);
+        }
+        setWallpaperDialog.show(fragmentManager, TAG_SET_WALLPAPER_DIALOG_FRAGMENT);
     }
 
     private void saveAndLockScreenOrientationIfNeeded(Activity activity) {
diff --git a/src/com/android/wallpaper/module/WallpaperStatusChecker.java b/src/com/android/wallpaper/module/WallpaperStatusChecker.java
new file mode 100644
index 0000000..04a2a2d
--- /dev/null
+++ b/src/com/android/wallpaper/module/WallpaperStatusChecker.java
@@ -0,0 +1,35 @@
+/*
+ * 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.wallpaper.module;
+
+import android.content.Context;
+
+/**
+ * Checks the status of the home/lock screen wallpaper in the device.
+ */
+public interface WallpaperStatusChecker {
+
+    /**
+     * Returns whether a static home wallpaper is set to the device.
+     */
+    boolean isHomeStaticWallpaperSet(Context context);
+
+    /**
+     * Returns an explicit lock wallpaper is set to the device independently (i.e.,independently
+     * shown under the keyguard and separate from the wallpaper shown under the user's launcher).
+     */
+    boolean isLockWallpaperSet(Context context);
+}
diff --git a/src/com/android/wallpaper/picker/AppbarFragment.java b/src/com/android/wallpaper/picker/AppbarFragment.java
index 4a71bb0..cda2263 100644
--- a/src/com/android/wallpaper/picker/AppbarFragment.java
+++ b/src/com/android/wallpaper/picker/AppbarFragment.java
@@ -110,6 +110,12 @@
         mToolbar = rootView.findViewById(getToolbarId());
 
         mTitleView = mToolbar.findViewById(R.id.custom_toolbar_title);
+
+        // Update toolbar and status bar color.
+        mToolbar.setBackgroundResource(getToolbarColorId());
+        getActivity().getWindow().setStatusBarColor(
+                getActivity().getResources().getColor(getToolbarColorId()));
+
         CharSequence title;
         if (getArguments() != null) {
             title = getArguments().getCharSequence(ARG_TITLE, getDefaultTitle());
@@ -139,6 +145,10 @@
         return R.id.toolbar;
     }
 
+    protected int getToolbarColorId() {
+        return R.color.settingslib_colorSurfaceHeader;
+    }
+
     /**
      * Set up arrow feature status to enabled or not. Enable it for updating
      * onBottomActionBarReady() while initializing without toolbar setup.
diff --git a/src/com/android/wallpaper/picker/CustomizationPickerActivity.java b/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
index d97f598..fcc97b0 100644
--- a/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
+++ b/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
@@ -17,6 +17,7 @@
 
 import static com.android.wallpaper.util.ActivityUtils.isSUWMode;
 import static com.android.wallpaper.util.ActivityUtils.isWallpaperOnlyMode;
+import static com.android.wallpaper.util.ActivityUtils.startActivityForResultSafely;
 
 import android.app.Activity;
 import android.content.Intent;
@@ -41,14 +42,17 @@
 import com.android.wallpaper.module.DailyLoggingAlarmScheduler;
 import com.android.wallpaper.module.Injector;
 import com.android.wallpaper.module.InjectorProvider;
+import com.android.wallpaper.module.LargeScreenTwoPanesChecker;
 import com.android.wallpaper.module.NetworkStatusNotifier;
 import com.android.wallpaper.module.NetworkStatusNotifier.NetworkStatus;
+import com.android.wallpaper.module.TwoPanesChecker;
 import com.android.wallpaper.module.UserEventLogger;
 import com.android.wallpaper.picker.AppbarFragment.AppbarFragmentHost;
 import com.android.wallpaper.picker.CategoryFragment.CategoryFragmentHost;
 import com.android.wallpaper.picker.CategorySelectorFragment.CategorySelectorFragmentHost;
 import com.android.wallpaper.picker.MyPhotosStarter.PermissionChangedListener;
 import com.android.wallpaper.picker.individual.IndividualPickerFragment.IndividualPickerFragmentHost;
+import com.android.wallpaper.util.ActivityUtils;
 import com.android.wallpaper.util.DeepLinkUtils;
 import com.android.wallpaper.util.LaunchUtils;
 import com.android.wallpaper.widget.BottomActionBar;
@@ -84,6 +88,18 @@
 
         // Restore this Activity's state before restoring contained Fragments state.
         super.onCreate(savedInstanceState);
+        // Trampoline for the two panes
+        final TwoPanesChecker mTwoPanesChecker = new LargeScreenTwoPanesChecker();
+        if (mTwoPanesChecker.isTwoPanesEnabled(this)) {
+            Intent intent = getIntent();
+            if (!ActivityUtils.isLaunchedFromSettingsTrampoline(intent)
+                    && !ActivityUtils.isLaunchedFromSettingsRelated(intent)) {
+                startActivityForResultSafely(this,
+                        mTwoPanesChecker.getTwoPanesIntent(this), /* requestCode= */ 0);
+                finish();
+            }
+        }
+
         setContentView(R.layout.activity_customization_picker);
         mBottomActionBar = findViewById(R.id.bottom_actionbar);
 
diff --git a/src/com/android/wallpaper/picker/CustomizationPickerFragment.java b/src/com/android/wallpaper/picker/CustomizationPickerFragment.java
index 8884c0e..c28af3a 100644
--- a/src/com/android/wallpaper/picker/CustomizationPickerFragment.java
+++ b/src/com/android/wallpaper/picker/CustomizationPickerFragment.java
@@ -133,6 +133,11 @@
     }
 
     @Override
+    protected int getToolbarColorId() {
+        return android.R.color.transparent;
+    }
+
+    @Override
     public boolean onBackPressed() {
         // TODO(b/191120122) Improve glitchy animation in Settings.
         if (ActivityUtils.isLaunchedFromSettingsSearch(getActivity().getIntent())) {
diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
index 1809c63..ae3d63c 100755
--- a/src/com/android/wallpaper/picker/ImagePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
@@ -144,6 +144,10 @@
         mTouchForwardingLayout = mContainer.findViewById(R.id.touch_forwarding_layout);
         mTouchForwardingLayout.setForwardingEnabled(true);
 
+        // Update preview header color which covers toolbar and status bar area.
+        View previewHeader = view.findViewById(R.id.preview_header);
+        previewHeader.setBackgroundColor(activity.getColor(R.color.settingslib_colorSurfaceHeader));
+
         // Set aspect ratio on the preview card dynamically.
         ConstraintSet set = new ConstraintSet();
         set.clone(mContainer);
diff --git a/src/com/android/wallpaper/picker/LivePreviewFragment.java b/src/com/android/wallpaper/picker/LivePreviewFragment.java
index 45217f1..5fbb9ee 100644
--- a/src/com/android/wallpaper/picker/LivePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/LivePreviewFragment.java
@@ -167,6 +167,11 @@
                 activity.getWindowManager().getDefaultDisplay());
         mPreviewContainer = view.findViewById(R.id.live_wallpaper_preview);
         mTouchForwardingLayout = view.findViewById(R.id.touch_forwarding_layout);
+
+        // Update preview header color which covers toolbar and status bar area.
+        View previewHeader = view.findViewById(R.id.preview_header);
+        previewHeader.setBackgroundColor(activity.getColor(R.color.settingslib_colorSurfaceHeader));
+
         // Set aspect ratio on the preview card.
         ConstraintSet set = new ConstraintSet();
         set.clone((ConstraintLayout) mPreviewContainer);
diff --git a/src/com/android/wallpaper/picker/PreviewFragment.java b/src/com/android/wallpaper/picker/PreviewFragment.java
index 172bacd..c91719e 100755
--- a/src/com/android/wallpaper/picker/PreviewFragment.java
+++ b/src/com/android/wallpaper/picker/PreviewFragment.java
@@ -182,6 +182,11 @@
     }
 
     @Override
+    protected int getToolbarColorId() {
+        return android.R.color.transparent;
+    }
+
+    @Override
     @CallSuper
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
@@ -201,6 +206,13 @@
 
                     mFullScreenAnimation.setWindowInsets(windowInsets);
                     mFullScreenAnimation.placeViews();
+
+                    // Update preview header's padding top to align status bar height.
+                    View previewHeader = v.findViewById(R.id.preview_header);
+                    previewHeader.setPadding(previewHeader.getPaddingLeft(),
+                            mFullScreenAnimation.getStatusBarHeight(),
+                            previewHeader.getPaddingRight(), previewHeader.getPaddingBottom());
+
                     return windowInsets.consumeSystemWindowInsets();
                 }
         );
diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
index 4436304..d00bc26 100755
--- a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
+++ b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
@@ -92,6 +92,7 @@
 import com.android.wallpaper.picker.WallpapersUiContainer;
 import com.android.wallpaper.picker.individual.SetIndividualHolder.OnSetListener;
 import com.android.wallpaper.util.DiskBasedLogger;
+import com.android.wallpaper.util.LaunchUtils;
 import com.android.wallpaper.util.SizeCalculator;
 import com.android.wallpaper.widget.WallpaperInfoView;
 import com.android.wallpaper.widget.WallpaperPickerRecyclerViewAccessibilityDelegate;
@@ -860,6 +861,9 @@
 
                                 activity.setResult(Activity.RESULT_OK);
                                 activity.finish();
+
+                                // Go back to launcher home.
+                                LaunchUtils.launchHome(appContext);
                             } else if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
                                 mAdapter.updateSelectedTile(SPECIAL_FIXED_TILE_ADAPTER_POSITION);
                             }
diff --git a/src/com/android/wallpaper/util/ActivityUtils.java b/src/com/android/wallpaper/util/ActivityUtils.java
index 1fccd2f..7456edd 100755
--- a/src/com/android/wallpaper/util/ActivityUtils.java
+++ b/src/com/android/wallpaper/util/ActivityUtils.java
@@ -17,6 +17,7 @@
 
 import static com.android.wallpaper.util.LaunchSourceUtils.LAUNCH_SETTINGS_SEARCH;
 import static com.android.wallpaper.util.LaunchSourceUtils.LAUNCH_SOURCE_SETTINGS;
+import static com.android.wallpaper.util.LaunchSourceUtils.LAUNCH_SOURCE_SETTINGS_HOMEPAGE;
 import static com.android.wallpaper.util.LaunchSourceUtils.WALLPAPER_LAUNCH_SOURCE;
 
 import android.app.Activity;
@@ -69,6 +70,16 @@
     }
 
     /**
+     * Checks if the Activity's launch source is from Settings' trampoline.
+     *
+     * @param intent intent to start the Activity
+     * @return {@code true} if the Activity's launch source is from Settings' trampoline.
+     */
+    public static boolean isLaunchedFromSettingsTrampoline(Intent intent) {
+        return isLaunchedFromSettingsHome(intent);
+    }
+
+    /**
      * Returns true if wallpaper launch source is from Settings.
      *
      * @param intent activity intent.
@@ -78,6 +89,10 @@
                 intent.getStringExtra(WALLPAPER_LAUNCH_SOURCE)));
     }
 
+    private static boolean isLaunchedFromSettingsHome(Intent intent) {
+        return (intent != null && intent.getBooleanExtra(LAUNCH_SOURCE_SETTINGS_HOMEPAGE, false));
+    }
+
     /**
      * Returns true if wallpaper launch source is from Settings Search.
      *
diff --git a/src/com/android/wallpaper/util/FullScreenAnimation.java b/src/com/android/wallpaper/util/FullScreenAnimation.java
index 0a97f72..bf123b3 100644
--- a/src/com/android/wallpaper/util/FullScreenAnimation.java
+++ b/src/com/android/wallpaper/util/FullScreenAnimation.java
@@ -128,7 +128,12 @@
         mIsHomeSelected = isHomeSelected;
     }
 
-    private int getStatusBarHeight() {
+    /**
+     * Returns the height of status bar.
+     *
+     * @return height of status bar.
+     */
+    public int getStatusBarHeight() {
         return mStatusBarHeight;
     }
 
diff --git a/src/com/android/wallpaper/util/LaunchSourceUtils.java b/src/com/android/wallpaper/util/LaunchSourceUtils.java
index a4048bd..0298186 100644
--- a/src/com/android/wallpaper/util/LaunchSourceUtils.java
+++ b/src/com/android/wallpaper/util/LaunchSourceUtils.java
@@ -10,4 +10,5 @@
     public static final String LAUNCH_SOURCE_TIPS = "app_launched_tips";
     public static final String LAUNCH_SOURCE_DEEP_LINK = "app_launched_deeplink";
     public static final String LAUNCH_SETTINGS_SEARCH = ":settings:fragment_args_key";
+    public static final String LAUNCH_SOURCE_SETTINGS_HOMEPAGE = "is_from_settings_homepage";
 }
diff --git a/tests/src/com/android/wallpaper/testing/TestInjector.java b/tests/src/com/android/wallpaper/testing/TestInjector.java
index fd9f68a..42cb7f5 100644
--- a/tests/src/com/android/wallpaper/testing/TestInjector.java
+++ b/tests/src/com/android/wallpaper/testing/TestInjector.java
@@ -27,11 +27,11 @@
 import com.android.wallpaper.module.AlarmManagerWrapper;
 import com.android.wallpaper.module.BitmapCropper;
 import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
+import com.android.wallpaper.module.CustomizationSections;
 import com.android.wallpaper.module.DefaultLiveWallpaperInfoFactory;
 import com.android.wallpaper.module.DrawableLayerResolver;
 import com.android.wallpaper.module.ExploreIntentChecker;
 import com.android.wallpaper.module.FormFactorChecker;
-import com.android.wallpaper.module.CustomizationSections;
 import com.android.wallpaper.module.Injector;
 import com.android.wallpaper.module.LiveWallpaperInfoFactory;
 import com.android.wallpaper.module.LoggingOptInStatusProvider;
@@ -44,6 +44,7 @@
 import com.android.wallpaper.module.WallpaperPreferences;
 import com.android.wallpaper.module.WallpaperRefresher;
 import com.android.wallpaper.module.WallpaperRotationRefresher;
+import com.android.wallpaper.module.WallpaperStatusChecker;
 import com.android.wallpaper.monitor.PerformanceMonitor;
 import com.android.wallpaper.network.Requester;
 import com.android.wallpaper.picker.ImagePreviewFragment;
@@ -136,6 +137,11 @@
     }
 
     @Override
+    public WallpaperStatusChecker getWallpaperStatusChecker() {
+        return null;
+    }
+
+    @Override
     public CurrentWallpaperInfoFactory getCurrentWallpaperFactory(Context context) {
         if (mCurrentWallpaperInfoFactory == null) {
             mCurrentWallpaperInfoFactory =