[LivePicker 4/n] Deduplicate PreviewFragment logic am: dc55b19fd0
Change-Id: I21a433ea3cd1e4d4392ac5197e757371d5ec2f4f
diff --git a/res/layout/preview_page_settings.xml b/res/layout/preview_page_settings.xml
index 72e83a5..4faebb6 100644
--- a/res/layout/preview_page_settings.xml
+++ b/res/layout/preview_page_settings.xml
@@ -37,7 +37,7 @@
<Button
style="@style/ButtonStyle"
- android:id="@+id/preview_attribution_pane_set_wallpaper_button"
+ android:id="@+id/preview_settings_pane_set_wallpaper_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_wallpaper_button_text"/>
diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
index 87e29c5..def680f 100755
--- a/src/com/android/wallpaper/picker/ImagePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
@@ -15,8 +15,6 @@
*/
package com.android.wallpaper.picker;
-import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
@@ -28,14 +26,11 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
-import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Button;
import android.widget.ImageView;
-import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
@@ -46,7 +41,6 @@
import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback;
import com.android.wallpaper.util.ScreenSizeCalculator;
import com.android.wallpaper.util.WallpaperCropUtils;
-import com.android.wallpaper.widget.MaterialProgressDrawable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.MemoryCategory;
@@ -54,8 +48,6 @@
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
-import java.util.List;
-
/**
* Fragment which displays the UI for previewing an individual static wallpaper and its attribution
* information.
@@ -63,22 +55,16 @@
public class ImagePreviewFragment extends PreviewFragment {
private static final float DEFAULT_WALLPAPER_MAX_ZOOM = 8f;
+ private static final int LOADING_TIME_MS = 500;
private SubsamplingScaleImageView mFullResImageView;
private Asset mWallpaperAsset;
- private TextView mAttributionTitle;
- private TextView mAttributionSubtitle1;
- private TextView mAttributionSubtitle2;
- private Button mExploreButton;
- private Button mSetWallpaperButton;
-
private Point mDefaultCropSurfaceSize;
private Point mScreenSize;
private Point mRawWallpaperSize; // Native size of wallpaper image.
- private ImageView mLoadingIndicator;
- private MaterialProgressDrawable mProgressDrawable;
private ImageView mLowResImageView;
- private View mSpacer;
+
+ private InfoPageController mInfoPageController;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -91,30 +77,29 @@
return R.layout.fragment_image_preview;
}
- @Override
+
protected int getBottomSheetResId() {
return R.id.bottom_sheet;
}
@Override
+ protected int getLoadingIndicatorResId() {
+ return R.id.loading_indicator;
+ }
+
+ @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
Activity activity = requireActivity();
- // Set toolbar as the action bar.
mFullResImageView = view.findViewById(R.id.full_res_image);
- mLoadingIndicator = view.findViewById(R.id.loading_indicator);
- mAttributionTitle = view.findViewById(R.id.preview_attribution_pane_title);
- mAttributionSubtitle1 = view.findViewById(R.id.preview_attribution_pane_subtitle1);
- mAttributionSubtitle2 = view.findViewById(R.id.preview_attribution_pane_subtitle2);
- mExploreButton = view.findViewById(R.id.preview_attribution_pane_explore_button);
- mSetWallpaperButton = view.findViewById(R.id.preview_attribution_pane_set_wallpaper_button);
+ mInfoPageController = new InfoPageController(view.findViewById(R.id.page_info),
+ mPreviewMode);
mLowResImageView = view.findViewById(R.id.low_res_image);
- mSpacer = view.findViewById(R.id.spacer);
// Trim some memory from Glide to make room for the full-size image in this fragment.
Glide.get(activity).setMemoryCategory(MemoryCategory.LOW);
@@ -148,8 +133,7 @@
setUpExploreIntent(ImagePreviewFragment.this::initFullResView);
});
- // Configure loading indicator with a MaterialProgressDrawable.
- setUpLoadingIndicator();
+ setUpLoadingIndicator(LOADING_TIME_MS);
return view;
}
@@ -159,32 +143,9 @@
// Nothing needed here.
}
- private void setUpLoadingIndicator() {
- Context context = requireContext();
- mProgressDrawable = new MaterialProgressDrawable(context.getApplicationContext(),
- mLoadingIndicator);
- mProgressDrawable.setAlpha(255);
- mProgressDrawable.setBackgroundColor(getResources().getColor(R.color.material_white_100,
- context.getTheme()));
- mProgressDrawable.setColorSchemeColors(getAttrColor(
- new ContextThemeWrapper(context, getDeviceDefaultTheme()),
- android.R.attr.colorAccent));
- mProgressDrawable.updateSizes(MaterialProgressDrawable.LARGE);
- mLoadingIndicator.setImageDrawable(mProgressDrawable);
-
- // We don't want to show the spinner every time we load an image if it loads quickly;
- // instead, only start showing the spinner if loading the image has taken longer than half
- // of a second.
- mLoadingIndicator.postDelayed(() -> {
- if (mFullResImageView != null && !mFullResImageView.hasImage()
- && !mTestingModeEnabled) {
- mLoadingIndicator.setVisibility(View.VISIBLE);
- mLoadingIndicator.setAlpha(1f);
- if (mProgressDrawable != null) {
- mProgressDrawable.start();
- }
- }
- }, 500);
+ @Override
+ protected boolean isLoaded() {
+ return mFullResImageView != null && mFullResImageView.hasImage();
}
@Override
@@ -214,63 +175,12 @@
@Override
protected void setBottomSheetContentAlpha(float alpha) {
- mExploreButton.setAlpha(alpha);
- mAttributionTitle.setAlpha(alpha);
- mAttributionSubtitle1.setAlpha(alpha);
- mAttributionSubtitle2.setAlpha(alpha);
+ mInfoPageController.setContentAlpha(alpha);
}
- private void populateAttributionPane() {
- final Context context = getContext();
-
- final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet);
-
- List<String> attributions = mWallpaper.getAttributions(context);
- if (attributions.size() > 0 && attributions.get(0) != null) {
- mAttributionTitle.setText(attributions.get(0));
- }
-
- 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));
- }
-
- setUpSetWallpaperButton(mSetWallpaperButton);
-
- setUpExploreButton(mExploreButton);
-
- if (mExploreButton.getVisibility() == View.VISIBLE
- && mSetWallpaperButton.getVisibility() == View.VISIBLE) {
- mSpacer.setVisibility(View.VISIBLE);
- } else {
- mSpacer.setVisibility(View.GONE);
- }
-
- mBottomSheet.setVisibility(View.VISIBLE);
-
- // Initialize the state of the BottomSheet based on the current state because if the initial
- // and current state are the same, the state change listener won't fire and set the correct
- // arrow asset and text alpha.
- if (bottomSheetBehavior.getState() == STATE_EXPANDED) {
- setPreviewChecked(false);
- mAttributionTitle.setAlpha(1f);
- mAttributionSubtitle1.setAlpha(1f);
- mAttributionSubtitle2.setAlpha(1f);
- } else {
- setPreviewChecked(true);
- mAttributionTitle.setAlpha(0f);
- mAttributionSubtitle1.setAlpha(0f);
- mAttributionSubtitle2.setAlpha(0f);
- }
-
- // Let the state change listener take care of animating a state change to the initial state
- // if there's a state change.
- bottomSheetBehavior.setState(mBottomSheetInitialState);
+ @Override
+ protected CharSequence getExploreButtonLabel(Context context) {
+ return context.getString(mWallpaper.getActionLabelRes(context));
}
/**
@@ -320,7 +230,7 @@
}
getActivity().invalidateOptionsMenu();
- populateAttributionPane();
+ populateInfoPage(mInfoPageController);
});
}
diff --git a/src/com/android/wallpaper/picker/LivePreviewFragment.java b/src/com/android/wallpaper/picker/LivePreviewFragment.java
index fee60a8..e6390e6 100644
--- a/src/com/android/wallpaper/picker/LivePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/LivePreviewFragment.java
@@ -15,12 +15,11 @@
*/
package com.android.wallpaper.picker;
-import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED;
-
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.WallpaperColors;
+import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.content.ComponentName;
import android.content.Context;
@@ -53,9 +52,6 @@
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.view.animation.AnimationUtils;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -70,9 +66,7 @@
import com.android.wallpaper.compat.BuildCompat;
import com.android.wallpaper.model.LiveWallpaperInfo;
import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback;
-import com.android.wallpaper.widget.MaterialProgressDrawable;
-import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
@@ -88,45 +82,37 @@
private static final String KEY_ACTION_DELETE_LIVE_WALLPAPER = "action_delete_live_wallpaper";
private static final String EXTRA_LIVE_WALLPAPER_INFO = "android.live_wallpaper.info";
+ private static final int LOADING_TIME_MS = 200;
/**
* Instance of {@link WallpaperConnection} used to bind to the live wallpaper service to show
* it in this preview fragment.
* @see IWallpaperConnection
*/
- private WallpaperConnection mWallpaperConnection;
+ protected WallpaperConnection mWallpaperConnection;
private Intent mWallpaperIntent;
private Intent mDeleteIntent;
private Intent mSettingsIntent;
private List<Pair<String, View>> mPages;
- private ImageView mLoadingIndicator;
- private TextView mAttributionTitle;
- private TextView mAttributionSubtitle1;
- private TextView mAttributionSubtitle2;
- private Button mExploreButton;
- private Button mSetWallpaperButton;
private ViewPager mViewPager;
private TabLayout mTabLayout;
private SliceView mSettingsSliceView;
private LiveData<Slice> mSettingsLiveData;
- private View mSpacer;
private View mLoadingScrim;
- private MaterialProgressDrawable mProgressDrawable;
+ private InfoPageController mInfoPageController;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
android.app.WallpaperInfo info = mWallpaper.getWallpaperComponent();
- mWallpaperIntent = new Intent(WallpaperService.SERVICE_INTERFACE)
- .setClassName(info.getPackageName(), info.getServiceName());
+ mWallpaperIntent = getWallpaperIntent(info);
setUpExploreIntent(null);
android.app.WallpaperInfo currentWallpaper =
WallpaperManager.getInstance(requireContext()).getWallpaperInfo();
- String deleteAction = getDeleteAction(info.getServiceInfo(),
- (currentWallpaper == null) ? null : currentWallpaper.getServiceInfo());
+ String deleteAction = getDeleteAction(info, currentWallpaper);
if (!TextUtils.isEmpty(deleteAction)) {
mDeleteIntent = new Intent(deleteAction);
@@ -134,7 +120,7 @@
mDeleteIntent.putExtra(EXTRA_LIVE_WALLPAPER_INFO, info);
}
- String settingsActivity = info.getSettingsActivity();
+ String settingsActivity = getSettingsActivity(info);
if (settingsActivity != null) {
mSettingsIntent = new Intent();
mSettingsIntent.setComponent(new ComponentName(info.getPackageName(),
@@ -149,6 +135,16 @@
}
}
+ @Nullable
+ protected String getSettingsActivity(WallpaperInfo info) {
+ return info.getSettingsActivity();
+ }
+
+ protected Intent getWallpaperIntent(WallpaperInfo info) {
+ return new Intent(WallpaperService.SERVICE_INTERFACE)
+ .setClassName(info.getPackageName(), info.getServiceName());
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -161,10 +157,10 @@
Activity activity = requireActivity();
mLoadingScrim = view.findViewById(R.id.loading);
- mLoadingIndicator = view.findViewById(R.id.loading_indicator);
- setUpLoadingIndicator();
+ setUpLoadingIndicator(LOADING_TIME_MS);
- mWallpaperConnection = new WallpaperConnection(mWallpaperIntent, activity);
+ mWallpaperConnection = new WallpaperConnection(mWallpaperIntent, activity,
+ getWallpaperConnectionListener());
container.post(() -> {
if (!mWallpaperConnection.connect()) {
mWallpaperConnection = null;
@@ -253,45 +249,18 @@
mViewPager.setCurrentItem(0);
}
- private void setUpLoadingIndicator() {
- Context context = requireContext();
- mProgressDrawable = new MaterialProgressDrawable(context.getApplicationContext(),
- mLoadingIndicator);
- mProgressDrawable.setAlpha(255);
- mProgressDrawable.setBackgroundColor(getResources().getColor(R.color.material_white_100,
- context.getTheme()));
- mProgressDrawable.setColorSchemeColors(getAttrColor(
- new ContextThemeWrapper(context, getDeviceDefaultTheme()),
- android.R.attr.colorAccent));
- mProgressDrawable.updateSizes(MaterialProgressDrawable.LARGE);
- mLoadingIndicator.setImageDrawable(mProgressDrawable);
+ protected WallpaperConnectionListener getWallpaperConnectionListener() {
+ return null;
+ }
- // We don't want to show the spinner every time we load a wallpaper if it loads quickly;
- // instead, only start showing the spinner after 100 ms
- mLoadingIndicator.postDelayed(() -> {
- if ((mWallpaperConnection == null || !mWallpaperConnection.isEngineReady())
- && !mTestingModeEnabled) {
- mLoadingIndicator.setVisibility(View.VISIBLE);
- mLoadingIndicator.setAlpha(1f);
- if (mProgressDrawable != null) {
- mProgressDrawable.start();
- }
- }
- }, 100);
+ @Override
+ protected boolean isLoaded() {
+ return mWallpaperConnection != null && mWallpaperConnection.isEngineReady();
}
private void initInfoPage() {
- View pageInfo = getLayoutInflater().inflate(R.layout.preview_page_info, null /* root */);
-
- mAttributionTitle = pageInfo.findViewById(R.id.preview_attribution_pane_title);
- mAttributionSubtitle1 = pageInfo.findViewById(R.id.preview_attribution_pane_subtitle1);
- mAttributionSubtitle2 = pageInfo.findViewById(R.id.preview_attribution_pane_subtitle2);
- mSpacer = pageInfo.findViewById(R.id.spacer);
-
- mExploreButton = pageInfo.findViewById(R.id.preview_attribution_pane_explore_button);
- mSetWallpaperButton = pageInfo.findViewById(
- R.id.preview_attribution_pane_set_wallpaper_button);
-
+ View pageInfo = InfoPageController.createView(getLayoutInflater());
+ mInfoPageController = new InfoPageController(pageInfo, mPreviewMode);
mPages.add(Pair.create(getString(R.string.tab_info), pageInfo));
}
@@ -312,68 +281,23 @@
mSettingsLiveData = SliceLiveData.fromUri(requireContext() /* context */, uriSettingsSlice);
mSettingsLiveData.observeForever(mSettingsSliceView);
+ pageSettings.findViewById(R.id.preview_settings_pane_set_wallpaper_button)
+ .setOnClickListener(this::onSetWallpaperClicked);
+
mPages.add(Pair.create(getResources().getString(R.string.tab_customize), pageSettings));
}
- private void populateAttributionPane() {
- final Context context = getContext();
-
- final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet);
-
- List<String> attributions = mWallpaper.getAttributions(context);
- if (attributions.size() > 0 && attributions.get(0) != null) {
- mAttributionTitle.setText(attributions.get(0));
+ @Override
+ protected CharSequence getExploreButtonLabel(Context context) {
+ CharSequence exploreLabel = ((LiveWallpaperInfo) mWallpaper).getActionDescription(context);
+ if (TextUtils.isEmpty(exploreLabel)) {
+ exploreLabel = context.getString(mWallpaper.getActionLabelRes(context));
}
-
- if (mWallpaper.getWallpaperComponent().getShowMetadataInPreview()) {
-
- 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);
-
- setUpExploreButton(mExploreButton);
-
- if (mExploreButton.getVisibility() == View.VISIBLE
- && mSetWallpaperButton.getVisibility() == View.VISIBLE) {
- mSpacer.setVisibility(View.VISIBLE);
- } else {
- mSpacer.setVisibility(View.GONE);
- }
-
- mBottomSheet.setVisibility(View.VISIBLE);
-
- // Initialize the state of the BottomSheet based on the current state because if the initial
- // and current state are the same, the state change listener won't fire and set the correct
- // arrow asset and text alpha.
- if (mBottomSheetInitialState == STATE_EXPANDED) {
- setPreviewChecked(false);
- mAttributionTitle.setAlpha(1f);
- mAttributionSubtitle1.setAlpha(1f);
- mAttributionSubtitle2.setAlpha(1f);
- } else {
- setPreviewChecked(true);
- mAttributionTitle.setAlpha(0f);
- mAttributionSubtitle1.setAlpha(0f);
- mAttributionSubtitle2.setAlpha(0f);
- }
-
- bottomSheetBehavior.setState(mBottomSheetInitialState);
+ return exploreLabel;
}
@SuppressLint("NewApi") //Already checking with isAtLeastQ
- private Uri getSettingsSliceUri(android.app.WallpaperInfo info) {
+ protected Uri getSettingsSliceUri(android.app.WallpaperInfo info) {
if (BuildCompat.isAtLeastQ()) {
return info.getSettingsSliceUri();
}
@@ -391,6 +315,11 @@
}
@Override
+ protected int getLoadingIndicatorResId() {
+ return R.id.loading_indicator;
+ }
+
+ @Override
protected void setCurrentWallpaper(int destination) {
mWallpaperSetter.setCurrentWallpaper(getActivity(), mWallpaper, null,
destination, 0, null, new SetWallpaperCallback() {
@@ -408,33 +337,20 @@
@Override
protected void setBottomSheetContentAlpha(float alpha) {
- mExploreButton.setAlpha(alpha);
- mAttributionTitle.setAlpha(alpha);
- mAttributionSubtitle1.setAlpha(alpha);
- mAttributionSubtitle2.setAlpha(alpha);
+ mInfoPageController.setContentAlpha(alpha);
}
- @Override
- protected void setUpExploreButton(Button exploreButton) {
- super.setUpExploreButton(exploreButton);
- if (exploreButton.getVisibility() != View.VISIBLE) {
- return;
- }
- Context context = requireContext();
- CharSequence exploreLabel = ((LiveWallpaperInfo) mWallpaper).getActionDescription(context);
- if (!TextUtils.isEmpty(exploreLabel)) {
- exploreButton.setText(exploreLabel);
- }
- }
@Nullable
- private String getDeleteAction(ServiceInfo serviceInfo,
- @Nullable ServiceInfo currentService) {
+ protected String getDeleteAction(android.app.WallpaperInfo wallpaperInfo,
+ @Nullable android.app.WallpaperInfo currentInfo) {
+ ServiceInfo serviceInfo = wallpaperInfo.getServiceInfo();
if (!isPackagePreInstalled(serviceInfo.applicationInfo)) {
Log.d(TAG, "This wallpaper is not pre-installed: " + serviceInfo.name);
return null;
}
+ ServiceInfo currentService = currentInfo == null ? null : currentInfo.getServiceInfo();
// A currently set Live wallpaper should not be deleted.
if (currentService != null && TextUtils.equals(serviceInfo.name, currentService.name)) {
return null;
@@ -510,10 +426,27 @@
return false;
}
- private class WallpaperConnection extends IWallpaperConnection.Stub
+ /**
+ * Interface to be notified of connect/disconnect events from {@link WallpaperConnection}
+ */
+ public interface WallpaperConnectionListener {
+ /**
+ * Called after the Wallpaper service has been bound.
+ */
+ void onConnected();
+
+ /**
+ * Called after the Wallpaper engine has been terminated and the service has been unbound.
+ */
+ void onDisconnected();
+ }
+
+ protected class WallpaperConnection extends IWallpaperConnection.Stub
implements ServiceConnection {
+
private final Activity mActivity;
private final Intent mIntent;
+ private final WallpaperConnectionListener mListener;
private IWallpaperService mService;
private IWallpaperEngine mEngine;
private boolean mConnected;
@@ -521,20 +454,26 @@
private boolean mIsEngineVisible;
private boolean mEngineReady;
- WallpaperConnection(Intent intent, Activity activity) {
+ WallpaperConnection(Intent intent, Activity activity,
+ @Nullable WallpaperConnectionListener listener) {
mActivity = activity;
mIntent = intent;
+ mListener = listener;
}
public boolean connect() {
synchronized (this) {
- if (!mActivity.bindService(mIntent, this, Context.BIND_AUTO_CREATE)) {
+ if (!mActivity.bindService(mIntent, this,
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT)) {
return false;
}
mConnected = true;
- return true;
}
+ if (mListener != null) {
+ mListener.onConnected();
+ }
+ return true;
}
public void disconnect() {
@@ -556,6 +495,9 @@
}
mService = null;
}
+ if (mListener != null) {
+ mListener.onDisconnected();
+ }
}
public void onServiceConnected(ComponentName name, IBinder service) {
@@ -599,6 +541,10 @@
}
}
+ public IWallpaperEngine getEngine() {
+ return mEngine;
+ }
+
public ParcelFileDescriptor setWallpaper(String name) {
return null;
}
@@ -626,7 +572,7 @@
mProgressDrawable.stop();
}
mLoadingScrim.setVisibility(View.INVISIBLE);
- populateAttributionPane();
+ populateInfoPage(mInfoPageController);
});
});
mEngineReady = true;
diff --git a/src/com/android/wallpaper/picker/PreviewFragment.java b/src/com/android/wallpaper/picker/PreviewFragment.java
index f1a1625..25723c2 100755
--- a/src/com/android/wallpaper/picker/PreviewFragment.java
+++ b/src/com/android/wallpaper/picker/PreviewFragment.java
@@ -21,7 +21,6 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.graphics.PorterDuff.Mode;
@@ -30,15 +29,19 @@
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
+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.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.CallSuper;
@@ -63,6 +66,7 @@
import com.android.wallpaper.module.WallpaperPersister.Destination;
import com.android.wallpaper.module.WallpaperPreferences;
import com.android.wallpaper.module.WallpaperSetter;
+import com.android.wallpaper.widget.MaterialProgressDrawable;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetBehavior.State;
@@ -78,7 +82,8 @@
LoadWallpaperErrorDialogFragment.Listener {
/**
- * User can view wallpaper and attributions in full screen, but "Set wallpaper" button is hidden.
+ * User can view wallpaper and attributions in full screen, but "Set wallpaper" button is
+ * hidden.
*/
static final int MODE_VIEW_ONLY = 0;
@@ -142,6 +147,8 @@
protected WallpaperSetter mWallpaperSetter;
protected UserEventLogger mUserEventLogger;
protected ViewGroup mBottomSheet;
+ protected ImageView mLoadingIndicator;
+ protected MaterialProgressDrawable mProgressDrawable;
protected CheckBox mPreview;
@@ -192,15 +199,12 @@
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
- List<String> attributions = mWallpaper.getAttributions(activity);
+ List<String> attributions = getAttributions(activity);
if (attributions.size() > 0 && attributions.get(0) != null) {
activity.setTitle(attributions.get(0));
}
}
- @LayoutRes
- protected abstract int getLayoutResId();
-
@Override
@CallSuper
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -236,6 +240,8 @@
R.dimen.preview_toolbar_set_wallpaper_button_end_padding),
/* bottom */ 0);
+ mLoadingIndicator = view.findViewById(getLoadingIndicatorResId());
+
mBottomSheet = view.findViewById(getBottomSheetResId());
setUpBottomSheetView(mBottomSheet);
@@ -257,11 +263,58 @@
return view;
}
+ protected void populateInfoPage(InfoPageController infoPage) {
+ Context context = requireContext();
+
+ BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet);
+
+ List<String> attributions = getAttributions(context);
+ boolean showMetadata = shouldShowMetadataInPreview();
+ CharSequence exploreLabel = getExploreButtonLabel(context);
+
+ infoPage.populate(attributions, showMetadata, this::onSetWallpaperClicked,
+ exploreLabel,
+ (showMetadata && mExploreIntent != null) ? this::onExploreClicked : null);
+
+ mBottomSheet.setVisibility(View.VISIBLE);
+
+ // Initialize the state of the BottomSheet based on the current state because if the initial
+ // and current state are the same, the state change listener won't fire and set the correct
+ // arrow asset and text alpha.
+ if (mBottomSheetInitialState == STATE_EXPANDED) {
+ setPreviewChecked(false);
+ infoPage.setContentAlpha(1f);
+ } else {
+ setPreviewChecked(true);
+ infoPage.setContentAlpha(0f);
+ }
+
+ bottomSheetBehavior.setState(mBottomSheetInitialState);
+ }
+
+ protected List<String> getAttributions(Context context) {
+ return mWallpaper.getAttributions(context);
+ }
+
+ protected boolean shouldShowMetadataInPreview() {
+ android.app.WallpaperInfo wallpaperComponent = mWallpaper.getWallpaperComponent();
+ return wallpaperComponent == null || wallpaperComponent.getShowMetadataInPreview();
+ }
+
+ @Nullable
+ protected abstract CharSequence getExploreButtonLabel(Context context);
+
+ @LayoutRes
+ protected abstract int getLayoutResId();
+
protected abstract void setUpBottomSheetView(ViewGroup bottomSheet);
@IdRes
protected abstract int getBottomSheetResId();
+ @IdRes
+ protected abstract int getLoadingIndicatorResId();
+
protected int getDeviceDefaultTheme() {
return android.R.style.Theme_DeviceDefault;
}
@@ -342,33 +395,6 @@
}
}
- protected void setUpSetWallpaperButton(Button setWallpaperButton) {
- if (mPreviewMode == MODE_VIEW_ONLY) {
- setWallpaperButton.setVisibility(View.GONE);
- } else {
- setWallpaperButton.setVisibility(View.VISIBLE);
- setWallpaperButton.setOnClickListener(this::onSetWallpaperClicked);
- }
- }
-
- protected void setUpExploreButton(Button exploreButton) {
- exploreButton.setVisibility(View.GONE);
- if (mExploreIntent == null) {
- return;
- }
- Context context = requireContext();
- exploreButton.setVisibility(View.VISIBLE);
- exploreButton.setText(context.getString(
- mWallpaper.getActionLabelRes(context)));
-
- exploreButton.setOnClickListener(view -> {
- mUserEventLogger.logActionClicked(mWallpaper.getCollectionId(context),
- mWallpaper.getActionLabelRes(context));
-
- startActivity(mExploreIntent);
- });
- }
-
protected void setUpExploreIntent(@Nullable Runnable callback) {
Context context = getContext();
if (context == null) {
@@ -397,6 +423,40 @@
}
}
+ /**
+ * Configure loading indicator with a MaterialProgressDrawable.
+ * We don't want to show the spinner every time we load an image if it loads quickly;
+ * instead, only start showing the spinner if loading the image has taken longer than the
+ * provided delayMs
+ * @param delayMs ms to wait before actually showing the loading indicator
+ */
+ protected void setUpLoadingIndicator(int delayMs) {
+ Context context = requireContext();
+ mProgressDrawable = new MaterialProgressDrawable(context.getApplicationContext(),
+ mLoadingIndicator);
+ mProgressDrawable.setAlpha(255);
+ mProgressDrawable.setBackgroundColor(getResources().getColor(R.color.material_white_100,
+ context.getTheme()));
+ mProgressDrawable.setColorSchemeColors(getAttrColor(
+ new ContextThemeWrapper(context, getDeviceDefaultTheme()),
+ android.R.attr.colorAccent));
+ mProgressDrawable.updateSizes(MaterialProgressDrawable.LARGE);
+ mLoadingIndicator.setImageDrawable(mProgressDrawable);
+
+
+ mLoadingIndicator.postDelayed(() -> {
+ if (!isLoaded() && !mTestingModeEnabled) {
+ mLoadingIndicator.setVisibility(View.VISIBLE);
+ mLoadingIndicator.setAlpha(1f);
+ if (mProgressDrawable != null) {
+ mProgressDrawable.start();
+ }
+ }
+ }, delayMs);
+ }
+
+ protected abstract boolean isLoaded();
+
@Override
public void onSet(int destination) {
setCurrentWallpaper(destination);
@@ -429,11 +489,22 @@
outState.putInt(KEY_BOTTOM_SHEET_STATE, bottomSheetBehavior.getState());
}
- private void onSetWallpaperClicked(View button) {
+ protected void onSetWallpaperClicked(View button) {
mWallpaperSetter.requestDestination(getContext(), getFragmentManager(), this,
mWallpaper instanceof LiveWallpaperInfo);
}
+ private void onExploreClicked(View button) {
+ if (getContext() == null) {
+ return;
+ }
+ Context context = getContext();
+ mUserEventLogger.logActionClicked(mWallpaper.getCollectionId(context),
+ mWallpaper.getActionLabelRes(context));
+
+ startActivity(mExploreIntent);
+ }
+
private void setUpBottomSheetListeners() {
final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet);
@@ -530,14 +601,6 @@
}
}
- @IntDef({
- ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,
- ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,
- ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,
- ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE})
- private @interface ActivityInfoScreenOrientation {
- }
-
/**
* Returns whether layout direction is RTL (or false for LTR). Since native RTL layout support
* was added in API 17, returns false for versions lower than 17.
@@ -546,4 +609,94 @@
return getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL;
}
+
+ protected static class InfoPageController {
+
+ public static View createView(LayoutInflater inflater) {
+ return inflater.inflate(R.layout.preview_page_info, null /* root */);
+ }
+
+ private final int mPreviewMode;
+ private final View mInfoPage;
+ private final TextView mAttributionTitle;
+ private final TextView mAttributionSubtitle1;
+ private final TextView mAttributionSubtitle2;
+ private final Button mExploreButton;
+ private final Button mSetWallpaperButton;
+ private final View mSpacer;
+
+ public InfoPageController(View infoPage, int previewMode) {
+ mInfoPage = infoPage;
+ mPreviewMode = previewMode;
+
+ mAttributionTitle = mInfoPage.findViewById(R.id.preview_attribution_pane_title);
+ mAttributionSubtitle1 = mInfoPage.findViewById(R.id.preview_attribution_pane_subtitle1);
+ mAttributionSubtitle2 = mInfoPage.findViewById(R.id.preview_attribution_pane_subtitle2);
+ mSpacer = mInfoPage.findViewById(R.id.spacer);
+
+ mExploreButton = mInfoPage.findViewById(R.id.preview_attribution_pane_explore_button);
+ mSetWallpaperButton = mInfoPage.findViewById(
+ R.id.preview_attribution_pane_set_wallpaper_button);
+ }
+
+ public void populate(List<String> attributions, boolean showMetadata,
+ OnClickListener setWallpaperOnClickListener,
+ CharSequence exploreButtonLabel,
+ @Nullable OnClickListener exploreOnClickListener) {
+ if (attributions.size() > 0 && attributions.get(0) != null) {
+ mAttributionTitle.setText(attributions.get(0));
+ }
+
+ if (showMetadata) {
+ 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));
+ }
+ }
+ setUpSetWallpaperButton(setWallpaperOnClickListener);
+
+ setUpExploreButton(exploreButtonLabel, exploreOnClickListener);
+
+ if (mExploreButton.getVisibility() == View.VISIBLE
+ && mSetWallpaperButton.getVisibility() == View.VISIBLE) {
+ mSpacer.setVisibility(View.VISIBLE);
+ } else {
+ mSpacer.setVisibility(View.GONE);
+ }
+ }
+
+ public void setContentAlpha(float alpha) {
+ mSetWallpaperButton.setAlpha(alpha);
+ mExploreButton.setAlpha(alpha);
+ mAttributionTitle.setAlpha(alpha);
+ mAttributionSubtitle1.setAlpha(alpha);
+ mAttributionSubtitle2.setAlpha(alpha);
+ }
+
+ private void setUpSetWallpaperButton(OnClickListener setWallpaperOnClickListener) {
+ if (mPreviewMode == MODE_VIEW_ONLY) {
+ mSetWallpaperButton.setVisibility(View.GONE);
+ } else {
+ mSetWallpaperButton.setVisibility(View.VISIBLE);
+ mSetWallpaperButton.setOnClickListener(setWallpaperOnClickListener);
+ }
+ }
+
+ private void setUpExploreButton(CharSequence label,
+ @Nullable OnClickListener exploreOnClickListener) {
+ mExploreButton.setVisibility(View.GONE);
+ if (exploreOnClickListener == null) {
+ return;
+ }
+ mExploreButton.setVisibility(View.VISIBLE);
+ mExploreButton.setText(label);
+
+ mExploreButton.setOnClickListener(exploreOnClickListener);
+ }
+ }
}
\ No newline at end of file