• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.wallpaperpicker;
18 
19 import android.annotation.TargetApi;
20 import android.app.Activity;
21 import android.app.WallpaperManager;
22 import android.content.Context;
23 import android.content.SharedPreferences;
24 import android.content.res.Resources;
25 import android.graphics.Point;
26 import android.os.Build;
27 import android.view.View;
28 import android.view.WindowManager;
29 
30 /**
31  * Utility methods for wallpaper management.
32  */
33 public final class WallpaperUtils {
34 
35     public static final String WALLPAPER_WIDTH_KEY = "wallpaper.width";
36     public static final String WALLPAPER_HEIGHT_KEY = "wallpaper.height";
37 
38     // An intent extra to indicate the horizontal scroll of the wallpaper.
39     public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET";
40 
41     public static final float WALLPAPER_SCREENS_SPAN = 2f;
42 
saveWallpaperDimensions(int width, int height, Activity activity)43     public static void saveWallpaperDimensions(int width, int height, Activity activity) {
44         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
45             // From Kitkat onwards, ImageWallpaper does not care about the
46             // desired width and desired height of the wallpaper.
47             return;
48         }
49         String spKey = WallpaperFiles.WALLPAPER_CROP_PREFERENCES_KEY;
50         SharedPreferences sp = activity.getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
51         SharedPreferences.Editor editor = sp.edit();
52         if (width != 0 && height != 0) {
53             editor.putInt(WALLPAPER_WIDTH_KEY, width);
54             editor.putInt(WALLPAPER_HEIGHT_KEY, height);
55         } else {
56             editor.remove(WALLPAPER_WIDTH_KEY);
57             editor.remove(WALLPAPER_HEIGHT_KEY);
58         }
59         editor.commit();
60         suggestWallpaperDimensionPreK(activity, true);
61     }
62 
suggestWallpaperDimensionPreK( Activity activity, boolean fallBackToDefaults)63     public static void suggestWallpaperDimensionPreK(
64             Activity activity, boolean fallBackToDefaults) {
65         final Point defaultWallpaperSize = getDefaultWallpaperSize(
66                 activity.getResources(), activity.getWindowManager());
67 
68         SharedPreferences sp = activity.getSharedPreferences(
69               WallpaperFiles.WALLPAPER_CROP_PREFERENCES_KEY, Context.MODE_MULTI_PROCESS);
70         // If we have saved a wallpaper width/height, use that instead
71         int width = sp.getInt(WALLPAPER_WIDTH_KEY, -1);
72         int height = sp.getInt(WALLPAPER_HEIGHT_KEY, -1);
73 
74         if (width == -1 || height == -1) {
75             if (!fallBackToDefaults) {
76                 return;
77             } else {
78                 width = defaultWallpaperSize.x;
79                 height = defaultWallpaperSize.y;
80             }
81         }
82 
83         WallpaperManager wm = WallpaperManager.getInstance(activity);
84         if (width != wm.getDesiredMinimumWidth() || height != wm.getDesiredMinimumHeight()) {
85             wm.suggestDesiredDimensions(width, height);
86         }
87     }
88 
suggestWallpaperDimension(Activity activity)89     public static void suggestWallpaperDimension(Activity activity) {
90         // Only live wallpapers care about desired size. Update the size to what launcher expects.
91         final Point size = getDefaultWallpaperSize(
92                 activity.getResources(), activity.getWindowManager());
93         WallpaperManager wm = WallpaperManager.getInstance(activity);
94         if (size.x != wm.getDesiredMinimumWidth() || size.y != wm.getDesiredMinimumHeight()) {
95             wm.suggestDesiredDimensions(size.x, size.y);
96         }
97     }
98 
99     /**
100      * As a ratio of screen height, the total distance we want the parallax effect to span
101      * horizontally
102      */
wallpaperTravelToScreenWidthRatio(int width, int height)103     private static float wallpaperTravelToScreenWidthRatio(int width, int height) {
104         float aspectRatio = width / (float) height;
105 
106         // At an aspect ratio of 16/10, the wallpaper parallax effect should span 1.5 * screen width
107         // At an aspect ratio of 10/16, the wallpaper parallax effect should span 1.2 * screen width
108         // We will use these two data points to extrapolate how much the wallpaper parallax effect
109         // to span (ie travel) at any aspect ratio:
110 
111         final float ASPECT_RATIO_LANDSCAPE = 16/10f;
112         final float ASPECT_RATIO_PORTRAIT = 10/16f;
113         final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f;
114         final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f;
115 
116         // To find out the desired width at different aspect ratios, we use the following two
117         // formulas, where the coefficient on x is the aspect ratio (width/height):
118         //   (16/10)x + y = 1.5
119         //   (10/16)x + y = 1.2
120         // We solve for x and y and end up with a final formula:
121         final float x =
122             (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) /
123             (ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT);
124         final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT;
125         return x * aspectRatio + y;
126     }
127 
128     private static Point sDefaultWallpaperSize;
129 
130     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
getDefaultWallpaperSize(Resources res, WindowManager windowManager)131     public static Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
132         if (sDefaultWallpaperSize == null) {
133             Point realSize = new Point();
134             windowManager.getDefaultDisplay().getRealSize(realSize);
135             int maxDim = Math.max(realSize.x, realSize.y);
136             int minDim = Math.min(realSize.x, realSize.y);
137 
138             // We need to ensure that there is enough extra space in the wallpaper
139             // for the intended parallax effects
140             final int defaultWidth, defaultHeight;
141             if (res.getConfiguration().smallestScreenWidthDp >= 720) {
142                 defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
143                 defaultHeight = maxDim;
144             } else {
145                 defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
146                 defaultHeight = maxDim;
147             }
148             sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight);
149         }
150         return sDefaultWallpaperSize;
151     }
152 
153     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
isRtl(Resources res)154     public static boolean isRtl(Resources res) {
155         return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 &&
156                 (res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
157     }
158 }
159