Skip to content

Commit b12e135

Browse files
author
Dianne Hackborn
committed
Maybe fix issue #7211766: bindService() to User u0 While u10 is...
...Forground Sometimes Doesn't Take The main change here is a one-liner in ActiveServices to check the uid when deciding whether to remove an item from mPendingServices. This could cause the problem being seen -- if the same service for two users is starting at the same time, the second one would blow away the pending start of the first one. Unfortunately I have had trouble reproducing the bug, so I don't know if this is actually fixing it. It's a bug, anyway. The reason so much has changed here is because I spread around logging and printing of the user ID associated with operations and objects to make it easier to debug these kind of multi-user things. Also includes some tweaks to the oom manager to allow more background processes (I have seen many times in logs where we thrash through processes because the LRU list is too short), plus to compensate an additional time-based metric for when to get rid of background processes, plus some new logic to try to help things like Chrome keep around their service processes. Change-Id: Icda77fb2a1dd349969e3ff2c8fff0f19b40b31d3
1 parent 2fd6cb0 commit b12e135

17 files changed

+313
-164
lines changed

cmds/am/src/com/android/commands/am/Am.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -804,8 +804,9 @@ private void runDumpHeap() throws Exception {
804804
ParcelFileDescriptor fd = null;
805805

806806
try {
807-
fd = ParcelFileDescriptor.open(
808-
new File(heapFile),
807+
File file = new File(heapFile);
808+
file.delete();
809+
fd = ParcelFileDescriptor.open(file,
809810
ParcelFileDescriptor.MODE_CREATE |
810811
ParcelFileDescriptor.MODE_TRUNCATE |
811812
ParcelFileDescriptor.MODE_READ_WRITE);

core/java/android/app/ActivityManagerNative.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1509,9 +1509,9 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
15091509
case DUMP_HEAP_TRANSACTION: {
15101510
data.enforceInterface(IActivityManager.descriptor);
15111511
String process = data.readString();
1512+
int userId = data.readInt();
15121513
boolean managed = data.readInt() != 0;
15131514
String path = data.readString();
1514-
int userId = data.readInt();
15151515
ParcelFileDescriptor fd = data.readInt() != 0
15161516
? data.readFileDescriptor() : null;
15171517
boolean res = dumpHeap(process, userId, managed, path, fd);

core/java/android/app/ActivityThread.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,7 +2711,7 @@ public final ActivityClientRecord performResumeActivity(IBinder token,
27112711
r.activity.performResume();
27122712

27132713
EventLog.writeEvent(LOG_ON_RESUME_CALLED,
2714-
r.activity.getComponentName().getClassName());
2714+
UserHandle.myUserId(), r.activity.getComponentName().getClassName());
27152715

27162716
r.paused = false;
27172717
r.stopped = false;
@@ -2979,7 +2979,8 @@ final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
29792979
// Now we are idle.
29802980
r.activity.mCalled = false;
29812981
mInstrumentation.callActivityOnPause(r.activity);
2982-
EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName());
2982+
EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
2983+
r.activity.getComponentName().getClassName());
29832984
if (!r.activity.mCalled) {
29842985
throw new SuperNotCalledException(
29852986
"Activity " + r.intent.getComponent().toShortString() +
@@ -3364,7 +3365,7 @@ private ActivityClientRecord performDestroyActivity(IBinder token, boolean finis
33643365
try {
33653366
r.activity.mCalled = false;
33663367
mInstrumentation.callActivityOnPause(r.activity);
3367-
EventLog.writeEvent(LOG_ON_PAUSE_CALLED,
3368+
EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
33683369
r.activity.getComponentName().getClassName());
33693370
if (!r.activity.mCalled) {
33703371
throw new SuperNotCalledException(

core/java/android/content/Context.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public abstract class Context {
178178
* Flag for {@link #bindService}: indicates that the client application
179179
* binding to this service considers the service to be more important than
180180
* the app itself. When set, the platform will try to have the out of
181-
* memory kill the app before it kills the service it is bound to, though
181+
* memory killer kill the app before it kills the service it is bound to, though
182182
* this is not guaranteed to be the case.
183183
*/
184184
public static final int BIND_ABOVE_CLIENT = 0x0008;
@@ -218,6 +218,19 @@ public abstract class Context {
218218
*/
219219
public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
220220

221+
/**
222+
* @hide An idea that is not yet implemented.
223+
* Flag for {@link #bindService}: If binding from an activity, consider
224+
* this service to be visible like the binding activity is. That is,
225+
* it will be treated as something more important to keep around than
226+
* invisible background activities. This will impact the number of
227+
* recent activities the user can switch between without having them
228+
* restart. There is no guarantee this will be respected, as the system
229+
* tries to balance such requests from one app vs. the importantance of
230+
* keeping other apps around.
231+
*/
232+
public static final int BIND_VISIBLE = 0x0100;
233+
221234
/**
222235
* Flag for {@link #bindService}: Don't consider the bound service to be
223236
* visible, even if the caller is visible.

services/java/com/android/server/am/ActiveServices.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import android.content.pm.PackageManager;
4545
import android.content.pm.ResolveInfo;
4646
import android.content.pm.ServiceInfo;
47-
import android.content.pm.UserInfo;
4847
import android.os.Binder;
4948
import android.os.IBinder;
5049
import android.os.Message;
@@ -391,7 +390,7 @@ public void setServiceForegroundLocked(ComponentName className, IBinder token,
391390
if (r.isForeground) {
392391
r.isForeground = false;
393392
if (r.app != null) {
394-
mAm.updateLruProcessLocked(r.app, false, true);
393+
mAm.updateLruProcessLocked(r.app, false);
395394
updateServiceForegroundLocked(r.app, true);
396395
}
397396
}
@@ -760,7 +759,8 @@ private ServiceLookupResult retrieveServiceLocked(Intent service,
760759
int N = mPendingServices.size();
761760
for (int i=0; i<N; i++) {
762761
ServiceRecord pr = mPendingServices.get(i);
763-
if (pr.name.equals(name)) {
762+
if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
763+
&& pr.name.equals(name)) {
764764
mPendingServices.remove(i);
765765
i--;
766766
N--;
@@ -942,7 +942,7 @@ private final boolean scheduleServiceRestartLocked(ServiceRecord r,
942942
Slog.w(TAG, "Scheduling restart of crashed service "
943943
+ r.shortName + " in " + r.restartDelay + "ms");
944944
EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
945-
r.shortName, r.restartDelay);
945+
r.userId, r.shortName, r.restartDelay);
946946

947947
return canceled;
948948
}
@@ -1083,14 +1083,14 @@ private final void realStartServiceLocked(ServiceRecord r,
10831083

10841084
app.services.add(r);
10851085
bumpServiceExecutingLocked(r, "create");
1086-
mAm.updateLruProcessLocked(app, true, true);
1086+
mAm.updateLruProcessLocked(app, true);
10871087

10881088
boolean created = false;
10891089
try {
10901090
mAm.mStringBuilder.setLength(0);
10911091
r.intent.getIntent().toShortString(mAm.mStringBuilder, true, false, true, false);
10921092
EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
1093-
System.identityHashCode(r), r.shortName,
1093+
r.userId, System.identityHashCode(r), r.shortName,
10941094
mAm.mStringBuilder.toString(), r.app.pid);
10951095
synchronized (r.stats.getBatteryStats()) {
10961096
r.stats.startLaunchedLocked();
@@ -1240,7 +1240,7 @@ private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
12401240

12411241
if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
12421242
EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
1243-
System.identityHashCode(r), r.shortName,
1243+
r.userId, System.identityHashCode(r), r.shortName,
12441244
(r.app != null) ? r.app.pid : -1);
12451245

12461246
mServiceMap.removeServiceByName(r.name, r.userId);
@@ -1664,7 +1664,7 @@ final void killServicesLocked(ProcessRecord app,
16641664
Slog.w(TAG, "Service crashed " + sr.crashCount
16651665
+ " times, stopping: " + sr);
16661666
EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
1667-
sr.crashCount, sr.shortName, app.pid);
1667+
sr.userId, sr.crashCount, sr.shortName, app.pid);
16681668
bringDownServiceLocked(sr, true);
16691669
} else if (!allowRestart) {
16701670
bringDownServiceLocked(sr, true);

0 commit comments

Comments
 (0)