diff options
| author | Dianne Hackborn <hackbod@google.com> | 2011-05-27 16:45:31 -0700 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2011-05-27 16:49:29 -0700 |
| commit | 8ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330d (patch) | |
| tree | a676c6b0daf45a90b600d3268bb37e81f23a2275 /services/java | |
| parent | b96cbbd11c4590bec846212c33361e02293f18b5 (diff) | |
| download | frameworks_base-8ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330d.zip frameworks_base-8ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330d.tar.gz frameworks_base-8ea5e1d79eb1f05ee7628b0d45ea8fc8eea5330d.tar.bz2 | |
Fix compat mode bugs when updating apps.
No longer accidentally puts an app into compatibility mode.
Also various cleanup, freezing screen while switching between modes.
Change-Id: Ic1b3958be7800189a93f68e9dee3c5adfc45fe57
Diffstat (limited to 'services/java')
5 files changed, 76 insertions, 32 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 65b3258..080cbda 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -3642,12 +3642,12 @@ public final class ActivityManagerService extends ActivityManagerNative + processName + " with config " + mConfiguration); ApplicationInfo appInfo = app.instrumentationInfo != null ? app.instrumentationInfo : app.info; + app.compat = compatibilityInfoForPackageLocked(appInfo); thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, app.instrumentationProfileFile, app.instrumentationArguments, app.instrumentationWatcher, testMode, isRestrictedBackupMode || !normalMode, - mConfiguration, compatibilityInfoForPackageLocked(appInfo), - getCommonServicesLocked(), + mConfiguration, app.compat, getCommonServicesLocked(), mCoreSettingsObserver.getCoreSettingsLocked()); updateLruProcessLocked(app, false, true); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); @@ -10977,13 +10977,11 @@ public final class ActivityManagerService extends ActivityManagerNative // Special case for adding a package: by default turn on compatibility // mode. } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { - if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { - Uri data = intent.getData(); - String ssp; - if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { - mCompatModePackages.setPackageScreenCompatModeLocked(ssp, - ActivityManager.COMPAT_MODE_ENABLED); - } + Uri data = intent.getData(); + String ssp; + if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { + mCompatModePackages.handlePackageAddedLocked(ssp, + intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); } } diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index d27cbda..33c12f4 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -24,6 +24,7 @@ import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.os.Build; @@ -78,6 +79,7 @@ class ActivityRecord extends IApplicationToken.Stub { long startTime; // last time this activity was started long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity Configuration configuration; // configuration activity was last running in + CompatibilityInfo compat;// last used compatibility mode ActivityRecord resultTo; // who started this entry, so will get our reply final String resultWho; // additional identifier for use by resultTo. final int requestCode; // code given by requester (resultTo) @@ -137,6 +139,7 @@ class ActivityRecord extends IApplicationToken.Stub { pw.print(" componentSpecified="); pw.print(componentSpecified); pw.print(" isHomeActivity="); pw.println(isHomeActivity); pw.print(prefix); pw.print("config="); pw.println(configuration); + pw.print(prefix); pw.print("compat="); pw.println(compat); if (resultTo != null || resultWho != null) { pw.print(prefix); pw.print("resultTo="); pw.print(resultTo); pw.print(" resultWho="); pw.print(resultWho); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index a704f88..65ea4f4 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -546,10 +546,10 @@ public class ActivityStack { r.sleeping = false; r.forceNewConfig = false; showAskCompatModeDialogLocked(r); + r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); app.thread.scheduleLaunchActivity(new Intent(r.intent), r, System.identityHashCode(r), - r.info, mService.compatibilityInfoForPackageLocked(r.info.applicationInfo), - r.icicle, results, newIntents, !andResume, + r.info, r.compat, r.icicle, results, newIntents, !andResume, mService.isNextTransitionForward()); if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java index 221b59b..8949f48 100644 --- a/services/java/com/android/server/am/CompatModePackages.java +++ b/services/java/com/android/server/am/CompatModePackages.java @@ -17,6 +17,7 @@ import com.android.internal.util.FastXmlSerializer; import android.app.ActivityManager; import android.app.AppGlobals; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.res.CompatibilityInfo; @@ -117,6 +118,37 @@ public class CompatModePackages { return flags != null ? flags : 0; } + public void handlePackageAddedLocked(String packageName, boolean updated) { + ApplicationInfo ai = null; + try { + ai = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0); + } catch (RemoteException e) { + } + if (ai == null) { + return; + } + CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai); + final boolean mayCompat = !ci.alwaysSupportsScreen() + && !ci.neverSupportsScreen(); + + if (!updated) { + // First time -- if the app may run in compat mode, enable that + // by default. + if (mayCompat) { + setPackageScreenCompatModeLocked(ai, ActivityManager.COMPAT_MODE_ENABLED); + } + } else { + // Update -- if the app no longer can run in compat mode, clear + // any current settings for it. + if (!mayCompat && mPackages.containsKey(packageName)) { + mPackages.remove(packageName); + mHandler.removeMessages(MSG_WRITE); + Message msg = mHandler.obtainMessage(MSG_WRITE); + mHandler.sendMessageDelayed(msg, 10000); + } + } + } + public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { return new CompatibilityInfo(ai, mService.mConfiguration.screenLayout, mService.mConfiguration.smallestScreenWidthDp, @@ -242,28 +274,47 @@ public class CompatModePackages { newFlags &= ~COMPAT_FLAG_ENABLED; } + CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai); + if (ci.alwaysSupportsScreen()) { + Slog.w(TAG, "Ignoring compat mode change of " + packageName + + "; compatibility never needed"); + newFlags = 0; + } + if (ci.neverSupportsScreen()) { + Slog.w(TAG, "Ignoring compat mode change of " + packageName + + "; compatibility always needed"); + newFlags = 0; + } + if (newFlags != curFlags) { if (newFlags != 0) { mPackages.put(packageName, newFlags); } else { mPackages.remove(packageName); } - CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai); - if (ci.alwaysSupportsScreen()) { - Slog.w(TAG, "Ignoring compat mode change of " + packageName - + "; compatibility never needed"); - return; - } - if (ci.neverSupportsScreen()) { - Slog.w(TAG, "Ignoring compat mode change of " + packageName - + "; compatibility always needed"); - return; - } + + // Need to get compatibility info in new state. + ci = compatibilityInfoForPackageLocked(ai); mHandler.removeMessages(MSG_WRITE); Message msg = mHandler.obtainMessage(MSG_WRITE); mHandler.sendMessageDelayed(msg, 10000); + ActivityRecord starting = mService.mMainStack.topRunningActivityLocked(null); + + // All activities that came from the package must be + // restarted as if there was a config change. + for (int i=mService.mMainStack.mHistory.size()-1; i>=0; i--) { + ActivityRecord a = (ActivityRecord)mService.mMainStack.mHistory.get(i); + if (a.info.packageName.equals(packageName)) { + a.forceNewConfig = true; + if (starting != null && a == starting && a.visible) { + a.startFreezingScreenLocked(starting.app, + ActivityInfo.CONFIG_SCREEN_LAYOUT); + } + } + } + // Tell all processes that loaded this package about the change. for (int i=mService.mLruProcesses.size()-1; i>=0; i--) { ProcessRecord app = mService.mLruProcesses.get(i); @@ -280,16 +331,6 @@ public class CompatModePackages { } } - // All activities that came from the packge must be - // restarted as if there was a config change. - for (int i=mService.mMainStack.mHistory.size()-1; i>=0; i--) { - ActivityRecord a = (ActivityRecord)mService.mMainStack.mHistory.get(i); - if (a.info.packageName.equals(packageName)) { - a.forceNewConfig = true; - } - } - - ActivityRecord starting = mService.mMainStack.topRunningActivityLocked(null); if (starting != null) { mService.mMainStack.ensureActivityConfigurationLocked(starting, 0); // And we need to make sure at this point that all other activities diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index a63ffae..5465e37 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -69,6 +69,7 @@ class ProcessRecord { IBinder forcingToForeground;// Token that is forcing this process to be foreground int adjSeq; // Sequence id for identifying oom_adj assignment cycles int lruSeq; // Sequence id for identifying LRU update cycles + CompatibilityInfo compat; // last used compatibility mode ComponentName instrumentationClass;// class installed to instrument app ApplicationInfo instrumentationInfo; // the application being instrumented String instrumentationProfileFile; // where to save profiling @@ -145,6 +146,7 @@ class ProcessRecord { pw.print(" publicDir="); pw.print(info.publicSourceDir); pw.print(" data="); pw.println(info.dataDir); pw.print(prefix); pw.print("packageList="); pw.println(pkgList); + pw.print(prefix); pw.print("compat="); pw.println(compat); if (instrumentationClass != null || instrumentationProfileFile != null || instrumentationArguments != null) { pw.print(prefix); pw.print("instrumentationClass="); |
