1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.wallpaper.model;
17 
18 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
19 
20 import android.animation.Animator;
21 import android.app.Activity;
22 import android.app.AlertDialog;
23 import android.app.WallpaperColors;
24 import android.app.WallpaperManager;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.pm.PackageManager;
28 import android.content.res.Resources;
29 import android.net.Uri;
30 import android.os.Bundle;
31 import android.provider.Settings;
32 import android.service.wallpaper.WallpaperService;
33 import android.view.LayoutInflater;
34 import android.view.SurfaceView;
35 import android.view.View;
36 import android.view.ViewGroup;
37 import android.widget.Button;
38 import android.widget.ImageView;
39 import android.widget.TextView;
40 
41 import androidx.annotation.MainThread;
42 import androidx.annotation.NonNull;
43 import androidx.annotation.Nullable;
44 import androidx.cardview.widget.CardView;
45 import androidx.core.widget.ContentLoadingProgressBar;
46 import androidx.lifecycle.Lifecycle;
47 import androidx.lifecycle.LifecycleObserver;
48 import androidx.lifecycle.LifecycleOwner;
49 import androidx.lifecycle.OnLifecycleEvent;
50 
51 import com.android.wallpaper.R;
52 import com.android.wallpaper.asset.Asset;
53 import com.android.wallpaper.asset.BitmapCachingAsset;
54 import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
55 import com.android.wallpaper.module.InjectorProvider;
56 import com.android.wallpaper.module.UserEventLogger;
57 import com.android.wallpaper.picker.CategorySelectorFragment;
58 import com.android.wallpaper.picker.MyPhotosStarter;
59 import com.android.wallpaper.picker.WallpaperSectionView;
60 import com.android.wallpaper.picker.WorkspaceSurfaceHolderCallback;
61 import com.android.wallpaper.util.ResourceUtils;
62 import com.android.wallpaper.util.WallpaperConnection;
63 import com.android.wallpaper.util.WallpaperSurfaceCallback;
64 import com.android.wallpaper.widget.LockScreenPreviewer;
65 
66 import java.util.concurrent.CompletableFuture;
67 import java.util.concurrent.Future;
68 
69 /** The class to control the wallpaper section view. */
70 public class WallpaperSectionController implements
71         CustomizationSectionController<WallpaperSectionView>,
72         LifecycleObserver {
73 
74     private static final String PERMISSION_READ_WALLPAPER_INTERNAL =
75             "android.permission.READ_WALLPAPER_INTERNAL";
76     private static final int SETTINGS_APP_INFO_REQUEST_CODE = 1;
77 
78     private CardView mHomePreviewCard;
79     private ContentLoadingProgressBar mHomePreviewProgress;
80     private SurfaceView mWorkspaceSurface;
81     private WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback;
82     private SurfaceView mHomeWallpaperSurface;
83     private WallpaperSurfaceCallback mHomeWallpaperSurfaceCallback;
84     private SurfaceView mLockWallpaperSurface;
85     private WallpaperSurfaceCallback mLockWallpaperSurfaceCallback;
86     private CardView mLockscreenPreviewCard;
87     private ViewGroup mLockPreviewContainer;
88     private ContentLoadingProgressBar mLockscreenPreviewProgress;
89     private WallpaperConnection mWallpaperConnection;
90 
91     // The wallpaper information which is currently shown on the home preview.
92     private WallpaperInfo mHomePreviewWallpaperInfo;
93     // The wallpaper information which is currently shown on the lock preview.
94     private WallpaperInfo mLockPreviewWallpaperInfo;
95 
96     private LockScreenPreviewer mLockScreenPreviewer;
97 
98     private final Activity mActivity;
99     private final Context mAppContext;
100     private final LifecycleOwner mLifecycleOwner;
101     private final PermissionRequester mPermissionRequester;
102     private final WallpaperColorsViewModel mWallpaperColorsViewModel;
103     private final WorkspaceViewModel mWorkspaceViewModel;
104     private final CustomizationSectionNavigationController mSectionNavigationController;
105     private final WallpaperPreviewNavigator mWallpaperPreviewNavigator;
106     private final Bundle mSavedInstanceState;
107 
WallpaperSectionController(Activity activity, LifecycleOwner lifecycleOwner, PermissionRequester permissionRequester, WallpaperColorsViewModel colorsViewModel, WorkspaceViewModel workspaceViewModel, CustomizationSectionNavigationController sectionNavigationController, WallpaperPreviewNavigator wallpaperPreviewNavigator, Bundle savedInstanceState)108     public WallpaperSectionController(Activity activity, LifecycleOwner lifecycleOwner,
109             PermissionRequester permissionRequester, WallpaperColorsViewModel colorsViewModel,
110             WorkspaceViewModel workspaceViewModel,
111             CustomizationSectionNavigationController sectionNavigationController,
112             WallpaperPreviewNavigator wallpaperPreviewNavigator,
113             Bundle savedInstanceState) {
114         mActivity = activity;
115         mLifecycleOwner = lifecycleOwner;
116         mPermissionRequester = permissionRequester;
117         mAppContext = mActivity.getApplicationContext();
118         mWallpaperColorsViewModel = colorsViewModel;
119         mWorkspaceViewModel = workspaceViewModel;
120         mSectionNavigationController = sectionNavigationController;
121         mWallpaperPreviewNavigator = wallpaperPreviewNavigator;
122         mSavedInstanceState = savedInstanceState;
123     }
124 
125     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
126     @MainThread
onResume()127     public void onResume() {
128         refreshCurrentWallpapers(/* forceRefresh= */ mSavedInstanceState == null);
129         if (mWallpaperConnection != null) {
130             mWallpaperConnection.setVisibility(true);
131         }
132     }
133 
134     @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
135     @MainThread
onPause()136     public void onPause() {
137         if (mWallpaperConnection != null) {
138             mWallpaperConnection.setVisibility(false);
139         }
140     }
141 
142     @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
143     @MainThread
onStop()144     public void onStop() {
145         if (mWallpaperConnection != null) {
146             mWallpaperConnection.disconnect();
147             mWallpaperConnection = null;
148         }
149     }
150 
151     @Override
isAvailable(Context context)152     public boolean isAvailable(Context context) {
153         return true;
154     }
155 
156     @Override
createView(Context context)157     public WallpaperSectionView createView(Context context) {
158         WallpaperSectionView wallpaperSectionView = (WallpaperSectionView) LayoutInflater.from(
159                 context).inflate(R.layout.wallpaper_section_view, /* root= */ null);
160         mHomePreviewCard = wallpaperSectionView.findViewById(R.id.home_preview);
161         mHomePreviewCard.setContentDescription(mAppContext.getString(
162                 R.string.wallpaper_preview_card_content_description));
163         mWorkspaceSurface = mHomePreviewCard.findViewById(R.id.workspace_surface);
164         mHomePreviewProgress = mHomePreviewCard.findViewById(R.id.wallpaper_preview_spinner);
165         mWorkspaceSurfaceCallback = new WorkspaceSurfaceHolderCallback(
166                 mWorkspaceSurface, mAppContext);
167         mHomeWallpaperSurface = mHomePreviewCard.findViewById(R.id.wallpaper_surface);
168 
169         Future<Integer> placeholderColor = CompletableFuture.completedFuture(
170                 ResourceUtils.getColorAttr(mActivity, android.R.attr.colorSecondary));
171 
172         mHomeWallpaperSurfaceCallback = new WallpaperSurfaceCallback(mActivity, mHomePreviewCard,
173                 mHomeWallpaperSurface, placeholderColor, () -> {
174             if (mHomePreviewWallpaperInfo != null) {
175                 maybeLoadThumbnail(mHomePreviewWallpaperInfo, mHomeWallpaperSurfaceCallback);
176             }
177         });
178 
179         mLockscreenPreviewCard = wallpaperSectionView.findViewById(R.id.lock_preview);
180         mLockscreenPreviewCard.setContentDescription(mAppContext.getString(
181                 R.string.lockscreen_wallpaper_preview_card_content_description));
182         mLockscreenPreviewProgress = mLockscreenPreviewCard.findViewById(
183                 R.id.wallpaper_preview_spinner);
184         mLockscreenPreviewCard.findViewById(R.id.workspace_surface).setVisibility(View.GONE);
185         mLockWallpaperSurface = mLockscreenPreviewCard.findViewById(R.id.wallpaper_surface);
186         mLockWallpaperSurfaceCallback = new WallpaperSurfaceCallback(mActivity,
187                 mLockscreenPreviewCard, mLockWallpaperSurface, placeholderColor, () -> {
188             if (mLockPreviewWallpaperInfo != null) {
189                 maybeLoadThumbnail(mLockPreviewWallpaperInfo, mLockWallpaperSurfaceCallback);
190             }
191         });
192         mLockPreviewContainer = mLockscreenPreviewCard.findViewById(
193                 R.id.lock_screen_preview_container);
194         mLockPreviewContainer.setVisibility(View.INVISIBLE);
195         mLockScreenPreviewer = new LockScreenPreviewer(mLifecycleOwner.getLifecycle(), context,
196                 mLockPreviewContainer);
197 
198         setupCurrentWallpaperPreview(wallpaperSectionView);
199         final int shortDuration = mAppContext.getResources().getInteger(
200                 android.R.integer.config_shortAnimTime);
201         fadeWallpaperPreview(true, shortDuration);
202         mLifecycleOwner.getLifecycle().addObserver(this);
203         updateWallpaperSurface();
204         updateWorkspaceSurface();
205 
206         wallpaperSectionView.findViewById(R.id.wallpaper_picker_entry).setOnClickListener(
207                 v -> mSectionNavigationController.navigateTo(new CategorySelectorFragment()));
208 
209         mWorkspaceViewModel.getUpdateWorkspace().observe(mLifecycleOwner, update ->
210                 updateWorkspacePreview(mWorkspaceSurface, mWorkspaceSurfaceCallback,
211                         mWallpaperColorsViewModel.getHomeWallpaperColors().getValue())
212         );
213 
214         return wallpaperSectionView;
215     }
216 
updateWorkspacePreview(SurfaceView workspaceSurface, WorkspaceSurfaceHolderCallback callback, @Nullable WallpaperColors colors)217     private void updateWorkspacePreview(SurfaceView workspaceSurface,
218             WorkspaceSurfaceHolderCallback callback, @Nullable WallpaperColors colors) {
219         // Reattach SurfaceView to trigger #surfaceCreated to update preview for different option.
220         ViewGroup parent = (ViewGroup) workspaceSurface.getParent();
221         int viewIndex = parent.indexOfChild(workspaceSurface);
222         parent.removeView(workspaceSurface);
223         if (callback != null) {
224             callback.resetLastSurface();
225             callback.setWallpaperColors(colors);
226         }
227         parent.addView(workspaceSurface, viewIndex);
228     }
229 
230     @Override
release()231     public void release() {
232         if (mLockScreenPreviewer != null) {
233             mLockScreenPreviewer.release();
234             mLockScreenPreviewer = null;
235         }
236         if (mHomeWallpaperSurfaceCallback != null) {
237             mHomeWallpaperSurfaceCallback.cleanUp();
238         }
239         if (mLockWallpaperSurfaceCallback != null) {
240             mLockWallpaperSurfaceCallback.cleanUp();
241         }
242         if (mWorkspaceSurfaceCallback != null) {
243             mWorkspaceSurfaceCallback.cleanUp();
244         }
245         mLifecycleOwner.getLifecycle().removeObserver(this);
246     }
247 
setupCurrentWallpaperPreview(View rootView)248     private void setupCurrentWallpaperPreview(View rootView) {
249         if (canShowCurrentWallpaper()) {
250             showCurrentWallpaper(rootView, true);
251         } else {
252             showCurrentWallpaper(rootView, false);
253 
254             Button mAllowAccessButton = rootView
255                     .findViewById(R.id.permission_needed_allow_access_button);
256             mAllowAccessButton.setOnClickListener(view ->
257                     mPermissionRequester.requestExternalStoragePermission(
258                             new MyPhotosStarter.PermissionChangedListener() {
259 
260                                 @Override
261                                 public void onPermissionsGranted() {
262                                     showCurrentWallpaper(rootView, true);
263                                 }
264 
265                                 @Override
266                                 public void onPermissionsDenied(boolean dontAskAgain) {
267                                     if (!dontAskAgain) {
268                                         return;
269                                     }
270                                     showPermissionNeededDialog();
271                                 }
272                             })
273             );
274 
275             // Replace explanation text with text containing the Wallpapers app name which replaces
276             // the placeholder.
277             Resources resources = mAppContext.getResources();
278             String appName = resources.getString(R.string.app_name);
279             String explanation = resources.getString(R.string.permission_needed_explanation,
280                     appName);
281             TextView explanationView = rootView.findViewById(R.id.permission_needed_explanation);
282             explanationView.setText(explanation);
283         }
284     }
285 
canShowCurrentWallpaper()286     private boolean canShowCurrentWallpaper() {
287         return isPermissionGranted(mAppContext, PERMISSION_READ_WALLPAPER_INTERNAL)
288                 || isPermissionGranted(mAppContext, READ_EXTERNAL_STORAGE);
289     }
290 
isPermissionGranted(Context context, String permission)291     private boolean isPermissionGranted(Context context, String permission) {
292         return context.getPackageManager().checkPermission(permission,
293                 context.getPackageName()) == PackageManager.PERMISSION_GRANTED;
294     }
295 
showCurrentWallpaper(View rootView, boolean show)296     private void showCurrentWallpaper(View rootView, boolean show) {
297         rootView.findViewById(R.id.home_preview)
298                 .setVisibility(show ? View.VISIBLE : View.GONE);
299         rootView.findViewById(R.id.lock_preview)
300                 .setVisibility(show ? View.VISIBLE : View.GONE);
301         rootView.findViewById(R.id.permission_needed)
302                 .setVisibility(show ? View.GONE : View.VISIBLE);
303     }
304 
showPermissionNeededDialog()305     private void showPermissionNeededDialog() {
306         String permissionNeededMessage = mAppContext.getResources().getString(
307                 R.string.permission_needed_explanation_go_to_settings);
308         AlertDialog dialog = new AlertDialog.Builder(mAppContext, R.style.LightDialogTheme)
309                 .setMessage(permissionNeededMessage)
310                 .setPositiveButton(android.R.string.ok, /* onClickListener= */ null)
311                 .setNegativeButton(
312                         R.string.settings_button_label,
313                         (dialogInterface, i) -> {
314                             Intent appInfoIntent = new Intent();
315                             appInfoIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
316                             Uri uri = Uri.fromParts("package",
317                                     mAppContext.getPackageName(), /* fragment= */ null);
318                             appInfoIntent.setData(uri);
319                             mActivity.startActivityForResult(appInfoIntent,
320                                     SETTINGS_APP_INFO_REQUEST_CODE);
321                         })
322                 .create();
323         dialog.show();
324     }
325 
326     /**
327      * Obtains the {@link WallpaperInfo} object(s) representing the wallpaper(s) currently set to
328      * the device from the {@link CurrentWallpaperInfoFactory}.
329      */
refreshCurrentWallpapers(boolean forceRefresh)330     private void refreshCurrentWallpapers(boolean forceRefresh) {
331         CurrentWallpaperInfoFactory factory = InjectorProvider.getInjector()
332                 .getCurrentWallpaperFactory(mAppContext);
333 
334         factory.createCurrentWallpaperInfos(
335                 (homeWallpaper, lockWallpaper, presentationMode) -> {
336                     // A config change may have destroyed the activity since the refresh
337                     // started, so check for that.
338                     if (!isActivityAlive()) {
339                         return;
340                     }
341 
342                     mHomePreviewWallpaperInfo = homeWallpaper;
343                     mLockPreviewWallpaperInfo =
344                             lockWallpaper == null ? homeWallpaper : lockWallpaper;
345 
346                     mHomePreviewWallpaperInfo.computePlaceholderColor(mAppContext);
347                     if (lockWallpaper != null) {
348                         lockWallpaper.computePlaceholderColor(mAppContext);
349                     }
350                     updatePreview(mHomePreviewWallpaperInfo, true);
351                     updatePreview(mLockPreviewWallpaperInfo, false);
352 
353                     WallpaperManager manager = WallpaperManager.getInstance(mAppContext);
354 
355                     WallpaperColors homeColors =
356                             manager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
357                     onHomeWallpaperColorsChanged(homeColors);
358                     WallpaperColors lockColors = homeColors;
359 
360                     if (lockWallpaper != null) {
361                         lockColors = manager.getWallpaperColors(WallpaperManager.FLAG_LOCK);
362 
363                     }
364                     onLockWallpaperColorsChanged(lockColors);
365                 }, forceRefresh);
366     }
367 
updatePreview(WallpaperInfo wallpaperInfo, boolean isHomeWallpaper)368     private void updatePreview(WallpaperInfo wallpaperInfo, boolean isHomeWallpaper) {
369         if (wallpaperInfo == null) {
370             return;
371         }
372 
373         if (!isActivityAlive()) {
374             return;
375         }
376 
377         UserEventLogger eventLogger = InjectorProvider.getInjector().getUserEventLogger(
378                 mAppContext);
379 
380         WallpaperSurfaceCallback surfaceCallback = isHomeWallpaper
381                 ? mHomeWallpaperSurfaceCallback : mLockWallpaperSurfaceCallback;
382         // Load thumb regardless of live wallpaper to make sure we have a placeholder while
383         // the live wallpaper initializes in that case.
384         maybeLoadThumbnail(wallpaperInfo, surfaceCallback);
385 
386         if (isHomeWallpaper) {
387             if (mWallpaperConnection != null) {
388                 mWallpaperConnection.disconnect();
389                 mWallpaperConnection = null;
390             }
391             if (wallpaperInfo instanceof LiveWallpaperInfo) {
392                 setUpLiveWallpaperPreview(wallpaperInfo);
393             }
394         }
395 
396         View preview = isHomeWallpaper ? mHomePreviewCard : mLockscreenPreviewCard;
397         preview.setOnClickListener(view -> {
398             mWallpaperPreviewNavigator.showViewOnlyPreview(wallpaperInfo, isHomeWallpaper);
399             eventLogger.logCurrentWallpaperPreviewed();
400         });
401     }
402 
403     @NonNull
maybeLoadThumbnail(WallpaperInfo wallpaperInfo, WallpaperSurfaceCallback surfaceCallback)404     private Asset maybeLoadThumbnail(WallpaperInfo wallpaperInfo,
405             WallpaperSurfaceCallback surfaceCallback) {
406         ImageView imageView = surfaceCallback.getHomeImageWallpaper();
407         Asset thumbAsset = new BitmapCachingAsset(mAppContext,
408                 wallpaperInfo.getThumbAsset(mAppContext));
409         if (imageView != null && imageView.getDrawable() == null) {
410             thumbAsset.loadPreviewImage(mActivity, imageView,
411                     ResourceUtils.getColorAttr(mActivity, android.R.attr.colorSecondary));
412         }
413         return thumbAsset;
414     }
415 
onHomeWallpaperColorsChanged(WallpaperColors wallpaperColors)416     private void onHomeWallpaperColorsChanged(WallpaperColors wallpaperColors) {
417         if (wallpaperColors != null && wallpaperColors.equals(
418                 mWallpaperColorsViewModel.getHomeWallpaperColors().getValue())) {
419             return;
420         }
421         mWallpaperColorsViewModel.getHomeWallpaperColors().setValue(wallpaperColors);
422     }
423 
onLockWallpaperColorsChanged(WallpaperColors wallpaperColors)424     private void onLockWallpaperColorsChanged(WallpaperColors wallpaperColors) {
425         if (wallpaperColors != null && wallpaperColors.equals(
426                 mWallpaperColorsViewModel.getLockWallpaperColors().getValue())) {
427             return;
428         }
429         mWallpaperColorsViewModel.getLockWallpaperColors().setValue(wallpaperColors);
430         if (mLockScreenPreviewer != null) {
431             mLockScreenPreviewer.setColor(wallpaperColors);
432         }
433     }
434 
setUpLiveWallpaperPreview(WallpaperInfo homeWallpaper)435     private void setUpLiveWallpaperPreview(WallpaperInfo homeWallpaper) {
436         if (!isActivityAlive()) {
437             return;
438         }
439 
440         if (WallpaperConnection.isPreviewAvailable()) {
441             final boolean isLockLive = mLockPreviewWallpaperInfo instanceof LiveWallpaperInfo;
442             mWallpaperConnection = new WallpaperConnection(
443                     getWallpaperIntent(homeWallpaper.getWallpaperComponent()), mActivity,
444                     new WallpaperConnection.WallpaperConnectionListener() {
445                         @Override
446                         public void onWallpaperColorsChanged(WallpaperColors colors,
447                                 int displayId) {
448                             if (isLockLive && mLockScreenPreviewer != null) {
449                                 mLockScreenPreviewer.setColor(colors);
450                                 onLockWallpaperColorsChanged(colors);
451                             }
452                             onHomeWallpaperColorsChanged(colors);
453                         }
454                     },
455                     mHomeWallpaperSurface, isLockLive ? mLockWallpaperSurface : null);
456 
457             mWallpaperConnection.setVisibility(true);
458             mHomeWallpaperSurface.post(() -> {
459                 if (mWallpaperConnection != null && !mWallpaperConnection.connect()) {
460                     mWallpaperConnection = null;
461                 }
462             });
463         }
464     }
465 
getWallpaperIntent(android.app.WallpaperInfo info)466     private Intent getWallpaperIntent(android.app.WallpaperInfo info) {
467         return new Intent(WallpaperService.SERVICE_INTERFACE)
468                 .setClassName(info.getPackageName(), info.getServiceName());
469     }
470 
updateWallpaperSurface()471     private void updateWallpaperSurface() {
472         mHomeWallpaperSurface.getHolder().addCallback(mHomeWallpaperSurfaceCallback);
473         mHomeWallpaperSurface.setZOrderMediaOverlay(true);
474         mLockWallpaperSurface.getHolder().addCallback(mLockWallpaperSurfaceCallback);
475         mLockWallpaperSurface.setZOrderMediaOverlay(true);
476     }
477 
updateWorkspaceSurface()478     private void updateWorkspaceSurface() {
479         mWorkspaceSurface.setZOrderMediaOverlay(true);
480         mWorkspaceSurface.getHolder().addCallback(mWorkspaceSurfaceCallback);
481     }
482 
isActivityAlive()483     private boolean isActivityAlive() {
484         return !mActivity.isDestroyed() && !mActivity.isFinishing();
485     }
486 
fadeWallpaperPreview(boolean isFadeIn, int duration)487     private void fadeWallpaperPreview(boolean isFadeIn, int duration) {
488         setupFade(mHomePreviewCard, mHomePreviewProgress, duration, isFadeIn);
489         setupFade(mLockscreenPreviewCard, mLockscreenPreviewProgress, duration, isFadeIn);
490     }
491 
setupFade(CardView cardView, ContentLoadingProgressBar progressBar, int duration, boolean fadeIn)492     private void setupFade(CardView cardView, ContentLoadingProgressBar progressBar, int duration,
493             boolean fadeIn) {
494         cardView.setAlpha(fadeIn ? 0.0f : 1.0f);
495         cardView.animate()
496                 .alpha(fadeIn ? 1.0f : 0.0f)
497                 .setDuration(duration)
498                 .setListener(new Animator.AnimatorListener() {
499                     @Override
500                     public void onAnimationCancel(Animator animator) {
501                         progressBar.hide();
502                         setWallpaperPreviewsVisibility(View.VISIBLE);
503                     }
504 
505                     @Override
506                     public void onAnimationEnd(Animator animator) {
507                         progressBar.hide();
508                         setWallpaperPreviewsVisibility(View.VISIBLE);
509                     }
510 
511                     @Override
512                     public void onAnimationRepeat(Animator animator) {
513                     }
514 
515                     @Override
516                     public void onAnimationStart(Animator animator) {
517                         setWallpaperPreviewsVisibility(View.INVISIBLE);
518                     }
519                 });
520         progressBar.animate()
521                 .alpha(fadeIn ? 1.0f : 0.0f)
522                 .setDuration(duration * 2)
523                 .setStartDelay(duration)
524                 .withStartAction(progressBar::show)
525                 .withEndAction(progressBar::hide);
526     }
527 
setWallpaperPreviewsVisibility(int visibility)528     private void setWallpaperPreviewsVisibility(int visibility) {
529         if (mHomeWallpaperSurface != null) {
530             mHomeWallpaperSurface.setVisibility(visibility);
531         }
532         if (mLockWallpaperSurface != null) {
533             mLockWallpaperSurface.setVisibility(visibility);
534         }
535         if (mWorkspaceSurface != null) {
536             mWorkspaceSurface.setVisibility(visibility);
537         }
538         if (mLockPreviewContainer != null) {
539             mLockPreviewContainer.setVisibility(visibility);
540         }
541     }
542 
543     @Override
onTransitionOut()544     public void onTransitionOut() {
545         if (mHomeWallpaperSurface != null) {
546             mHomeWallpaperSurface.setUseAlpha();
547             mHomeWallpaperSurface.setAlpha(0f);
548         }
549         if (mLockWallpaperSurface != null) {
550             mLockWallpaperSurface.setUseAlpha();
551             mLockWallpaperSurface.setAlpha(0f);
552         }
553         if (mWorkspaceSurface != null) {
554             mWorkspaceSurface.setUseAlpha();
555             mWorkspaceSurface.setAlpha(0f);
556         }
557         if (mLockPreviewContainer != null) {
558             mLockPreviewContainer.setAlpha(0f);
559         }
560     }
561 }
562