1 /* 2 * Copyright (C) 2019 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.picker; 17 18 import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS; 19 import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES; 20 21 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY; 22 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.CUSTOMIZE; 23 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.DELETE; 24 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.EDIT; 25 import static com.android.wallpaper.widget.BottomActionBar.BottomAction.INFORMATION; 26 27 import android.annotation.SuppressLint; 28 import android.app.Activity; 29 import android.app.AlertDialog; 30 import android.app.WallpaperColors; 31 import android.app.WallpaperInfo; 32 import android.app.WallpaperManager; 33 import android.content.ComponentName; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.pm.ActivityInfo; 37 import android.content.pm.ApplicationInfo; 38 import android.content.pm.PackageManager; 39 import android.content.pm.ServiceInfo; 40 import android.graphics.Color; 41 import android.graphics.Point; 42 import android.net.Uri; 43 import android.os.Build; 44 import android.os.Bundle; 45 import android.os.RemoteException; 46 import android.service.wallpaper.IWallpaperConnection; 47 import android.service.wallpaper.WallpaperService; 48 import android.service.wallpaper.WallpaperSettingsActivity; 49 import android.text.TextUtils; 50 import android.util.Log; 51 import android.view.LayoutInflater; 52 import android.view.MotionEvent; 53 import android.view.SurfaceView; 54 import android.view.View; 55 import android.view.ViewGroup; 56 import android.widget.ImageView; 57 58 import androidx.annotation.NonNull; 59 import androidx.annotation.Nullable; 60 import androidx.cardview.widget.CardView; 61 import androidx.constraintlayout.widget.ConstraintLayout; 62 import androidx.constraintlayout.widget.ConstraintSet; 63 import androidx.lifecycle.LiveData; 64 import androidx.slice.Slice; 65 import androidx.slice.widget.SliceLiveData; 66 import androidx.slice.widget.SliceView; 67 68 import com.android.wallpaper.R; 69 import com.android.wallpaper.model.SetWallpaperViewModel; 70 import com.android.wallpaper.model.WallpaperInfo.ColorInfo; 71 import com.android.wallpaper.module.LargeScreenMultiPanesChecker; 72 import com.android.wallpaper.util.FullScreenAnimation; 73 import com.android.wallpaper.util.ResourceUtils; 74 import com.android.wallpaper.util.ScreenSizeCalculator; 75 import com.android.wallpaper.util.SizeCalculator; 76 import com.android.wallpaper.util.WallpaperConnection; 77 import com.android.wallpaper.util.WallpaperSurfaceCallback; 78 import com.android.wallpaper.widget.BottomActionBar; 79 import com.android.wallpaper.widget.BottomActionBar.AccessibilityCallback; 80 import com.android.wallpaper.widget.BottomActionBar.BottomSheetContent; 81 import com.android.wallpaper.widget.LockScreenPreviewer; 82 import com.android.wallpaper.widget.WallpaperColorsLoader; 83 84 import java.util.Locale; 85 import java.util.concurrent.ExecutionException; 86 import java.util.concurrent.Future; 87 import java.util.concurrent.TimeUnit; 88 import java.util.concurrent.TimeoutException; 89 90 /** 91 * Fragment which displays the UI for previewing an individual live wallpaper, its attribution 92 * information and settings slices if available. 93 */ 94 public class LivePreviewFragment extends PreviewFragment implements 95 WallpaperConnection.WallpaperConnectionListener { 96 97 public static final String EXTRA_LIVE_WALLPAPER_INFO = "android.live_wallpaper.info"; 98 public static final String KEY_ACTION_DELETE_LIVE_WALLPAPER = "action_delete_live_wallpaper"; 99 100 private static final String TAG = "LivePreviewFragment"; 101 102 /** 103 * Instance of {@link WallpaperConnection} used to bind to the live wallpaper service to show 104 * it in this preview fragment. 105 * @see IWallpaperConnection 106 */ 107 protected WallpaperConnection mWallpaperConnection; 108 protected CardView mHomePreviewCard; 109 protected SurfaceView mWorkspaceSurface; 110 protected WallpaperSurfaceCallback mWallpaperSurfaceCallback; 111 protected WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback; 112 protected ViewGroup mLockPreviewContainer; 113 protected LockScreenPreviewer mLockScreenPreviewer; 114 115 private Intent mDeleteIntent; 116 private Intent mSettingsIntent; 117 private SliceView mSettingsSliceView; 118 private LiveData<Slice> mSettingsLiveData; 119 private Point mScreenSize; 120 private ViewGroup mPreviewContainer; 121 private TouchForwardingLayout mTouchForwardingLayout; 122 private SurfaceView mWallpaperSurface; 123 private Future<ColorInfo> mColorFuture; 124 private WallpaperColors mWallpaperColors; 125 126 @Override onCreate(Bundle savedInstanceState)127 public void onCreate(Bundle savedInstanceState) { 128 super.onCreate(savedInstanceState); 129 android.app.WallpaperInfo info = mWallpaper.getWallpaperComponent(); 130 mColorFuture = mWallpaper.computeColorInfo(getContext()); 131 132 String deleteAction = getDeleteAction(info); 133 if (!TextUtils.isEmpty(deleteAction)) { 134 mDeleteIntent = new Intent(deleteAction); 135 mDeleteIntent.setPackage(info.getPackageName()); 136 mDeleteIntent.putExtra(EXTRA_LIVE_WALLPAPER_INFO, info); 137 } 138 String settingsActivity = getSettingsActivity(info); 139 if (settingsActivity != null) { 140 mSettingsIntent = new Intent(); 141 mSettingsIntent.setComponent(new ComponentName(info.getPackageName(), 142 settingsActivity)); 143 mSettingsIntent.putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true); 144 PackageManager pm = requireContext().getPackageManager(); 145 ActivityInfo activityInfo = mSettingsIntent.resolveActivityInfo(pm, 0); 146 if (activityInfo == null) { 147 Log.i(TAG, "Couldn't find wallpaper settings activity: " + settingsActivity); 148 mSettingsIntent = null; 149 } 150 } 151 } 152 153 @Nullable getSettingsActivity(WallpaperInfo info)154 protected String getSettingsActivity(WallpaperInfo info) { 155 return info.getSettingsActivity(); 156 } 157 getWallpaperIntent(WallpaperInfo info)158 protected Intent getWallpaperIntent(WallpaperInfo info) { 159 return new Intent(WallpaperService.SERVICE_INTERFACE) 160 .setClassName(info.getPackageName(), info.getServiceName()); 161 } 162 163 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)164 public View onCreateView(LayoutInflater inflater, ViewGroup container, 165 Bundle savedInstanceState) { 166 View view = super.onCreateView(inflater, container, savedInstanceState); 167 168 Activity activity = requireActivity(); 169 mScreenSize = ScreenSizeCalculator.getInstance().getScreenSize( 170 activity.getWindowManager().getDefaultDisplay()); 171 mPreviewContainer = view.findViewById(R.id.container); 172 mTouchForwardingLayout = view.findViewById(R.id.touch_forwarding_layout); 173 174 // Update preview header color which covers toolbar and status bar area. 175 updatePreviewHeader(view); 176 177 // Set aspect ratio on the preview card. 178 ConstraintSet set = new ConstraintSet(); 179 set.clone((ConstraintLayout) mPreviewContainer); 180 String ratio = String.format(Locale.US, "%d:%d", mScreenSize.x, mScreenSize.y); 181 set.setDimensionRatio(mTouchForwardingLayout.getId(), ratio); 182 set.applyTo((ConstraintLayout) mPreviewContainer); 183 184 mHomePreviewCard = mPreviewContainer.findViewById(R.id.wallpaper_full_preview_card); 185 mLockPreviewContainer = mPreviewContainer.findViewById(R.id.lock_screen_preview_container); 186 mLockScreenPreviewer = new LockScreenPreviewer(getLifecycle(), getContext(), 187 mLockPreviewContainer); 188 mLockScreenPreviewer.setDateViewVisibility(!mFullScreenAnimation.isFullScreen()); 189 mFullScreenAnimation.setFullScreenStatusListener( 190 isFullScreen -> { 191 mLockScreenPreviewer.setDateViewVisibility(!isFullScreen); 192 if (!isFullScreen) { 193 mBottomActionBar.focusAccessibilityAction(EDIT); 194 } 195 }); 196 mWallpaperSurface = mHomePreviewCard.findViewById(R.id.wallpaper_surface); 197 mTouchForwardingLayout.setTargetView(mHomePreviewCard); 198 mTouchForwardingLayout.setForwardingEnabled(true); 199 mWorkspaceSurface = mHomePreviewCard.findViewById(R.id.workspace_surface); 200 201 mWorkspaceSurfaceCallback = createWorkspaceSurfaceCallback(mWorkspaceSurface); 202 mWallpaperSurfaceCallback = new WallpaperSurfaceCallback(getContext(), mHomePreviewCard, 203 mWallpaperSurface, mColorFuture, 204 new WallpaperSurfaceCallback.SurfaceListener() { 205 @Override 206 public void onSurfaceCreated() { 207 previewLiveWallpaper(null); 208 } 209 }); 210 211 setUpTabs(view.findViewById(R.id.separated_tabs)); 212 213 view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 214 @Override 215 public void onLayoutChange(View thisView, int left, int top, int right, int bottom, 216 int oldLeft, int oldTop, int oldRight, int oldBottom) { 217 mHomePreviewCard.setRadius(SizeCalculator.getPreviewCornerRadius(activity, 218 mHomePreviewCard.getMeasuredWidth())); 219 view.removeOnLayoutChangeListener(this); 220 } 221 }); 222 223 return view; 224 } 225 226 @Override onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)227 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 228 super.onViewCreated(view, savedInstanceState); 229 updateWallpaperSurface(); 230 setupCurrentWallpaperPreview(); 231 renderWorkspaceSurface(); 232 } 233 updateWallpaperSurface()234 private void updateWallpaperSurface() { 235 mWallpaperSurface.getHolder().addCallback(mWallpaperSurfaceCallback); 236 mWallpaperSurface.setZOrderMediaOverlay(true); 237 } 238 239 @Override updateScreenPreview(boolean isHomeSelected)240 protected void updateScreenPreview(boolean isHomeSelected) { 241 mWorkspaceSurface.setVisibility(isHomeSelected ? View.VISIBLE : View.INVISIBLE); 242 243 mLockPreviewContainer.setVisibility(isHomeSelected ? View.INVISIBLE : View.VISIBLE); 244 245 mFullScreenAnimation.setIsHomeSelected(isHomeSelected); 246 } 247 setupCurrentWallpaperPreview()248 private void setupCurrentWallpaperPreview() { 249 mHomePreviewCard.setOnTouchListener((v, ev) -> { 250 if (mWallpaperConnection != null && mWallpaperConnection.getEngine() != null) { 251 float scaleRatio = 252 (float) mTouchForwardingLayout.getWidth() / (float) mScreenSize.x; 253 int action = ev.getActionMasked(); 254 if (action == MotionEvent.ACTION_DOWN) { 255 mBottomActionBar.collapseBottomSheetIfExpanded(); 256 } 257 MotionEvent dup = MotionEvent.obtainNoHistory(ev); 258 dup.setLocation(ev.getX() / scaleRatio, ev.getY() / scaleRatio); 259 try { 260 mWallpaperConnection.getEngine().dispatchPointer(dup); 261 if (action == MotionEvent.ACTION_UP) { 262 mWallpaperConnection.getEngine().dispatchWallpaperCommand( 263 WallpaperManager.COMMAND_TAP, 264 (int) ev.getX(), (int) ev.getY(), 0, null); 265 } else if (action == MotionEvent.ACTION_POINTER_UP) { 266 int pointerIndex = ev.getActionIndex(); 267 mWallpaperConnection.getEngine().dispatchWallpaperCommand( 268 WallpaperManager.COMMAND_SECONDARY_TAP, 269 (int) ev.getX(pointerIndex), (int) ev.getY(pointerIndex), 0, null); 270 } 271 } catch (RemoteException e) { 272 Log.e(TAG, "Remote exception of wallpaper connection"); 273 } 274 } 275 return false; 276 }); 277 } 278 279 @Override onDestroyView()280 public void onDestroyView() { 281 super.onDestroyView(); 282 if (mSettingsLiveData != null && mSettingsLiveData.hasObservers() 283 && mSettingsSliceView != null) { 284 mSettingsLiveData.removeObserver(mSettingsSliceView); 285 mSettingsLiveData = null; 286 } 287 if (mWallpaperConnection != null) { 288 mWallpaperConnection.disconnect(); 289 mWallpaperConnection = null; 290 } 291 if (mLockScreenPreviewer != null) { 292 mLockScreenPreviewer.release(); 293 } 294 mWorkspaceSurfaceCallback.cleanUp(); 295 mWorkspaceSurface.getHolder().removeCallback(mWorkspaceSurfaceCallback); 296 mWallpaperSurfaceCallback.cleanUp(); 297 mWallpaperSurface.getHolder().removeCallback(mWallpaperSurfaceCallback); 298 } 299 previewLiveWallpaper(ImageView thumbnailView)300 protected void previewLiveWallpaper(ImageView thumbnailView) { 301 mWallpaperSurface.post(() -> { 302 Activity activity = getActivity(); 303 if (activity == null) { 304 return; 305 } 306 if (mWallpaperSurfaceCallback.getHomeImageWallpaper() != null) { 307 mWallpaperSurfaceCallback.setHomeImageWallpaperBlur(true); 308 ColorInfo colorInfo = getColorInfo(); 309 Integer placeholderColor = colorInfo.getPlaceholderColor(); 310 mWallpaper.getThumbAsset(activity.getApplicationContext()) 311 .loadLowResDrawable(activity, 312 mWallpaperSurfaceCallback.getHomeImageWallpaper(), 313 placeholderColor != null 314 ? placeholderColor 315 : ResourceUtils.getColorAttr(activity, 316 android.R.attr.colorBackground), 317 mPreviewBitmapTransformation); 318 } 319 setUpLiveWallpaperPreview(mWallpaper); 320 }); 321 } 322 getColorInfo()323 private ColorInfo getColorInfo() { 324 ColorInfo colorInfo = null; 325 try { 326 colorInfo = mColorFuture.get(50, TimeUnit.MILLISECONDS); 327 } catch (InterruptedException | ExecutionException | TimeoutException e) { 328 Log.i(TAG, "Couldn't obtain placeholder color", e); 329 } 330 if (colorInfo == null) { 331 colorInfo = new ColorInfo(new WallpaperColors(Color.valueOf(Color.TRANSPARENT), 332 /* secondaryColor= */ null, /* tertiaryColor= */ null), 333 /* placeholderColor= */ null); 334 } 335 return colorInfo; 336 } 337 setUpLiveWallpaperPreview( com.android.wallpaper.model.WallpaperInfo homeWallpaper)338 protected void setUpLiveWallpaperPreview( 339 com.android.wallpaper.model.WallpaperInfo homeWallpaper) { 340 Activity activity = getActivity(); 341 if (activity == null || activity.isFinishing()) { 342 return; 343 } 344 if (mWallpaperConnection != null) { 345 mWallpaperConnection.disconnect(); 346 } 347 348 if (WallpaperConnection.isPreviewAvailable()) { 349 mWallpaperConnection = new WallpaperConnection( 350 getWallpaperIntent(homeWallpaper.getWallpaperComponent()), 351 activity, 352 /* listener= */ this, 353 mWallpaperSurface); 354 355 mWallpaperConnection.setVisibility(true); 356 } else { 357 WallpaperColorsLoader.getWallpaperColors( 358 activity, 359 homeWallpaper.getThumbAsset(activity), 360 colors -> onWallpaperColorsChanged(colors, 0)); 361 } 362 if (mWallpaperConnection != null && !mWallpaperConnection.connect()) { 363 mWallpaperConnection = null; 364 } 365 } 366 renderWorkspaceSurface()367 private void renderWorkspaceSurface() { 368 mWorkspaceSurface.setZOrderMediaOverlay(true); 369 mWorkspaceSurface.getHolder().addCallback(mWorkspaceSurfaceCallback); 370 } 371 372 @Override onBottomActionBarReady(BottomActionBar bottomActionBar)373 protected void onBottomActionBarReady(BottomActionBar bottomActionBar) { 374 super.onBottomActionBarReady(bottomActionBar); 375 Activity activity = getActivity(); 376 LargeScreenMultiPanesChecker checker = new LargeScreenMultiPanesChecker(); 377 if (activity != null 378 && (activity.isInMultiWindowMode() || checker.isMultiPanesEnabled(getContext()))) { 379 mBottomActionBar.showActionsOnly(INFORMATION, DELETE, CUSTOMIZE, APPLY); 380 } else { 381 mBottomActionBar.showActionsOnly(INFORMATION, DELETE, EDIT, CUSTOMIZE, APPLY); 382 } 383 mBottomActionBar.setActionClickListener(APPLY, 384 unused -> onSetWallpaperClicked(null, mWallpaper)); 385 mBottomActionBar.bindBottomSheetContentWithAction( 386 new WallpaperInfoContent(getContext()), INFORMATION); 387 388 View separatedTabsContainer = getView().findViewById(R.id.separated_tabs_container); 389 // Update target view's accessibility param since it will be blocked by the bottom sheet 390 // when expanded. 391 mBottomActionBar.setAccessibilityCallback(new AccessibilityCallback() { 392 @Override 393 public void onBottomSheetCollapsed() { 394 mPreviewContainer.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); 395 separatedTabsContainer.setImportantForAccessibility( 396 IMPORTANT_FOR_ACCESSIBILITY_YES); 397 } 398 399 @Override 400 public void onBottomSheetExpanded() { 401 mPreviewContainer.setImportantForAccessibility( 402 IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); 403 separatedTabsContainer.setImportantForAccessibility( 404 IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); 405 } 406 }); 407 final Uri uriSettingsSlice = getSettingsSliceUri(mWallpaper.getWallpaperComponent()); 408 if (uriSettingsSlice != null) { 409 mSettingsLiveData = SliceLiveData.fromUri(requireContext(), uriSettingsSlice); 410 mBottomActionBar.bindBottomSheetContentWithAction( 411 new PreviewCustomizeSettingsContent(getContext()), CUSTOMIZE); 412 } else { 413 if (mSettingsIntent != null) { 414 mBottomActionBar.setActionClickListener(CUSTOMIZE, listener -> 415 startActivity(mSettingsIntent)); 416 } else { 417 mBottomActionBar.hideActions(CUSTOMIZE); 418 } 419 } 420 421 if (TextUtils.isEmpty(getDeleteAction(mWallpaper.getWallpaperComponent()))) { 422 mBottomActionBar.hideActions(DELETE); 423 } else { 424 mBottomActionBar.setActionClickListener(DELETE, listener -> 425 showDeleteConfirmDialog()); 426 } 427 mBottomActionBar.show(); 428 // Action buttons are disabled when live wallpaper is not loaded. 429 mBottomActionBar.disableActions(); 430 // Enable buttons if loaded, or wait for it. 431 if (isLoaded()) { 432 mBottomActionBar.enableActions(); 433 } 434 } 435 436 @Override onEngineShown()437 public void onEngineShown() { 438 Activity activity = getActivity(); 439 if (activity == null) { 440 return; 441 } 442 mWallpaperSurfaceCallback.getHomeImageWallpaper().animate() 443 .setStartDelay(250) 444 .setDuration(250) 445 .alpha(0f) 446 .setInterpolator(ALPHA_OUT) 447 .start(); 448 449 if (mBottomActionBar != null) { 450 mBottomActionBar.enableActions(); 451 } 452 } 453 454 @Override onWallpaperColorsChanged(WallpaperColors colors, int displayId)455 public void onWallpaperColorsChanged(WallpaperColors colors, int displayId) { 456 mWallpaperColors = colors; 457 mLockScreenPreviewer.setColor(colors); 458 459 mFullScreenAnimation.setFullScreenTextColor( 460 colors == null || (colors.getColorHints() 461 & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0 462 ? FullScreenAnimation.FullScreenTextColor.LIGHT 463 : FullScreenAnimation.FullScreenTextColor.DARK); 464 } 465 466 @Override isLoaded()467 protected boolean isLoaded() { 468 return mWallpaperConnection != null && mWallpaperConnection.isEngineReady(); 469 } 470 471 @SuppressLint("NewApi") //Already checking with isAtLeastQ getSettingsSliceUri(android.app.WallpaperInfo info)472 protected Uri getSettingsSliceUri(android.app.WallpaperInfo info) { 473 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { 474 return info.getSettingsSliceUri(); 475 } 476 return null; 477 } 478 479 @Override getLayoutResId()480 protected int getLayoutResId() { 481 return R.layout.fragment_live_preview; 482 } 483 484 @Override setCurrentWallpaper(int destination)485 protected void setCurrentWallpaper(int destination) { 486 mWallpaperSetter.setCurrentWallpaper(getActivity(), mWallpaper, null, 487 destination, 0, null, 488 mWallpaperColors != null ? mWallpaperColors : getColorInfo().getWallpaperColors(), 489 SetWallpaperViewModel.getCallback(mViewModelProvider)); 490 } 491 492 @Nullable getDeleteAction(android.app.WallpaperInfo wallpaperInfo)493 protected String getDeleteAction(android.app.WallpaperInfo wallpaperInfo) { 494 android.app.WallpaperInfo currentInfo = 495 WallpaperManager.getInstance(requireContext()).getWallpaperInfo(); 496 ServiceInfo serviceInfo = wallpaperInfo.getServiceInfo(); 497 if (!isPackagePreInstalled(serviceInfo.applicationInfo)) { 498 Log.d(TAG, "This wallpaper is not pre-installed: " + serviceInfo.name); 499 return null; 500 } 501 502 ServiceInfo currentService = currentInfo == null ? null : currentInfo.getServiceInfo(); 503 // A currently set Live wallpaper should not be deleted. 504 if (currentService != null && TextUtils.equals(serviceInfo.name, currentService.name)) { 505 return null; 506 } 507 508 final Bundle metaData = serviceInfo.metaData; 509 if (metaData != null) { 510 return metaData.getString(KEY_ACTION_DELETE_LIVE_WALLPAPER); 511 } 512 return null; 513 } 514 515 @Override onResume()516 public void onResume() { 517 super.onResume(); 518 if (mWallpaperConnection != null) { 519 mWallpaperConnection.setVisibility(true); 520 } 521 } 522 523 @Override onPause()524 public void onPause() { 525 super.onPause(); 526 if (mWallpaperConnection != null) { 527 mWallpaperConnection.setVisibility(false); 528 } 529 } 530 531 @Override onStop()532 public void onStop() { 533 super.onStop(); 534 if (mWallpaperConnection != null) { 535 mWallpaperConnection.disconnect(); 536 mWallpaperConnection = null; 537 } 538 } 539 showDeleteConfirmDialog()540 private void showDeleteConfirmDialog() { 541 final AlertDialog alertDialog = new AlertDialog.Builder(getContext()) 542 .setMessage(R.string.delete_wallpaper_confirmation) 543 .setOnDismissListener(dialog -> mBottomActionBar.deselectAction(DELETE)) 544 .setPositiveButton(R.string.delete_live_wallpaper, 545 (dialog, which) -> deleteLiveWallpaper()) 546 .setNegativeButton(android.R.string.cancel, null /* listener */) 547 .create(); 548 alertDialog.show(); 549 } 550 deleteLiveWallpaper()551 private void deleteLiveWallpaper() { 552 if (mDeleteIntent != null) { 553 requireContext().startService(mDeleteIntent); 554 finishActivity(/* success= */ false); 555 } 556 } 557 isPackagePreInstalled(ApplicationInfo info)558 private boolean isPackagePreInstalled(ApplicationInfo info) { 559 return info != null && (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 560 } 561 562 private final class PreviewCustomizeSettingsContent extends BottomSheetContent<View> { 563 PreviewCustomizeSettingsContent(Context context)564 private PreviewCustomizeSettingsContent(Context context) { 565 super(context); 566 } 567 568 @Override getViewId()569 public int getViewId() { 570 return R.layout.preview_customize_settings; 571 } 572 573 @Override onViewCreated(View previewPage)574 public void onViewCreated(View previewPage) { 575 mSettingsSliceView = previewPage.findViewById(R.id.settings_slice); 576 mSettingsSliceView.setMode(SliceView.MODE_LARGE); 577 mSettingsSliceView.setScrollable(false); 578 if (mSettingsLiveData != null) { 579 mSettingsLiveData.observeForever(mSettingsSliceView); 580 } 581 } 582 583 @Override onRecreateView(View oldPreviewPage)584 public void onRecreateView(View oldPreviewPage) { 585 super.onRecreateView(oldPreviewPage); 586 if (mSettingsLiveData != null && mSettingsLiveData.hasObservers() 587 && mSettingsSliceView != null) { 588 mSettingsLiveData.removeObserver(mSettingsSliceView); 589 } 590 } 591 } 592 } 593