Home | History | Annotate | Download | only in util
      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