summaryrefslogtreecommitdiffstats
path: root/services/java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java')
-rw-r--r--services/java/com/android/server/SystemServer.java13
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java14
-rw-r--r--services/java/com/android/server/accessibility/TouchExplorer.java143
-rw-r--r--services/java/com/android/server/am/ActiveServices.java97
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java290
-rw-r--r--services/java/com/android/server/am/ActivityStack.java12
-rw-r--r--services/java/com/android/server/am/ActivityStackSupervisor.java3
-rw-r--r--services/java/com/android/server/am/BroadcastQueue.java3
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java6
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java2
10 files changed, 411 insertions, 172 deletions
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0e0f156..bb14259 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1104,6 +1104,19 @@ public class SystemServer {
private static native void nativeInit();
public static void main(String[] args) {
+
+ /*
+ * In case the runtime switched since last boot (such as when
+ * the old runtime was removed in an OTA), set the system
+ * property so that it is in sync. We can't do this in
+ * libnativehelper's JniInvocation::Init code where we already
+ * had to fallback to a different runtime because it is
+ * running as root and we need to be the system user to set
+ * the property. http://b/11463182
+ */
+ SystemProperties.set("persist.sys.dalvik.vm.lib",
+ VMRuntime.getRuntime().vmLibrary());
+
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 6957bac..c1a60ee 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -648,6 +648,10 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("width and height must be > 0");
}
+ // Make sure it is at least as large as the display's maximum size.
+ int maxSizeDimension = getMaximumSizeDimension();
+ width = Math.max(width, maxSizeDimension);
+ height = Math.max(height, maxSizeDimension);
if (width != wallpaper.width || height != wallpaper.height) {
wallpaper.width = width;
@@ -1146,9 +1150,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
// We always want to have some reasonable width hint.
- WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
- Display d = wm.getDefaultDisplay();
- int baseSize = d.getMaximumSizeDimension();
+ int baseSize = getMaximumSizeDimension();
if (wallpaper.width < baseSize) {
wallpaper.width = baseSize;
}
@@ -1157,6 +1159,12 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
+ private int getMaximumSizeDimension() {
+ WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
+ Display d = wm.getDefaultDisplay();
+ return d.getMaximumSizeDimension();
+ }
+
// Called by SystemBackupAgent after files are restored to disk.
void settingsRestored() {
// TODO: If necessary, make it work for secondary users as well. This currently assumes
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index a99b58a..43f12eb 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -76,7 +76,7 @@ class TouchExplorer implements EventStreamTransformation {
private static final int STATE_DELEGATING = 0x00000004;
private static final int STATE_GESTURE_DETECTING = 0x00000005;
- // The minimum of the cosine between the vectors of two moving
+ // The maximum of the cosine between the vectors of two moving
// pointers so they can be considered moving in the same direction.
private static final float MAX_DRAGGING_ANGLE_COS = 0.525321989f; // cos(pi/4)
@@ -436,13 +436,19 @@ class TouchExplorer implements EventStreamTransformation {
final int pointerIdBits = (1 << pointerId);
mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits,
policyFlags);
+ } else {
+ // Cache the event until we discern exploration from gesturing.
+ mSendHoverEnterAndMoveDelayed.addEvent(event);
}
- // Cache the event until we discern exploration from gesturing.
- mSendHoverEnterAndMoveDelayed.addEvent(event);
}
} break;
case MotionEvent.ACTION_POINTER_DOWN: {
- /* do nothing - let the code for ACTION_MOVE decide what to do */
+ // Another finger down means that if we have not started to deliver
+ // hover events, we will not have to. The code for ACTION_MOVE will
+ // decide what we will actually do next.
+ mSendHoverEnterAndMoveDelayed.cancel();
+ mSendHoverExitDelayed.cancel();
+ mPerformLongPressDelayed.cancel();
} break;
case MotionEvent.ACTION_MOVE: {
final int pointerId = receivedTracker.getPrimaryPointerId();
@@ -518,14 +524,11 @@ class TouchExplorer implements EventStreamTransformation {
mPerformLongPressDelayed.cancel();
}
}
- // The user is either double tapping or performing a long
- // press, so do not send move events yet.
- if (mDoubleTapDetector.firstTapDetected()) {
- break;
+ if (mTouchExplorationInProgress) {
+ sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
+ sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits,
+ policyFlags);
}
- sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
- sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits,
- policyFlags);
}
} break;
case 2: {
@@ -539,22 +542,24 @@ class TouchExplorer implements EventStreamTransformation {
mPerformLongPressDelayed.cancel();
} else {
mPerformLongPressDelayed.cancel();
- // If the user is touch exploring the second pointer may be
- // performing a double tap to activate an item without need
- // for the user to lift his exploring finger.
- // It is *important* to use the distance traveled by the pointers
- // on the screen which may or may not be magnified.
- final float deltaX = receivedTracker.getReceivedPointerDownX(pointerId)
- - rawEvent.getX(pointerIndex);
- final float deltaY = receivedTracker.getReceivedPointerDownY(pointerId)
- - rawEvent.getY(pointerIndex);
- final double moveDelta = Math.hypot(deltaX, deltaY);
- if (moveDelta < mDoubleTapSlop) {
- break;
+ if (mTouchExplorationInProgress) {
+ // If the user is touch exploring the second pointer may be
+ // performing a double tap to activate an item without need
+ // for the user to lift his exploring finger.
+ // It is *important* to use the distance traveled by the pointers
+ // on the screen which may or may not be magnified.
+ final float deltaX = receivedTracker.getReceivedPointerDownX(
+ pointerId) - rawEvent.getX(pointerIndex);
+ final float deltaY = receivedTracker.getReceivedPointerDownY(
+ pointerId) - rawEvent.getY(pointerIndex);
+ final double moveDelta = Math.hypot(deltaX, deltaY);
+ if (moveDelta < mDoubleTapSlop) {
+ break;
+ }
+ // We are sending events so send exit and gesture
+ // end since we transition to another state.
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
}
- // We are sending events so send exit and gesture
- // end since we transition to another state.
- sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
}
// We know that a new state transition is to happen and the
@@ -736,20 +741,34 @@ class TouchExplorer implements EventStreamTransformation {
+ "there is at least one pointer down!");
}
case MotionEvent.ACTION_UP: {
- mAms.onTouchInteractionEnd();
+ // Offset the event if we are doing a long press as the
+ // target is not necessarily under the user's finger.
+ if (mLongPressingPointerId >= 0) {
+ event = offsetEvent(event, - mLongPressingPointerDeltaX,
+ - mLongPressingPointerDeltaY);
+ // Clear the long press state.
+ mLongPressingPointerId = -1;
+ mLongPressingPointerDeltaX = 0;
+ mLongPressingPointerDeltaY = 0;
+ }
+
+ // Deliver the event.
+ sendMotionEvent(event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
+
// Announce the end of a the touch interaction.
+ mAms.onTouchInteractionEnd();
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
- mLongPressingPointerId = -1;
- mLongPressingPointerDeltaX = 0;
- mLongPressingPointerDeltaY = 0;
+
mCurrentState = STATE_TOUCH_EXPLORING;
} break;
case MotionEvent.ACTION_CANCEL: {
clear(event, policyFlags);
} break;
+ default: {
+ // Deliver the event.
+ sendMotionEvent(event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
+ }
}
- // Deliver the event.
- sendMotionEvent(event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
}
private void handleMotionEventGestureDetecting(MotionEvent event, int policyFlags) {
@@ -959,27 +978,8 @@ class TouchExplorer implements EventStreamTransformation {
// long press it, or even worse to avoid the user long pressing
// on the wrong item since click and long press behave differently.
if (mLongPressingPointerId >= 0) {
- final int remappedIndex = event.findPointerIndex(mLongPressingPointerId);
- final int pointerCount = event.getPointerCount();
- PointerProperties[] props = PointerProperties.createArray(pointerCount);
- PointerCoords[] coords = PointerCoords.createArray(pointerCount);
- for (int i = 0; i < pointerCount; i++) {
- event.getPointerProperties(i, props[i]);
- event.getPointerCoords(i, coords[i]);
- if (i == remappedIndex) {
- coords[i].x -= mLongPressingPointerDeltaX;
- coords[i].y -= mLongPressingPointerDeltaY;
- }
- }
- MotionEvent remapped = MotionEvent.obtain(event.getDownTime(),
- event.getEventTime(), event.getAction(), event.getPointerCount(),
- props, coords, event.getMetaState(), event.getButtonState(),
- 1.0f, 1.0f, event.getDeviceId(), event.getEdgeFlags(),
- event.getSource(), event.getFlags());
- if (event != prototype) {
- event.recycle();
- }
- event = remapped;
+ event = offsetEvent(event, - mLongPressingPointerDeltaX,
+ - mLongPressingPointerDeltaY);
}
if (DEBUG) {
@@ -1004,6 +1004,39 @@ class TouchExplorer implements EventStreamTransformation {
}
/**
+ * Offsets all pointers in the given event by adding the specified X and Y
+ * offsets.
+ *
+ * @param event The event to offset.
+ * @param offsetX The X offset.
+ * @param offsetY The Y offset.
+ * @return An event with the offset pointers or the original event if both
+ * offsets are zero.
+ */
+ private MotionEvent offsetEvent(MotionEvent event, int offsetX, int offsetY) {
+ if (offsetX == 0 && offsetY == 0) {
+ return event;
+ }
+ final int remappedIndex = event.findPointerIndex(mLongPressingPointerId);
+ final int pointerCount = event.getPointerCount();
+ PointerProperties[] props = PointerProperties.createArray(pointerCount);
+ PointerCoords[] coords = PointerCoords.createArray(pointerCount);
+ for (int i = 0; i < pointerCount; i++) {
+ event.getPointerProperties(i, props[i]);
+ event.getPointerCoords(i, coords[i]);
+ if (i == remappedIndex) {
+ coords[i].x += offsetX;
+ coords[i].y += offsetY;
+ }
+ }
+ return MotionEvent.obtain(event.getDownTime(),
+ event.getEventTime(), event.getAction(), event.getPointerCount(),
+ props, coords, event.getMetaState(), event.getButtonState(),
+ 1.0f, 1.0f, event.getDeviceId(), event.getEdgeFlags(),
+ event.getSource(), event.getFlags());
+ }
+
+ /**
* Computes the action for an injected event based on a masked action
* and a pointer index.
*
@@ -1674,7 +1707,6 @@ class TouchExplorer implements EventStreamTransformation {
// Keep track of the last up pointer data.
private long mLastReceivedUpPointerDownTime;
- private int mLastReceivedUpPointerId;
private float mLastReceivedUpPointerDownX;
private float mLastReceivedUpPointerDownY;
@@ -1690,7 +1722,6 @@ class TouchExplorer implements EventStreamTransformation {
mReceivedPointersDown = 0;
mPrimaryPointerId = 0;
mLastReceivedUpPointerDownTime = 0;
- mLastReceivedUpPointerId = 0;
mLastReceivedUpPointerDownX = 0;
mLastReceivedUpPointerDownY = 0;
}
@@ -1823,7 +1854,6 @@ class TouchExplorer implements EventStreamTransformation {
final int pointerId = event.getPointerId(pointerIndex);
final int pointerFlag = (1 << pointerId);
- mLastReceivedUpPointerId = 0;
mLastReceivedUpPointerDownTime = 0;
mLastReceivedUpPointerDownX = 0;
mLastReceivedUpPointerDownX = 0;
@@ -1848,7 +1878,6 @@ class TouchExplorer implements EventStreamTransformation {
final int pointerId = event.getPointerId(pointerIndex);
final int pointerFlag = (1 << pointerId);
- mLastReceivedUpPointerId = pointerId;
mLastReceivedUpPointerDownTime = getReceivedPointerDownTime(pointerId);
mLastReceivedUpPointerDownX = mReceivedPointerDownX[pointerId];
mLastReceivedUpPointerDownY = mReceivedPointerDownY[pointerId];
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index a64940c..ea0b978a 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -26,6 +26,7 @@ import java.util.List;
import android.os.Handler;
import android.os.Looper;
+import android.os.SystemProperties;
import android.util.ArrayMap;
import com.android.internal.app.ProcessStats;
import com.android.internal.os.BatteryStatsImpl;
@@ -76,7 +77,7 @@ public final class ActiveServices {
// How long a service needs to be running until restarting its process
// is no longer considered to be a relaunch of the service.
- static final int SERVICE_RESTART_DURATION = 5*1000;
+ static final int SERVICE_RESTART_DURATION = 1*1000;
// How long a service needs to be running until it will start back at
// SERVICE_RESTART_DURATION after being killed.
@@ -239,7 +240,12 @@ public final class ActiveServices {
public ActiveServices(ActivityManagerService service) {
mAm = service;
- mMaxStartingBackground = ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
+ int maxBg = 0;
+ try {
+ maxBg = Integer.parseInt(SystemProperties.get("ro.config.max_starting_bg", "0"));
+ } catch(RuntimeException e) {
+ }
+ mMaxStartingBackground = maxBg > 0 ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
}
ServiceRecord getServiceByName(ComponentName name, int callingUser) {
@@ -301,7 +307,7 @@ public final class ActiveServices {
ServiceRecord r = res.record;
NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
callingUid, r.packageName, service, service.getFlags(), null);
- if (unscheduleServiceRestartLocked(r)) {
+ if (unscheduleServiceRestartLocked(r, callingUid)) {
if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
}
r.lastActivity = SystemClock.uptimeMillis();
@@ -564,7 +570,7 @@ public final class ActiveServices {
if (r.isForeground) {
r.isForeground = false;
if (r.app != null) {
- mAm.updateLruProcessLocked(r.app, false, false);
+ mAm.updateLruProcessLocked(r.app, false, null);
updateServiceForegroundLocked(r.app, true);
}
}
@@ -597,6 +603,42 @@ public final class ActiveServices {
}
}
+ private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
+ ConnectionRecord modCr) {
+ if (modCr != null && modCr.binding.client != null) {
+ if (modCr.binding.client.activities.size() <= 0) {
+ // This connection is from a client without activities, so adding
+ // and removing is not interesting.
+ return false;
+ }
+ }
+
+ boolean anyClientActivities = false;
+ for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
+ ServiceRecord sr = proc.services.valueAt(i);
+ for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
+ ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
+ for (int cri=clist.size()-1; cri>=0; cri--) {
+ ConnectionRecord cr = clist.get(cri);
+ if (cr.binding.client == null || cr.binding.client == proc) {
+ // Binding to ourself is not interesting.
+ continue;
+ }
+ if (cr.binding.client.activities.size() > 0) {
+ anyClientActivities = true;
+ break;
+ }
+ }
+ }
+ }
+ if (anyClientActivities != proc.hasClientActivities) {
+ proc.hasClientActivities = anyClientActivities;
+ mAm.updateLruProcessLocked(proc, anyClientActivities, null);
+ return true;
+ }
+ return false;
+ }
+
int bindServiceLocked(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
@@ -659,7 +701,7 @@ public final class ActiveServices {
final long origId = Binder.clearCallingIdentity();
try {
- if (unscheduleServiceRestartLocked(s)) {
+ if (unscheduleServiceRestartLocked(s, callerApp.info.uid)) {
if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
+ s);
}
@@ -698,6 +740,9 @@ public final class ActiveServices {
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.hasAboveClient = true;
}
+ if (s.app != null) {
+ updateServiceClientActivitiesLocked(s.app, c);
+ }
clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
@@ -714,6 +759,7 @@ public final class ActiveServices {
if (s.app != null) {
// This could have made the service more important.
+ mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
mAm.updateOomAdjLocked(s.app);
}
@@ -1101,16 +1147,9 @@ public final class ActiveServices {
r.restartCount = 1;
r.restartDelay = minDuration;
} else {
- if ((r.serviceInfo.applicationInfo.flags
- &ApplicationInfo.FLAG_PERSISTENT) != 0) {
- // Services in peristent processes will restart much more
- // quickly, since they are pretty important. (Think SystemUI).
- r.restartDelay += minDuration/2;
- } else {
- r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
- if (r.restartDelay < minDuration) {
- r.restartDelay = minDuration;
- }
+ r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
+ if (r.restartDelay < minDuration) {
+ r.restartDelay = minDuration;
}
}
}
@@ -1137,7 +1176,7 @@ public final class ActiveServices {
} while (repeat);
} else {
- // Persistent processes are immediately restrted, so there is no
+ // Persistent processes are immediately restarted, so there is no
// reason to hold of on restarting their services.
r.totalRestartCount++;
r.restartCount = 0;
@@ -1170,12 +1209,17 @@ public final class ActiveServices {
bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
}
- private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
+ private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid) {
if (r.restartDelay == 0) {
return false;
}
- r.resetRestartCounter();
- mRestartingServices.remove(r);
+ // Remove from the restarting list; if the service is currently on the
+ // restarting list, or the call is coming from another app, then this
+ // service has become of much more interest so we reset the restart interval.
+ boolean removed = mRestartingServices.remove(r);
+ if (removed || callingUid != r.appInfo.uid) {
+ r.resetRestartCounter();
+ }
mAm.mHandler.removeCallbacks(r.restarter);
return true;
}
@@ -1316,7 +1360,8 @@ public final class ActiveServices {
app.services.add(r);
bumpServiceExecutingLocked(r, execInFg, "create");
- mAm.updateLruProcessLocked(app, true, false);
+ mAm.updateLruProcessLocked(app, false, null);
+ mAm.updateOomAdjLocked();
boolean created = false;
try {
@@ -1508,7 +1553,7 @@ public final class ActiveServices {
smap.mServicesByName.remove(r.name);
smap.mServicesByIntent.remove(r.intent);
r.totalRestartCount = 0;
- unscheduleServiceRestartLocked(r);
+ unscheduleServiceRestartLocked(r, 0);
// Also make sure it is not on the pending list.
int N = mPendingServices.size();
@@ -1601,6 +1646,9 @@ public final class ActiveServices {
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.updateHasAboveClientLocked();
}
+ if (s.app != null) {
+ updateServiceClientActivitiesLocked(s.app, c);
+ }
}
clist = mServiceConnections.get(binder);
if (clist != null) {
@@ -1621,6 +1669,13 @@ public final class ActiveServices {
&& b.intent.hasBound) {
try {
bumpServiceExecutingLocked(s, false, "unbind");
+ if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
+ && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
+ // If this service's process is not already in the cached list,
+ // then update it in the LRU list here because this may be causing
+ // it to go down there and we want it to start out near the top.
+ mAm.updateLruProcessLocked(s.app, false, null);
+ }
mAm.updateOomAdjLocked(s.app);
b.intent.hasBound = false;
// Assume the client doesn't want to know about a rebind;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d75fe5e..164e7b7 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -34,7 +34,6 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.ProcessStats;
-import com.android.internal.app.ResolverActivity;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.ProcessCpuTracker;
@@ -218,6 +217,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final boolean DEBUG_IMMERSIVE = localLOGV || false;
static final boolean DEBUG_MU = localLOGV || false;
static final boolean DEBUG_OOM_ADJ = localLOGV || false;
+ static final boolean DEBUG_LRU = localLOGV || false;
static final boolean DEBUG_PAUSE = localLOGV || false;
static final boolean DEBUG_POWER = localLOGV || false;
static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
@@ -457,6 +457,23 @@ public final class ActivityManagerService extends ActivityManagerNative
final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
/**
+ * Information about a process that is currently marked as bad.
+ */
+ static final class BadProcessInfo {
+ BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
+ this.time = time;
+ this.shortMsg = shortMsg;
+ this.longMsg = longMsg;
+ this.stack = stack;
+ }
+
+ final long time;
+ final String shortMsg;
+ final String longMsg;
+ final String stack;
+ }
+
+ /**
* Set of applications that we consider to be bad, and will reject
* incoming broadcasts from (which the user has no control over).
* Processes are added to this set when they have crashed twice within
@@ -464,7 +481,7 @@ public final class ActivityManagerService extends ActivityManagerNative
* later restarted (hopefully due to some user action). The value is the
* time it was added to the list.
*/
- final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
+ final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
/**
* All of the processes we currently have running organized by pid.
@@ -1743,7 +1760,8 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (mSelf.mPidsSelfLocked) {
mSelf.mPidsSelfLocked.put(app.pid, app);
}
- mSelf.updateLruProcessLocked(app, true, false);
+ mSelf.updateLruProcessLocked(app, false, null);
+ mSelf.updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
@@ -2269,7 +2287,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int lrui = mLruProcesses.lastIndexOf(app);
if (lrui < 0) {
- Log.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
+ Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
+ what + " " + obj + " from " + srcApp);
return index;
}
@@ -2289,6 +2307,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (index > 0) {
index--;
}
+ if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
+ + " in LRU list: " + app);
mLruProcesses.add(index, app);
return index;
}
@@ -2306,8 +2326,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean activityChange) {
- final boolean hasActivity = app.activities.size() > 0;
+ final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
+ ProcessRecord client) {
+ final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
final boolean hasService = false; // not impl yet. app.services.size() > 0;
if (!activityChange && hasActivity) {
// The process has activties, so we are only going to allow activity-based
@@ -2321,8 +2342,65 @@ public final class ActivityManagerService extends ActivityManagerNative
final long now = SystemClock.uptimeMillis();
app.lastActivityTime = now;
+ // First a quick reject: if the app is already at the position we will
+ // put it, then there is nothing to do.
+ if (hasActivity) {
+ final int N = mLruProcesses.size();
+ if (N > 0 && mLruProcesses.get(N-1) == app) {
+ if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
+ return;
+ }
+ } else {
+ if (mLruProcessServiceStart > 0
+ && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
+ if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
+ return;
+ }
+ }
+
int lrui = mLruProcesses.lastIndexOf(app);
+ if (app.persistent && lrui >= 0) {
+ // We don't care about the position of persistent processes, as long as
+ // they are in the list.
+ if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
+ return;
+ }
+
+ /* In progress: compute new position first, so we can avoid doing work
+ if the process is not actually going to move. Not yet working.
+ int addIndex;
+ int nextIndex;
+ boolean inActivity = false, inService = false;
+ if (hasActivity) {
+ // Process has activities, put it at the very tipsy-top.
+ addIndex = mLruProcesses.size();
+ nextIndex = mLruProcessServiceStart;
+ inActivity = true;
+ } else if (hasService) {
+ // Process has services, put it at the top of the service list.
+ addIndex = mLruProcessActivityStart;
+ nextIndex = mLruProcessServiceStart;
+ inActivity = true;
+ inService = true;
+ } else {
+ // Process not otherwise of interest, it goes to the top of the non-service area.
+ addIndex = mLruProcessServiceStart;
+ if (client != null) {
+ int clientIndex = mLruProcesses.lastIndexOf(client);
+ if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
+ + app);
+ if (clientIndex >= 0 && addIndex > clientIndex) {
+ addIndex = clientIndex;
+ }
+ }
+ nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
+ }
+
+ Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
+ + mLruProcessActivityStart + "): " + app);
+ */
+
if (lrui >= 0) {
if (lrui < mLruProcessActivityStart) {
mLruProcessActivityStart--;
@@ -2330,23 +2408,91 @@ public final class ActivityManagerService extends ActivityManagerNative
if (lrui < mLruProcessServiceStart) {
mLruProcessServiceStart--;
}
+ /*
+ if (addIndex > lrui) {
+ addIndex--;
+ }
+ if (nextIndex > lrui) {
+ nextIndex--;
+ }
+ */
mLruProcesses.remove(lrui);
}
+ /*
+ mLruProcesses.add(addIndex, app);
+ if (inActivity) {
+ mLruProcessActivityStart++;
+ }
+ if (inService) {
+ mLruProcessActivityStart++;
+ }
+ */
+
int nextIndex;
if (hasActivity) {
- // Process has activities, put it at the very tipsy-top.
- mLruProcesses.add(app);
- nextIndex = mLruProcessActivityStart;
+ final int N = mLruProcesses.size();
+ if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
+ // Process doesn't have activities, but has clients with
+ // activities... move it up, but one below the top (the top
+ // should always have a real activity).
+ if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
+ mLruProcesses.add(N-1, app);
+ // To keep it from spamming the LRU list (by making a bunch of clients),
+ // we will push down any other entries owned by the app.
+ final int uid = app.info.uid;
+ for (int i=N-2; i>mLruProcessActivityStart; i--) {
+ ProcessRecord subProc = mLruProcesses.get(i);
+ if (subProc.info.uid == uid) {
+ // We want to push this one down the list. If the process after
+ // it is for the same uid, however, don't do so, because we don't
+ // want them internally to be re-ordered.
+ if (mLruProcesses.get(i-1).info.uid != uid) {
+ if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
+ + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
+ ProcessRecord tmp = mLruProcesses.get(i);
+ mLruProcesses.set(i, mLruProcesses.get(i-1));
+ mLruProcesses.set(i-1, tmp);
+ i--;
+ }
+ } else {
+ // A gap, we can stop here.
+ break;
+ }
+ }
+ } else {
+ // Process has activities, put it at the very tipsy-top.
+ if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
+ mLruProcesses.add(app);
+ }
+ nextIndex = mLruProcessServiceStart;
} else if (hasService) {
// Process has services, put it at the top of the service list.
+ if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
mLruProcesses.add(mLruProcessActivityStart, app);
nextIndex = mLruProcessServiceStart;
mLruProcessActivityStart++;
} else {
// Process not otherwise of interest, it goes to the top of the non-service area.
- mLruProcesses.add(mLruProcessServiceStart, app);
- nextIndex = mLruProcessServiceStart-1;
+ int index = mLruProcessServiceStart;
+ if (client != null) {
+ // If there is a client, don't allow the process to be moved up higher
+ // in the list than that client.
+ int clientIndex = mLruProcesses.lastIndexOf(client);
+ if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
+ + " when updating " + app);
+ if (clientIndex <= lrui) {
+ // Don't allow the client index restriction to push it down farther in the
+ // list than it already is.
+ clientIndex = lrui;
+ }
+ if (clientIndex >= 0 && index > clientIndex) {
+ index = clientIndex;
+ }
+ }
+ if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
+ mLruProcesses.add(index, app);
+ nextIndex = index-1;
mLruProcessActivityStart++;
mLruProcessServiceStart++;
}
@@ -2357,23 +2503,19 @@ public final class ActivityManagerService extends ActivityManagerNative
ConnectionRecord cr = app.connections.valueAt(j);
if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
&& cr.binding.service.app != null
- && cr.binding.service.app.lruSeq != mLruSeq) {
+ && cr.binding.service.app.lruSeq != mLruSeq
+ && !cr.binding.service.app.persistent) {
nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
"service connection", cr, app);
}
}
for (int j=app.conProviders.size()-1; j>=0; j--) {
ContentProviderRecord cpr = app.conProviders.get(j).provider;
- if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
+ if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
"provider reference", cpr, app);
}
}
-
- //Slog.i(TAG, "Putting proc to front: " + app.processName);
- if (oomAdj) {
- updateOomAdjLocked();
- }
}
final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
@@ -4831,7 +4973,7 @@ public final class ActivityManagerService extends ActivityManagerNative
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
- updateLruProcessLocked(app, false, false);
+ updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
// todo: Yikes! What should we do? For now we will try to
@@ -7419,7 +7561,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// make sure to count it as being accessed and thus
// back up on the LRU list. This is good because
// content providers are often expensive to start.
- updateLruProcessLocked(cpr.proc, false, false);
+ updateLruProcessLocked(cpr.proc, false, null);
}
}
@@ -8028,7 +8170,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (isolated) {
mIsolatedProcesses.put(app.uid, app);
}
- updateLruProcessLocked(app, true, false);
+ updateLruProcessLocked(app, false, null);
+ updateOomAdjLocked();
}
// This package really, really can not be stopped.
@@ -9292,7 +9435,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
startAppProblemLocked(app);
app.stopFreezingAllLocked();
- return handleAppCrashLocked(app);
+ return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
}
private void makeAppNotRespondingLocked(ProcessRecord app,
@@ -9347,13 +9490,14 @@ public final class ActivityManagerService extends ActivityManagerNative
app.waitDialog = null;
}
if (app.pid > 0 && app.pid != MY_PID) {
- handleAppCrashLocked(app);
+ handleAppCrashLocked(app, null, null, null);
killUnneededProcessLocked(app, "user request after error");
}
}
}
- private boolean handleAppCrashLocked(ProcessRecord app) {
+ private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
+ String stackTrace) {
if (mHeadless) {
Log.e(TAG, "handleAppCrashLocked: " + app.processName);
return false;
@@ -9383,7 +9527,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!app.isolated) {
// XXX We don't have a way to mark isolated processes
// as bad, since they don't have a peristent identity.
- mBadProcesses.put(app.info.processName, app.uid, now);
+ mBadProcesses.put(app.info.processName, app.uid,
+ new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
mProcessCrashTimes.remove(app.info.processName, app.uid);
}
app.bad = true;
@@ -10101,7 +10246,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.persistent) {
outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
}
- if (app.hasActivities) {
+ if (app.activities.size() > 0) {
outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
}
outInfo.lastTrimLevel = app.trimMemoryLevel;
@@ -10645,11 +10790,11 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mBadProcesses.getMap().size() > 0) {
boolean printed = false;
- final ArrayMap<String, SparseArray<Long>> pmap = mBadProcesses.getMap();
+ final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
final int NP = pmap.size();
for (int ip=0; ip<NP; ip++) {
String pname = pmap.keyAt(ip);
- SparseArray<Long> uids = pmap.valueAt(ip);
+ SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
final int N = uids.size();
for (int i=0; i<N; i++) {
int puid = uids.keyAt(i);
@@ -10664,10 +10809,33 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(" Bad processes:");
printedAnything = true;
}
+ BadProcessInfo info = uids.valueAt(i);
pw.print(" Bad process "); pw.print(pname);
pw.print(" uid "); pw.print(puid);
- pw.print(": crashed at time ");
- pw.println(uids.valueAt(i));
+ pw.print(": crashed at time "); pw.println(info.time);
+ if (info.shortMsg != null) {
+ pw.print(" Short msg: "); pw.println(info.shortMsg);
+ }
+ if (info.longMsg != null) {
+ pw.print(" Long msg: "); pw.println(info.longMsg);
+ }
+ if (info.stack != null) {
+ pw.println(" Stack:");
+ int lastPos = 0;
+ for (int pos=0; pos<info.stack.length(); pos++) {
+ if (info.stack.charAt(pos) == '\n') {
+ pw.print(" ");
+ pw.write(info.stack, lastPos, pos-lastPos);
+ pw.println();
+ lastPos = pos+1;
+ }
+ }
+ if (lastPos < info.stack.length()) {
+ pw.print(" ");
+ pw.write(info.stack, lastPos, info.stack.length()-lastPos);
+ pw.println();
+ }
+ }
}
}
}
@@ -11857,7 +12025,7 @@ public final class ActivityManagerService extends ActivityManagerNative
thread = r.thread;
pid = r.pid;
oomAdj = r.getSetAdjWithServices();
- hasActivities = r.hasActivities;
+ hasActivities = r.activities.size() > 0;
}
if (thread != null) {
if (!isCheckinRequest && dumpDetails) {
@@ -14079,7 +14247,6 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjTarget = null;
app.empty = false;
app.cached = false;
- app.hasClientActivities = false;
final int activitiesSize = app.activities.size();
@@ -14089,7 +14256,6 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjType = "fixed";
app.adjSeq = mAdjSeq;
app.curRawAdj = app.maxAdj;
- app.hasActivities = false;
app.foregroundActivities = false;
app.keeping = true;
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -14101,16 +14267,12 @@ public final class ActivityManagerService extends ActivityManagerNative
app.systemNoUi = true;
if (app == TOP_APP) {
app.systemNoUi = false;
- app.hasActivities = true;
} else if (activitiesSize > 0) {
for (int j = 0; j < activitiesSize; j++) {
final ActivityRecord r = app.activities.get(j);
if (r.visible) {
app.systemNoUi = false;
}
- if (r.app == app) {
- app.hasActivities = true;
- }
}
}
if (!app.systemNoUi) {
@@ -14121,7 +14283,6 @@ public final class ActivityManagerService extends ActivityManagerNative
app.keeping = false;
app.systemNoUi = false;
- app.hasActivities = false;
// Determine the importance of the process, starting with most
// important to least, and assign an appropriate OOM adjustment.
@@ -14138,7 +14299,6 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjType = "top-activity";
foregroundActivities = true;
interesting = true;
- app.hasActivities = true;
procState = ActivityManager.PROCESS_STATE_TOP;
} else if (app.instrumentationClass != null) {
// Don't want to kill running instrumentation.
@@ -14187,7 +14347,6 @@ public final class ActivityManagerService extends ActivityManagerNative
+ app + "?!?");
continue;
}
- app.hasActivities = true;
if (r.visible) {
// App has a visible activity; only upgrade adjustment.
if (adj > ProcessList.VISIBLE_APP_ADJ) {
@@ -14436,27 +14595,6 @@ public final class ActivityManagerService extends ActivityManagerNative
clientAdj = adj;
}
}
- } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
- if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
- // If this connection is keeping the service
- // created, then we want to try to better follow
- // its memory management semantics for activities.
- // That is, if it is sitting in the background
- // LRU list as a cached process (with activities),
- // we don't want the service it is connected to
- // to go into the empty LRU and quickly get killed,
- // because all we'll do is just end up restarting
- // the service.
- if (client.hasActivities) {
- if (procState >
- ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT) {
- procState =
- ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
- app.adjType = "cch-client-act";
- }
- app.hasClientActivities = true;
- }
- }
}
if (adj > clientAdj) {
// If this process has recently shown UI, and
@@ -14674,6 +14812,12 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
+ // This is a cached process, but with client activities. Mark it so.
+ procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
+ app.adjType = "cch-client-act";
+ }
+
if (adj == ProcessList.SERVICE_ADJ) {
if (doingAll) {
app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
@@ -15302,7 +15446,6 @@ public final class ActivityManagerService extends ActivityManagerNative
// application processes based on their current state.
int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextCachedAdj = curCachedAdj+1;
- int curClientCachedAdj = curCachedAdj+1;
int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextEmptyAdj = curEmptyAdj+2;
for (int i=N-1; i>=0; i--) {
@@ -15317,11 +15460,15 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
switch (app.curProcState) {
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
+ case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
// This process is a cached process holding activities...
// assign it the next cached value for that type, and then
// step that cached level.
app.curRawAdj = curCachedAdj;
app.curAdj = app.modifyRawOomAdj(curCachedAdj);
+ if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
+ + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
+ + ")");
if (curCachedAdj != nextCachedAdj) {
stepCached++;
if (stepCached >= cachedFactor) {
@@ -15331,25 +15478,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
}
- if (curClientCachedAdj <= curCachedAdj) {
- curClientCachedAdj = curCachedAdj + 1;
- if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
- curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
- }
- }
}
}
break;
- case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
- // Special case for cached client processes... just step
- // down from after regular cached processes.
- app.curRawAdj = curClientCachedAdj;
- app.curAdj = app.modifyRawOomAdj(curClientCachedAdj);
- curClientCachedAdj++;
- if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
- curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
- }
- break;
default:
// For everything else, assign next empty cached process
// level and bump that up. Note that this means that
@@ -15358,6 +15489,9 @@ public final class ActivityManagerService extends ActivityManagerNative
// state is still as a service), which is what we want.
app.curRawAdj = curEmptyAdj;
app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
+ if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
+ + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
+ + ")");
if (curEmptyAdj != nextEmptyAdj) {
stepEmpty++;
if (stepEmpty >= emptyFactor) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 44ff3bc..8337613 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -61,7 +61,6 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -997,8 +996,8 @@ final class ActivityStack {
if (r.isHomeActivity()) {
return true;
}
- if (!r.finishing && r.visible && r.fullscreen) {
- // Passed activity is over a visible fullscreen activity.
+ if (!r.finishing && r.fullscreen) {
+ // Passed activity is over a fullscreen activity.
return false;
}
}
@@ -1398,7 +1397,7 @@ final class ActivityStack {
if (next.app != null && next.app.thread != null) {
// No reason to do full oom adj update here; we'll let that
// happen whenever it needs to later.
- mService.updateLruProcessLocked(next.app, false, true);
+ mService.updateLruProcessLocked(next.app, true, null);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
@@ -1526,8 +1525,9 @@ final class ActivityStack {
mResumedActivity = next;
next.task.touchActiveTime();
mService.addRecentTaskLocked(next.task);
- mService.updateLruProcessLocked(next.app, true, true);
+ mService.updateLruProcessLocked(next.app, true, null);
updateLRUListLocked(next);
+ mService.updateOomAdjLocked();
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order.
@@ -2781,7 +2781,7 @@ final class ActivityStack {
}
if (r.app.activities.isEmpty()) {
// No longer have activities, so update LRU list and oom adj.
- mService.updateLruProcessLocked(r.app, false, false);
+ mService.updateLruProcessLocked(r.app, false, null);
mService.updateOomAdjLocked();
}
}
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 7650a65..8251364 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -905,7 +905,8 @@ public final class ActivityStackSupervisor {
if (idx < 0) {
app.activities.add(r);
}
- mService.updateLruProcessLocked(app, true, true);
+ mService.updateLruProcessLocked(app, true, null);
+ mService.updateOomAdjLocked();
final ActivityStack stack = r.task.stack;
try {
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index 5e80135..dd3d8aa 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -220,7 +220,8 @@ public final class BroadcastQueue {
r.curApp = app;
app.curReceiver = r;
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
- mService.updateLruProcessLocked(app, true, false);
+ mService.updateLruProcessLocked(app, false, null);
+ mService.updateOomAdjLocked();
// Tell the application to launch this receiver.
r.intent.setComponent(r.curComponent);
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 486e916..187cd44 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -86,7 +86,6 @@ final class ProcessRecord {
boolean keeping; // Actively running code so don't kill due to that?
boolean setIsForeground; // Running foreground UI when last set?
boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle?
- boolean hasActivities; // Are there any activities running in this process?
boolean hasClientActivities; // Are there any client services with activities?
boolean hasStartedServices; // Are there any started services running in this process?
boolean foregroundServices; // Running any services that are foreground?
@@ -265,9 +264,8 @@ final class ProcessRecord {
pw.print(prefix); pw.print("persistent="); pw.print(persistent);
pw.print(" removed="); pw.println(removed);
}
- if (hasActivities || hasClientActivities || foregroundActivities) {
- pw.print(prefix); pw.print("hasActivities="); pw.print(hasActivities);
- pw.print(" hasClientActivities="); pw.print(hasClientActivities);
+ if (hasClientActivities || foregroundActivities) {
+ pw.print(prefix); pw.print("hasClientActivities="); pw.print(hasClientActivities);
pw.print(" foregroundActivities="); pw.println(foregroundActivities);
}
if (hasStartedServices) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 63e09db..a645c01 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -8269,7 +8269,7 @@ public class WindowManagerService extends IWindowManager.Stub
// windows, since that means "perform layout as normal,
// just don't display").
if (!gone || !win.mHaveFrame || win.mLayoutNeeded
- || (win.mAttrs.type == TYPE_KEYGUARD && win.isConfigChanged())
+ || win.isConfigChanged()
|| win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
if (!win.mLayoutAttached) {
if (initial) {