blob: 64425e5e6618a419c4c9d0d905e409b5007537a9 [file] [log] [blame]
Jon Miranda16ea1b12017-12-12 14:52:48 -08001/*
2 * Copyright (C) 2017 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 */
16package com.android.wallpaper.picker;
17
Jon Miranda16ea1b12017-12-12 14:52:48 -080018import android.app.Activity;
19import android.app.ProgressDialog;
Jon Miranda16ea1b12017-12-12 14:52:48 -080020import android.content.Context;
21import android.content.Intent;
Jon Miranda16ea1b12017-12-12 14:52:48 -080022import android.graphics.Color;
23import android.graphics.Point;
24import android.graphics.PorterDuff.Mode;
25import android.graphics.drawable.Drawable;
26import android.net.Uri;
27import android.os.AsyncTask;
28import android.os.Build.VERSION;
29import android.os.Build.VERSION_CODES;
30import android.os.Bundle;
Jon Miranda16ea1b12017-12-12 14:52:48 -080031import android.util.Log;
32import android.view.View;
33import android.view.View.OnClickListener;
34import android.widget.Button;
35import android.widget.FrameLayout;
36import android.widget.ImageView;
37import android.widget.LinearLayout;
38import android.widget.TextView;
39
Santiago Etchebehere635e96f2018-12-04 18:31:34 -080040import androidx.annotation.NonNull;
41import androidx.annotation.Nullable;
42import androidx.appcompat.app.AlertDialog;
43import androidx.appcompat.widget.Toolbar;
44import androidx.fragment.app.Fragment;
45import androidx.fragment.app.FragmentManager;
46
Jon Miranda16ea1b12017-12-12 14:52:48 -080047import com.android.wallpaper.R;
48import com.android.wallpaper.asset.Asset;
49import com.android.wallpaper.compat.ButtonDrawableSetterCompat;
Jon Miranda16ea1b12017-12-12 14:52:48 -080050import com.android.wallpaper.config.Flags;
51import com.android.wallpaper.model.Category;
Jon Miranda16ea1b12017-12-12 14:52:48 -080052import com.android.wallpaper.model.ImageWallpaperInfo;
Jon Miranda16ea1b12017-12-12 14:52:48 -080053import com.android.wallpaper.model.WallpaperInfo;
54import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
55import com.android.wallpaper.module.CurrentWallpaperInfoFactory.WallpaperInfoCallback;
56import com.android.wallpaper.module.DailyLoggingAlarmScheduler;
57import com.android.wallpaper.module.ExploreIntentChecker;
58import com.android.wallpaper.module.FormFactorChecker;
Jon Miranda16ea1b12017-12-12 14:52:48 -080059import com.android.wallpaper.module.Injector;
60import com.android.wallpaper.module.InjectorProvider;
61import com.android.wallpaper.module.NetworkStatusNotifier;
62import com.android.wallpaper.module.NetworkStatusNotifier.NetworkStatus;
63import com.android.wallpaper.module.UserEventLogger;
64import com.android.wallpaper.module.UserEventLogger.WallpaperSetFailureReason;
65import com.android.wallpaper.module.WallpaperPersister;
66import com.android.wallpaper.module.WallpaperPersister.Destination;
67import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback;
68import com.android.wallpaper.module.WallpaperPersister.WallpaperPosition;
69import com.android.wallpaper.module.WallpaperPreferences;
70import com.android.wallpaper.module.WallpaperPreferences.PresentationMode;
71import com.android.wallpaper.module.WallpaperRotationRefresher;
72import com.android.wallpaper.module.WallpaperRotationRefresher.Listener;
Santiago Etchebehere635e96f2018-12-04 18:31:34 -080073import com.android.wallpaper.picker.CategoryFragment.CategoryFragmentHost;
Jon Miranda16ea1b12017-12-12 14:52:48 -080074import com.android.wallpaper.picker.WallpaperDisabledFragment.WallpaperSupportLevel;
Jon Miranda16ea1b12017-12-12 14:52:48 -080075import com.android.wallpaper.picker.individual.IndividualPickerFragment;
76import com.android.wallpaper.util.ScreenSizeCalculator;
77import com.android.wallpaper.util.ThrowableAnalyzer;
78
Sunny Goyal8600a3f2018-08-15 12:48:01 -070079import com.google.android.material.bottomsheet.BottomSheetBehavior;
80import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback;
81import com.google.android.material.tabs.TabLayout;
82import com.google.android.material.tabs.TabLayout.OnTabSelectedListener;
83import com.google.android.material.tabs.TabLayout.Tab;
84
Jon Miranda16ea1b12017-12-12 14:52:48 -080085import java.util.List;
86
87/**
88 * Activity allowing users to select a category of wallpapers to choose from.
89 */
90public class TopLevelPickerActivity extends BaseActivity implements WallpapersUiContainer,
91 CurrentWallpaperBottomSheetPresenter, SetWallpaperErrorDialogFragment.Listener,
Santiago Etchebehere635e96f2018-12-04 18:31:34 -080092 MyPhotosLauncher, CategoryFragmentHost {
Jon Miranda16ea1b12017-12-12 14:52:48 -080093
94 private static final String TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT =
95 "toplevel_set_wallpaper_error_dialog";
96
97 private static final String TAG = "TopLevelPicker";
98 private static final String KEY_SELECTED_CATEGORY_TAB = "selected_category_tab";
99
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800100 private WallpaperPickerDelegate mDelegate;
Jon Miranda16ea1b12017-12-12 14:52:48 -0800101 private int mLastSelectedCategoryTabIndex;
Jon Miranda16ea1b12017-12-12 14:52:48 -0800102 private UserEventLogger mUserEventLogger;
103 private NetworkStatusNotifier mNetworkStatusNotifier;
104 private NetworkStatusNotifier.Listener mNetworkStatusListener;
105 private WallpaperPersister mWallpaperPersister;
106 private boolean mWasCustomPhotoWallpaperSet;
107 @WallpaperPosition
108 private int mCustomPhotoWallpaperPosition;
109
110 /**
111 * Progress dialogs for "refresh daily wallpaper" and "set wallpaper" operations.
112 */
113 private ProgressDialog mRefreshWallpaperProgressDialog;
114 private ProgressDialog mSetWallpaperProgressDialog;
115
116 /**
117 * Designates a test mode of operation -- in which certain UI features are disabled to allow for
118 * UI tests to run correctly.
119 */
120 private boolean mTestingMode;
121
122 /**
123 * UI for the "currently set wallpaper" BottomSheet.
124 */
125 private LinearLayout mBottomSheet;
126 private ImageView mCurrentWallpaperImage;
127 private TextView mCurrentWallpaperPresentationMode;
128 private TextView mCurrentWallpaperTitle;
129 private TextView mCurrentWallpaperSubtitle;
130 private Button mCurrentWallpaperExploreButton;
131 private Button mCurrentWallpaperSkipWallpaperButton;
132 private FrameLayout mFragmentContainer;
133 private FrameLayout mLoadingIndicatorContainer;
134 private LinearLayout mWallpaperPositionOptions;
135
Jon Miranda16ea1b12017-12-12 14:52:48 -0800136 /**
137 * Staged error dialog fragments that were unable to be shown when the activity didn't allow
138 * committing fragment transactions.
139 */
140 private SetWallpaperErrorDialogFragment mStagedSetWallpaperErrorDialogFragment;
141
142 /**
143 * A wallpaper pending set to the device--we retain a reference to this in order to facilitate
144 * retry or re-crop operations.
145 */
146 private WallpaperInfo mPendingSetWallpaperInfo;
147
148 private static int getTextColorIdForWallpaperPositionButton(boolean isSelected) {
149 return isSelected ? R.color.accent_color : R.color.material_grey500;
150 }
151
152 @Override
153 protected void onCreate(Bundle savedInstanceState) {
154 super.onCreate(savedInstanceState);
155
Jon Miranda16ea1b12017-12-12 14:52:48 -0800156 mLastSelectedCategoryTabIndex = -1;
157
158 Injector injector = InjectorProvider.getInjector();
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800159 mDelegate = new WallpaperPickerDelegate(this, this, injector);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800160 mUserEventLogger = injector.getUserEventLogger(this);
161 mNetworkStatusNotifier = injector.getNetworkStatusNotifier(this);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800162 mWallpaperPersister = injector.getWallpaperPersister(this);
163 mWasCustomPhotoWallpaperSet = false;
164
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800165 @WallpaperSupportLevel int wallpaperSupportLevel = mDelegate.getWallpaperSupportLevel();
Jon Miranda16ea1b12017-12-12 14:52:48 -0800166 if (wallpaperSupportLevel != WallpaperDisabledFragment.SUPPORTED_CAN_SET) {
167 setContentView(R.layout.activity_single_fragment);
168
169 FragmentManager fm = getSupportFragmentManager();
170 WallpaperDisabledFragment wallpaperDisabledFragment =
171 WallpaperDisabledFragment.newInstance(wallpaperSupportLevel);
172 fm.beginTransaction()
173 .add(R.id.fragment_container, wallpaperDisabledFragment)
174 .commit();
175 return;
176 }
177
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800178 if (mDelegate.getFormFactor() == FormFactorChecker.FORM_FACTOR_MOBILE) {
Jon Miranda16ea1b12017-12-12 14:52:48 -0800179 initializeMobile();
180 } else { // DESKTOP
181 initializeDesktop(savedInstanceState);
182 }
183 }
184
185 @Override
186 protected void onResume() {
187 super.onResume();
188
189 // Show the staged 'load wallpaper' or 'set wallpaper' error dialog fragments if there is one
190 // that was unable to be shown earlier when this fragment's hosting activity didn't allow
191 // committing fragment transactions.
192 if (mStagedSetWallpaperErrorDialogFragment != null) {
193 mStagedSetWallpaperErrorDialogFragment.show(
194 getSupportFragmentManager(), TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT);
195 mStagedSetWallpaperErrorDialogFragment = null;
196 }
197 }
198
199 @Override
200 protected void onDestroy() {
201 super.onDestroy();
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800202 mDelegate.cleanUp();
Jon Miranda16ea1b12017-12-12 14:52:48 -0800203 if (mNetworkStatusListener != null) {
204 mNetworkStatusNotifier.unregisterListener(mNetworkStatusListener);
205 }
206
207 if (mRefreshWallpaperProgressDialog != null) {
208 mRefreshWallpaperProgressDialog.dismiss();
209 }
210 if (mSetWallpaperProgressDialog != null) {
211 mSetWallpaperProgressDialog.dismiss();
212 }
213
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800214 if (mDelegate.getFormFactor() == FormFactorChecker.FORM_FACTOR_DESKTOP
215 && mWasCustomPhotoWallpaperSet) {
Jon Miranda16ea1b12017-12-12 14:52:48 -0800216 mUserEventLogger.logWallpaperPosition(mCustomPhotoWallpaperPosition);
217 }
218 }
219
220 @Override
221 public void requestCustomPhotoPicker(PermissionChangedListener listener) {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800222 mDelegate.requestCustomPhotoPicker(listener);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800223 }
224
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800225 @Override
226 public void requestExternalStoragePermission(PermissionChangedListener listener) {
227 mDelegate.requestExternalStoragePermission(listener);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800228 }
229
230 /**
231 * Returns whether READ_EXTERNAL_STORAGE has been granted for the application.
232 */
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800233 public boolean isReadExternalStoragePermissionGranted() {
234 return mDelegate.isReadExternalStoragePermissionGranted();
Jon Miranda16ea1b12017-12-12 14:52:48 -0800235 }
236
237 private void initializeMobile() {
238 setContentView(R.layout.activity_single_fragment_with_toolbar);
239
240 // Set toolbar as the action bar.
241 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
242 setSupportActionBar(toolbar);
243
244 FragmentManager fm = getSupportFragmentManager();
245 Fragment fragment = fm.findFragmentById(R.id.fragment_container);
246
247 boolean forceCategoryRefresh = false;
248 if (fragment == null) {
249 // App launch specific logic: log the "app launched" event and set up daily logging.
250 mUserEventLogger.logAppLaunched();
251 DailyLoggingAlarmScheduler.setAlarm(getApplicationContext());
252
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800253 CategoryFragment newFragment = new CategoryFragment();
Jon Miranda16ea1b12017-12-12 14:52:48 -0800254 fm.beginTransaction()
255 .add(R.id.fragment_container, newFragment)
256 .commit();
257
258 forceCategoryRefresh = true;
259 }
260
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800261 mDelegate.initialize(forceCategoryRefresh);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800262 }
263
264 private void initializeDesktop(Bundle savedInstanceState) {
265 setContentView(R.layout.activity_top_level_desktop);
266
267 mBottomSheet = (LinearLayout) findViewById(R.id.bottom_sheet);
268 mCurrentWallpaperImage = (ImageView) mBottomSheet.findViewById(R.id.current_wallpaper_image);
269 mCurrentWallpaperImage.getLayoutParams().width = getSingleWallpaperImageWidthPx();
270
271 mCurrentWallpaperPresentationMode =
272 (TextView) mBottomSheet.findViewById(R.id.current_wallpaper_presentation_mode);
273 mCurrentWallpaperTitle = (TextView) findViewById(R.id.current_wallpaper_title);
274 mCurrentWallpaperSubtitle = (TextView) findViewById(R.id.current_wallpaper_subtitle);
275 mCurrentWallpaperExploreButton = (Button) findViewById(
276 R.id.current_wallpaper_explore_button);
277 mCurrentWallpaperSkipWallpaperButton = (Button) findViewById(
278 R.id.current_wallpaper_skip_wallpaper_button);
279 mFragmentContainer = (FrameLayout) findViewById(R.id.fragment_container);
280 mLoadingIndicatorContainer = (FrameLayout) findViewById(R.id.loading_indicator_container);
281 mWallpaperPositionOptions = (LinearLayout) findViewById(
282 R.id.desktop_wallpaper_position_options);
283
284 final TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
285 tabLayout.addOnTabSelectedListener(new OnTabSelectedListener() {
286 @Override
287 public void onTabSelected(Tab tab) {
288 Category category = (Category) tab.getTag();
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800289 showCategoryDesktop(category.getCollectionId());
Jon Miranda16ea1b12017-12-12 14:52:48 -0800290 mLastSelectedCategoryTabIndex = tabLayout.getSelectedTabPosition();
291 }
292
293 @Override
294 public void onTabUnselected(Tab tab) {
295 }
296
297 @Override
298 public void onTabReselected(Tab tab) {
299 Category category = (Category) tab.getTag();
300 // If offline, "My photos" may be the only visible category. In this case we want to allow
301 // re-selection so user can still select a photo as wallpaper while offline.
302 if (!category.isEnumerable()) {
303 onTabSelected(tab);
304 }
305 }
306 });
307
308 FragmentManager fm = getSupportFragmentManager();
309 Fragment fragment = fm.findFragmentById(R.id.fragment_container);
310
311 if (fragment == null) {
312 // App launch specific logic: log the "app launched" event and set up daily logging.
313 mUserEventLogger.logAppLaunched();
314 DailyLoggingAlarmScheduler.setAlarm(getApplicationContext());
315 }
316
317 mNetworkStatusListener = new NetworkStatusNotifier.Listener() {
318 @Override
319 public void onNetworkChanged(@NetworkStatus int networkStatus) {
320 initializeDesktopBasedOnNetwork(networkStatus, savedInstanceState);
321 }
322 };
323 // Upon registering a listener, the onNetworkChanged method is immediately called with the
324 // initial network status.
325 mNetworkStatusNotifier.registerListener(mNetworkStatusListener);
326 }
327
328 private void initializeDesktopBasedOnNetwork(@NetworkStatus int networkStatus,
329 Bundle savedInstanceState) {
330 if (networkStatus == NetworkStatusNotifier.NETWORK_CONNECTED) {
331 initializeDesktopOnline(savedInstanceState);
332 } else {
333 initializeDesktopOffline();
334 }
335 }
336
337 private void initializeDesktopOnline(Bundle savedInstanceState) {
338 FragmentManager fm = getSupportFragmentManager();
339 Fragment fragment = fm.findFragmentById(R.id.fragment_container);
340
341 // Require a category refresh if this is the first load of the app or if the app is now
342 // returning online after having been offline.
343 boolean forceCategoryRefresh = fragment == null || fragment instanceof OfflineDesktopFragment;
344
345 if (fragment != null) {
346 fm.beginTransaction()
347 .remove(fragment)
348 .commit();
349 }
350
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800351 mLastSelectedCategoryTabIndex = savedInstanceState != null
Jon Miranda16ea1b12017-12-12 14:52:48 -0800352 ? savedInstanceState.getInt(KEY_SELECTED_CATEGORY_TAB) : -1;
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800353 mDelegate.populateCategories(forceCategoryRefresh);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800354
355 setDesktopLoading(true);
356 setUpBottomSheet();
357 refreshCurrentWallpapers(null /* refreshListener */);
358 }
359
360 private void initializeDesktopOffline() {
361 FragmentManager fm = getSupportFragmentManager();
362 Fragment fragment = fm.findFragmentById(R.id.fragment_container);
363
364 if (fragment != null) {
365 fm.beginTransaction()
366 .remove(fragment)
367 .commit();
368 }
369 OfflineDesktopFragment newFragment = new OfflineDesktopFragment();
370 fm.beginTransaction()
371 .add(R.id.fragment_container, newFragment)
372 .commit();
373
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800374 // Reset the last selected category tab index to ensure the app doesn't try to reselect a
375 // tab for a category not yet repopulated.
Jon Miranda16ea1b12017-12-12 14:52:48 -0800376 mLastSelectedCategoryTabIndex = -1;
377
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800378 mDelegate.populateCategories(true /* forceCategoryRefresh */);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800379
380 setDesktopLoading(false);
381 setCurrentWallpapersExpanded(false);
382 }
383
384 /**
385 * Sets the status of the loading indicator overlay in desktop mode.
386 *
387 * @param loading Whether an indeterminate loading indicator is displayed in place of the main
388 * fragment.
389 */
390 private void setDesktopLoading(boolean loading) {
391 if (loading) {
392 mLoadingIndicatorContainer.setVisibility(View.VISIBLE);
393 mFragmentContainer.setVisibility(View.GONE);
394 } else {
395 mLoadingIndicatorContainer.setVisibility(View.GONE);
396 mFragmentContainer.setVisibility(View.VISIBLE);
397 }
398 }
399
400 /**
401 * Returns the width (in physical px) to use for the "currently set wallpaper" thumbnail.
402 */
403 private int getSingleWallpaperImageWidthPx() {
404 Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize(
405 getWindowManager().getDefaultDisplay());
406
407 int height = getResources().getDimensionPixelSize(
408 R.dimen.current_wallpaper_bottom_sheet_thumb_height);
409 return height * screenSize.x / screenSize.y;
410 }
411
412 /**
413 * Enables and populates the "Currently set" wallpaper BottomSheet.
414 */
415 private void setUpBottomSheet() {
416 mBottomSheet.setVisibility(View.VISIBLE);
417
Jon Miranda16ea1b12017-12-12 14:52:48 -0800418 if (Flags.skipDailyWallpaperButtonEnabled) {
419 // Add "next" icon to the Next Wallpaper button
420 Drawable nextWallpaperButtonDrawable = getResources().getDrawable(
Santiago Etchebehered24506c2018-04-05 17:02:42 -0700421 R.drawable.ic_refresh_18px);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800422
423 // This Drawable's state is shared across the app, so make a copy of it before applying a
424 // color tint as not to affect other clients elsewhere in the app.
425 nextWallpaperButtonDrawable =
426 nextWallpaperButtonDrawable.getConstantState().newDrawable().mutate();
427 // Color the "compass" icon with the accent color.
428 nextWallpaperButtonDrawable.setColorFilter(
429 getResources().getColor(R.color.accent_color), Mode.SRC_IN);
430 ButtonDrawableSetterCompat.setDrawableToButtonStart(
431 mCurrentWallpaperSkipWallpaperButton, nextWallpaperButtonDrawable);
432 }
433
434 final BottomSheetBehavior<LinearLayout> bottomSheetBehavior =
435 BottomSheetBehavior.from(mBottomSheet);
436 bottomSheetBehavior.setBottomSheetCallback(new BottomSheetCallback() {
437 @Override
438 public void onStateChanged(@NonNull View view, int i) {
439 }
440
441 @Override
442 public void onSlide(@NonNull View view, float slideOffset) {
443 float alpha;
444 if (slideOffset >= 0) {
445 alpha = slideOffset;
446 } else {
447 alpha = 1f - slideOffset;
448 }
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800449 LinearLayout bottomSheetContents = findViewById(R.id.bottom_sheet_contents);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800450 bottomSheetContents.setAlpha(alpha);
451 }
452 });
453 }
454
455 /**
456 * Enables a test mode of operation -- in which certain UI features are disabled to allow for
457 * UI tests to run correctly. Works around issue in ProgressDialog currently where the dialog
458 * constantly keeps the UI thread alive and blocks a test forever.
459 */
460 void setTestingMode(boolean testingMode) {
461 mTestingMode = testingMode;
462 }
463
464 /**
465 * Obtains the {@link WallpaperInfo} object(s) representing the wallpaper(s) currently set to the
466 * device from the {@link CurrentWallpaperInfoFactory} and displays them in the BottomSheet.
467 */
468 @Override
469 public void refreshCurrentWallpapers(@Nullable RefreshListener refreshListener) {
470 final Injector injector = InjectorProvider.getInjector();
471 final Context appContext = getApplicationContext();
472
473 CurrentWallpaperInfoFactory factory = injector.getCurrentWallpaperFactory(this);
474 factory.createCurrentWallpaperInfos(new WallpaperInfoCallback() {
475 @Override
476 public void onWallpaperInfoCreated(
477 final WallpaperInfo homeWallpaper,
478 @Nullable final WallpaperInfo lockWallpaper,
479 @PresentationMode final int presentationMode) {
480
481 if (isDestroyed()) {
482 return;
483 }
484
485 // Fetch the home wallpaper's thumbnail asset asynchronously to work around expensive
486 // method call to WallpaperManager#getWallpaperFile made from the CurrentWallpaperInfoVN
487 // getAsset() method.
488 AssetReceiver assetReceiver = (Asset thumbAsset) -> {
489 if (isDestroyed()) {
490 return;
491 }
492
493 homeWallpaper.getThumbAsset(appContext).loadDrawableWithTransition(
494 TopLevelPickerActivity.this,
495 mCurrentWallpaperImage,
496 200 /* transitionDurationMillis */,
497 () -> {
498 if (refreshListener != null) {
499 refreshListener.onCurrentWallpaperRefreshed();
500 }
501 },
502 Color.TRANSPARENT);
503 };
504 new FetchThumbAssetTask(appContext, homeWallpaper, assetReceiver).executeOnExecutor(
505 AsyncTask.THREAD_POOL_EXECUTOR);
506
507 mCurrentWallpaperPresentationMode.setText(
508 AttributionFormatter.getHumanReadableWallpaperPresentationMode(
509 TopLevelPickerActivity.this, presentationMode));
510
511 List<String> attributions = homeWallpaper.getAttributions(appContext);
512 if (attributions.size() > 0 && attributions.get(0) != null) {
513 mCurrentWallpaperTitle.setText(attributions.get(0));
514 }
515
516 mCurrentWallpaperSubtitle.setText(
517 AttributionFormatter.formatWallpaperSubtitle(appContext, homeWallpaper));
518
519 final String actionUrl = homeWallpaper.getActionUrl(appContext);
520 if (actionUrl != null && !actionUrl.isEmpty()) {
521 Uri exploreUri = Uri.parse(actionUrl);
522
523 ExploreIntentChecker intentChecker = injector.getExploreIntentChecker(appContext);
524 intentChecker.fetchValidActionViewIntent(exploreUri, (@Nullable Intent exploreIntent) -> {
525 if (exploreIntent != null && !isDestroyed()) {
Santiago Etchebehered1bd5092018-04-18 16:03:30 -0700526 // Set the icon for the button
527 Drawable exploreButtonDrawable = getResources().getDrawable(
Santiago Etchebeheree0810d02018-05-10 17:39:40 -0700528 homeWallpaper.getActionIconRes(appContext));
Santiago Etchebehered1bd5092018-04-18 16:03:30 -0700529
530 // This Drawable's state is shared across the app, so make a copy of it
531 // before applying a color tint as not to affect other clients elsewhere
532 // in the app.
533 exploreButtonDrawable = exploreButtonDrawable.getConstantState()
534 .newDrawable().mutate();
535 // Color the "compass" icon with the accent color.
536 exploreButtonDrawable.setColorFilter(
537 getResources().getColor(R.color.accent_color), Mode.SRC_IN);
538
539 ButtonDrawableSetterCompat.setDrawableToButtonStart(
540 mCurrentWallpaperExploreButton, exploreButtonDrawable);
541 mCurrentWallpaperExploreButton.setText(getString(
Santiago Etchebeheree0810d02018-05-10 17:39:40 -0700542 homeWallpaper.getActionLabelRes(appContext)));
Jon Miranda16ea1b12017-12-12 14:52:48 -0800543 mCurrentWallpaperExploreButton.setVisibility(View.VISIBLE);
544 mCurrentWallpaperExploreButton.setOnClickListener(new OnClickListener() {
545 @Override
546 public void onClick(View v) {
Santiago Etchebeherece5613f2018-06-01 13:22:47 -0700547 mUserEventLogger.logActionClicked(
548 homeWallpaper.getCollectionId(appContext),
549 homeWallpaper.getActionLabelRes(appContext));
Jon Miranda16ea1b12017-12-12 14:52:48 -0800550 startActivity(exploreIntent);
551 }
552 });
553 }
554 });
555 } else {
556 mCurrentWallpaperExploreButton.setVisibility(View.GONE);
557 }
558
559 // Hide the wallpaper position options UI if the current home wallpaper is not from
560 // "my photos".
561 String homeCollectionId = homeWallpaper.getCollectionId(TopLevelPickerActivity.this);
562 if (mWallpaperPositionOptions != null
563 && homeCollectionId != null // May be null if app is being used for the first time.
564 && !homeCollectionId.equals(getString(R.string.image_wallpaper_collection_id))) {
565 mWallpaperPositionOptions.setVisibility(View.GONE);
566 }
567
568 boolean showSkipWallpaperButton = Flags.skipDailyWallpaperButtonEnabled
569 && presentationMode == WallpaperPreferences.PRESENTATION_MODE_ROTATING;
570 if (showSkipWallpaperButton) {
571 mCurrentWallpaperSkipWallpaperButton.setVisibility(View.VISIBLE);
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800572 mCurrentWallpaperSkipWallpaperButton.setOnClickListener(
573 v -> refreshDailyWallpaper());
Jon Miranda16ea1b12017-12-12 14:52:48 -0800574 } else {
575 mCurrentWallpaperSkipWallpaperButton.setVisibility(View.GONE);
576 }
577
578 if (refreshListener != null) {
579 refreshListener.onCurrentWallpaperRefreshed();
580 }
581 }
582 }, true /* forceRefresh */);
583 }
584
585 @Override
586 public void onSaveInstanceState(Bundle savedInstanceState) {
587 FormFactorChecker formFactorChecker = InjectorProvider.getInjector().getFormFactorChecker(this);
588 if (formFactorChecker.getFormFactor() == FormFactorChecker.FORM_FACTOR_DESKTOP) {
589 TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
590
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800591 // tabLayout is only present when the main IndividualPickerFragment is present (as
592 // opposed to
Jon Miranda16ea1b12017-12-12 14:52:48 -0800593 // the WallpaperDisabledFragment), so need this null check.
594 if (tabLayout != null) {
595 savedInstanceState.putInt(KEY_SELECTED_CATEGORY_TAB, tabLayout.getSelectedTabPosition());
596 }
597 }
598
599 super.onSaveInstanceState(savedInstanceState);
600 }
601
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800602 @Override
Santiago Etchebehere1ee76a22018-05-15 15:02:24 -0700603 @Nullable
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800604 public CategoryFragment getCategoryFragment() {
605 if (mDelegate.getFormFactor() != FormFactorChecker.FORM_FACTOR_MOBILE) {
Santiago Etchebehere1ee76a22018-05-15 15:02:24 -0700606 return null;
607 }
608 FragmentManager fm = getSupportFragmentManager();
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800609 return (CategoryFragment) fm.findFragmentById(R.id.fragment_container);
Santiago Etchebehere1ee76a22018-05-15 15:02:24 -0700610 }
611
Jon Miranda16ea1b12017-12-12 14:52:48 -0800612 /**
613 * Populates the category tabs on DESKTOP form factor.
614 *
615 * @param selectedTabPosition The position of the tab to show as selected, or -1 if no particular
616 * tab should be selected (in which case: the tab of the category for the currently set
617 * wallpaper will be selected if enumerable; if not, the first enumerable category's tab will
618 * be selected).
619 */
620 private void populateCategoryTabs(int selectedTabPosition) {
621 final TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
622 tabLayout.removeAllTabs();
623
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800624 String currentlySetCollectionId = mDelegate.getPreferences().getHomeWallpaperCollectionId();
Jon Miranda16ea1b12017-12-12 14:52:48 -0800625
626 Tab tabToSelect = null;
627 Tab firstEnumerableCategoryTab = null;
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800628 for (int i = 0; i < mDelegate.getCategoryProvider().getSize(); i++) {
629 Category category = mDelegate.getCategoryProvider().getCategory(i);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800630
631 Tab tab = tabLayout.newTab();
632 tab.setText(category.getTitle());
633 tab.setTag(category);
634 tabLayout.addTab(tab, false /* setSelected */);
635
636 if (firstEnumerableCategoryTab == null && category.isEnumerable()) {
637 firstEnumerableCategoryTab = tab;
638 }
639
640 boolean shouldSelectTab = (i == selectedTabPosition)
641 || (selectedTabPosition == -1
642 && tabToSelect == null
643 && category.isEnumerable()
644 && currentlySetCollectionId != null
645 && currentlySetCollectionId.equals(category.getCollectionId()));
646
647 if (shouldSelectTab) {
648 tabToSelect = tab;
649 }
650 }
651
652 // If the above loop did not identify a specific tab to select, then just select the tab for
653 // the first enumerable category.
654 if (tabToSelect == null) {
655 tabToSelect = firstEnumerableCategoryTab;
656 }
657
658 // There may be no enumerable tabs (e.g., offline case), so we need to null-check again.
659 if (tabToSelect != null) {
660 tabToSelect.select();
661 }
662 }
663
664 /**
665 * Refreshes the current wallpaper in a daily wallpaper rotation.
666 */
667 private void refreshDailyWallpaper() {
668 // ProgressDialog endlessly updates the UI thread, keeping it from going idle which therefore
669 // causes Espresso to hang once the dialog is shown.
670 if (!mTestingMode) {
671 int themeResId;
672 if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
673 themeResId = R.style.ProgressDialogThemePreL;
674 } else {
675 themeResId = R.style.LightDialogTheme;
676 }
677 mRefreshWallpaperProgressDialog = new ProgressDialog(this, themeResId);
678 mRefreshWallpaperProgressDialog.setTitle(null);
679 mRefreshWallpaperProgressDialog.setMessage(
680 getResources().getString(R.string.refreshing_daily_wallpaper_dialog_message));
681 mRefreshWallpaperProgressDialog.setIndeterminate(true);
682 mRefreshWallpaperProgressDialog.show();
683 }
684
685 WallpaperRotationRefresher wallpaperRotationRefresher =
686 InjectorProvider.getInjector().getWallpaperRotationRefresher();
687 wallpaperRotationRefresher.refreshWallpaper(this, new Listener() {
688 @Override
689 public void onRefreshed() {
690 if (isDestroyed()) {
691 return;
692 }
693
694 if (mRefreshWallpaperProgressDialog != null) {
695 mRefreshWallpaperProgressDialog.dismiss();
696 }
697
698 refreshCurrentWallpapers(null /* refreshListener */);
699 }
700
701 @Override
702 public void onError() {
703 if (mRefreshWallpaperProgressDialog != null) {
704 mRefreshWallpaperProgressDialog.dismiss();
705 }
706
707 AlertDialog errorDialog = new AlertDialog.Builder(
708 TopLevelPickerActivity.this, R.style.LightDialogTheme)
709 .setMessage(R.string.refresh_daily_wallpaper_failed_message)
710 .setPositiveButton(android.R.string.ok, null /* onClickListener */)
711 .create();
712 errorDialog.show();
713 }
714 });
715 }
716
717 @Override
718 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
719 super.onActivityResult(requestCode, resultCode, data);
720
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800721 if (requestCode == WallpaperPickerDelegate.SHOW_CATEGORY_REQUEST_CODE
722 && resultCode == Activity.RESULT_OK) {
Jon Miranda16ea1b12017-12-12 14:52:48 -0800723 Uri imageUri = (data == null) ? null : data.getData();
724 if (imageUri != null) {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800725 // User selected an image from the system picker, so launch the preview for that
726 // image.
Jon Miranda16ea1b12017-12-12 14:52:48 -0800727 ImageWallpaperInfo imageWallpaper = new ImageWallpaperInfo(imageUri);
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800728 if (mDelegate.getFormFactor() == FormFactorChecker.FORM_FACTOR_DESKTOP) {
Jon Miranda16ea1b12017-12-12 14:52:48 -0800729 setCustomPhotoWallpaper(imageWallpaper);
730 return;
731 }
732
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800733 imageWallpaper.showPreview(this, mDelegate.getPreviewIntentFactory(),
734 WallpaperPickerDelegate.PREVIEW_WALLPAPER_REQUEST_CODE);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800735 } else {
736 // User finished viewing a category without any data, which implies that the user previewed
737 // and selected a wallpaper in-app, so finish this activity.
738 finishActivityWithResultOk();
739 }
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800740 } else if (requestCode == WallpaperPickerDelegate.PREVIEW_WALLPAPER_REQUEST_CODE
741 && resultCode == Activity.RESULT_OK) {
Jon Miranda16ea1b12017-12-12 14:52:48 -0800742 // User previewed and selected a wallpaper, so finish this activity.
743 finishActivityWithResultOk();
744 }
745 }
746
747 /**
748 * Shows the view-only preview activity for the given wallpaper.
749 */
750 public void showViewOnlyPreview(WallpaperInfo wallpaperInfo) {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800751 mDelegate.showViewOnlyPreview(wallpaperInfo);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800752 }
753
754 @Override
755 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
756 @NonNull int[] grantResults) {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800757 mDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800758 }
759
760 /**
761 * Shows the picker activity for the given category.
762 */
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800763 @Override
Jon Miranda16ea1b12017-12-12 14:52:48 -0800764 public void show(String collectionId) {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800765 mDelegate.show(collectionId);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800766 }
767
768 private void reselectLastTab() {
769 TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
770
771 // In the offline case, "My photos" could be the only category. Thus we need this check --
772 // to ensure that we don't try to select the "previously selected" category which was -1.
773 if (mLastSelectedCategoryTabIndex > -1) {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800774 Tab tabToSelect = tabLayout.getTabAt(
775 mLastSelectedCategoryTabIndex);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800776 if (((Category) tabToSelect.getTag()).isEnumerable()) {
777 tabToSelect.select();
778 }
779 }
780 }
781
Jon Miranda16ea1b12017-12-12 14:52:48 -0800782 private void showCategoryDesktop(String collectionId) {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800783 Category category = mDelegate.findCategoryForCollectionId(collectionId);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800784 if (category == null) {
785 return;
786 }
787
788 if (category.isEnumerable()) {
789 // Replace contained IndividualPickerFragment with a new instance for the given category.
790 final FragmentManager fm = getSupportFragmentManager();
791 Fragment fragment = fm.findFragmentById(R.id.fragment_container);
792 if (fragment != null) {
793 fm.beginTransaction()
794 .remove(fragment)
795 .commit();
796 }
797 IndividualPickerFragment newFragment = IndividualPickerFragment.newInstance(collectionId);
798 fm.beginTransaction()
799 .add(R.id.fragment_container, newFragment)
800 .commit();
801 newFragment.setCurrentWallpaperBottomSheetPresenter(this);
802 newFragment.setWallpapersUiContainer(this);
803 } else {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800804 category.show(this, mDelegate.getPickerIntentFactory(),
805 WallpaperPickerDelegate.SHOW_CATEGORY_REQUEST_CODE);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800806
807 // Need to select the tab here in case we are coming back from a "My photos" in which case
808 // the tab would have been set to "My photos" while viewing a regular image category.
809 reselectLastTab();
810 }
811 }
812
813 private void finishActivityWithResultOk() {
814 overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
815 setResult(Activity.RESULT_OK);
816 finish();
817 }
818
Jon Miranda16ea1b12017-12-12 14:52:48 -0800819 @Override
820 public void setCurrentWallpapersExpanded(boolean expanded) {
821 final BottomSheetBehavior<LinearLayout> bottomSheetBehavior =
822 BottomSheetBehavior.from(mBottomSheet);
823 bottomSheetBehavior.setState(
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800824 expanded ? BottomSheetBehavior.STATE_EXPANDED
825 : BottomSheetBehavior.STATE_COLLAPSED);
826 }
827
828 @Override
829 public void doneFetchingCategories() {
830 populateCategoryTabs(mLastSelectedCategoryTabIndex);
Jon Miranda16ea1b12017-12-12 14:52:48 -0800831 }
832
833 @Override
834 public void onWallpapersReady() {
835 setDesktopLoading(false);
836 setCurrentWallpapersExpanded(true);
837 }
838
839 @Override
840 public void onClickTryAgain(@Destination int unused) {
841 // Retry the set wallpaper operation with the default center-crop setting.
842 if (mPendingSetWallpaperInfo != null) {
843 setCustomPhotoWallpaper(mPendingSetWallpaperInfo);
844 }
845 }
846
847 /**
848 * Sets the provides wallpaper to the device with center-cropped and scaled to fit the device's
849 * default display.
850 */
851 private void setCustomPhotoWallpaper(final WallpaperInfo wallpaper) {
852 // Save this WallpaperInfo so we can retry this operation later if it fails.
853 mPendingSetWallpaperInfo = wallpaper;
854
855 showSettingWallpaperProgressDialog();
856
857 mWallpaperPersister.setIndividualWallpaperWithPosition(this, wallpaper,
858 WallpaperPersister.WALLPAPER_POSITION_CENTER_CROP, new SetWallpaperCallback() {
859 @Override
860 public void onSuccess() {
861 dismissSettingWallpaperProgressDialog();
862 refreshCurrentWallpapers(null /* refreshListener */);
863
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800864 mDelegate.getPreferences().setPendingWallpaperSetStatus(
Jon Miranda16ea1b12017-12-12 14:52:48 -0800865 WallpaperPreferences.WALLPAPER_SET_NOT_PENDING);
866 mUserEventLogger.logWallpaperSet(
867 wallpaper.getCollectionId(getApplicationContext()),
868 wallpaper.getWallpaperId());
869 mUserEventLogger.logWallpaperSetResult(UserEventLogger.WALLPAPER_SET_RESULT_SUCCESS);
870
871 // The user may have closed the activity before the set wallpaper operation completed.
872 if (isDestroyed()) {
873 return;
874 }
875
876 // Show the wallpaper crop option selector and bind click event handlers.
877 mWallpaperPositionOptions.setVisibility(View.VISIBLE);
878
879 mWasCustomPhotoWallpaperSet = true;
880 mCustomPhotoWallpaperPosition = WallpaperPersister.WALLPAPER_POSITION_CENTER_CROP;
881
882 initializeWallpaperPositionOptionClickHandlers(wallpaper);
883 }
884
885 @Override
886 public void onError(Throwable throwable) {
887 dismissSettingWallpaperProgressDialog();
888 showSetWallpaperErrorDialog();
889
Santiago Etchebehere635e96f2018-12-04 18:31:34 -0800890 mDelegate.getPreferences().setPendingWallpaperSetStatus(
Jon Miranda16ea1b12017-12-12 14:52:48 -0800891 WallpaperPreferences.WALLPAPER_SET_NOT_PENDING);
892 mUserEventLogger.logWallpaperSetResult(
893 UserEventLogger.WALLPAPER_SET_RESULT_FAILURE);
894 @WallpaperSetFailureReason int failureReason = ThrowableAnalyzer.isOOM(throwable)
895 ? UserEventLogger.WALLPAPER_SET_FAILURE_REASON_OOM
896 : UserEventLogger.WALLPAPER_SET_FAILURE_REASON_OTHER;
897 mUserEventLogger.logWallpaperSetFailureReason(failureReason);
898 Log.e(TAG, "Unable to set wallpaper from 'my photos'.");
899 }
900 });
901 }
902
903 /**
904 * Initializes the wallpaper position button click handlers to change the way the provided
905 * wallpaper is set to the device.
906 */
907 private void initializeWallpaperPositionOptionClickHandlers(final WallpaperInfo wallpaperInfo) {
908 Button centerCropOptionBtn = (Button) findViewById(R.id.wallpaper_position_option_center_crop);
909 Button stretchOptionBtn = (Button) findViewById(R.id.wallpaper_position_option_stretched);
910 Button centerOptionBtn = (Button) findViewById(R.id.wallpaper_position_option_center);
911
912 // The "center crop" wallpaper position button is selected by default.
913 setCenterCropWallpaperPositionButtonSelected(centerCropOptionBtn, true /* isSelected */);
914 centerCropOptionBtn.setOnClickListener(new OnClickListener() {
915 @Override
916 public void onClick(View view) {
917 mWallpaperPersister.setIndividualWallpaperWithPosition(TopLevelPickerActivity.this,
918 wallpaperInfo, WallpaperPersister.WALLPAPER_POSITION_CENTER_CROP,
919 new SetWallpaperCallback() {
920 @Override
921 public void onSuccess() {
922 // The user may have closed the activity before the set wallpaper operation
923 // completed.
924 if (isDestroyed()) {
925 return;
926 }
927
928 refreshCurrentWallpapers(null /* refreshListener */);
929
930 setCenterCropWallpaperPositionButtonSelected(
931 centerCropOptionBtn, true /* isSelected */);
932 setCenterWallpaperPositionButtonSelected(centerOptionBtn, false /* isSelected */);
933 setStretchWallpaperPositionButtonSelected(stretchOptionBtn, false /* isSelected */);
934
935 mCustomPhotoWallpaperPosition = WallpaperPersister.WALLPAPER_POSITION_CENTER_CROP;
936 }
937
938 @Override
939 public void onError(@Nullable Throwable throwable) {
940 // no-op
941 }
942 });
943 }
944 });
945
946 // "Stretch" is not selected by default.
947 setStretchWallpaperPositionButtonSelected(stretchOptionBtn, false /* isSelected */);
948 stretchOptionBtn.setOnClickListener(new OnClickListener() {
949 @Override
950 public void onClick(View view) {
951 mWallpaperPersister.setIndividualWallpaperWithPosition(TopLevelPickerActivity.this,
952 wallpaperInfo, WallpaperPersister.WALLPAPER_POSITION_STRETCH,
953 new SetWallpaperCallback() {
954 @Override
955 public void onSuccess() {
956 // The user may have closed the activity before the set wallpaper operation
957 // completed.
958 if (isDestroyed()) {
959 return;
960 }
961
962 refreshCurrentWallpapers(null /* refreshListener */);
963
964 setStretchWallpaperPositionButtonSelected(stretchOptionBtn, true /* isSelected */);
965 setCenterCropWallpaperPositionButtonSelected(
966 centerCropOptionBtn, false /* isSelected */);
967 setCenterWallpaperPositionButtonSelected(centerOptionBtn, false /* isSelected */);
968
969 mCustomPhotoWallpaperPosition = WallpaperPersister.WALLPAPER_POSITION_STRETCH;
970 }
971
972 @Override
973 public void onError(@Nullable Throwable throwable) {
974 // no-op
975 }
976 });
977 }
978 });
979
980 // "Center" is not selected by default.
981 setCenterWallpaperPositionButtonSelected(centerOptionBtn, false /* isSelected */);
982 centerOptionBtn.setOnClickListener(new OnClickListener() {
983 @Override
984 public void onClick(View view) {
985 mWallpaperPersister.setIndividualWallpaperWithPosition(TopLevelPickerActivity.this,
986 wallpaperInfo, WallpaperPersister.WALLPAPER_POSITION_CENTER,
987 new SetWallpaperCallback() {
988 @Override
989 public void onSuccess() {
990 // The user may have closed the activity before the set wallpaper operation
991 // completed.
992 if (isDestroyed()) {
993 return;
994 }
995
996 refreshCurrentWallpapers(null /* refreshListener */);
997
998 setCenterWallpaperPositionButtonSelected(centerOptionBtn, true /* isSelected */);
999 setCenterCropWallpaperPositionButtonSelected(
1000 centerCropOptionBtn, false /* isSelected */);
1001 setStretchWallpaperPositionButtonSelected(stretchOptionBtn, false /* isSelected */);
1002
1003 mCustomPhotoWallpaperPosition = WallpaperPersister.WALLPAPER_POSITION_CENTER;
1004 }
1005
1006 @Override
1007 public void onError(@Nullable Throwable throwable) {
1008 // no-op
1009 }
1010 });
1011 }
1012 });
1013 }
1014
1015 private void setCenterWallpaperPositionButtonSelected(Button button, boolean isSelected) {
1016 int drawableId = isSelected ? R.drawable.center_blue : R.drawable.center_grey;
1017 ButtonDrawableSetterCompat.setDrawableToButtonStart(button, getDrawable(drawableId));
1018 button.setTextColor(getColor(getTextColorIdForWallpaperPositionButton(isSelected)));
1019 }
1020
1021 private void setCenterCropWallpaperPositionButtonSelected(Button button, boolean isSelected) {
1022 int drawableId = isSelected ? R.drawable.center_crop_blue : R.drawable.center_crop_grey;
1023 ButtonDrawableSetterCompat.setDrawableToButtonStart(button, getDrawable(drawableId));
1024 button.setTextColor(getColor(getTextColorIdForWallpaperPositionButton(isSelected)));
1025 }
1026
1027 private void setStretchWallpaperPositionButtonSelected(Button button, boolean isSelected) {
1028 int drawableId = isSelected ? R.drawable.stretch_blue : R.drawable.stretch_grey;
1029 ButtonDrawableSetterCompat.setDrawableToButtonStart(button, getDrawable(drawableId));
1030 button.setTextColor(getColor(getTextColorIdForWallpaperPositionButton(isSelected)));
1031 }
1032
1033 private void showSettingWallpaperProgressDialog() {
Santiago Etchebehere635e96f2018-12-04 18:31:34 -08001034 // ProgressDialog endlessly updates the UI thread, keeping it from going idle which
1035 // therefore causes Espresso to hang once the dialog is shown.
Jon Miranda16ea1b12017-12-12 14:52:48 -08001036 if (!mTestingMode) {
1037 int themeResId;
1038 if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
1039 themeResId = R.style.ProgressDialogThemePreL;
1040 } else {
1041 themeResId = R.style.LightDialogTheme;
1042 }
1043 mSetWallpaperProgressDialog = new ProgressDialog(this, themeResId);
1044 mSetWallpaperProgressDialog.setTitle(null);
1045 mSetWallpaperProgressDialog.setMessage(
1046 getResources().getString(R.string.set_wallpaper_progress_message));
1047 mSetWallpaperProgressDialog.setIndeterminate(true);
1048 mSetWallpaperProgressDialog.show();
1049 }
1050 }
1051
1052 private void dismissSettingWallpaperProgressDialog() {
1053 if (mSetWallpaperProgressDialog != null) {
1054 mSetWallpaperProgressDialog.dismiss();
1055 }
1056 }
1057
1058 private void showSetWallpaperErrorDialog() {
1059 SetWallpaperErrorDialogFragment dialogFragment = SetWallpaperErrorDialogFragment.newInstance(
1060 R.string.set_wallpaper_error_message, WallpaperPersister.DEST_BOTH);
1061
1062 if (isSafeToCommitFragmentTransaction()) {
1063 dialogFragment.show(getSupportFragmentManager(), TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT);
1064 } else {
1065 mStagedSetWallpaperErrorDialogFragment = dialogFragment;
1066 }
1067 }
1068
1069 private interface AssetReceiver {
1070 void onAssetReceived(Asset asset);
1071 }
1072
1073 /**
1074 * An AsyncTask for asynchronously fetching the thumbnail asset for a given WallpaperInfo.
1075 * Used to work around expensive method call to WallpaperManager#getWallpaperFile made from the
1076 * CurrentWallpaperInfoVN getAsset() method.
1077 */
1078 private static class FetchThumbAssetTask extends AsyncTask<Void, Void, Asset> {
1079 private Context mAppContext;
1080 private WallpaperInfo mWallpaperInfo;
1081 private AssetReceiver mReceiver;
1082
1083 public FetchThumbAssetTask(Context appContext, WallpaperInfo wallpaperInfo,
1084 AssetReceiver receiver) {
1085 mAppContext = appContext;
1086 mWallpaperInfo = wallpaperInfo;
1087 mReceiver = receiver;
1088 }
1089
1090 @Override
1091 protected Asset doInBackground(Void... params) {
1092 return mWallpaperInfo.getThumbAsset(mAppContext);
1093 }
1094
1095 @Override
1096 protected void onPostExecute(Asset thumbAsset) {
1097 mReceiver.onAssetReceived(thumbAsset);
1098 }
1099 }
1100}