18890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette/* 28890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Copyright (C) 2015 The Android Open Source Project 38890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * 48890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 58890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * you may not use this file except in compliance with the License. 68890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * You may obtain a copy of the License at 78890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * 88890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * http://www.apache.org/licenses/LICENSE-2.0 98890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * 108890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Unless required by applicable law or agreed to in writing, software 118890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 128890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * See the License for the specific language governing permissions and 148890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * limitations under the License. 158890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette */ 168890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 178890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverettepackage com.android.settingslib.display; 188890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 198890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport com.android.settingslib.R; 208890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 218890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.content.Context; 228890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.content.res.Resources; 238890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.os.AsyncTask; 248890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.os.RemoteException; 258890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.util.DisplayMetrics; 268890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.util.Log; 278890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.util.MathUtils; 288890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.view.Display; 298890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.view.IWindowManager; 308890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport android.view.WindowManagerGlobal; 318890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 328890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viveretteimport java.util.Arrays; 338890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 348890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette/** 358890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Utility methods for working with display density. 368890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette */ 378890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverettepublic class DisplayDensityUtils { 388890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static final String LOG_TAG = "DisplayDensityUtils"; 398890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 408890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** Minimum increment between density scales. */ 418890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static final float MIN_SCALE_INTERVAL = 0.09f; 428890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 438890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** Minimum density scale. This is available on all devices. */ 448890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static final float MIN_SCALE = 0.85f; 458890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 468890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** Maximum density scale. The actual scale used depends on the device. */ 478890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static final float MAX_SCALE = 1.50f; 488890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 498890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** Summary used for "default" scale. */ 508890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public static final int SUMMARY_DEFAULT = R.string.screen_zoom_summary_default; 518890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 528890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** Summary used for "custom" scale. */ 538890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static final int SUMMARY_CUSTOM = R.string.screen_zoom_summary_custom; 548890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 558890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** 568890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Summaries for scales smaller than "default" in order of smallest to 578890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * largest. 588890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette */ 598890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static final int[] SUMMARIES_SMALLER = new int[] { 608890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette R.string.screen_zoom_summary_small 618890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette }; 628890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 638890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** 648890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Summaries for scales larger than "default" in order of smallest to 658890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * largest. 668890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette */ 678890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static final int[] SUMMARIES_LARGER = new int[] { 688890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette R.string.screen_zoom_summary_large, 698890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette R.string.screen_zoom_summary_very_large, 708890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette R.string.screen_zoom_summary_extremely_large, 718890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette }; 728890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 738890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** 748890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Minimum allowed screen dimension, corresponds to resource qualifiers 758890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * "small" or "sw320dp". This value must be at least the minimum screen 768890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * size required by the CDD so that we meet developer expectations. 778890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette */ 788890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static final int MIN_DIMENSION_DP = 320; 798890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 808890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private final String[] mEntries; 818890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private final int[] mValues; 828890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 838890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private final int mDefaultDensity; 848890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private final int mCurrentIndex; 858890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 868890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public DisplayDensityUtils(Context context) { 878890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int defaultDensity = DisplayDensityUtils.getDefaultDisplayDensity( 888890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette Display.DEFAULT_DISPLAY); 898890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette if (defaultDensity <= 0) { 908890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette mEntries = null; 918890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette mValues = null; 928890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette mDefaultDensity = 0; 938890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette mCurrentIndex = -1; 948890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette return; 958890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 968890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 978890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final Resources res = context.getResources(); 988890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final DisplayMetrics metrics = res.getDisplayMetrics(); 998890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int currentDensity = metrics.densityDpi; 1008890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette int currentDensityIndex = -1; 1018890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1028890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette // Compute number of "larger" and "smaller" scales for this display. 1038890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int minDimensionPx = Math.min(metrics.widthPixels, metrics.heightPixels); 1048890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP; 1058890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final float maxScale = Math.min(MAX_SCALE, maxDensity / (float) defaultDensity); 1068890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final float minScale = MIN_SCALE; 1078890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int numLarger = (int) MathUtils.constrain((maxScale - 1) / MIN_SCALE_INTERVAL, 1088890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 0, SUMMARIES_LARGER.length); 1098890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int numSmaller = (int) MathUtils.constrain((1 - minScale) / MIN_SCALE_INTERVAL, 1108890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 0, SUMMARIES_SMALLER.length); 1118890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1128890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette String[] entries = new String[1 + numSmaller + numLarger]; 1138890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette int[] values = new int[entries.length]; 1148890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette int curIndex = 0; 1158890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1168890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette if (numSmaller > 0) { 1178890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final float interval = (1 - minScale) / numSmaller; 1188890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette for (int i = numSmaller - 1; i >= 0; i--) { 1198890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette // Round down to a multiple of 2 by truncating the low bit. 1208890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int density = ((int) (defaultDensity * (1 - (i + 1) * interval))) & ~1; 1218890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette if (currentDensity == density) { 1228890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette currentDensityIndex = curIndex; 1238890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1248890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette entries[curIndex] = res.getString(SUMMARIES_SMALLER[i]); 1258890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette values[curIndex] = density; 1268890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette curIndex++; 1278890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1288890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1298890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1308890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette if (currentDensity == defaultDensity) { 1318890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette currentDensityIndex = curIndex; 1328890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1338890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette values[curIndex] = defaultDensity; 1348890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette entries[curIndex] = res.getString(SUMMARY_DEFAULT); 1358890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette curIndex++; 1368890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1378890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette if (numLarger > 0) { 1388890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final float interval = (maxScale - 1) / numLarger; 1398890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette for (int i = 0; i < numLarger; i++) { 1408890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette // Round down to a multiple of 2 by truncating the low bit. 1418890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int density = ((int) (defaultDensity * (1 + (i + 1) * interval))) & ~1; 1428890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette if (currentDensity == density) { 1438890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette currentDensityIndex = curIndex; 1448890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1458890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette values[curIndex] = density; 1468890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette entries[curIndex] = res.getString(SUMMARIES_LARGER[i]); 1478890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette curIndex++; 1488890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1498890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1508890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1518890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final int displayIndex; 1528890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette if (currentDensityIndex >= 0) { 1538890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette displayIndex = currentDensityIndex; 1548890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } else { 1558890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette // We don't understand the current density. Must have been set by 1568890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette // someone else. Make room for another entry... 1578890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette int newLength = values.length + 1; 1588890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette values = Arrays.copyOf(values, newLength); 1598890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette values[curIndex] = currentDensity; 1608890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1618890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette entries = Arrays.copyOf(entries, newLength); 1628890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette entries[curIndex] = res.getString(SUMMARY_CUSTOM, currentDensity); 1638890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1648890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette displayIndex = curIndex; 1658890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1668890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1678890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette mDefaultDensity = defaultDensity; 1688890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette mCurrentIndex = displayIndex; 1698890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette mEntries = entries; 1708890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette mValues = values; 1718890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1728890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1738890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public String[] getEntries() { 1748890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette return mEntries; 1758890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1768890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1778890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public int[] getValues() { 1788890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette return mValues; 1798890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1808890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1818890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public int getCurrentIndex() { 1828890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette return mCurrentIndex; 1838890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1848890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1858890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public int getDefaultDensity() { 1868890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette return mDefaultDensity; 1878890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 1888890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 1898890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** 1908890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Returns the default density for the specified display. 1918890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * 1928890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * @param displayId the identifier of the display 1938890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * @return the default density of the specified display, or {@code -1} if 1948890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * the display does not exist or the density could not be obtained 1958890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette */ 1968890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette private static int getDefaultDisplayDensity(int displayId) { 1978890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette try { 1988890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); 1998890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette return wm.getInitialDisplayDensity(displayId); 2008890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } catch (RemoteException exc) { 2018890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette return -1; 2028890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 2038890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 2048890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 2058890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** 2068890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Asynchronously applies display density changes to the specified display. 2078890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * 2088890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * @param displayId the identifier of the display to modify 2098890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette */ 2108890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public static void clearForcedDisplayDensity(final int displayId) { 2118890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette AsyncTask.execute(new Runnable() { 2128890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette @Override 2138890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public void run() { 2148890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette try { 2158890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); 2168890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette wm.clearForcedDisplayDensity(displayId); 2178890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } catch (RemoteException exc) { 2188890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette Log.w(LOG_TAG, "Unable to clear forced display density setting"); 2198890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 2208890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 2218890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette }); 2228890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 2238890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette 2248890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette /** 2258890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * Asynchronously applies display density changes to the specified display. 2268890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * 2278890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * @param displayId the identifier of the display to modify 2288890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette * @param density the density to force for the specified display 2298890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette */ 2308890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public static void setForcedDisplayDensity(final int displayId, final int density) { 2318890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette AsyncTask.execute(new Runnable() { 2328890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette @Override 2338890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette public void run() { 2348890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette try { 2358890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); 2368890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette wm.setForcedDisplayDensity(displayId, density); 2378890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } catch (RemoteException exc) { 2388890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette Log.w(LOG_TAG, "Unable to save forced display density setting"); 2398890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 2408890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 2418890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette }); 2428890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette } 2438890cfa67f4dec6ee2916dd4c92494fd2901fc06Alan Viverette} 244