1c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner/* 2c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * Copyright (C) 2014 The Android Open Source Project 3c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * 4c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * Licensed under the Apache License, Version 2.0 (the "License"); 5c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * you may not use this file except in compliance with the License. 6c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * You may obtain a copy of the License at 7c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * 8c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * http://www.apache.org/licenses/LICENSE-2.0 9c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * 10c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * Unless required by applicable law or agreed to in writing, software 11c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * distributed under the License is distributed on an "AS IS" BASIS, 12c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * See the License for the specific language governing permissions and 14c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner * limitations under the License. 15c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner */ 16c2c0a61cf5f779b4726f089f28d966c03ccbba54Craig Mautner 170f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornpackage com.android.server.am; 180f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 190f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport java.io.File; 200f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport java.io.FileInputStream; 210f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport java.io.FileOutputStream; 2236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport java.util.HashMap; 230f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport java.util.Iterator; 2436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport java.util.Map; 250f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 260f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport org.xmlpull.v1.XmlPullParser; 270f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport org.xmlpull.v1.XmlPullParserException; 280f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport org.xmlpull.v1.XmlSerializer; 290f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 300f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport com.android.internal.util.FastXmlSerializer; 310f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 320f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.app.ActivityManager; 330f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.app.AppGlobals; 340f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.content.pm.ApplicationInfo; 350f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.content.pm.IPackageManager; 360f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.content.res.CompatibilityInfo; 370f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.os.Handler; 386f357d3284a833cc50a990e14b39f389b8972254Jeff Brownimport android.os.Looper; 390f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.os.Message; 400f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.os.RemoteException; 4139606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackbornimport android.util.AtomicFile; 420f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.util.Slog; 430f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.util.Xml; 440f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 45be4e6aaa0252dd7da28b7aa85beba982538efa46Dianne Hackbornpublic final class CompatModePackages { 460f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn private final String TAG = ActivityManagerService.TAG; 470f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn private final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION; 480f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 490f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn private final ActivityManagerService mService; 500f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn private final AtomicFile mFile; 510f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 5236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn // Compatibility state: no longer ask user to select the mode. 5336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public static final int COMPAT_FLAG_DONT_ASK = 1<<0; 5436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn // Compatibility state: compatibility mode is enabled. 5536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public static final int COMPAT_FLAG_ENABLED = 1<<1; 5636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 5736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>(); 580f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 5940c8db5a28e9abae2033facce1354e3677911fccDianne Hackborn private static final int MSG_WRITE = ActivityManagerService.FIRST_COMPAT_MODE_MSG; 600f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 616f357d3284a833cc50a990e14b39f389b8972254Jeff Brown private final CompatHandler mHandler; 626f357d3284a833cc50a990e14b39f389b8972254Jeff Brown 636f357d3284a833cc50a990e14b39f389b8972254Jeff Brown private final class CompatHandler extends Handler { 646f357d3284a833cc50a990e14b39f389b8972254Jeff Brown public CompatHandler(Looper looper) { 656f357d3284a833cc50a990e14b39f389b8972254Jeff Brown super(looper, null, true); 666f357d3284a833cc50a990e14b39f389b8972254Jeff Brown } 676f357d3284a833cc50a990e14b39f389b8972254Jeff Brown 686f357d3284a833cc50a990e14b39f389b8972254Jeff Brown @Override 696f357d3284a833cc50a990e14b39f389b8972254Jeff Brown public void handleMessage(Message msg) { 700f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn switch (msg.what) { 710f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn case MSG_WRITE: 720f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn saveCompatModes(); 730f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn break; 740f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 750f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 760f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn }; 770f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 786f357d3284a833cc50a990e14b39f389b8972254Jeff Brown public CompatModePackages(ActivityManagerService service, File systemDir, Handler handler) { 790f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn mService = service; 800f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn mFile = new AtomicFile(new File(systemDir, "packages-compat.xml")); 816f357d3284a833cc50a990e14b39f389b8972254Jeff Brown mHandler = new CompatHandler(handler.getLooper()); 820f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 830f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn FileInputStream fis = null; 840f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn try { 850f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn fis = mFile.openRead(); 860f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn XmlPullParser parser = Xml.newPullParser(); 870f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn parser.setInput(fis, null); 880f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn int eventType = parser.getEventType(); 892ac3cb7aef7c8a51cbeb6d34b648dedcb4363994Narayan Kamath while (eventType != XmlPullParser.START_TAG && 902ac3cb7aef7c8a51cbeb6d34b648dedcb4363994Narayan Kamath eventType != XmlPullParser.END_DOCUMENT) { 910f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn eventType = parser.next(); 920f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 932ac3cb7aef7c8a51cbeb6d34b648dedcb4363994Narayan Kamath if (eventType == XmlPullParser.END_DOCUMENT) { 942ac3cb7aef7c8a51cbeb6d34b648dedcb4363994Narayan Kamath return; 952ac3cb7aef7c8a51cbeb6d34b648dedcb4363994Narayan Kamath } 962ac3cb7aef7c8a51cbeb6d34b648dedcb4363994Narayan Kamath 970f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn String tagName = parser.getName(); 980f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if ("compat-packages".equals(tagName)) { 990f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn eventType = parser.next(); 1000f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn do { 1010f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (eventType == XmlPullParser.START_TAG) { 1020f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn tagName = parser.getName(); 1030f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (parser.getDepth() == 2) { 1040f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if ("pkg".equals(tagName)) { 1050f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn String pkg = parser.getAttributeValue(null, "name"); 1060f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (pkg != null) { 10736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn String mode = parser.getAttributeValue(null, "mode"); 10836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn int modeInt = 0; 10936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (mode != null) { 11036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn try { 11136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn modeInt = Integer.parseInt(mode); 11236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } catch (NumberFormatException e) { 11336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 11436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 11536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mPackages.put(pkg, modeInt); 1160f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1170f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1180f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1190f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1200f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn eventType = parser.next(); 1210f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } while (eventType != XmlPullParser.END_DOCUMENT); 1220f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1230f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } catch (XmlPullParserException e) { 1240f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn Slog.w(TAG, "Error reading compat-packages", e); 1250f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } catch (java.io.IOException e) { 1260f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (fis != null) Slog.w(TAG, "Error reading compat-packages", e); 1270f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } finally { 1280f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (fis != null) { 1290f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn try { 1300f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn fis.close(); 1310f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } catch (java.io.IOException e1) { 1320f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1330f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1340f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1350f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1360f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 13736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public HashMap<String, Integer> getPackages() { 1380f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return mPackages; 1390f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1400f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 14136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private int getPackageFlags(String packageName) { 14236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn Integer flags = mPackages.get(packageName); 14336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn return flags != null ? flags : 0; 14436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 14536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 1468ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn public void handlePackageAddedLocked(String packageName, boolean updated) { 1478ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn ApplicationInfo ai = null; 1488ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn try { 149483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0); 1508ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } catch (RemoteException e) { 1518ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 1528ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if (ai == null) { 1538ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn return; 1548ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 1558ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai); 1568ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn final boolean mayCompat = !ci.alwaysSupportsScreen() 1578ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn && !ci.neverSupportsScreen(); 1588ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 159a9551706a279a798c91d8ef593b2acb16a30c682Dianne Hackborn if (updated) { 1608ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn // Update -- if the app no longer can run in compat mode, clear 1618ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn // any current settings for it. 1628ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if (!mayCompat && mPackages.containsKey(packageName)) { 1638ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn mPackages.remove(packageName); 1648ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn mHandler.removeMessages(MSG_WRITE); 1658ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn Message msg = mHandler.obtainMessage(MSG_WRITE); 1668ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn mHandler.sendMessageDelayed(msg, 10000); 1678ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 1688ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 1698ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 1708ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 1710f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 1722f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn CompatibilityInfo ci = new CompatibilityInfo(ai, mService.mConfiguration.screenLayout, 173df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn mService.mConfiguration.smallestScreenWidthDp, 17436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0); 1752f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn //Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci); 1762f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn return ci; 1770f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1780f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 17936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public int computeCompatModeLocked(ApplicationInfo ai) { 18036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0; 1810f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn CompatibilityInfo info = new CompatibilityInfo(ai, 182df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn mService.mConfiguration.screenLayout, 183df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn mService.mConfiguration.smallestScreenWidthDp, enabled); 1840f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (info.alwaysSupportsScreen()) { 1850f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return ActivityManager.COMPAT_MODE_NEVER; 1860f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1870f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (info.neverSupportsScreen()) { 1880f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return ActivityManager.COMPAT_MODE_ALWAYS; 1890f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1900f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return enabled ? ActivityManager.COMPAT_MODE_ENABLED 1910f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn : ActivityManager.COMPAT_MODE_DISABLED; 1920f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 1930f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 19436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public boolean getFrontActivityAskCompatModeLocked() { 195ce5f3cba6b95e1fbc800c0fc43d13bb830e87423Craig Mautner ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null); 19636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (r == null) { 19736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn return false; 19836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 19936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn return getPackageAskCompatModeLocked(r.packageName); 20036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 20136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 20236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public boolean getPackageAskCompatModeLocked(String packageName) { 20336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn return (getPackageFlags(packageName)&COMPAT_FLAG_DONT_ASK) == 0; 20436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 20536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 20636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public void setFrontActivityAskCompatModeLocked(boolean ask) { 207ce5f3cba6b95e1fbc800c0fc43d13bb830e87423Craig Mautner ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null); 20836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (r != null) { 20936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn setPackageAskCompatModeLocked(r.packageName, ask); 21036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 21136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 21236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 21336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public void setPackageAskCompatModeLocked(String packageName, boolean ask) { 21436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn int curFlags = getPackageFlags(packageName); 21536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn int newFlags = ask ? (curFlags&~COMPAT_FLAG_DONT_ASK) : (curFlags|COMPAT_FLAG_DONT_ASK); 21636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (curFlags != newFlags) { 21736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (newFlags != 0) { 21836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mPackages.put(packageName, newFlags); 21936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } else { 22036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mPackages.remove(packageName); 22136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 22236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mHandler.removeMessages(MSG_WRITE); 22336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn Message msg = mHandler.obtainMessage(MSG_WRITE); 22436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mHandler.sendMessageDelayed(msg, 10000); 22536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 22636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 22736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 2280f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn public int getFrontActivityScreenCompatModeLocked() { 229ce5f3cba6b95e1fbc800c0fc43d13bb830e87423Craig Mautner ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null); 2300f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (r == null) { 2310f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return ActivityManager.COMPAT_MODE_UNKNOWN; 2320f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2330f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return computeCompatModeLocked(r.info.applicationInfo); 2340f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2350f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 2360f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn public void setFrontActivityScreenCompatModeLocked(int mode) { 237ce5f3cba6b95e1fbc800c0fc43d13bb830e87423Craig Mautner ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null); 2380f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (r == null) { 2390f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity"); 2400f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return; 2410f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2420f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn setPackageScreenCompatModeLocked(r.info.applicationInfo, mode); 2430f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2440f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 2450f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn public int getPackageScreenCompatModeLocked(String packageName) { 2460f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn ApplicationInfo ai = null; 2470f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn try { 248483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0); 2490f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } catch (RemoteException e) { 2500f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2510f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (ai == null) { 2520f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return ActivityManager.COMPAT_MODE_UNKNOWN; 2530f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2540f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return computeCompatModeLocked(ai); 2550f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2560f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 2570f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn public void setPackageScreenCompatModeLocked(String packageName, int mode) { 2580f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn ApplicationInfo ai = null; 2590f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn try { 260483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0); 2610f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } catch (RemoteException e) { 2620f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2630f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (ai == null) { 2640f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn Slog.w(TAG, "setPackageScreenCompatMode failed: unknown package " + packageName); 2650f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return; 2660f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2670f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn setPackageScreenCompatModeLocked(ai, mode); 2680f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 2690f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 2700f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn private void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) { 2710f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn final String packageName = ai.packageName; 2720f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 27336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn int curFlags = getPackageFlags(packageName); 27436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 2750f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn boolean enable; 2760f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn switch (mode) { 2770f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn case ActivityManager.COMPAT_MODE_DISABLED: 2780f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn enable = false; 2790f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn break; 2800f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn case ActivityManager.COMPAT_MODE_ENABLED: 2810f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn enable = true; 2820f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn break; 2830f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn case ActivityManager.COMPAT_MODE_TOGGLE: 28436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn enable = (curFlags&COMPAT_FLAG_ENABLED) == 0; 2850f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn break; 2860f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn default: 2870f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn Slog.w(TAG, "Unknown screen compat mode req #" + mode + "; ignoring"); 2880f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn return; 2890f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 29036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 29136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn int newFlags = curFlags; 2920f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (enable) { 29336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn newFlags |= COMPAT_FLAG_ENABLED; 2940f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } else { 29536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn newFlags &= ~COMPAT_FLAG_ENABLED; 29636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 29736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 2988ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai); 2998ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if (ci.alwaysSupportsScreen()) { 3008ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn Slog.w(TAG, "Ignoring compat mode change of " + packageName 3018ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn + "; compatibility never needed"); 3028ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn newFlags = 0; 3038ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 3048ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn if (ci.neverSupportsScreen()) { 3058ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn Slog.w(TAG, "Ignoring compat mode change of " + packageName 3068ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn + "; compatibility always needed"); 3078ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn newFlags = 0; 3088ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn } 3098ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 31036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (newFlags != curFlags) { 31136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (newFlags != 0) { 31236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mPackages.put(packageName, newFlags); 31336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } else { 3140f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn mPackages.remove(packageName); 3150f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3168ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 3178ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn // Need to get compatibility info in new state. 3188ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn ci = compatibilityInfoForPackageLocked(ai); 3190f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 3200f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn mHandler.removeMessages(MSG_WRITE); 3210f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn Message msg = mHandler.obtainMessage(MSG_WRITE); 3220f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn mHandler.sendMessageDelayed(msg, 10000); 3230f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 324ce5f3cba6b95e1fbc800c0fc43d13bb830e87423Craig Mautner final ActivityStack stack = mService.getFocusedStack(); 32520e7227454bf6f3500c6eb97a17483dd8b764341Craig Mautner ActivityRecord starting = stack.restartPackage(packageName); 3268ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn 3270f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn // Tell all processes that loaded this package about the change. 3280f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn for (int i=mService.mLruProcesses.size()-1; i>=0; i--) { 3290f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn ProcessRecord app = mService.mLruProcesses.get(i); 33078a369c90f61981c9d0ddd5fcbc77202bfbe74f6Dianne Hackborn if (!app.pkgList.containsKey(packageName)) { 3310f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn continue; 3320f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3330f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn try { 3340f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (app.thread != null) { 3350f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 3360f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn + app.processName + " new compat " + ci); 3370f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn app.thread.updatePackageCompatibilityInfo(packageName, ci); 3380f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3390f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } catch (Exception e) { 3400f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3410f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3420f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 3430f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (starting != null) { 34420e7227454bf6f3500c6eb97a17483dd8b764341Craig Mautner stack.ensureActivityConfigurationLocked(starting, 0); 3450f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn // And we need to make sure at this point that all other activities 3460f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn // are made visible with the correct configuration. 34720e7227454bf6f3500c6eb97a17483dd8b764341Craig Mautner stack.ensureActivitiesVisibleLocked(starting, 0); 3480f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3490f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3500f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3510f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 3520f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn void saveCompatModes() { 35336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn HashMap<String, Integer> pkgs; 3540f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn synchronized (mService) { 35536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn pkgs = new HashMap<String, Integer>(mPackages); 3560f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3570f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 3580f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn FileOutputStream fos = null; 3590f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 3600f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn try { 3610f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn fos = mFile.startWrite(); 3620f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn XmlSerializer out = new FastXmlSerializer(); 3630f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.setOutput(fos, "utf-8"); 3640f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.startDocument(null, true); 3650f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 3660f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.startTag(null, "compat-packages"); 3670f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 3680f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn final IPackageManager pm = AppGlobals.getPackageManager(); 3690f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn final int screenLayout = mService.mConfiguration.screenLayout; 370df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn final int smallestScreenWidthDp = mService.mConfiguration.smallestScreenWidthDp; 37136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn final Iterator<Map.Entry<String, Integer>> it = pkgs.entrySet().iterator(); 3720f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn while (it.hasNext()) { 37336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn Map.Entry<String, Integer> entry = it.next(); 37436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn String pkg = entry.getKey(); 37536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn int mode = entry.getValue(); 37636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (mode == 0) { 37736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn continue; 37836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 3790f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn ApplicationInfo ai = null; 3800f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn try { 381483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani ai = pm.getApplicationInfo(pkg, 0, 0); 3820f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } catch (RemoteException e) { 3830f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3840f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (ai == null) { 3850f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn continue; 3860f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 387df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn CompatibilityInfo info = new CompatibilityInfo(ai, screenLayout, 388df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn smallestScreenWidthDp, false); 3890f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (info.alwaysSupportsScreen()) { 3900f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn continue; 3910f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3920f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (info.neverSupportsScreen()) { 3930f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn continue; 3940f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 3950f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.startTag(null, "pkg"); 3960f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.attribute(null, "name", pkg); 39736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn out.attribute(null, "mode", Integer.toString(mode)); 3980f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.endTag(null, "pkg"); 3990f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 4000f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 4010f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.endTag(null, "compat-packages"); 4020f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn out.endDocument(); 4030f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn 4040f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn mFile.finishWrite(fos); 4050f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } catch (java.io.IOException e1) { 4060f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn Slog.w(TAG, "Error writing compat packages", e1); 4070f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn if (fos != null) { 4080f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn mFile.failWrite(fos); 4090f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 4100f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 4110f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn } 4120f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn} 413