19189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima/* 29189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * Copyright (C) 2006 The Android Open Source Project 39189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * 49189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * Licensed under the Apache License, Version 2.0 (the "License"); 59189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * you may not use this file except in compliance with the License. 69189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * You may obtain a copy of the License at 79189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * 89189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * http://www.apache.org/licenses/LICENSE-2.0 99189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * 109189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * Unless required by applicable law or agreed to in writing, software 119189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * distributed under the License is distributed on an "AS IS" BASIS, 129189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * See the License for the specific language governing permissions and 149189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * limitations under the License. 159189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima */ 169189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 179189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshimapackage android.content.res; 189189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 199189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshimaimport android.content.pm.ApplicationInfo; 2064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.graphics.Canvas; 21a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tateimport android.graphics.PointF; 2264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.graphics.Rect; 2364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.graphics.Region; 24e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackbornimport android.os.Parcel; 25e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackbornimport android.os.Parcelable; 269189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshimaimport android.util.DisplayMetrics; 2764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.view.MotionEvent; 2864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.view.WindowManager; 2964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.view.WindowManager.LayoutParams; 309189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 319189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima/** 329189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * CompatibilityInfo class keeps the information about compatibility mode that the application is 339189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * running under. 349189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * 359189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * {@hide} 369189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima */ 37e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackbornpublic class CompatibilityInfo implements Parcelable { 389189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima /** default compatibility info object for compatible applications */ 395a2b91dc14e4c92e91c6abcc795f54ac98ee5866Mitsuru Oshima public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo() { 405a2b91dc14e4c92e91c6abcc795f54ac98ee5866Mitsuru Oshima }; 419189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 429189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima /** 43e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn * This is the number of pixels we would like to have along the 44e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn * short axis of an app that needs to run on a normal size screen. 459189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima */ 46e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public static final int DEFAULT_NORMAL_SHORT_DIMENSION = 320; 479189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 489189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima /** 49e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn * This is the maximum aspect ratio we will allow while keeping 50e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn * applications in a compatible screen size. 51e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn */ 52e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public static final float MAXIMUM_ASPECT_RATIO = (854f/480f); 539189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 549189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima /** 5564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * A compatibility flags 569189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima */ 57e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn private final int mCompatibilityFlags; 589189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 599189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima /** 6064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * A flag mask to tell if the application needs scaling (when mApplicationScale != 1.0f) 6164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * {@see compatibilityFlag} 6264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 6364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima private static final int SCALING_REQUIRED = 1; 6464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 6564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 660f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn * Application must always run in compatibility mode? 670f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn */ 688ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn private static final int ALWAYS_NEEDS_COMPAT = 2; 690f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 700f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn /** 710f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn * Application never should run in compatibility mode? 720f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn */ 738ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn private static final int NEVER_NEEDS_COMPAT = 4; 740f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 750f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn /** 76e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn * Set if the application needs to run in screen size compatibility mode. 7714cee9f688c32d63d8521188e7422811629bb7c2Dianne Hackborn */ 788ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn private static final int NEEDS_SCREEN_COMPAT = 8; 7964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 8064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 812784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn * The effective screen density we have selected for this application. 822784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn */ 832784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn public final int applicationDensity; 842784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn 852784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn /** 8664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Application's scale. 879189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima */ 8864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public final float applicationScale; 89e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima 90e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima /** 9164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Application's inverted scale. 92e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima */ 9364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public final float applicationInvertedScale; 9464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 95df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw, 96df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn boolean forceCompat) { 97e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn int compatFlags = 0; 98e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 992762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn if (appInfo.requiresSmallestWidthDp != 0 || appInfo.compatibleWidthLimitDp != 0 1002762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn || appInfo.largestWidthLimitDp != 0) { 101df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // New style screen requirements spec. 102df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn int required = appInfo.requiresSmallestWidthDp != 0 103df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn ? appInfo.requiresSmallestWidthDp 104df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn : appInfo.compatibleWidthLimitDp; 1052762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn if (required == 0) { 1062762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn required = appInfo.largestWidthLimitDp; 1072762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn } 108df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn int compat = appInfo.compatibleWidthLimitDp != 0 1092762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn ? appInfo.compatibleWidthLimitDp : required; 110df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if (compat < required) { 111df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn compat = required; 112e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 1132762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn int largest = appInfo.largestWidthLimitDp; 1142762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn 1152762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn if (required > DEFAULT_NORMAL_SHORT_DIMENSION) { 1162762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // For now -- if they require a size larger than the only 1172762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // size we can do in compatibility mode, then don't ever 1182762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // allow the app to go in to compat mode. Trying to run 1192762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // it at a smaller size it can handle will make it far more 1202762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // broken than running at a larger size than it wants or 1212762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // thinks it can handle. 1222762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn compatFlags |= NEVER_NEEDS_COMPAT; 1232762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn } else if (largest != 0 && sw > largest) { 1242762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // If the screen size is larger than the largest size the 1252762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // app thinks it can work with, then always force it in to 1262762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // compatibility mode. 1272762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn compatFlags |= NEEDS_SCREEN_COMPAT | ALWAYS_NEEDS_COMPAT; 1282762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn } else if (compat >= sw) { 1292762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // The screen size is something the app says it was designed 1302762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // for, so never do compatibility mode. 1318ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn compatFlags |= NEVER_NEEDS_COMPAT; 132df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } else if (forceCompat) { 1332762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // The app may work better with or without compatibility mode. 1342762ff3dc864018352362f6d103de471f9529ba6Dianne Hackborn // Let the user decide. 135df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn compatFlags |= NEEDS_SCREEN_COMPAT; 13636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 1375be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn 138df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // Modern apps always support densities. 139df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationDensity = DisplayMetrics.DENSITY_DEVICE; 140df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationScale = 1.0f; 141df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationInvertedScale = 1.0f; 142e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 143df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } else { 1448ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn /** 1458ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn * Has the application said that its UI is expandable? Based on the 1468ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn * <supports-screen> android:expandible in the manifest. 1478ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn */ 1488ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn final int EXPANDABLE = 2; 1498ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 1508ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn /** 1518ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn * Has the application said that its UI supports large screens? Based on the 1528ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn * <supports-screen> android:largeScreens in the manifest. 1538ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn */ 1548ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn final int LARGE_SCREENS = 8; 1558ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 1568ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn /** 1578ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn * Has the application said that its UI supports xlarge screens? Based on the 1588ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn * <supports-screen> android:xlargeScreens in the manifest. 1598ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn */ 1608ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn final int XLARGE_SCREENS = 32; 1618ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 1628ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn int sizeInfo = 0; 1638ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 164df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // We can't rely on the application always setting 165df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // FLAG_RESIZEABLE_FOR_SCREENS so will compute it based on various input. 166df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn boolean anyResizeable = false; 167df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn 168df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { 1698ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sizeInfo |= LARGE_SCREENS; 170df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn anyResizeable = true; 171df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if (!forceCompat) { 172df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // If we aren't forcing the app into compatibility mode, then 173df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // assume if it supports large screens that we should allow it 174df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // to use the full space of an xlarge screen as well. 1758ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sizeInfo |= XLARGE_SCREENS | EXPANDABLE; 176e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 177df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 178df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { 179df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn anyResizeable = true; 180df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if (!forceCompat) { 1818ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sizeInfo |= XLARGE_SCREENS | EXPANDABLE; 1820f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 183df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 184df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { 185df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn anyResizeable = true; 1868ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sizeInfo |= EXPANDABLE; 187df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 188df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn 189df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if (forceCompat) { 190df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // If we are forcing compatibility mode, then ignore an app that 191df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // just says it is resizable for screens. We'll only have it fill 192df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // the screen if it explicitly says it supports the screen size we 193df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn // are running in. 1948ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sizeInfo &= ~EXPANDABLE; 195df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 196df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn 1978ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn compatFlags |= NEEDS_SCREEN_COMPAT; 198df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn switch (screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK) { 199df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn case Configuration.SCREENLAYOUT_SIZE_XLARGE: 2008ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if ((sizeInfo&XLARGE_SCREENS) != 0) { 2018ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn compatFlags &= ~NEEDS_SCREEN_COMPAT; 202df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 203df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { 2048ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn compatFlags |= NEVER_NEEDS_COMPAT; 205df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 206df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn break; 207df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn case Configuration.SCREENLAYOUT_SIZE_LARGE: 2088ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if ((sizeInfo&LARGE_SCREENS) != 0) { 2098ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn compatFlags &= ~NEEDS_SCREEN_COMPAT; 210df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 211df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { 2128ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn compatFlags |= NEVER_NEEDS_COMPAT; 213df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 214df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn break; 215df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 216df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn 217df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) != 0) { 2188ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if ((sizeInfo&EXPANDABLE) != 0) { 2198ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn compatFlags &= ~NEEDS_SCREEN_COMPAT; 220df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } else if (!anyResizeable) { 2218ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn compatFlags |= ALWAYS_NEEDS_COMPAT; 222e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 22339ec8fb9572b6f7a6c3dbc135f32f2a8cbcd640fDianne Hackborn } else { 22439ec8fb9572b6f7a6c3dbc135f32f2a8cbcd640fDianne Hackborn compatFlags &= ~NEEDS_SCREEN_COMPAT; 22539ec8fb9572b6f7a6c3dbc135f32f2a8cbcd640fDianne Hackborn compatFlags |= NEVER_NEEDS_COMPAT; 226df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 227e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 228df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { 229df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationDensity = DisplayMetrics.DENSITY_DEVICE; 230df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationScale = 1.0f; 231df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationInvertedScale = 1.0f; 232df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } else { 233df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationDensity = DisplayMetrics.DENSITY_DEFAULT; 234df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationScale = DisplayMetrics.DENSITY_DEVICE 235df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn / (float) DisplayMetrics.DENSITY_DEFAULT; 236df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn applicationInvertedScale = 1.0f / applicationScale; 237df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn compatFlags |= SCALING_REQUIRED; 238df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn } 2399189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima } 240e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 241e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn mCompatibilityFlags = compatFlags; 2429189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima } 2439189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 244e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn private CompatibilityInfo(int compFlags, 2452784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn int dens, float scale, float invertedScale) { 246569076c9f6bdadb4d3285a26e069634a839b5b87Mitsuru Oshima mCompatibilityFlags = compFlags; 2472784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn applicationDensity = dens; 248569076c9f6bdadb4d3285a26e069634a839b5b87Mitsuru Oshima applicationScale = scale; 249569076c9f6bdadb4d3285a26e069634a839b5b87Mitsuru Oshima applicationInvertedScale = invertedScale; 250569076c9f6bdadb4d3285a26e069634a839b5b87Mitsuru Oshima } 251569076c9f6bdadb4d3285a26e069634a839b5b87Mitsuru Oshima 2529189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima private CompatibilityInfo() { 2538ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn this(NEVER_NEEDS_COMPAT, DisplayMetrics.DENSITY_DEVICE, 254569076c9f6bdadb4d3285a26e069634a839b5b87Mitsuru Oshima 1.0f, 255569076c9f6bdadb4d3285a26e069634a839b5b87Mitsuru Oshima 1.0f); 2569189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima } 2579189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima 25864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 25964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * @return true if the scaling is required 26064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 26164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public boolean isScalingRequired() { 2628ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn return (mCompatibilityFlags&SCALING_REQUIRED) != 0; 26364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 26464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 2651ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima public boolean supportsScreen() { 266e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return (mCompatibilityFlags&NEEDS_SCREEN_COMPAT) == 0; 2671ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima } 2681ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima 2690f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn public boolean neverSupportsScreen() { 2702f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn return (mCompatibilityFlags&ALWAYS_NEEDS_COMPAT) != 0; 2710f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2720f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 2730f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn public boolean alwaysSupportsScreen() { 2742f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn return (mCompatibilityFlags&NEVER_NEEDS_COMPAT) != 0; 27564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 27664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 27764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 278589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima * Returns the translator which translates the coordinates in compatibility mode. 27964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * @param params the window's parameter 28064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 281589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima public Translator getTranslator() { 282589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima return isScalingRequired() ? new Translator() : null; 28364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 28464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 28564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 28664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * A helper object to translate the screen and window coordinates back and forth. 28764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * @hide 28864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 28964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public class Translator { 29064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima final public float applicationScale; 29164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima final public float applicationInvertedScale; 29264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 29364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima private Rect mContentInsetsBuffer = null; 2941ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima private Rect mVisibleInsetsBuffer = null; 295fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown private Region mTouchableAreaBuffer = null; 29664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 2971ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima Translator(float applicationScale, float applicationInvertedScale) { 29864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima this.applicationScale = applicationScale; 29964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima this.applicationInvertedScale = applicationInvertedScale; 30064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 30164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 30264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima Translator() { 3031ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima this(CompatibilityInfo.this.applicationScale, 3041ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima CompatibilityInfo.this.applicationInvertedScale); 30564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 30664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 30764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 30864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate the screen rect to the application frame. 30964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 31064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public void translateRectInScreenToAppWinFrame(Rect rect) { 3111ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima rect.scale(applicationInvertedScale); 31264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 31364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 31464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 31564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate the region in window to screen. 31664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 31764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public void translateRegionInWindowToScreen(Region transparentRegion) { 3181ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima transparentRegion.scale(applicationScale); 31964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 32064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 32164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 32264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Apply translation to the canvas that is necessary to draw the content. 32364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 32464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public void translateCanvas(Canvas canvas) { 325b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed if (applicationScale == 1.5f) { 326b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed /* When we scale for compatibility, we can put our stretched 327b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed bitmaps and ninepatches on exacty 1/2 pixel boundaries, 328b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed which can give us inconsistent drawing due to imperfect 329b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed float precision in the graphics engine's inverse matrix. 330b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed 331b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed As a work-around, we translate by a tiny amount to avoid 332b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed landing on exact pixel centers and boundaries, giving us 333b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed the slop we need to draw consistently. 334b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed 335b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed This constant is meant to resolve to 1/255 after it is 336b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed scaled by 1.5 (applicationScale). Note, this is just a guess 337b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed as to what is small enough not to create its own artifacts, 338b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed and big enough to avoid the precision problems. Feel free 339b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed to experiment with smaller values as you choose. 340b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed */ 341b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed final float tinyOffset = 2.0f / (3 * 255); 342b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed canvas.translate(tinyOffset, tinyOffset); 343b5c17a64edbdac47d8aa48951b50ea0a8e982655Mike Reed } 3441ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima canvas.scale(applicationScale, applicationScale); 34564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 34664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 34764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 34864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate the motion event captured on screen to the application's window. 34964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 35064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public void translateEventInScreenToAppWindow(MotionEvent event) { 3511ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima event.scale(applicationInvertedScale); 35264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 35364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 35464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 35564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate the window's layout parameter, from application's view to 35664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Screen's view. 35764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 35864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public void translateWindowLayout(WindowManager.LayoutParams params) { 3591ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima params.scale(applicationScale); 36064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 36164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 36264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 36364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate a Rect in application's window to screen. 36464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 36564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public void translateRectInAppWindowToScreen(Rect rect) { 3661ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima rect.scale(applicationScale); 36764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 36864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 36964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 37064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate a Rect in screen coordinates into the app window's coordinates. 37164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 37264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public void translateRectInScreenToAppWindow(Rect rect) { 3731ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima rect.scale(applicationInvertedScale); 37464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 37564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 37664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 377a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * Translate a Point in screen coordinates into the app window's coordinates. 378a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate */ 379a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate public void translatePointInScreenToAppWindow(PointF point) { 380a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate final float scale = applicationInvertedScale; 381a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate if (scale != 1.0f) { 382a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate point.x *= scale; 383a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate point.y *= scale; 384a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate } 385a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate } 386a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate 387a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate /** 38864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate the location of the sub window. 38964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * @param params 39064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 39164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public void translateLayoutParamsInAppWindowToScreen(LayoutParams params) { 3921ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima params.scale(applicationScale); 39364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 39464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 39564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 39664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate the content insets in application window to Screen. This uses 39764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * the internal buffer for content insets to avoid extra object allocation. 39864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 39964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima public Rect getTranslatedContentInsets(Rect contentInsets) { 40064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima if (mContentInsetsBuffer == null) mContentInsetsBuffer = new Rect(); 40164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima mContentInsetsBuffer.set(contentInsets); 40264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima translateRectInAppWindowToScreen(mContentInsetsBuffer); 40364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima return mContentInsetsBuffer; 40464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 40564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 40664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima /** 40764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima * Translate the visible insets in application window to Screen. This uses 408fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * the internal buffer for visible insets to avoid extra object allocation. 40964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima */ 410fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown public Rect getTranslatedVisibleInsets(Rect visibleInsets) { 4111ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima if (mVisibleInsetsBuffer == null) mVisibleInsetsBuffer = new Rect(); 4121ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima mVisibleInsetsBuffer.set(visibleInsets); 4131ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima translateRectInAppWindowToScreen(mVisibleInsetsBuffer); 4141ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima return mVisibleInsetsBuffer; 4151ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima } 416fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown 417fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown /** 418fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * Translate the touchable area in application window to Screen. This uses 419fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * the internal buffer for touchable area to avoid extra object allocation. 420fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown */ 421fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown public Region getTranslatedTouchableArea(Region touchableArea) { 422fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown if (mTouchableAreaBuffer == null) mTouchableAreaBuffer = new Region(); 423fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown mTouchableAreaBuffer.set(touchableArea); 424fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown mTouchableAreaBuffer.scale(applicationScale); 425fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown return mTouchableAreaBuffer; 426fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown } 4271ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima } 4281ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima 429e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public void applyToDisplayMetrics(DisplayMetrics inoutDm) { 430e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (!supportsScreen()) { 431e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn // This is a larger screen device and the app is not 432e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn // compatible with large screens, so diddle it. 4332f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn CompatibilityInfo.computeCompatibleScaling(inoutDm, inoutDm); 4345be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn } else { 4352b31d53161789358de57fd396716a6503855c5daDianne Hackborn inoutDm.widthPixels = inoutDm.noncompatWidthPixels; 4362b31d53161789358de57fd396716a6503855c5daDianne Hackborn inoutDm.heightPixels = inoutDm.noncompatHeightPixels; 437e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 438e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 439e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (isScalingRequired()) { 440e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn float invertedRatio = applicationInvertedScale; 4412b31d53161789358de57fd396716a6503855c5daDianne Hackborn inoutDm.density = inoutDm.noncompatDensity * invertedRatio; 442908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn inoutDm.densityDpi = (int)((inoutDm.noncompatDensityDpi * invertedRatio) + .5f); 4432b31d53161789358de57fd396716a6503855c5daDianne Hackborn inoutDm.scaledDensity = inoutDm.noncompatScaledDensity * invertedRatio; 4442b31d53161789358de57fd396716a6503855c5daDianne Hackborn inoutDm.xdpi = inoutDm.noncompatXdpi * invertedRatio; 4452b31d53161789358de57fd396716a6503855c5daDianne Hackborn inoutDm.ydpi = inoutDm.noncompatYdpi * invertedRatio; 446e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn inoutDm.widthPixels = (int) (inoutDm.widthPixels * invertedRatio + 0.5f); 447e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn inoutDm.heightPixels = (int) (inoutDm.heightPixels * invertedRatio + 0.5f); 448e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 449e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 450e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 451908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn public void applyToConfiguration(int displayDensity, Configuration inoutConfig) { 452e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (!supportsScreen()) { 453e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn // This is a larger screen device and the app is not 454e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn // compatible with large screens, so we are forcing it to 455e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn // run as if the screen is normal size. 456e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn inoutConfig.screenLayout = 457e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn (inoutConfig.screenLayout&~Configuration.SCREENLAYOUT_SIZE_MASK) 458e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn | Configuration.SCREENLAYOUT_SIZE_NORMAL; 4595fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackborn inoutConfig.screenWidthDp = inoutConfig.compatScreenWidthDp; 4605fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackborn inoutConfig.screenHeightDp = inoutConfig.compatScreenHeightDp; 4615fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackborn inoutConfig.smallestScreenWidthDp = inoutConfig.compatSmallestScreenWidthDp; 462e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 463908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn inoutConfig.densityDpi = displayDensity; 464908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn if (isScalingRequired()) { 465908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn float invertedRatio = applicationInvertedScale; 466908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn inoutConfig.densityDpi = (int)((inoutConfig.densityDpi * invertedRatio) + .5f); 467908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn } 468e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 469e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 4701ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima /** 471e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn * Compute the frame Rect for applications runs under compatibility mode. 4721ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima * 4731ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima * @param dm the display metrics used to compute the frame size. 47448d0d1886731ff19ed3fb47a5997be5df0d1bba8Craig Mautner * @param outDm If non-null the width and height will be set to their scaled values. 475e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn * @return Returns the scaling factor for the window. 4761ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima */ 4772f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn public static float computeCompatibleScaling(DisplayMetrics dm, DisplayMetrics outDm) { 4782b31d53161789358de57fd396716a6503855c5daDianne Hackborn final int width = dm.noncompatWidthPixels; 4792b31d53161789358de57fd396716a6503855c5daDianne Hackborn final int height = dm.noncompatHeightPixels; 480e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn int shortSize, longSize; 481e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (width < height) { 482e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn shortSize = width; 483e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn longSize = height; 484e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } else { 485e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn shortSize = height; 486e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn longSize = width; 487e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 488e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn int newShortSize = (int)(DEFAULT_NORMAL_SHORT_DIMENSION * dm.density + 0.5f); 489e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn float aspect = ((float)longSize) / shortSize; 490e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (aspect > MAXIMUM_ASPECT_RATIO) { 491e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn aspect = MAXIMUM_ASPECT_RATIO; 492e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 493e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn int newLongSize = (int)(newShortSize * aspect + 0.5f); 494e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn int newWidth, newHeight; 495e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (width < height) { 496e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn newWidth = newShortSize; 497e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn newHeight = newLongSize; 4981ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima } else { 499e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn newWidth = newLongSize; 500e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn newHeight = newShortSize; 501e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 502e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 503e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn float sw = width/(float)newWidth; 504e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn float sh = height/(float)newHeight; 505e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn float scale = sw < sh ? sw : sh; 506e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (scale < 1) { 507e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn scale = 1; 50864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 509e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 510e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (outDm != null) { 511e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn outDm.widthPixels = newWidth; 512e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn outDm.heightPixels = newHeight; 513e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 514e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 515e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return scale; 516e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 517e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 518e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn @Override 519e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public boolean equals(Object o) { 52048d0d1886731ff19ed3fb47a5997be5df0d1bba8Craig Mautner if (this == o) { 52148d0d1886731ff19ed3fb47a5997be5df0d1bba8Craig Mautner return true; 52248d0d1886731ff19ed3fb47a5997be5df0d1bba8Craig Mautner } 523e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn try { 524e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn CompatibilityInfo oc = (CompatibilityInfo)o; 525e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (mCompatibilityFlags != oc.mCompatibilityFlags) return false; 526e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (applicationDensity != oc.applicationDensity) return false; 527e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (applicationScale != oc.applicationScale) return false; 528e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn if (applicationInvertedScale != oc.applicationInvertedScale) return false; 529e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return true; 530e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } catch (ClassCastException e) { 531e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return false; 532e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 533e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 534e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 535e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn @Override 5368ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn public String toString() { 5378ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn StringBuilder sb = new StringBuilder(128); 5388ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sb.append("{"); 5398ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sb.append(applicationDensity); 5408ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sb.append("dpi"); 5418ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if (isScalingRequired()) { 5422b31d53161789358de57fd396716a6503855c5daDianne Hackborn sb.append(" "); 5432b31d53161789358de57fd396716a6503855c5daDianne Hackborn sb.append(applicationScale); 5442b31d53161789358de57fd396716a6503855c5daDianne Hackborn sb.append("x"); 5458ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 5468ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if (!supportsScreen()) { 5478ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sb.append(" resizing"); 5488ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 5498ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if (neverSupportsScreen()) { 5508ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sb.append(" never-compat"); 5518ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 5528ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if (alwaysSupportsScreen()) { 5538ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sb.append(" always-compat"); 5548ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 5558ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn sb.append("}"); 5568ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn return sb.toString(); 5578ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 5588ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 5598ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn @Override 560e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public int hashCode() { 561e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn int result = 17; 562e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn result = 31 * result + mCompatibilityFlags; 563e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn result = 31 * result + applicationDensity; 564e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn result = 31 * result + Float.floatToIntBits(applicationScale); 565e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn result = 31 * result + Float.floatToIntBits(applicationInvertedScale); 566e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return result; 567e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 568e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 569e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn @Override 570e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public int describeContents() { 571e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return 0; 572e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 573e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 574e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn @Override 575e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public void writeToParcel(Parcel dest, int flags) { 576e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn dest.writeInt(mCompatibilityFlags); 577e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn dest.writeInt(applicationDensity); 578e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn dest.writeFloat(applicationScale); 579e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn dest.writeFloat(applicationInvertedScale); 580e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 581e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 582e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public static final Parcelable.Creator<CompatibilityInfo> CREATOR 583e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn = new Parcelable.Creator<CompatibilityInfo>() { 58448d0d1886731ff19ed3fb47a5997be5df0d1bba8Craig Mautner @Override 585e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public CompatibilityInfo createFromParcel(Parcel source) { 586e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return new CompatibilityInfo(source); 587e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 588e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 58948d0d1886731ff19ed3fb47a5997be5df0d1bba8Craig Mautner @Override 590e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn public CompatibilityInfo[] newArray(int size) { 591e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return new CompatibilityInfo[size]; 592e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 593e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn }; 594e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 595e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn private CompatibilityInfo(Parcel source) { 596e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn mCompatibilityFlags = source.readInt(); 597e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn applicationDensity = source.readInt(); 598e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn applicationScale = source.readFloat(); 599e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn applicationInvertedScale = source.readFloat(); 6009189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima } 601569076c9f6bdadb4d3285a26e069634a839b5b87Mitsuru Oshima} 602