blob: cfb693ef6107e76575abf4206285344fc2d21a21 [file] [log] [blame]
/*
* 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.picker;
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.service.wallpaper.WallpaperService;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceControlViewHost;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.cardview.widget.CardView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.android.wallpaper.R;
import com.android.wallpaper.model.Category;
import com.android.wallpaper.model.LiveWallpaperInfo;
import com.android.wallpaper.model.WallpaperInfo;
import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
import com.android.wallpaper.module.CurrentWallpaperInfoFactory.WallpaperInfoCallback;
import com.android.wallpaper.module.InjectorProvider;
import com.android.wallpaper.module.UserEventLogger;
import com.android.wallpaper.module.WallpaperPersister;
import com.android.wallpaper.module.WallpaperPreferences;
import com.android.wallpaper.module.WallpaperPreferences.PresentationMode;
import com.android.wallpaper.picker.CategorySelectorFragment.CategorySelectorFragmentHost;
import com.android.wallpaper.picker.MyPhotosStarter.MyPhotosStarterProvider;
import com.android.wallpaper.picker.MyPhotosStarter.PermissionChangedListener;
import com.android.wallpaper.picker.individual.IndividualPickerFragment;
import com.android.wallpaper.picker.individual.IndividualPickerFragment.ThumbnailUpdater;
import com.android.wallpaper.picker.individual.IndividualPickerFragment.WallpaperDestinationCallback;
import com.android.wallpaper.util.SizeCalculator;
import com.android.wallpaper.util.WallpaperConnection;
import com.android.wallpaper.widget.LiveTileOverlay;
import com.android.wallpaper.widget.LockScreenOverlayUpdater;
import com.android.wallpaper.widget.PreviewPager;
import com.android.wallpaper.widget.WallpaperColorsLoader;
import com.bumptech.glide.Glide;
import com.bumptech.glide.MemoryCategory;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
* Displays the Main UI for picking a category of wallpapers to choose from.
*/
public class CategoryFragment extends AppbarFragment
implements CategorySelectorFragmentHost, ThumbnailUpdater, WallpaperDestinationCallback {
private final Rect mPreviewLocalRect = new Rect();
private final Rect mPreviewGlobalRect = new Rect();
private final int[] mLivePreviewLocation = new int[2];
/**
* Interface to be implemented by an Activity hosting a {@link CategoryFragment}
*/
public interface CategoryFragmentHost extends MyPhotosStarterProvider {
void requestExternalStoragePermission(PermissionChangedListener listener);
boolean isReadExternalStoragePermissionGranted();
void showViewOnlyPreview(WallpaperInfo wallpaperInfo, boolean isViewAsHome);
}
public static CategoryFragment newInstance(CharSequence title) {
CategoryFragment fragment = new CategoryFragment();
fragment.setArguments(AppbarFragment.createArguments(title));
return fragment;
}
private static final String TAG = "CategoryFragment";
private static final int SETTINGS_APP_INFO_REQUEST_CODE = 1;
private static final String PERMISSION_READ_WALLPAPER_INTERNAL =
"android.permission.READ_WALLPAPER_INTERNAL";
private static final boolean NEW_SCROLL_INTERACTION =
IndividualPickerFragment.NEW_SCROLL_INTERACTION;
private ImageView mHomePreview;
private SurfaceView mWorkspaceSurface;
private WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback;
private SurfaceView mWallpaperSurface;
private ImageView mLockscreenPreview;
private PreviewPager mPreviewPager;
private List<View> mWallPaperPreviews;
private WallpaperConnection mWallpaperConnection;
private CategorySelectorFragment mCategorySelectorFragment;
private IndividualPickerFragment mIndividualPickerFragment;
private boolean mShowSelectedWallpaper;
private BottomSheetBehavior<View> mBottomSheetBehavior;
private int mSelectedPreviewPage;
// The wallpaper information which is currently shown on the home preview.
private WallpaperInfo mHomePreviewWallpaperInfo;
// The wallpaper information which is currently shown on the lock preview.
private WallpaperInfo mLockPreviewWallpaperInfo;
// Home workspace surface is behind the app window, and so must the home image wallpaper like
// the live wallpaper. This view is rendered on mWallpaperSurface for home image wallpaper.
private ImageView mHomeImageWallpaper;
private boolean mIsCollapsingByUserSelecting;
private LockScreenOverlayUpdater mLockScreenOverlayUpdater;
public CategoryFragment() {
mCategorySelectorFragment = new CategorySelectorFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.fragment_category_picker, container, /* attachToRoot= */ false);
mWallPaperPreviews = new ArrayList<>();
CardView homePreviewCard = (CardView) inflater.inflate(
R.layout.wallpaper_preview_card, null);
mHomePreview = homePreviewCard.findViewById(R.id.wallpaper_preview_image);
mWorkspaceSurface = homePreviewCard.findViewById(R.id.workspace_surface);
mWorkspaceSurfaceCallback = new WorkspaceSurfaceHolderCallback(
mWorkspaceSurface, getContext());
mWallpaperSurface = homePreviewCard.findViewById(R.id.wallpaper_surface);
mWallPaperPreviews.add(homePreviewCard);
CardView lockscreenPreviewCard = (CardView) inflater.inflate(
R.layout.wallpaper_preview_card, null);
mLockscreenPreview = lockscreenPreviewCard.findViewById(R.id.wallpaper_preview_image);
lockscreenPreviewCard.findViewById(R.id.workspace_surface).setVisibility(View.GONE);
lockscreenPreviewCard.findViewById(R.id.wallpaper_surface).setVisibility(View.GONE);
View lockOverlay = lockscreenPreviewCard.findViewById(R.id.lock_overlay);
lockOverlay.setVisibility(View.VISIBLE);
mLockScreenOverlayUpdater = new LockScreenOverlayUpdater(
getContext(), lockOverlay, getLifecycle());
mWallPaperPreviews.add(lockscreenPreviewCard);
mPreviewPager = view.findViewById(R.id.wallpaper_preview_pager);
if (mPreviewPager.isRtl()) {
Collections.reverse(mWallPaperPreviews);
}
mPreviewPager.setAdapter(new PreviewPagerAdapter(mWallPaperPreviews));
mPreviewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
// For live wallpaper, show its thumbnail when scrolling.
if (mWallpaperConnection != null && mWallpaperConnection.isEngineReady()
&& mHomePreviewWallpaperInfo instanceof LiveWallpaperInfo) {
if (positionOffset == 0.0f || positionOffset == 1.0f
|| positionOffsetPixels == 0) {
// The page is not moved. Show live wallpaper.
mWallpaperSurface.setZOrderMediaOverlay(false);
} else {
// The page is moving. Show live wallpaper's thumbnail.
mWallpaperSurface.setZOrderMediaOverlay(true);
}
}
if (mWallpaperConnection != null && mWallpaperConnection.isEngineReady()
&& mLockPreviewWallpaperInfo instanceof LiveWallpaperInfo) {
if (positionOffset == 0.0f || positionOffset == 1.0f
|| positionOffsetPixels == 0) {
// The page is not moved. Show live wallpaper.
LiveTileOverlay.INSTANCE.attach(mLockscreenPreview.getOverlay());
} else {
// The page is moving. Show live wallpaper's thumbnail.
LiveTileOverlay.INSTANCE.detach(mLockscreenPreview.getOverlay());
}
} else {
LiveTileOverlay.INSTANCE.detach(mLockscreenPreview.getOverlay());
}
}
@Override
public void onPageSelected(int i) {
mSelectedPreviewPage = i;
if (mIndividualPickerFragment != null && mIndividualPickerFragment.isVisible()) {
mIndividualPickerFragment.highlightAppliedWallpaper(i);
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
setupCurrentWallpaperPreview(view);
ViewGroup fragmentContainer = view.findViewById(R.id.category_fragment_container);
mBottomSheetBehavior = BottomSheetBehavior.from(fragmentContainer);
if (!NEW_SCROLL_INTERACTION) {
fragmentContainer.getLayoutParams().height = MATCH_PARENT;
mBottomSheetBehavior.setBottomSheetCallback(
new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (mIsCollapsingByUserSelecting) {
mIsCollapsingByUserSelecting = newState != STATE_COLLAPSED;
return;
}
if (mIndividualPickerFragment != null
&& mIndividualPickerFragment.isVisible()) {
mIndividualPickerFragment.resizeLayout(newState == STATE_COLLAPSED
? mBottomSheetBehavior.getPeekHeight() : MATCH_PARENT);
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
View rootContainer = view.findViewById(R.id.root_container);
fragmentContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View containerView, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
int minimumHeight = rootContainer.getHeight() - mPreviewPager.getMeasuredHeight();
mBottomSheetBehavior.setPeekHeight(minimumHeight);
containerView.setMinimumHeight(minimumHeight);
((CardView) mHomePreview.getParent())
.setRadius(SizeCalculator.getPreviewCornerRadius(
getActivity(), homePreviewCard.getMeasuredWidth()));
if (mLockscreenPreview != null) {
((CardView) mLockscreenPreview.getParent())
.setRadius(SizeCalculator.getPreviewCornerRadius(
getActivity(), mLockscreenPreview.getMeasuredWidth()));
}
}});
fragmentContainer.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
@Override
public void onChildViewAdded(View parent, View child) {
child.requestApplyInsets();
}
@Override
public void onChildViewRemoved(View parent, View child) {
}
});
setUpToolbar(view);
getChildFragmentManager()
.beginTransaction()
.replace(R.id.category_fragment_container, mCategorySelectorFragment)
.commitNow();
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
updateWallpaperSurface();
updateWorkspaceSurface();
}
@Override
public CharSequence getDefaultTitle() {
return getContext().getString(R.string.app_name);
}
@Override
public void onResume() {
super.onResume();
WallpaperPreferences preferences = InjectorProvider.getInjector().getPreferences(getActivity());
preferences.setLastAppActiveTimestamp(new Date().getTime());
// Reset Glide memory settings to a "normal" level of usage since it may have been lowered in
// PreviewFragment.
Glide.get(getActivity()).setMemoryCategory(MemoryCategory.NORMAL);
// The wallpaper may have been set while this fragment was paused, so force refresh the current
// wallpapers and presentation mode.
if (!mShowSelectedWallpaper) {
refreshCurrentWallpapers(/* forceRefresh= */ true);
}
if (mWallpaperConnection != null) {
mWallpaperConnection.setVisibility(true);
}
}
@Override
public void onPause() {
super.onPause();
if (mWallpaperConnection != null) {
mWallpaperConnection.setVisibility(false);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
LiveTileOverlay.INSTANCE.detach(mHomePreview.getOverlay());
LiveTileOverlay.INSTANCE.detach(mLockscreenPreview.getOverlay());
if (mWallpaperConnection != null) {
mWallpaperConnection.disconnect();
mWallpaperConnection = null;
}
mPreviewPager.setAdapter(null);
mWallPaperPreviews.forEach(view -> ((ViewGroup) view).removeAllViews());
mWallPaperPreviews.clear();
}
@Override
public void onDestroy() {
super.onDestroy();
if (mWallpaperConnection != null) {
mWallpaperConnection.disconnect();
mWallpaperConnection = null;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SETTINGS_APP_INFO_REQUEST_CODE) {
mCategorySelectorFragment.notifyDataSetChanged();
}
}
@Override
public void requestCustomPhotoPicker(PermissionChangedListener listener) {
getFragmentHost().getMyPhotosStarter().requestCustomPhotoPicker(listener);
}
@Override
public void show(String collectionId) {
mIndividualPickerFragment =
InjectorProvider.getInjector().getIndividualPickerFragment(collectionId);
mIndividualPickerFragment.highlightAppliedWallpaper(mSelectedPreviewPage);
mIndividualPickerFragment.setOnWallpaperSelectedListener(position -> {
// Scroll to the selected wallpaper and collapse the sheet if needed.
// Resize and scroll here because we want to let the RecyclerView's scrolling and
// BottomSheet's collapsing can be executed together instead of scrolling
// the RecyclerView after the BottomSheet is collapsed.
mIndividualPickerFragment.resizeLayout(mBottomSheetBehavior.getPeekHeight());
mIndividualPickerFragment.scrollToPosition(position);
if (mBottomSheetBehavior.getState() != STATE_COLLAPSED) {
mIsCollapsingByUserSelecting = true;
mBottomSheetBehavior.setState(STATE_COLLAPSED);
}
});
getChildFragmentManager()
.beginTransaction()
.replace(R.id.category_fragment_container, mIndividualPickerFragment)
.addToBackStack(null)
.commit();
getChildFragmentManager().executePendingTransactions();
}
@Override
public void setToolbarTitle(CharSequence title) {
setTitle(title);
}
@Override
public void updateThumbnail(WallpaperInfo wallpaperInfo) {
new android.os.Handler().post(() -> {
// A config change may have destroyed the activity since the refresh started, so check
// for that.
if (getActivity() == null) {
return;
}
mHomePreviewWallpaperInfo = wallpaperInfo;
mLockPreviewWallpaperInfo = wallpaperInfo;
updateThumbnail(mHomePreviewWallpaperInfo, mHomePreview, true);
updateThumbnail(mLockPreviewWallpaperInfo, mLockscreenPreview, false);
mShowSelectedWallpaper = true;
});
}
@Override
public void restoreThumbnails() {
refreshCurrentWallpapers(/* forceRefresh= */ true);
mShowSelectedWallpaper = false;
}
@Override
public void onDestinationSet(@WallpaperPersister.Destination int destination) {
if (destination == WallpaperPersister.DEST_BOTH) {
return;
}
mPreviewPager.switchPreviewPage(destination);
}
@Override
public boolean onBackPressed() {
Fragment childFragment = getChildFragmentManager().findFragmentById(
R.id.category_fragment_container);
return childFragment instanceof BottomActionBarFragment
&& ((BottomActionBarFragment) childFragment).onBackPressed();
}
/**
* Pops the child fragment from the stack if {@link CategoryFragment} is visible to the users.
*
* @return {@code true} if the child fragment is popped, {@code false} otherwise.
*/
public boolean popChildFragment() {
return isVisible() && getChildFragmentManager().popBackStackImmediate();
}
/**
* Inserts the given category into the categories list in priority order.
*/
void addCategory(Category category, boolean loading) {
mCategorySelectorFragment.addCategory(category, loading);
}
void removeCategory(Category category) {
mCategorySelectorFragment.removeCategory(category);
}
void updateCategory(Category category) {
mCategorySelectorFragment.updateCategory(category);
}
void clearCategories() {
mCategorySelectorFragment.clearCategories();
}
/**
* Notifies the CategoryFragment that no further categories are expected so it may hide
* the loading indicator.
*/
void doneFetchingCategories() {
mCategorySelectorFragment.doneFetchingCategories();
}
private boolean canShowCurrentWallpaper() {
Activity activity = getActivity();
CategoryFragmentHost host = getFragmentHost();
PackageManager packageManager = activity.getPackageManager();
String packageName = activity.getPackageName();
boolean hasReadWallpaperInternal = packageManager.checkPermission(
PERMISSION_READ_WALLPAPER_INTERNAL, packageName) == PackageManager.PERMISSION_GRANTED;
return hasReadWallpaperInternal || host.isReadExternalStoragePermissionGranted();
}
private void showCurrentWallpaper(View rootView, boolean show) {
rootView.findViewById(R.id.wallpaper_preview_pager)
.setVisibility(show ? View.VISIBLE : View.GONE);
rootView.findViewById(R.id.permission_needed)
.setVisibility(show ? View.GONE : View.VISIBLE);
}
private void setupCurrentWallpaperPreview(View rootView) {
if (canShowCurrentWallpaper()) {
showCurrentWallpaper(rootView, true);
} else {
showCurrentWallpaper(rootView, false);
Button mAllowAccessButton = rootView
.findViewById(R.id.permission_needed_allow_access_button);
mAllowAccessButton.setOnClickListener(view ->
getFragmentHost().requestExternalStoragePermission(
new PermissionChangedListener() {
@Override
public void onPermissionsGranted() {
showCurrentWallpaper(rootView, true);
mCategorySelectorFragment.notifyDataSetChanged();
}
@Override
public void onPermissionsDenied(boolean dontAskAgain) {
if (!dontAskAgain) {
return;
}
showPermissionNeededDialog();
}
})
);
// Replace explanation text with text containing the Wallpapers app name which replaces
// the placeholder.
String appName = getString(R.string.app_name);
String explanation = getString(R.string.permission_needed_explanation, appName);
TextView explanationView = rootView.findViewById(R.id.permission_needed_explanation);
explanationView.setText(explanation);
}
}
private void showPermissionNeededDialog() {
String permissionNeededMessage = getString(
R.string.permission_needed_explanation_go_to_settings);
AlertDialog dialog = new AlertDialog.Builder(getActivity(), R.style.LightDialogTheme)
.setMessage(permissionNeededMessage)
.setPositiveButton(android.R.string.ok, /* onClickListener= */ null)
.setNegativeButton(
R.string.settings_button_label,
(dialogInterface, i) -> {
Intent appInfoIntent = new Intent();
appInfoIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
getActivity().getPackageName(), /* fragment= */ null);
appInfoIntent.setData(uri);
startActivityForResult(appInfoIntent, SETTINGS_APP_INFO_REQUEST_CODE);
})
.create();
dialog.show();
}
private CategoryFragmentHost getFragmentHost() {
return (CategoryFragmentHost) getActivity();
}
private Intent getWallpaperIntent(android.app.WallpaperInfo info) {
return new Intent(WallpaperService.SERVICE_INTERFACE)
.setClassName(info.getPackageName(), info.getServiceName());
}
/**
* Obtains the {@link WallpaperInfo} object(s) representing the wallpaper(s) currently set to
* the device from the {@link CurrentWallpaperInfoFactory}.
*/
private void refreshCurrentWallpapers(boolean forceRefresh) {
CurrentWallpaperInfoFactory factory = InjectorProvider.getInjector()
.getCurrentWallpaperFactory(getActivity().getApplicationContext());
factory.createCurrentWallpaperInfos(new WallpaperInfoCallback() {
@Override
public void onWallpaperInfoCreated(
final WallpaperInfo homeWallpaper,
@Nullable final WallpaperInfo lockWallpaper,
@PresentationMode final int presentationMode) {
// Update the metadata displayed on screen. Do this in a Handler so it is scheduled at the
// end of the message queue. This is necessary to ensure we do not remove or add data from
// the adapter while the layout is being computed. RecyclerView documentation therefore
// recommends performing such changes in a Handler.
new android.os.Handler().post(new Runnable() {
@Override
public void run() {
final Activity activity = getActivity();
// A config change may have destroyed the activity since the refresh
// started, so check for that.
if (activity == null) {
return;
}
mHomePreviewWallpaperInfo = homeWallpaper;
mLockPreviewWallpaperInfo =
lockWallpaper == null ? homeWallpaper : lockWallpaper;
updateThumbnail(mHomePreviewWallpaperInfo, mHomePreview, true);
updateThumbnail(mLockPreviewWallpaperInfo, mLockscreenPreview, false);
}
});
}
}, forceRefresh);
}
private void setUpLiveWallpaperPreview(WallpaperInfo homeWallpaper) {
Activity activity = getActivity();
if (activity == null) {
return;
}
if (mWallpaperConnection != null) {
mWallpaperConnection.disconnect();
}
ImageView previewView = mSelectedPreviewPage == 0 ? mHomePreview : mLockscreenPreview;
previewView.getLocationOnScreen(mLivePreviewLocation);
mPreviewGlobalRect.set(0, 0, previewView.getMeasuredWidth(),
previewView.getMeasuredHeight());
mPreviewLocalRect.set(mPreviewGlobalRect);
mPreviewGlobalRect.offset(mLivePreviewLocation[0], mLivePreviewLocation[1]);
mWallpaperConnection = new WallpaperConnection(
getWallpaperIntent(homeWallpaper.getWallpaperComponent()), activity,
/* listener= */ null, mPreviewGlobalRect);
LiveTileOverlay.INSTANCE.update(new RectF(mPreviewLocalRect),
((CardView) previewView.getParent()).getRadius());
mWallpaperConnection.setVisibility(true);
previewView.post(() -> {
if (mWallpaperConnection != null && !mWallpaperConnection.connect()) {
mWallpaperConnection = null;
LiveTileOverlay.INSTANCE.detach(previewView.getOverlay());
}
});
}
private void updateThumbnail(WallpaperInfo wallpaperInfo, ImageView thumbnailView,
boolean isHomeWallpaper) {
if (wallpaperInfo == null) {
return;
}
if (thumbnailView == null) {
return;
}
Activity activity = getActivity();
if (activity == null) {
return;
}
UserEventLogger eventLogger = InjectorProvider.getInjector().getUserEventLogger(activity);
boolean renderInImageWallpaperSurface =
!(wallpaperInfo instanceof LiveWallpaperInfo) && isHomeWallpaper;
wallpaperInfo.getThumbAsset(activity.getApplicationContext())
.loadPreviewImage(activity,
renderInImageWallpaperSurface ? mHomeImageWallpaper : thumbnailView,
getResources().getColor(R.color.secondary_color));
if (isHomeWallpaper) {
LiveTileOverlay.INSTANCE.detach(thumbnailView.getOverlay());
if (wallpaperInfo instanceof LiveWallpaperInfo) {
wallpaperInfo.getThumbAsset(activity.getApplicationContext()).loadPreviewImage(
activity, mHomeImageWallpaper,
getResources().getColor(R.color.secondary_color));
setUpLiveWallpaperPreview(wallpaperInfo);
} else {
if (mWallpaperConnection != null) {
mWallpaperConnection.disconnect();
mWallpaperConnection = null;
}
}
} else {
// lock screen wallpaper
if (wallpaperInfo instanceof LiveWallpaperInfo) {
LiveTileOverlay.INSTANCE.attach(thumbnailView.getOverlay());
} else {
LiveTileOverlay.INSTANCE.detach(thumbnailView.getOverlay());
}
WallpaperColorsLoader.getWallpaperColors(
activity,
wallpaperInfo.getThumbAsset(activity),
mLockScreenOverlayUpdater::setColor);
}
((View) thumbnailView.getParent()).setOnClickListener(view -> {
getFragmentHost().showViewOnlyPreview(wallpaperInfo, isHomeWallpaper);
eventLogger.logCurrentWallpaperPreviewed();
});
}
private void updateWallpaperSurface() {
mWallpaperSurface.getHolder().addCallback(mWallpaperSurfaceCallback);
}
private void updateWorkspaceSurface() {
mWorkspaceSurface.setZOrderMediaOverlay(true);
mWorkspaceSurface.getHolder().addCallback(mWorkspaceSurfaceCallback);
}
private final SurfaceHolder.Callback mWallpaperSurfaceCallback = new SurfaceHolder.Callback() {
private Surface mLastSurface;
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mLastSurface != holder.getSurface()) {
mLastSurface = holder.getSurface();
mHomeImageWallpaper = new ImageView(getContext());
mHomeImageWallpaper.setBackgroundColor(
ContextCompat.getColor(getContext(), R.color.primary_color));
mHomeImageWallpaper.measure(makeMeasureSpec(mHomePreview.getWidth(), EXACTLY),
makeMeasureSpec(mHomePreview.getHeight(), EXACTLY));
mHomeImageWallpaper.layout(0, 0, mHomePreview.getWidth(), mHomePreview.getHeight());
SurfaceControlViewHost host = new SurfaceControlViewHost(getContext(),
getContext().getDisplay(), mWallpaperSurface.getHostToken());
host.setView(mHomeImageWallpaper, mHomeImageWallpaper.getWidth(),
mHomeImageWallpaper.getHeight());
mWallpaperSurface.setChildSurfacePackage(host.getSurfacePackage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }
@Override
public void surfaceDestroyed(SurfaceHolder holder) { }
};
private static class PreviewPagerAdapter extends PagerAdapter {
private List<View> mPages;
PreviewPagerAdapter(List<View> pages) {
mPages = pages;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position,
@NonNull Object object) {
container.removeView((View) object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View view = mPages.get(position);
container.addView(view);
return view;
}
@Override
public int getCount() {
return mPages.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return view == o;
}
}
}