diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-09-07 18:31:28 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2011-09-08 10:35:11 -0700 |
commit | 905577f6345c014fc2489a8068ea967ba8c18012 (patch) | |
tree | 5bfcb7463ebe929bc0cf8c2905bba9c345b8f14b | |
parent | 9f443fb6e70f4dafdc9610385c66425410bb3ff1 (diff) | |
download | frameworks_base-905577f6345c014fc2489a8068ea967ba8c18012.zip frameworks_base-905577f6345c014fc2489a8068ea967ba8c18012.tar.gz frameworks_base-905577f6345c014fc2489a8068ea967ba8c18012.tar.bz2 |
Fix issue #5263361: Browser instance not created in application picker
The resolver activity was hiding the following activity from recents.
Also some other fixes: a little better memory use debugging, removed
some unneeded code from window manager, moved some system activities
into their own process, added some more running process information for
manage apps.
Change-Id: I66687d16989ff965d524b92dc360f37c19199717
-rw-r--r-- | core/java/android/app/ActivityManager.java | 8 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 3 | ||||
-rw-r--r-- | core/java/com/android/internal/app/ResolverActivity.java | 13 | ||||
-rw-r--r-- | core/res/AndroidManifest.xml | 24 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 143 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityStack.java | 2 | ||||
-rw-r--r-- | services/java/com/android/server/am/ProcessRecord.java | 1 | ||||
-rw-r--r-- | services/java/com/android/server/wm/WindowManagerService.java | 21 |
8 files changed, 126 insertions, 89 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 102fac1..4fe9cef 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1254,6 +1254,12 @@ public class ActivityManager { */ public ComponentName importanceReasonComponent; + /** + * When {@link importanceReasonPid} is non-0, this is the importance + * of the other pid. @hide + */ + public int importanceReasonImportance; + public RunningAppProcessInfo() { importance = IMPORTANCE_FOREGROUND; importanceReasonCode = REASON_UNKNOWN; @@ -1280,6 +1286,7 @@ public class ActivityManager { dest.writeInt(importanceReasonCode); dest.writeInt(importanceReasonPid); ComponentName.writeToParcel(importanceReasonComponent, dest); + dest.writeInt(importanceReasonImportance); } public void readFromParcel(Parcel source) { @@ -1293,6 +1300,7 @@ public class ActivityManager { importanceReasonCode = source.readInt(); importanceReasonPid = source.readInt(); importanceReasonComponent = ComponentName.readFromParcel(source); + importanceReasonImportance = source.readInt(); } public static final Creator<RunningAppProcessInfo> CREATOR = diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 46712a9..48f94d0 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -239,6 +239,9 @@ public abstract class Context { * methods of activities and other components are called. Note that you * <em>must</em> be sure to use {@link #unregisterComponentCallbacks} when * appropriate in the future; this will not be removed for you. + * + * @param callback The interface to call. This can be either a + * {@link ComponentCallbacks} or {@link ComponentCallbacks2} interface. */ public void registerComponentCallbacks(ComponentCallbacks callback) { getApplicationContext().registerComponentCallbacks(callback); diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index ba2f5d4..3fba1be 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -58,9 +58,20 @@ public class ResolverActivity extends AlertActivity implements private TextView mClearDefaultHint; private PackageManager mPm; + private Intent makeMyIntent() { + Intent intent = new Intent(getIntent()); + // The resolver activity is set to be hidden from recent tasks. + // we don't want this attribute to be propagated to the next activity + // being launched. Note that if the original Intent also had this + // flag set, we are now losing it. That should be a very rare case + // and we can live with this. + intent.setFlags(intent.getFlags()&~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + return intent; + } + @Override protected void onCreate(Bundle savedInstanceState) { - onCreate(savedInstanceState, new Intent(getIntent()), + onCreate(savedInstanceState, makeMyIntent(), getResources().getText(com.android.internal.R.string.whichApplication), null, null, true); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 16490da..72863a2 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1499,19 +1499,23 @@ android:theme="@style/Theme.Holo.Dialog" android:label="@string/heavy_weight_switcher_title" android:finishOnCloseSystemDialogs="true" - android:excludeFromRecents="true"> + android:excludeFromRecents="true" + android:process=":ui"> </activity> <activity android:name="com.android.internal.app.PlatLogoActivity" - android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"> + android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen" + android:process=":ui"> </activity> <activity android:name="com.android.internal.app.DisableCarModeActivity" android:theme="@style/Theme.NoDisplay" - android:excludeFromRecents="true"> + android:excludeFromRecents="true" + android:process=":ui"> </activity> <activity android:name="com.android.internal.app.RingtonePickerActivity" android:theme="@style/Theme.Holo.Dialog.Alert" android:excludeFromRecents="true" - android:multiprocess="true"> + android:multiprocess="true" + android:process=":ui"> <intent-filter> <action android:name="android.intent.action.RINGTONE_PICKER" /> <category android:name="android.intent.category.DEFAULT" /> @@ -1522,18 +1526,21 @@ android:excludeFromRecents="true" android:exported="true" android:theme="@android:style/Theme.Holo.Dialog" - android:label="@string/choose_account_label"> + android:label="@string/choose_account_label" + android:process=":ui"> </activity> <activity android:name="android.accounts.GrantCredentialsPermissionActivity" android:excludeFromRecents="true" android:exported="true" - android:theme="@android:style/Theme.Holo.DialogWhenLarge"> + android:theme="@android:style/Theme.Holo.DialogWhenLarge" + android:process=":ui"> </activity> <activity android:name="android.content.SyncActivityTooManyDeletes" android:theme="@android:style/Theme.Holo.Dialog" - android:label="@string/sync_too_many_deletes"> + android:label="@string/sync_too_many_deletes" + android:process=":ui"> </activity> <activity android:name="com.android.server.ShutdownActivity" @@ -1551,7 +1558,8 @@ <activity android:name="com.android.internal.app.NetInitiatedActivity" android:theme="@style/Theme.Holo.Dialog.Alert" - android:excludeFromRecents="true"> + android:excludeFromRecents="true" + android:process=":ui"> </activity> <receiver android:name="com.android.server.BootReceiver" > diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 9db56ce..57bfaed 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -106,6 +106,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.provider.Settings; import android.util.EventLog; +import android.util.Pair; import android.util.Slog; import android.util.Log; import android.util.PrintWriterPrinter; @@ -5004,7 +5005,13 @@ public final class ActivityManagerService extends ActivityManagerNative maxNum < N ? maxNum : N); for (int i=0; i<N && maxNum > 0; i++) { TaskRecord tr = mRecentTasks.get(i); - if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) + // Return the entry if desired by the caller. We always return + // the first entry, because callers always expect this to be the + // forground app. We may filter others if the caller has + // not supplied RECENT_WITH_EXCLUDED and there is some reason + // we should exclude the entry. + if (i == 0 + || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) || (tr.intent == null) || ((tr.intent.getFlags() &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { @@ -7546,7 +7553,33 @@ public final class ActivityManagerService extends ActivityManagerNative return errList; } - + + static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { + if (adj >= ProcessList.EMPTY_APP_ADJ) { + return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; + } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { + if (currApp != null) { + currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; + } + return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; + } else if (adj >= ProcessList.HOME_APP_ADJ) { + if (currApp != null) { + currApp.lru = 0; + } + return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; + } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) { + return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; + } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { + return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; + } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { + return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; + } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { + return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; + } else { + return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; + } + } + public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { // Lazy instantiation of list List<ActivityManager.RunningAppProcessInfo> runList = null; @@ -7567,28 +7600,12 @@ public final class ActivityManagerService extends ActivityManagerNative currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; } int adj = app.curAdj; - if (adj >= ProcessList.EMPTY_APP_ADJ) { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; - } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; - currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; - } else if (adj >= ProcessList.HOME_APP_ADJ) { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; - currApp.lru = 0; - } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; - } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; - } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; - } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; - } else { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; - } + currApp.importance = oomAdjToImportance(adj, currApp); currApp.importanceReasonCode = app.adjTypeCode; if (app.adjSource instanceof ProcessRecord) { currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; + currApp.importanceReasonImportance = oomAdjToImportance( + app.adjSourceOom, null); } else if (app.adjSource instanceof ActivityRecord) { ActivityRecord r = (ActivityRecord)app.adjSource; if (r.app != null) currApp.importanceReasonPid = r.app.pid; @@ -7891,7 +7908,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (mLruProcesses.size() > 0) { if (needSep) pw.println(" "); needSep = true; - pw.println(" Process LRU list (most recent first):"); + pw.println(" Process LRU list (sorted by oom_adj):"); dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false); needSep = true; @@ -8069,29 +8086,6 @@ public final class ActivityManagerService extends ActivityManagerNative boolean needSep = false; if (mLruProcesses.size() > 0) { - ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses); - - Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() { - @Override - public int compare(ProcessRecord object1, ProcessRecord object2) { - if (object1.setAdj != object2.setAdj) { - return object1.setAdj > object2.setAdj ? -1 : 1; - } - if (object1.setSchedGroup != object2.setSchedGroup) { - return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1; - } - if (object1.keeping != object2.keeping) { - return object1.keeping ? -1 : 1; - } - if (object1.pid != object2.pid) { - return object1.pid > object2.pid ? -1 : 1; - } - return 0; - } - }; - - Collections.sort(procs, comparator); - if (needSep) pw.println(" "); needSep = true; pw.println(" OOM levels:"); @@ -8110,7 +8104,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (needSep) pw.println(" "); needSep = true; pw.println(" Process OOM control:"); - dumpProcessOomList(pw, this, procs, " ", + dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true); needSep = true; } @@ -8859,10 +8853,33 @@ public final class ActivityManagerService extends ActivityManagerNative } private static final void dumpProcessOomList(PrintWriter pw, - ActivityManagerService service, List<ProcessRecord> list, + ActivityManagerService service, List<ProcessRecord> origList, String prefix, String normalLabel, String persistentLabel, boolean inclDetails) { + ArrayList<Pair<ProcessRecord, Integer>> list + = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); + for (int i=0; i<origList.size(); i++) { + list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); + } + + Comparator<Pair<ProcessRecord, Integer>> comparator + = new Comparator<Pair<ProcessRecord, Integer>>() { + @Override + public int compare(Pair<ProcessRecord, Integer> object1, + Pair<ProcessRecord, Integer> object2) { + if (object1.first.setAdj != object2.first.setAdj) { + return object1.first.setAdj > object2.first.setAdj ? -1 : 1; + } + if (object1.second.intValue() != object2.second.intValue()) { + return object1.second.intValue() > object2.second.intValue() ? -1 : 1; + } + return 0; + } + }; + + Collections.sort(list, comparator); + final long curRealtime = SystemClock.elapsedRealtime(); final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; final long curUptime = SystemClock.uptimeMillis(); @@ -8870,7 +8887,7 @@ public final class ActivityManagerService extends ActivityManagerNative final int N = list.size()-1; for (int i=N; i>=0; i--) { - ProcessRecord r = list.get(i); + ProcessRecord r = list.get(i).first; String oomAdj; if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) { oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ); @@ -8919,7 +8936,7 @@ public final class ActivityManagerService extends ActivityManagerNative } pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", prefix, (r.persistent ? persistentLabel : normalLabel), - N-i, oomAdj, schedGroup, foreground, r.trimMemoryLevel, + N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); if (r.adjSource != null || r.adjTarget != null) { pw.print(prefix); @@ -13118,6 +13135,7 @@ public final class ActivityManagerService extends ActivityManagerNative app.adjTypeCode = ActivityManager.RunningAppProcessInfo .REASON_SERVICE_IN_USE; app.adjSource = cr.binding.client; + app.adjSourceOom = clientAdj; app.adjTarget = s.name; } if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { @@ -13140,6 +13158,7 @@ public final class ActivityManagerService extends ActivityManagerNative app.adjTypeCode = ActivityManager.RunningAppProcessInfo .REASON_SERVICE_IN_USE; app.adjSource = a; + app.adjSourceOom = adj; app.adjTarget = s.name; } } @@ -13201,6 +13220,7 @@ public final class ActivityManagerService extends ActivityManagerNative app.adjTypeCode = ActivityManager.RunningAppProcessInfo .REASON_PROVIDER_IN_USE; app.adjSource = client; + app.adjSourceOom = clientAdj; app.adjTarget = cpr.name; } if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { @@ -13511,16 +13531,21 @@ public final class ActivityManagerService extends ActivityManagerNative computeOomAdjLocked(app, hiddenAdj, TOP_APP, false); if (app.curRawAdj != app.setRawAdj) { - if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ - && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) { - // If this app is transitioning from foreground to - // non-foreground, have it do a gc. - scheduleAppGcLocked(app); - } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ - && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { - // Likewise do a gc when an app is moving in to the - // background (such as a service stopping). - scheduleAppGcLocked(app); + if (false) { + // Removing for now. Forcing GCs is not so useful anymore + // with Dalvik, and the new memory level hint facility is + // better for what we need to do these days. + if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ + && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) { + // If this app is transitioning from foreground to + // non-foreground, have it do a gc. + scheduleAppGcLocked(app); + } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ + && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { + // Likewise do a gc when an app is moving in to the + // background (such as a service stopping). + scheduleAppGcLocked(app); + } } if (wasKeeping && !app.keeping) { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 4ad0f45..a0aedf9 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -1151,6 +1151,7 @@ final class ActivityStack { try { mService.mWindowManager.setAppVisibility(r, true); r.sleeping = false; + r.app.pendingUiClean = true; r.app.thread.scheduleWindowVisibility(r, true); r.stopFreezingScreenLocked(false); } catch (Exception e) { @@ -1497,6 +1498,7 @@ final class ActivityStack { next.sleeping = false; showAskCompatModeDialogLocked(next); + next.app.pendingUiClean = true; next.app.thread.scheduleResumeActivity(next, mService.isNextTransitionForward()); diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index 24d92cf..9392bb4 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -99,6 +99,7 @@ class ProcessRecord { String adjType; // Debugging: primary thing impacting oom_adj. int adjTypeCode; // Debugging: adj code to report to app. Object adjSource; // Debugging: option dependent object. + int adjSourceOom; // Debugging: oom_adj of adjSource's process. Object adjTarget; // Debugging: target component impacting oom_adj. // contains HistoryRecord objects diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 755a268..211c4da 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -5824,27 +5824,6 @@ public class WindowManagerService extends IWindowManager.Stub config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale); config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh); - // We need to determine the smallest width that will occur under normal - // operation. To this, start with the base screen size and compute the - // width under the different possible rotations. We need to un-rotate - // the current screen dimensions before doing this. - int unrotDw, unrotDh; - if (rotated) { - unrotDw = dh; - unrotDh = dw; - } else { - unrotDw = dw; - unrotDh = dh; - } - config.smallestScreenWidthDp = reduceConfigWidthSize(unrotDw, - Surface.ROTATION_0, dm.density, unrotDw); - config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp, - Surface.ROTATION_90, dm.density, unrotDh); - config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp, - Surface.ROTATION_180, dm.density, unrotDw); - config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp, - Surface.ROTATION_270, dm.density, unrotDh); - // Compute the screen layout size class. int screenLayout; int longSize = dw; |