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