1 /* 2 * Copyright (C) 2015 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 17 package com.android.launcher3.util; 18 19 import android.annotation.TargetApi; 20 import android.app.WallpaperManager; 21 import android.content.SharedPreferences; 22 import android.content.res.Resources; 23 import android.graphics.Point; 24 import android.os.Build; 25 import android.view.WindowManager; 26 27 import com.android.launcher3.Utilities; 28 29 /** 30 * Utility methods for wallpaper management. 31 */ 32 public final class WallpaperUtils { 33 34 public static final String WALLPAPER_WIDTH_KEY = "wallpaper.width"; 35 public static final String WALLPAPER_HEIGHT_KEY = "wallpaper.height"; 36 public static final float WALLPAPER_SCREENS_SPAN = 2f; 37 suggestWallpaperDimension(Resources res, final SharedPreferences sharedPrefs, WindowManager windowManager, final WallpaperManager wallpaperManager, boolean fallBackToDefaults)38 public static void suggestWallpaperDimension(Resources res, 39 final SharedPreferences sharedPrefs, 40 WindowManager windowManager, 41 final WallpaperManager wallpaperManager, boolean fallBackToDefaults) { 42 final Point defaultWallpaperSize = WallpaperUtils.getDefaultWallpaperSize(res, windowManager); 43 // If we have saved a wallpaper width/height, use that instead 44 45 int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, -1); 46 int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, -1); 47 48 if (savedWidth == -1 || savedHeight == -1) { 49 if (!fallBackToDefaults) { 50 return; 51 } else { 52 savedWidth = defaultWallpaperSize.x; 53 savedHeight = defaultWallpaperSize.y; 54 } 55 } 56 57 if (savedWidth != wallpaperManager.getDesiredMinimumWidth() || 58 savedHeight != wallpaperManager.getDesiredMinimumHeight()) { 59 wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight); 60 } 61 } 62 63 /** 64 * As a ratio of screen height, the total distance we want the parallax effect to span 65 * horizontally 66 */ wallpaperTravelToScreenWidthRatio(int width, int height)67 public static float wallpaperTravelToScreenWidthRatio(int width, int height) { 68 float aspectRatio = width / (float) height; 69 70 // At an aspect ratio of 16/10, the wallpaper parallax effect should span 1.5 * screen width 71 // At an aspect ratio of 10/16, the wallpaper parallax effect should span 1.2 * screen width 72 // We will use these two data points to extrapolate how much the wallpaper parallax effect 73 // to span (ie travel) at any aspect ratio: 74 75 final float ASPECT_RATIO_LANDSCAPE = 16/10f; 76 final float ASPECT_RATIO_PORTRAIT = 10/16f; 77 final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f; 78 final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f; 79 80 // To find out the desired width at different aspect ratios, we use the following two 81 // formulas, where the coefficient on x is the aspect ratio (width/height): 82 // (16/10)x + y = 1.5 83 // (10/16)x + y = 1.2 84 // We solve for x and y and end up with a final formula: 85 final float x = 86 (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) / 87 (ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT); 88 final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT; 89 return x * aspectRatio + y; 90 } 91 92 private static Point sDefaultWallpaperSize; 93 94 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) getDefaultWallpaperSize(Resources res, WindowManager windowManager)95 public static Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) { 96 if (sDefaultWallpaperSize == null) { 97 Point minDims = new Point(); 98 Point maxDims = new Point(); 99 windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims); 100 101 int maxDim = Math.max(maxDims.x, maxDims.y); 102 int minDim = Math.max(minDims.x, minDims.y); 103 104 if (Utilities.ATLEAST_JB_MR1) { 105 Point realSize = new Point(); 106 windowManager.getDefaultDisplay().getRealSize(realSize); 107 maxDim = Math.max(realSize.x, realSize.y); 108 minDim = Math.min(realSize.x, realSize.y); 109 } 110 111 // We need to ensure that there is enough extra space in the wallpaper 112 // for the intended parallax effects 113 final int defaultWidth, defaultHeight; 114 if (res.getConfiguration().smallestScreenWidthDp >= 720) { 115 defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim)); 116 defaultHeight = maxDim; 117 } else { 118 defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim); 119 defaultHeight = maxDim; 120 } 121 sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight); 122 } 123 return sDefaultWallpaperSize; 124 } 125 } 126