10f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornpackage com.android.server.am;
20f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
30f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport java.io.File;
40f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport java.io.FileInputStream;
50f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport java.io.FileOutputStream;
636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport java.util.HashMap;
70f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport java.util.Iterator;
836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport java.util.Map;
90f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
100f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport org.xmlpull.v1.XmlPullParser;
110f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport org.xmlpull.v1.XmlPullParserException;
120f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport org.xmlpull.v1.XmlSerializer;
130f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
140f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport com.android.internal.util.FastXmlSerializer;
150f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
160f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.app.ActivityManager;
170f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.app.AppGlobals;
188ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackbornimport android.content.pm.ActivityInfo;
190f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.content.pm.ApplicationInfo;
200f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.content.pm.IPackageManager;
210f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.content.res.CompatibilityInfo;
220f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.os.Handler;
230f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.os.Message;
240f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.os.RemoteException;
2539606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackbornimport android.util.AtomicFile;
260f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.util.Slog;
270f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornimport android.util.Xml;
280f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
290f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackbornpublic class CompatModePackages {
300f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    private final String TAG = ActivityManagerService.TAG;
310f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    private final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION;
320f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
330f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    private final ActivityManagerService mService;
340f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    private final AtomicFile mFile;
350f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
3636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    // Compatibility state: no longer ask user to select the mode.
3736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    public static final int COMPAT_FLAG_DONT_ASK = 1<<0;
3836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    // Compatibility state: compatibility mode is enabled.
3936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    public static final int COMPAT_FLAG_ENABLED = 1<<1;
4036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
4136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
420f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
4340c8db5a28e9abae2033facce1354e3677911fccDianne Hackborn    private static final int MSG_WRITE = ActivityManagerService.FIRST_COMPAT_MODE_MSG;
440f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
450f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    private final Handler mHandler = new Handler() {
460f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        @Override public void handleMessage(Message msg) {
470f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            switch (msg.what) {
480f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                case MSG_WRITE:
490f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    saveCompatModes();
500f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    break;
510f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                default:
520f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    super.handleMessage(msg);
530f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    break;
540f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
550f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
560f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    };
570f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
580f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    public CompatModePackages(ActivityManagerService service, File systemDir) {
590f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        mService = service;
600f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        mFile = new AtomicFile(new File(systemDir, "packages-compat.xml"));
610f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
620f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        FileInputStream fis = null;
630f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        try {
640f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            fis = mFile.openRead();
650f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            XmlPullParser parser = Xml.newPullParser();
660f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            parser.setInput(fis, null);
670f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            int eventType = parser.getEventType();
680f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            while (eventType != XmlPullParser.START_TAG) {
690f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                eventType = parser.next();
700f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
710f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            String tagName = parser.getName();
720f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            if ("compat-packages".equals(tagName)) {
730f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                eventType = parser.next();
740f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                do {
750f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    if (eventType == XmlPullParser.START_TAG) {
760f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                        tagName = parser.getName();
770f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                        if (parser.getDepth() == 2) {
780f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                            if ("pkg".equals(tagName)) {
790f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                                String pkg = parser.getAttributeValue(null, "name");
800f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                                if (pkg != null) {
8136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                    String mode = parser.getAttributeValue(null, "mode");
8236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                    int modeInt = 0;
8336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                    if (mode != null) {
8436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                        try {
8536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                            modeInt = Integer.parseInt(mode);
8636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                        } catch (NumberFormatException e) {
8736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                        }
8836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                    }
8936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                                    mPackages.put(pkg, modeInt);
900f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                                }
910f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                            }
920f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                        }
930f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    }
940f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    eventType = parser.next();
950f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                } while (eventType != XmlPullParser.END_DOCUMENT);
960f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
970f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        } catch (XmlPullParserException e) {
980f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            Slog.w(TAG, "Error reading compat-packages", e);
990f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        } catch (java.io.IOException e) {
1000f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            if (fis != null) Slog.w(TAG, "Error reading compat-packages", e);
1010f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        } finally {
1020f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            if (fis != null) {
1030f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                try {
1040f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    fis.close();
1050f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                } catch (java.io.IOException e1) {
1060f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                }
1070f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
1080f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
1090f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
1100f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
11136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    public HashMap<String, Integer> getPackages() {
1120f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        return mPackages;
1130f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
1140f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
11536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    private int getPackageFlags(String packageName) {
11636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        Integer flags = mPackages.get(packageName);
11736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        return flags != null ? flags : 0;
11836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    }
11936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
1208ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn    public void handlePackageAddedLocked(String packageName, boolean updated) {
1218ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        ApplicationInfo ai = null;
1228ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        try {
123483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0);
1248ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        } catch (RemoteException e) {
1258ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        }
1268ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        if (ai == null) {
1278ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            return;
1288ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        }
1298ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai);
1308ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        final boolean mayCompat = !ci.alwaysSupportsScreen()
1318ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn                && !ci.neverSupportsScreen();
1328ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn
133a9551706a279a798c91d8ef593b2acb16a30c682Dianne Hackborn        if (updated) {
1348ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            // Update -- if the app no longer can run in compat mode, clear
1358ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            // any current settings for it.
1368ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            if (!mayCompat && mPackages.containsKey(packageName)) {
1378ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn                mPackages.remove(packageName);
1388ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn                mHandler.removeMessages(MSG_WRITE);
1398ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn                Message msg = mHandler.obtainMessage(MSG_WRITE);
1408ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn                mHandler.sendMessageDelayed(msg, 10000);
1418ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            }
1428ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        }
1438ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn    }
1448ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn
1450f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
1462f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn        CompatibilityInfo ci = new CompatibilityInfo(ai, mService.mConfiguration.screenLayout,
147df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn                mService.mConfiguration.smallestScreenWidthDp,
14836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0);
1492f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn        //Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci);
1502f0b17573d4324832f7a20402a3d2b5920bc4866Dianne Hackborn        return ci;
1510f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
1520f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
15336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    public int computeCompatModeLocked(ApplicationInfo ai) {
15436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0;
1550f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        CompatibilityInfo info = new CompatibilityInfo(ai,
156df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn                mService.mConfiguration.screenLayout,
157df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn                mService.mConfiguration.smallestScreenWidthDp, enabled);
1580f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        if (info.alwaysSupportsScreen()) {
1590f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            return ActivityManager.COMPAT_MODE_NEVER;
1600f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
1610f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        if (info.neverSupportsScreen()) {
1620f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            return ActivityManager.COMPAT_MODE_ALWAYS;
1630f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
1640f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        return enabled ? ActivityManager.COMPAT_MODE_ENABLED
1650f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                : ActivityManager.COMPAT_MODE_DISABLED;
1660f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
1670f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
16836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    public boolean getFrontActivityAskCompatModeLocked() {
16936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
17036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        if (r == null) {
17136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            return false;
17236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        }
17336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        return getPackageAskCompatModeLocked(r.packageName);
17436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    }
17536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
17636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    public boolean getPackageAskCompatModeLocked(String packageName) {
17736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        return (getPackageFlags(packageName)&COMPAT_FLAG_DONT_ASK) == 0;
17836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    }
17936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
18036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    public void setFrontActivityAskCompatModeLocked(boolean ask) {
18136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
18236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        if (r != null) {
18336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            setPackageAskCompatModeLocked(r.packageName, ask);
18436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        }
18536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    }
18636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
18736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    public void setPackageAskCompatModeLocked(String packageName, boolean ask) {
18836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        int curFlags = getPackageFlags(packageName);
18936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        int newFlags = ask ? (curFlags&~COMPAT_FLAG_DONT_ASK) : (curFlags|COMPAT_FLAG_DONT_ASK);
19036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        if (curFlags != newFlags) {
19136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            if (newFlags != 0) {
19236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                mPackages.put(packageName, newFlags);
19336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            } else {
19436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                mPackages.remove(packageName);
19536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            }
19636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            mHandler.removeMessages(MSG_WRITE);
19736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            Message msg = mHandler.obtainMessage(MSG_WRITE);
19836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            mHandler.sendMessageDelayed(msg, 10000);
19936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        }
20036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn    }
20136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
2020f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    public int getFrontActivityScreenCompatModeLocked() {
2030f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
2040f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        if (r == null) {
2050f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            return ActivityManager.COMPAT_MODE_UNKNOWN;
2060f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
2070f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        return computeCompatModeLocked(r.info.applicationInfo);
2080f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
2090f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
2100f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    public void setFrontActivityScreenCompatModeLocked(int mode) {
2110f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
2120f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        if (r == null) {
2130f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
2140f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            return;
2150f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
2160f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        setPackageScreenCompatModeLocked(r.info.applicationInfo, mode);
2170f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
2180f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
2190f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    public int getPackageScreenCompatModeLocked(String packageName) {
2200f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        ApplicationInfo ai = null;
2210f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        try {
222483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0);
2230f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        } catch (RemoteException e) {
2240f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
2250f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        if (ai == null) {
2260f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            return ActivityManager.COMPAT_MODE_UNKNOWN;
2270f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
2280f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        return computeCompatModeLocked(ai);
2290f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
2300f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
2310f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    public void setPackageScreenCompatModeLocked(String packageName, int mode) {
2320f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        ApplicationInfo ai = null;
2330f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        try {
234483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani            ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0);
2350f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        } catch (RemoteException e) {
2360f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
2370f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        if (ai == null) {
2380f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            Slog.w(TAG, "setPackageScreenCompatMode failed: unknown package " + packageName);
2390f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            return;
2400f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
2410f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        setPackageScreenCompatModeLocked(ai, mode);
2420f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
2430f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
2440f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    private void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) {
2450f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        final String packageName = ai.packageName;
2460f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
24736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        int curFlags = getPackageFlags(packageName);
24836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
2490f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        boolean enable;
2500f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        switch (mode) {
2510f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            case ActivityManager.COMPAT_MODE_DISABLED:
2520f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                enable = false;
2530f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                break;
2540f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            case ActivityManager.COMPAT_MODE_ENABLED:
2550f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                enable = true;
2560f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                break;
2570f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            case ActivityManager.COMPAT_MODE_TOGGLE:
25836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                enable = (curFlags&COMPAT_FLAG_ENABLED) == 0;
2590f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                break;
2600f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            default:
2610f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                Slog.w(TAG, "Unknown screen compat mode req #" + mode + "; ignoring");
2620f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                return;
2630f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
26436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
26536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        int newFlags = curFlags;
2660f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        if (enable) {
26736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            newFlags |= COMPAT_FLAG_ENABLED;
2680f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        } else {
26936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            newFlags &= ~COMPAT_FLAG_ENABLED;
27036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        }
27136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn
2728ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai);
2738ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        if (ci.alwaysSupportsScreen()) {
2748ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            Slog.w(TAG, "Ignoring compat mode change of " + packageName
2758ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn                    + "; compatibility never needed");
2768ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            newFlags = 0;
2778ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        }
2788ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        if (ci.neverSupportsScreen()) {
2798ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            Slog.w(TAG, "Ignoring compat mode change of " + packageName
2808ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn                    + "; compatibility always needed");
2818ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            newFlags = 0;
2828ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn        }
2838ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn
28436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        if (newFlags != curFlags) {
28536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            if (newFlags != 0) {
28636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                mPackages.put(packageName, newFlags);
28736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            } else {
2880f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                mPackages.remove(packageName);
2890f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
2908ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn
2918ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            // Need to get compatibility info in new state.
2928ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn            ci = compatibilityInfoForPackageLocked(ai);
2930f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
2940f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            mHandler.removeMessages(MSG_WRITE);
2950f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            Message msg = mHandler.obtainMessage(MSG_WRITE);
2960f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            mHandler.sendMessageDelayed(msg, 10000);
2970f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
2982ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner            ActivityRecord starting = mService.mMainStack.topRunningActivityLocked(null);
2992ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner
3002ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner            // All activities that came from the package must be
3012ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner            // restarted as if there was a config change.
3022ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner            for (int i=mService.mMainStack.mHistory.size()-1; i>=0; i--) {
3032ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner                ActivityRecord a = (ActivityRecord)mService.mMainStack.mHistory.get(i);
3042ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner                if (a.info.packageName.equals(packageName)) {
3052ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner                    a.forceNewConfig = true;
3062ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner                    if (starting != null && a == starting && a.visible) {
3072ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner                        a.startFreezingScreenLocked(starting.app,
3082ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner                                ActivityInfo.CONFIG_SCREEN_LAYOUT);
3092ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner                    }
3102ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner                }
3112ad920759b1981eaf526fd37a314fbc5a3ed90aeCraig Mautner            }
3128ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330dDianne Hackborn
3130f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            // Tell all processes that loaded this package about the change.
3140f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            for (int i=mService.mLruProcesses.size()-1; i>=0; i--) {
3150f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                ProcessRecord app = mService.mLruProcesses.get(i);
3160f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                if (!app.pkgList.contains(packageName)) {
3170f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    continue;
3180f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                }
3190f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                try {
3200f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    if (app.thread != null) {
3210f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
3220f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                                + app.processName + " new compat " + ci);
3230f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                        app.thread.updatePackageCompatibilityInfo(packageName, ci);
3240f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    }
3250f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                } catch (Exception e) {
3260f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                }
3270f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
3280f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
3290f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            if (starting != null) {
3300f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                mService.mMainStack.ensureActivityConfigurationLocked(starting, 0);
3310f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                // And we need to make sure at this point that all other activities
3320f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                // are made visible with the correct configuration.
3330f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                mService.mMainStack.ensureActivitiesVisibleLocked(starting, 0);
3340f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
3350f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
3360f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
3370f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
3380f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    void saveCompatModes() {
33936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn        HashMap<String, Integer> pkgs;
3400f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        synchronized (mService) {
34136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            pkgs = new HashMap<String, Integer>(mPackages);
3420f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
3430f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
3440f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        FileOutputStream fos = null;
3450f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
3460f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        try {
3470f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            fos = mFile.startWrite();
3480f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            XmlSerializer out = new FastXmlSerializer();
3490f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            out.setOutput(fos, "utf-8");
3500f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            out.startDocument(null, true);
3510f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
3520f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            out.startTag(null, "compat-packages");
3530f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
3540f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            final IPackageManager pm = AppGlobals.getPackageManager();
3550f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            final int screenLayout = mService.mConfiguration.screenLayout;
356df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn            final int smallestScreenWidthDp = mService.mConfiguration.smallestScreenWidthDp;
35736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn            final Iterator<Map.Entry<String, Integer>> it = pkgs.entrySet().iterator();
3580f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            while (it.hasNext()) {
35936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                Map.Entry<String, Integer> entry = it.next();
36036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                String pkg = entry.getKey();
36136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                int mode = entry.getValue();
36236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                if (mode == 0) {
36336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                    continue;
36436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                }
3650f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                ApplicationInfo ai = null;
3660f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                try {
367483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    ai = pm.getApplicationInfo(pkg, 0, 0);
3680f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                } catch (RemoteException e) {
3690f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                }
3700f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                if (ai == null) {
3710f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    continue;
3720f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                }
373df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn                CompatibilityInfo info = new CompatibilityInfo(ai, screenLayout,
374df6e980e3f63eb0f6f9eb437fa925d5009cd9c44Dianne Hackborn                        smallestScreenWidthDp, false);
3750f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                if (info.alwaysSupportsScreen()) {
3760f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    continue;
3770f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                }
3780f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                if (info.neverSupportsScreen()) {
3790f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                    continue;
3800f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                }
3810f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                out.startTag(null, "pkg");
3820f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                out.attribute(null, "name", pkg);
38336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn                out.attribute(null, "mode", Integer.toString(mode));
3840f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                out.endTag(null, "pkg");
3850f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
3860f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
3870f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            out.endTag(null, "compat-packages");
3880f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            out.endDocument();
3890f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn
3900f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            mFile.finishWrite(fos);
3910f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        } catch (java.io.IOException e1) {
3920f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            Slog.w(TAG, "Error writing compat packages", e1);
3930f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            if (fos != null) {
3940f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn                mFile.failWrite(fos);
3950f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn            }
3960f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn        }
3970f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn    }
3980f1de9adde0b52d2a385a76232bd7ac30c3eeea2Dianne Hackborn}
399