WallpaperUtils.java revision 748dfe025b128ea88ba626c8bfb7da315d5af29c
1748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal/* 2748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * Copyright (C) 2015 The Android Open Source Project 3748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * 4748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * Licensed under the Apache License, Version 2.0 (the "License"); 5748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * you may not use this file except in compliance with the License. 6748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * You may obtain a copy of the License at 7748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * 8748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * http://www.apache.org/licenses/LICENSE-2.0 9748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * 10748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * Unless required by applicable law or agreed to in writing, software 11748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * distributed under the License is distributed on an "AS IS" BASIS, 12748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * See the License for the specific language governing permissions and 14748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * limitations under the License. 15748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal */ 16748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 17748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalpackage com.android.wallpaperpicker; 18748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 19748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.annotation.TargetApi; 20748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.app.Activity; 21748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.app.WallpaperManager; 22748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.content.Context; 23748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.content.SharedPreferences; 24748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.content.res.Resources; 25748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.graphics.Point; 26748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.os.Build; 27748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.view.View; 28748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalimport android.view.WindowManager; 29748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 30748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal/** 31748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * Utility methods for wallpaper management. 32748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal */ 33748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyalpublic final class WallpaperUtils { 34748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 35748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal public static final String WALLPAPER_WIDTH_KEY = "wallpaper.width"; 36748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal public static final String WALLPAPER_HEIGHT_KEY = "wallpaper.height"; 37748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal public static final float WALLPAPER_SCREENS_SPAN = 2f; 38748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 39748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal public static void saveWallpaperDimensions(int width, int height, Activity activity) { 40748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 41748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // From Kitkat onwards, ImageWallpaper does not care about the 42748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // desired width and desired height of the wallpaper. 43748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal return; 44748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 45748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal String spKey = WallpaperFiles.WALLPAPER_CROP_PREFERENCES_KEY; 46748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal SharedPreferences sp = activity.getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS); 47748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal SharedPreferences.Editor editor = sp.edit(); 48748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (width != 0 && height != 0) { 49748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal editor.putInt(WALLPAPER_WIDTH_KEY, width); 50748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal editor.putInt(WALLPAPER_HEIGHT_KEY, height); 51748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } else { 52748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal editor.remove(WALLPAPER_WIDTH_KEY); 53748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal editor.remove(WALLPAPER_HEIGHT_KEY); 54748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 55748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal editor.commit(); 56748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal suggestWallpaperDimensionPreK(activity, true); 57748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 58748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 59748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal public static void suggestWallpaperDimensionPreK( 60748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal Activity activity, boolean fallBackToDefaults) { 61748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final Point defaultWallpaperSize = getDefaultWallpaperSize( 62748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal activity.getResources(), activity.getWindowManager()); 63748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 64748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal SharedPreferences sp = activity.getSharedPreferences( 65748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal WallpaperFiles.WALLPAPER_CROP_PREFERENCES_KEY, Context.MODE_MULTI_PROCESS); 66748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // If we have saved a wallpaper width/height, use that instead 67748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal int width = sp.getInt(WALLPAPER_WIDTH_KEY, -1); 68748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal int height = sp.getInt(WALLPAPER_HEIGHT_KEY, -1); 69748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 70748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (width == -1 || height == -1) { 71748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (!fallBackToDefaults) { 72748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal return; 73748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } else { 74748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal width = defaultWallpaperSize.x; 75748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal height = defaultWallpaperSize.y; 76748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 77748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 78748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 79748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal WallpaperManager wm = WallpaperManager.getInstance(activity); 80748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (width != wm.getDesiredMinimumWidth() || height != wm.getDesiredMinimumHeight()) { 81748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal wm.suggestDesiredDimensions(width, height); 82748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 83748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 84748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 85748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal public static void suggestWallpaperDimension(Activity activity) { 86748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // Only live wallpapers care about desired size. Update the size to what launcher expects. 87748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final Point size = getDefaultWallpaperSize( 88748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal activity.getResources(), activity.getWindowManager()); 89748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal WallpaperManager wm = WallpaperManager.getInstance(activity); 90748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (size.x != wm.getDesiredMinimumWidth() || size.y != wm.getDesiredMinimumHeight()) { 91748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal wm.suggestDesiredDimensions(size.x, size.y); 92748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 93748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 94748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 95748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal /** 96748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * As a ratio of screen height, the total distance we want the parallax effect to span 97748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal * horizontally 98748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal */ 99748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal private static float wallpaperTravelToScreenWidthRatio(int width, int height) { 100748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal float aspectRatio = width / (float) height; 101748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 102748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // At an aspect ratio of 16/10, the wallpaper parallax effect should span 1.5 * screen width 103748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // At an aspect ratio of 10/16, the wallpaper parallax effect should span 1.2 * screen width 104748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // We will use these two data points to extrapolate how much the wallpaper parallax effect 105748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // to span (ie travel) at any aspect ratio: 106748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 107748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final float ASPECT_RATIO_LANDSCAPE = 16/10f; 108748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final float ASPECT_RATIO_PORTRAIT = 10/16f; 109748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f; 110748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f; 111748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 112748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // To find out the desired width at different aspect ratios, we use the following two 113748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // formulas, where the coefficient on x is the aspect ratio (width/height): 114748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // (16/10)x + y = 1.5 115748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // (10/16)x + y = 1.2 116748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // We solve for x and y and end up with a final formula: 117748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final float x = 118748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) / 119748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal (ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT); 120748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT; 121748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal return x * aspectRatio + y; 122748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 123748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 124748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal private static Point sDefaultWallpaperSize; 125748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 126748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 127748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal public static Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) { 128748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (sDefaultWallpaperSize == null) { 129748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal Point realSize = new Point(); 130748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal windowManager.getDefaultDisplay().getRealSize(realSize); 131748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal int maxDim = Math.max(realSize.x, realSize.y); 132748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal int minDim = Math.min(realSize.x, realSize.y); 133748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 134748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // We need to ensure that there is enough extra space in the wallpaper 135748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal // for the intended parallax effects 136748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal final int defaultWidth, defaultHeight; 137748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal if (res.getConfiguration().smallestScreenWidthDp >= 720) { 138748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim)); 139748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal defaultHeight = maxDim; 140748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } else { 141748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim); 142748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal defaultHeight = maxDim; 143748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 144748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight); 145748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 146748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal return sDefaultWallpaperSize; 147748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 148748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal 149748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 150748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal public static boolean isRtl(Resources res) { 151748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && 152748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal (res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL); 153748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal } 154748dfe025b128ea88ba626c8bfb7da315d5af29cSunny Goyal} 155