blob: bfc0456586c1115a189a8913b7e0c7fee6cabc5c [file] [log] [blame]
Craig Mautnerc2c0a612014-02-20 20:25:41 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070017package com.android.server.am;
18
Wale Ogunwalee23149f2015-03-06 15:39:44 -080019import static com.android.server.am.ActivityManagerDebugConfig.*;
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -070020import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080021
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070022import java.io.File;
23import java.io.FileInputStream;
24import java.io.FileOutputStream;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +010025import java.nio.charset.StandardCharsets;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -070026import java.util.HashMap;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070027import java.util.Iterator;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -070028import java.util.Map;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070029
30import org.xmlpull.v1.XmlPullParser;
31import org.xmlpull.v1.XmlPullParserException;
32import org.xmlpull.v1.XmlSerializer;
33
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070034import com.android.internal.util.FastXmlSerializer;
35
36import android.app.ActivityManager;
37import android.app.AppGlobals;
38import android.content.pm.ApplicationInfo;
39import android.content.pm.IPackageManager;
40import android.content.res.CompatibilityInfo;
Andrii Kulian1779e612016-10-12 21:58:25 -070041import android.content.res.Configuration;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070042import android.os.Handler;
Jeff Brown6f357d32014-01-15 20:40:55 -080043import android.os.Looper;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070044import android.os.Message;
45import android.os.RemoteException;
Dianne Hackborn39606a02012-07-31 17:54:35 -070046import android.util.AtomicFile;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070047import android.util.Slog;
48import android.util.Xml;
49
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070050public final class CompatModePackages {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080051 private static final String TAG = TAG_WITH_CLASS_NAME ? "CompatModePackages" : TAG_AM;
Wale Ogunwale3ab9a272015-03-16 09:55:45 -070052 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070053
54 private final ActivityManagerService mService;
55 private final AtomicFile mFile;
56
Dianne Hackborn36cd41f2011-05-25 21:00:46 -070057 // Compatibility state: no longer ask user to select the mode.
58 public static final int COMPAT_FLAG_DONT_ASK = 1<<0;
59 // Compatibility state: compatibility mode is enabled.
60 public static final int COMPAT_FLAG_ENABLED = 1<<1;
Alan Viverette7df9b452016-06-16 12:47:58 -040061 // Unsupported zoom state: don't warn the user about unsupported zoom mode.
62 public static final int UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY = 1<<2;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -070063
64 private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070065
Dianne Hackborn40c8db52012-02-10 18:59:48 -080066 private static final int MSG_WRITE = ActivityManagerService.FIRST_COMPAT_MODE_MSG;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070067
Jeff Brown6f357d32014-01-15 20:40:55 -080068 private final CompatHandler mHandler;
69
70 private final class CompatHandler extends Handler {
71 public CompatHandler(Looper looper) {
72 super(looper, null, true);
73 }
74
75 @Override
76 public void handleMessage(Message msg) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070077 switch (msg.what) {
78 case MSG_WRITE:
79 saveCompatModes();
80 break;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070081 }
82 }
83 };
84
Jeff Brown6f357d32014-01-15 20:40:55 -080085 public CompatModePackages(ActivityManagerService service, File systemDir, Handler handler) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070086 mService = service;
87 mFile = new AtomicFile(new File(systemDir, "packages-compat.xml"));
Jeff Brown6f357d32014-01-15 20:40:55 -080088 mHandler = new CompatHandler(handler.getLooper());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070089
90 FileInputStream fis = null;
91 try {
92 fis = mFile.openRead();
93 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +010094 parser.setInput(fis, StandardCharsets.UTF_8.name());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070095 int eventType = parser.getEventType();
Narayan Kamath2ac3cb72014-01-06 11:31:35 +000096 while (eventType != XmlPullParser.START_TAG &&
97 eventType != XmlPullParser.END_DOCUMENT) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070098 eventType = parser.next();
99 }
Narayan Kamath2ac3cb72014-01-06 11:31:35 +0000100 if (eventType == XmlPullParser.END_DOCUMENT) {
101 return;
102 }
103
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700104 String tagName = parser.getName();
105 if ("compat-packages".equals(tagName)) {
106 eventType = parser.next();
107 do {
108 if (eventType == XmlPullParser.START_TAG) {
109 tagName = parser.getName();
110 if (parser.getDepth() == 2) {
111 if ("pkg".equals(tagName)) {
112 String pkg = parser.getAttributeValue(null, "name");
113 if (pkg != null) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700114 String mode = parser.getAttributeValue(null, "mode");
115 int modeInt = 0;
116 if (mode != null) {
117 try {
118 modeInt = Integer.parseInt(mode);
119 } catch (NumberFormatException e) {
120 }
121 }
122 mPackages.put(pkg, modeInt);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700123 }
124 }
125 }
126 }
127 eventType = parser.next();
128 } while (eventType != XmlPullParser.END_DOCUMENT);
129 }
130 } catch (XmlPullParserException e) {
131 Slog.w(TAG, "Error reading compat-packages", e);
132 } catch (java.io.IOException e) {
133 if (fis != null) Slog.w(TAG, "Error reading compat-packages", e);
134 } finally {
135 if (fis != null) {
136 try {
137 fis.close();
138 } catch (java.io.IOException e1) {
139 }
140 }
141 }
142 }
143
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700144 public HashMap<String, Integer> getPackages() {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700145 return mPackages;
146 }
147
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700148 private int getPackageFlags(String packageName) {
149 Integer flags = mPackages.get(packageName);
150 return flags != null ? flags : 0;
151 }
152
Alan Viverette7df9b452016-06-16 12:47:58 -0400153 public void handlePackageDataClearedLocked(String packageName) {
154 // User has explicitly asked to clear all associated data.
155 removePackage(packageName);
156 }
157
158 public void handlePackageUninstalledLocked(String packageName) {
159 // Clear settings when app is uninstalled since this is an explicit
160 // signal from the user to remove the app and all associated data.
161 removePackage(packageName);
162 }
163
164 private void removePackage(String packageName) {
165 if (mPackages.containsKey(packageName)) {
166 mPackages.remove(packageName);
167 scheduleWrite();
168 }
169 }
170
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700171 public void handlePackageAddedLocked(String packageName, boolean updated) {
172 ApplicationInfo ai = null;
173 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -0700174 ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0);
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700175 } catch (RemoteException e) {
176 }
177 if (ai == null) {
178 return;
179 }
180 CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai);
181 final boolean mayCompat = !ci.alwaysSupportsScreen()
182 && !ci.neverSupportsScreen();
183
Dianne Hackborna9551702011-06-14 21:05:03 -0700184 if (updated) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700185 // Update -- if the app no longer can run in compat mode, clear
186 // any current settings for it.
187 if (!mayCompat && mPackages.containsKey(packageName)) {
188 mPackages.remove(packageName);
Alan Viverette7df9b452016-06-16 12:47:58 -0400189 scheduleWrite();
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700190 }
191 }
192 }
193
Alan Viverette7df9b452016-06-16 12:47:58 -0400194 private void scheduleWrite() {
195 mHandler.removeMessages(MSG_WRITE);
196 Message msg = mHandler.obtainMessage(MSG_WRITE);
197 mHandler.sendMessageDelayed(msg, 10000);
198 }
199
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700200 public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Andrii Kulian1779e612016-10-12 21:58:25 -0700201 final Configuration globalConfig = mService.getGlobalConfiguration();
202 CompatibilityInfo ci = new CompatibilityInfo(ai, globalConfig.screenLayout,
203 globalConfig.smallestScreenWidthDp,
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700204 (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700205 //Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci);
206 return ci;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700207 }
208
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700209 public int computeCompatModeLocked(ApplicationInfo ai) {
Andrii Kulian1779e612016-10-12 21:58:25 -0700210 final boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0;
211 final Configuration globalConfig = mService.getGlobalConfiguration();
212 final CompatibilityInfo info = new CompatibilityInfo(ai, globalConfig.screenLayout,
213 globalConfig.smallestScreenWidthDp, enabled);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700214 if (info.alwaysSupportsScreen()) {
215 return ActivityManager.COMPAT_MODE_NEVER;
216 }
217 if (info.neverSupportsScreen()) {
218 return ActivityManager.COMPAT_MODE_ALWAYS;
219 }
220 return enabled ? ActivityManager.COMPAT_MODE_ENABLED
221 : ActivityManager.COMPAT_MODE_DISABLED;
222 }
223
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700224 public boolean getFrontActivityAskCompatModeLocked() {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700225 ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700226 if (r == null) {
227 return false;
228 }
229 return getPackageAskCompatModeLocked(r.packageName);
230 }
231
232 public boolean getPackageAskCompatModeLocked(String packageName) {
233 return (getPackageFlags(packageName)&COMPAT_FLAG_DONT_ASK) == 0;
234 }
235
Alan Viverette7df9b452016-06-16 12:47:58 -0400236 public boolean getPackageNotifyUnsupportedZoomLocked(String packageName) {
237 return (getPackageFlags(packageName)&UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY) == 0;
238 }
239
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700240 public void setFrontActivityAskCompatModeLocked(boolean ask) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700241 ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700242 if (r != null) {
243 setPackageAskCompatModeLocked(r.packageName, ask);
244 }
245 }
246
247 public void setPackageAskCompatModeLocked(String packageName, boolean ask) {
248 int curFlags = getPackageFlags(packageName);
249 int newFlags = ask ? (curFlags&~COMPAT_FLAG_DONT_ASK) : (curFlags|COMPAT_FLAG_DONT_ASK);
250 if (curFlags != newFlags) {
251 if (newFlags != 0) {
252 mPackages.put(packageName, newFlags);
253 } else {
254 mPackages.remove(packageName);
255 }
Alan Viverette7df9b452016-06-16 12:47:58 -0400256 scheduleWrite();
257 }
258 }
259
260 public void setPackageNotifyUnsupportedZoomLocked(String packageName, boolean notify) {
261 final int curFlags = getPackageFlags(packageName);
262 final int newFlags = notify ? (curFlags&~UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY) :
263 (curFlags|UNSUPPORTED_ZOOM_FLAG_DONT_NOTIFY);
264 if (curFlags != newFlags) {
265 if (newFlags != 0) {
266 mPackages.put(packageName, newFlags);
267 } else {
268 mPackages.remove(packageName);
269 }
270 scheduleWrite();
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700271 }
272 }
273
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700274 public int getFrontActivityScreenCompatModeLocked() {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700275 ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700276 if (r == null) {
277 return ActivityManager.COMPAT_MODE_UNKNOWN;
278 }
279 return computeCompatModeLocked(r.info.applicationInfo);
280 }
281
282 public void setFrontActivityScreenCompatModeLocked(int mode) {
Filip Gruszczynski3e85ba22015-10-05 22:48:30 -0700283 ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700284 if (r == null) {
285 Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
286 return;
287 }
288 setPackageScreenCompatModeLocked(r.info.applicationInfo, mode);
289 }
290
291 public int getPackageScreenCompatModeLocked(String packageName) {
292 ApplicationInfo ai = null;
293 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -0700294 ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700295 } catch (RemoteException e) {
296 }
297 if (ai == null) {
298 return ActivityManager.COMPAT_MODE_UNKNOWN;
299 }
300 return computeCompatModeLocked(ai);
301 }
302
303 public void setPackageScreenCompatModeLocked(String packageName, int mode) {
304 ApplicationInfo ai = null;
305 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -0700306 ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700307 } catch (RemoteException e) {
308 }
309 if (ai == null) {
310 Slog.w(TAG, "setPackageScreenCompatMode failed: unknown package " + packageName);
311 return;
312 }
313 setPackageScreenCompatModeLocked(ai, mode);
314 }
315
316 private void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) {
317 final String packageName = ai.packageName;
318
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700319 int curFlags = getPackageFlags(packageName);
320
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700321 boolean enable;
322 switch (mode) {
323 case ActivityManager.COMPAT_MODE_DISABLED:
324 enable = false;
325 break;
326 case ActivityManager.COMPAT_MODE_ENABLED:
327 enable = true;
328 break;
329 case ActivityManager.COMPAT_MODE_TOGGLE:
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700330 enable = (curFlags&COMPAT_FLAG_ENABLED) == 0;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700331 break;
332 default:
333 Slog.w(TAG, "Unknown screen compat mode req #" + mode + "; ignoring");
334 return;
335 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700336
337 int newFlags = curFlags;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700338 if (enable) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700339 newFlags |= COMPAT_FLAG_ENABLED;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700340 } else {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700341 newFlags &= ~COMPAT_FLAG_ENABLED;
342 }
343
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700344 CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai);
345 if (ci.alwaysSupportsScreen()) {
346 Slog.w(TAG, "Ignoring compat mode change of " + packageName
347 + "; compatibility never needed");
348 newFlags = 0;
349 }
350 if (ci.neverSupportsScreen()) {
351 Slog.w(TAG, "Ignoring compat mode change of " + packageName
352 + "; compatibility always needed");
353 newFlags = 0;
354 }
355
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700356 if (newFlags != curFlags) {
357 if (newFlags != 0) {
358 mPackages.put(packageName, newFlags);
359 } else {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700360 mPackages.remove(packageName);
361 }
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700362
363 // Need to get compatibility info in new state.
364 ci = compatibilityInfoForPackageLocked(ai);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700365
Alan Viverette7df9b452016-06-16 12:47:58 -0400366 scheduleWrite();
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700367
Craig Mautnerce5f3cb2013-04-22 08:58:54 -0700368 final ActivityStack stack = mService.getFocusedStack();
Craig Mautner20e72272013-04-01 13:45:53 -0700369 ActivityRecord starting = stack.restartPackage(packageName);
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700370
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700371 // Tell all processes that loaded this package about the change.
372 for (int i=mService.mLruProcesses.size()-1; i>=0; i--) {
373 ProcessRecord app = mService.mLruProcesses.get(i);
Dianne Hackborn78a369c2013-06-11 17:10:32 -0700374 if (!app.pkgList.containsKey(packageName)) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700375 continue;
376 }
377 try {
378 if (app.thread != null) {
Wale Ogunwale3ab9a272015-03-16 09:55:45 -0700379 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700380 + app.processName + " new compat " + ci);
381 app.thread.updatePackageCompatibilityInfo(packageName, ci);
382 }
383 } catch (Exception e) {
384 }
385 }
386
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700387 if (starting != null) {
Andrii Kulian21713ac2016-10-12 22:05:05 -0700388 starting.ensureActivityConfigurationLocked(0 /* globalChanges */,
389 false /* preserveWindow */);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700390 // And we need to make sure at this point that all other activities
391 // are made visible with the correct configuration.
Filip Gruszczynskibc5a6c52015-09-22 13:13:24 -0700392 stack.ensureActivitiesVisibleLocked(starting, 0, !PRESERVE_WINDOWS);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700393 }
394 }
395 }
396
397 void saveCompatModes() {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700398 HashMap<String, Integer> pkgs;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700399 synchronized (mService) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700400 pkgs = new HashMap<String, Integer>(mPackages);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700401 }
402
403 FileOutputStream fos = null;
404
405 try {
406 fos = mFile.startWrite();
407 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +0100408 out.setOutput(fos, StandardCharsets.UTF_8.name());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700409 out.startDocument(null, true);
410 out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
411 out.startTag(null, "compat-packages");
412
413 final IPackageManager pm = AppGlobals.getPackageManager();
Andrii Kulian1779e612016-10-12 21:58:25 -0700414 final Configuration globalConfig = mService.getGlobalConfiguration();
415 final int screenLayout = globalConfig.screenLayout;
416 final int smallestScreenWidthDp = globalConfig.smallestScreenWidthDp;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700417 final Iterator<Map.Entry<String, Integer>> it = pkgs.entrySet().iterator();
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700418 while (it.hasNext()) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700419 Map.Entry<String, Integer> entry = it.next();
420 String pkg = entry.getKey();
421 int mode = entry.getValue();
422 if (mode == 0) {
423 continue;
424 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700425 ApplicationInfo ai = null;
426 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -0700427 ai = pm.getApplicationInfo(pkg, 0, 0);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700428 } catch (RemoteException e) {
429 }
430 if (ai == null) {
431 continue;
432 }
Dianne Hackborndf6e9802011-05-26 14:20:23 -0700433 CompatibilityInfo info = new CompatibilityInfo(ai, screenLayout,
434 smallestScreenWidthDp, false);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700435 if (info.alwaysSupportsScreen()) {
436 continue;
437 }
438 if (info.neverSupportsScreen()) {
439 continue;
440 }
441 out.startTag(null, "pkg");
442 out.attribute(null, "name", pkg);
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700443 out.attribute(null, "mode", Integer.toString(mode));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700444 out.endTag(null, "pkg");
445 }
446
447 out.endTag(null, "compat-packages");
448 out.endDocument();
449
450 mFile.finishWrite(fos);
451 } catch (java.io.IOException e1) {
452 Slog.w(TAG, "Error writing compat packages", e1);
453 if (fos != null) {
454 mFile.failWrite(fos);
455 }
456 }
457 }
458}