import android.util.ArrayMap;
import android.util.ArraySet;
-import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.app.procstats.ServiceState;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.TransferPipe;
mAm.updateProcessForegroundLocked(proc, anyForeground, oomAdj);
}
+ private void updateWhitelistManagerLocked(ProcessRecord proc) {
+ proc.whitelistManager = false;
+ for (int i=proc.services.size()-1; i>=0; i--) {
+ ServiceRecord sr = proc.services.valueAt(i);
+ if (sr.whitelistManager) {
+ proc.whitelistManager = true;
+ break;
+ }
+ }
+ }
+
public void updateServiceConnectionActivitiesLocked(ProcessRecord clientProc) {
ArraySet<ProcessRecord> updatedProcesses = null;
for (int i = 0; i < clientProc.connections.size(); i++) {
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.hasAboveClient = true;
}
+ if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
+ s.whitelistManager = true;
+ }
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
s.app.treatLikeActivity = true;
}
+ if (s.whitelistManager) {
+ s.app.whitelistManager = true;
+ }
// This could have made the service more important.
mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
|| s.app.treatLikeActivity, b.client);
}
}
+ if (r.whitelistManager) {
+ app.whitelistManager = true;
+ }
+
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
r.stats.stopLaunchedLocked();
}
r.app.services.remove(r);
+ if (r.whitelistManager) {
+ updateWhitelistManagerLocked(r.app);
+ }
if (r.app.thread != null) {
updateServiceForegroundLocked(r.app, false);
try {
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.updateHasAboveClientLocked();
}
+ // If this connection requested whitelist management, see if we should
+ // now clear that state.
+ if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
+ s.updateWhitelistManager();
+ if (!s.whitelistManager && s.app != null) {
+ updateWhitelistManagerLocked(s.app);
+ }
+ }
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
if (finishing) {
if (r.app != null && !r.app.persistent) {
r.app.services.remove(r);
+ if (r.whitelistManager) {
+ updateWhitelistManagerLocked(r.app);
+ }
}
r.app = null;
}
service.app.removed = killProcess;
if (!service.app.persistent) {
service.app.services.remove(service);
+ if (service.whitelistManager) {
+ updateWhitelistManagerLocked(service.app);
+ }
}
}
service.app = null;
updateServiceConnectionActivitiesLocked(app);
app.connections.clear();
+ app.whitelistManager = false;
+
// Clear app state from services.
for (int i = app.services.size() - 1; i >= 0; i--) {
ServiceRecord sr = app.services.valueAt(i);
ProcessRecord isolatedProc; // keep track of isolated process, if requested
ServiceState tracker; // tracking service execution, may be null
ServiceState restartTracker; // tracking service restart
+ boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
boolean delayed; // are we waiting to start this service in the background?
boolean isForeground; // is service currently in foreground mode?
int foregroundId; // Notification ID of last foreground req.
if (isolatedProc != null) {
pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc);
}
+ if (whitelistManager) {
+ pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager);
+ }
if (delayed) {
pw.print(prefix); pw.print("delayed="); pw.println(delayed);
}
return false;
}
+ public void updateWhitelistManager() {
+ whitelistManager = false;
+ for (int conni=connections.size()-1; conni>=0; conni--) {
+ ArrayList<ConnectionRecord> cr = connections.valueAt(conni);
+ for (int i=0; i<cr.size(); i++) {
+ if ((cr.get(i).flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
+ whitelistManager = true;
+ return;
+ }
+ }
+ }
+ }
+
public void resetRestartCounter() {
restartCount = 0;
restartDelay = 0;