[LivePicker 3/n] Enable LivePreviewFragment

Add support for delete and settings actions and hook up
LivePreviewFragment (disabled for now)

There's still redundancy between ImagePreviewFragment and
LivePreviewFragment, follow up CLs will clean this up.

Bug: 141391722
Change-Id: I14afa659919b8a61959706fa23a049f90dc6536b
diff --git a/res/drawable/ic_delete_24px.xml b/res/drawable/ic_delete_24px.xml
new file mode 100644
index 0000000..bc83f36
--- /dev/null
+++ b/res/drawable/ic_delete_24px.xml
@@ -0,0 +1,30 @@
+<!--
+     Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V6h1V4H15zM17,19H7V6h10V19z"/>
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M9,8h2v9h-2z"/>
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M13,8h2v9h-2z"/>
+</vector>
diff --git a/res/drawable/ic_settings.xml b/res/drawable/ic_settings.xml
new file mode 100644
index 0000000..f24a0a8
--- /dev/null
+++ b/res/drawable/ic_settings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+
+     Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24.0dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
+    android:width="24.0dp" >
+
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z" />
+
+</vector>
\ No newline at end of file
diff --git a/res/menu/preview_menu.xml b/res/menu/preview_menu.xml
index 7c9d610..f83560e 100755
--- a/res/menu/preview_menu.xml
+++ b/res/menu/preview_menu.xml
@@ -20,4 +20,18 @@
           app:actionLayout="@layout/preview_action"
           app:showAsAction="always|withText"
           android:title="@string/preview"/>
+
+    <item
+        android:id="@+id/configure"
+        android:icon="@drawable/ic_settings"
+        app:showAsAction="ifRoom"
+        android:title="@string/configure_wallpaper"
+        android:visible="false"/>
+
+    <item
+        android:id="@+id/delete_wallpaper"
+        android:icon="@drawable/ic_delete_24px"
+        app:showAsAction="ifRoom"
+        android:title="@string/delete_live_wallpaper"
+        android:visible="false"/>
 </menu>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7d2a752..0201f96 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -306,4 +306,13 @@
     <!-- Label for the 'Customize' tab of view pager in wallpaper preview activity.
          [CHAR_LIMIT=25] -->
     <string name="tab_customize">Customize</string>
+
+    <!-- List item for configuring the current wallpaper [CHAR LIMIT=30] -->
+    <string name="configure_wallpaper">Settings…</string>
+
+    <!-- List item for deleting the current wallpaper [CHAR LIMIT=30] -->
+    <string name="delete_live_wallpaper">Delete</string>
+
+    <!-- Confirmation dialog. Shown after user selects to delete one wallpaper. [CHAR LIMIT=NONE] -->
+    <string name="delete_wallpaper_confirmation">Delete this wallpaper from your phone?</string>
 </resources>
diff --git a/src/com/android/wallpaper/model/InlinePreviewIntentFactory.java b/src/com/android/wallpaper/model/InlinePreviewIntentFactory.java
index ce29761..28062d8 100755
--- a/src/com/android/wallpaper/model/InlinePreviewIntentFactory.java
+++ b/src/com/android/wallpaper/model/InlinePreviewIntentFactory.java
@@ -23,6 +23,16 @@
  * wallpaper, if appropriate for that wallpaper.
  */
 public interface InlinePreviewIntentFactory {
+
+    /**
+     * @return whether it's possible to use the internal live picker, or {@code false} to use the
+     * the Framework Activity.
+     */
+    default boolean shouldUseInternalLivePicker(Context context) {
+        return false; // Disable always for now
+        //     ContextCompat.checkSelfPermission(context, BIND_WALLPAPER) == PERMISSION_GRANTED;
+    }
+
     /**
      * Gets an intent to show the preview activity for the given wallpaper.
      *
@@ -30,5 +40,5 @@
      * @param wallpaper
      * @return Intent to show the inline preview activity.
      */
-    public Intent newIntent(Context ctx, WallpaperInfo wallpaper);
+    Intent newIntent(Context ctx, WallpaperInfo wallpaper);
 }
diff --git a/src/com/android/wallpaper/model/LiveWallpaperInfo.java b/src/com/android/wallpaper/model/LiveWallpaperInfo.java
index ad752b7..4337230 100755
--- a/src/com/android/wallpaper/model/LiveWallpaperInfo.java
+++ b/src/com/android/wallpaper/model/LiveWallpaperInfo.java
@@ -245,7 +245,7 @@
         return wallpaperInfos;
     }
 
-    static boolean isSystemApp(ApplicationInfo appInfo) {
+    private static boolean isSystemApp(ApplicationInfo appInfo) {
         return (appInfo.flags & (ApplicationInfo.FLAG_SYSTEM
                 | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
     }
@@ -333,9 +333,14 @@
     @Override
     public void showPreview(Activity srcActivity, InlinePreviewIntentFactory factory,
                             int requestCode) {
-        Intent preview = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
-        preview.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, mInfo.getComponent());
-        ActivityUtils.startActivityForResultSafely(srcActivity, preview, requestCode);
+        //Only use internal live picker if available, otherwise, default to the Framework one
+        if (factory.shouldUseInternalLivePicker(srcActivity)) {
+            srcActivity.startActivityForResult(factory.newIntent(srcActivity, this), requestCode);
+        } else {
+            Intent preview = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
+            preview.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, mInfo.getComponent());
+            ActivityUtils.startActivityForResultSafely(srcActivity, preview, requestCode);
+        }
     }
 
     @Override
diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
index e514075..87e29c5 100755
--- a/src/com/android/wallpaper/picker/ImagePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
@@ -42,7 +42,6 @@
 
 import com.android.wallpaper.R;
 import com.android.wallpaper.asset.Asset;
-import com.android.wallpaper.model.WallpaperInfo;
 import com.android.wallpaper.module.WallpaperPersister.Destination;
 import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback;
 import com.android.wallpaper.util.ScreenSizeCalculator;
@@ -81,22 +80,6 @@
     private ImageView mLowResImageView;
     private View mSpacer;
 
-    /**
-     * Creates and returns new instance of {@link ImagePreviewFragment} with the provided wallpaper
-     * set as an argument.
-     */
-    public static ImagePreviewFragment newInstance(
-            WallpaperInfo wallpaperInfo, @PreviewMode int mode, boolean testingModeEnabled) {
-        Bundle args = new Bundle();
-        args.putParcelable(ARG_WALLPAPER, wallpaperInfo);
-        args.putInt(ARG_PREVIEW_MODE, mode);
-        args.putBoolean(ARG_TESTING_MODE_ENABLED, testingModeEnabled);
-
-        ImagePreviewFragment fragment = new ImagePreviewFragment();
-        fragment.setArguments(args);
-        return fragment;
-    }
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
diff --git a/src/com/android/wallpaper/picker/LivePreviewFragment.java b/src/com/android/wallpaper/picker/LivePreviewFragment.java
index ca199a2..fee60a8 100644
--- a/src/com/android/wallpaper/picker/LivePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/LivePreviewFragment.java
@@ -19,12 +19,16 @@
 
 import android.annotation.SuppressLint;
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.app.WallpaperColors;
+import android.app.WallpaperManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.graphics.Rect;
 import android.net.Uri;
@@ -36,11 +40,15 @@
 import android.service.wallpaper.IWallpaperEngine;
 import android.service.wallpaper.IWallpaperService;
 import android.service.wallpaper.WallpaperService;
+import android.service.wallpaper.WallpaperSettingsActivity;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager.LayoutParams;
@@ -89,6 +97,8 @@
     private WallpaperConnection mWallpaperConnection;
 
     private Intent mWallpaperIntent;
+    private Intent mDeleteIntent;
+    private Intent mSettingsIntent;
 
     private List<Pair<String, View>> mPages;
     private ImageView mLoadingIndicator;
@@ -105,22 +115,6 @@
     private View mLoadingScrim;
     private MaterialProgressDrawable mProgressDrawable;
 
-    /**
-     * Creates and returns new instance of {@link LivePreviewFragment} with the provided wallpaper
-     * set as an argument.
-     */
-    public static LivePreviewFragment newInstance(
-            LiveWallpaperInfo wallpaperInfo, @PreviewMode int mode, boolean testingModeEnabled) {
-        Bundle args = new Bundle();
-        args.putParcelable(ARG_WALLPAPER, wallpaperInfo);
-        args.putInt(ARG_PREVIEW_MODE, mode);
-        args.putBoolean(ARG_TESTING_MODE_ENABLED, testingModeEnabled);
-
-        LivePreviewFragment fragment = new LivePreviewFragment();
-        fragment.setArguments(args);
-        return fragment;
-    }
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -128,6 +122,31 @@
         mWallpaperIntent = new Intent(WallpaperService.SERVICE_INTERFACE)
                 .setClassName(info.getPackageName(), info.getServiceName());
         setUpExploreIntent(null);
+
+        android.app.WallpaperInfo currentWallpaper =
+                WallpaperManager.getInstance(requireContext()).getWallpaperInfo();
+        String deleteAction = getDeleteAction(info.getServiceInfo(),
+                (currentWallpaper == null) ? null : currentWallpaper.getServiceInfo());
+
+        if (!TextUtils.isEmpty(deleteAction)) {
+            mDeleteIntent = new Intent(deleteAction);
+            mDeleteIntent.setPackage(info.getPackageName());
+            mDeleteIntent.putExtra(EXTRA_LIVE_WALLPAPER_INFO, info);
+        }
+
+        String settingsActivity = info.getSettingsActivity();
+        if (settingsActivity != null) {
+            mSettingsIntent = new Intent();
+            mSettingsIntent.setComponent(new ComponentName(info.getPackageName(),
+                    settingsActivity));
+            mSettingsIntent.putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true);
+            PackageManager pm = requireContext().getPackageManager();
+            ActivityInfo activityInfo = mSettingsIntent.resolveActivityInfo(pm, 0);
+            if (activityInfo == null) {
+                Log.i(TAG, "Couldn't find wallpaper settings activity: " + settingsActivity);
+                mSettingsIntent = null;
+            }
+        }
     }
 
     @Override
@@ -306,14 +325,20 @@
             mAttributionTitle.setText(attributions.get(0));
         }
 
-        if (attributions.size() > 1 && attributions.get(1) != null) {
-            mAttributionSubtitle1.setVisibility(View.VISIBLE);
-            mAttributionSubtitle1.setText(attributions.get(1));
-        }
+        if (mWallpaper.getWallpaperComponent().getShowMetadataInPreview()) {
 
-        if (attributions.size() > 2 && attributions.get(2) != null) {
-            mAttributionSubtitle2.setVisibility(View.VISIBLE);
-            mAttributionSubtitle2.setText(attributions.get(2));
+            if (attributions.size() > 1 && attributions.get(1) != null) {
+                mAttributionSubtitle1.setVisibility(View.VISIBLE);
+                mAttributionSubtitle1.setText(attributions.get(1));
+            }
+
+            if (attributions.size() > 2 && attributions.get(2) != null) {
+                mAttributionSubtitle2.setVisibility(View.VISIBLE);
+                mAttributionSubtitle2.setText(attributions.get(2));
+            }
+
+        } else {
+            mExploreIntent = null;
         }
 
         setUpSetWallpaperButton(mSetWallpaperButton);
@@ -438,6 +463,46 @@
         }
     }
 
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        menu.findItem(R.id.configure).setVisible(mSettingsIntent != null);
+        menu.findItem(R.id.delete_wallpaper).setVisible(mDeleteIntent != null);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        int id = item.getItemId();
+        if (id == R.id.configure) {
+            if (getActivity() != null) {
+                startActivity(mSettingsIntent);
+                return true;
+            }
+        } else if (id == R.id.delete_wallpaper) {
+            showDeleteConfirmDialog();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void showDeleteConfirmDialog() {
+        final AlertDialog alertDialog = new AlertDialog.Builder(
+                new ContextThemeWrapper(getContext(), getDeviceDefaultTheme()))
+                .setMessage(R.string.delete_wallpaper_confirmation)
+                .setPositiveButton(R.string.delete_live_wallpaper,
+                        (dialog, which) -> deleteLiveWallpaper())
+                .setNegativeButton(android.R.string.cancel, null /* listener */)
+                .create();
+        alertDialog.show();
+    }
+
+    private void deleteLiveWallpaper() {
+        if (mDeleteIntent != null) {
+            requireContext().startService(mDeleteIntent);
+            finishActivityWithResultOk();
+        }
+    }
+
     private boolean isPackagePreInstalled(ApplicationInfo info) {
         if (info != null && (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
             return true;
diff --git a/src/com/android/wallpaper/picker/PreviewFragment.java b/src/com/android/wallpaper/picker/PreviewFragment.java
index 3715f9f..f1a1625 100755
--- a/src/com/android/wallpaper/picker/PreviewFragment.java
+++ b/src/com/android/wallpaper/picker/PreviewFragment.java
@@ -100,6 +100,26 @@
     public static final String ARG_WALLPAPER = "wallpaper";
     public static final String ARG_PREVIEW_MODE = "preview_mode";
     public static final String ARG_TESTING_MODE_ENABLED = "testing_mode_enabled";
+
+    /**
+     * Creates and returns new instance of {@link ImagePreviewFragment} with the provided wallpaper
+     * set as an argument.
+     */
+    public static PreviewFragment newInstance(
+            WallpaperInfo wallpaperInfo, @PreviewMode int mode, boolean testingModeEnabled) {
+
+        boolean isLive = wallpaperInfo instanceof LiveWallpaperInfo;
+
+        Bundle args = new Bundle();
+        args.putParcelable(ARG_WALLPAPER, wallpaperInfo);
+        args.putInt(ARG_PREVIEW_MODE, mode);
+        args.putBoolean(ARG_TESTING_MODE_ENABLED, testingModeEnabled);
+
+        PreviewFragment fragment = isLive ? new LivePreviewFragment() : new ImagePreviewFragment();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
     private static final String TAG_LOAD_WALLPAPER_ERROR_DIALOG_FRAGMENT =
             "load_wallpaper_error_dialog";
     private static final String TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT =
@@ -354,11 +374,11 @@
         if (context == null) {
             return;
         }
-        ExploreIntentChecker intentChecker =
-                InjectorProvider.getInjector().getExploreIntentChecker(context);
         String actionUrl = mWallpaper.getActionUrl(context);
         if (actionUrl != null && !actionUrl.isEmpty()) {
             Uri exploreUri = Uri.parse(mWallpaper.getActionUrl(context));
+            ExploreIntentChecker intentChecker =
+                    InjectorProvider.getInjector().getExploreIntentChecker(context);
 
             intentChecker.fetchValidActionViewIntent(exploreUri, exploreIntent -> {
                 if (getActivity() == null) {