Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f88dd0b3 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Small service cleanup.

Get rid of duplication between find/retrieve service funcs; when
a service in a persistent process crashes, restart it immediately
since the persistent process is going to be immediately restarted
anyway; when a new process is attaching, immediately restart any
services associated with it that are waiting to restart, since
it is weird to not let them run if the process comes back for some
other reason.

Change-Id: Id087fe04ebf2b6a4bd00732796c8326364765ea7
parent ee8655c6
Loading
Loading
Loading
Loading
+110 −132
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ public class ActiveServices {

        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType,
                    callingPid, callingUid, UserId.getUserId(callingUid));
                    callingPid, callingUid, UserId.getUserId(callingUid), true);
        if (res == null) {
            return null;
        }
@@ -277,8 +277,10 @@ public class ActiveServices {
        }

        // If this service is active, make sure it is stopped.
        ServiceLookupResult r = findServiceLocked(service, resolvedType,
                callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
        ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
                Binder.getCallingPid(), Binder.getCallingUid(),
                callerApp == null ? UserId.getCallingUserId() : callerApp.userId,
                false);
        if (r != null) {
            if (r.record != null) {
                final long origId = Binder.clearCallingIdentity();
@@ -296,8 +298,9 @@ public class ActiveServices {
    }

    IBinder peekServiceLocked(Intent service, String resolvedType) {
        ServiceLookupResult r = findServiceLocked(service, resolvedType,
                UserId.getCallingUserId());
        ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
                Binder.getCallingPid(), Binder.getCallingUid(),
                UserId.getCallingUserId(), false);

        IBinder ret = null;
        if (r != null) {
@@ -471,7 +474,7 @@ public class ActiveServices {

        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType,
                    Binder.getCallingPid(), Binder.getCallingUid(), userId);
                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true);
        if (res == null) {
            return 0;
        }
@@ -482,7 +485,7 @@ public class ActiveServices {
                res.record.serviceInfo.name, res.record.serviceInfo.flags)) {
            userId = 0;
            res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
                    Binder.getCallingUid(), 0);
                    Binder.getCallingUid(), 0, true);
        }
        ServiceRecord s = res.record;

@@ -689,60 +692,6 @@ public class ActiveServices {
            record = _record;
            permission = _permission;
        }
    };

    private ServiceLookupResult findServiceLocked(Intent service,
            String resolvedType, int userId) {
        ServiceRecord r = null;
        if (service.getComponent() != null) {
            r = mServiceMap.getServiceByName(service.getComponent(), userId);
        }
        if (r == null) {
            Intent.FilterComparison filter = new Intent.FilterComparison(service);
            r = mServiceMap.getServiceByIntent(filter, userId);
        }

        if (r == null) {
            try {
                ResolveInfo rInfo =
                    AppGlobals.getPackageManager().resolveService(
                                service, resolvedType, 0, userId);
                ServiceInfo sInfo =
                    rInfo != null ? rInfo.serviceInfo : null;
                if (sInfo == null) {
                    return null;
                }

                ComponentName name = new ComponentName(
                        sInfo.applicationInfo.packageName, sInfo.name);
                r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
            } catch (RemoteException ex) {
                // pm is in same process, this will never happen.
            }
        }
        if (r != null) {
            int callingPid = Binder.getCallingPid();
            int callingUid = Binder.getCallingUid();
            if (mAm.checkComponentPermission(r.permission,
                    callingPid, callingUid, r.appInfo.uid, r.exported)
                    != PackageManager.PERMISSION_GRANTED) {
                if (!r.exported) {
                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
                            + " from pid=" + callingPid
                            + ", uid=" + callingUid
                            + " that is not exported from uid " + r.appInfo.uid);
                    return new ServiceLookupResult(null, "not exported from uid "
                            + r.appInfo.uid);
                }
                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
                        + " from pid=" + callingPid
                        + ", uid=" + callingUid
                        + " requires " + r.permission);
                return new ServiceLookupResult(null, r.permission);
            }
            return new ServiceLookupResult(r, null);
        }
        return null;
    }

    private class ServiceRestarter implements Runnable {
@@ -760,7 +709,8 @@ public class ActiveServices {
    }

    private ServiceLookupResult retrieveServiceLocked(Intent service,
            String resolvedType, int callingPid, int callingUid, int userId) {
            String resolvedType, int callingPid, int callingUid, int userId,
            boolean createIfNeeded) {
        ServiceRecord r = null;
        if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
                + " type=" + resolvedType + " callingUid=" + callingUid);
@@ -796,7 +746,7 @@ public class ActiveServices {
                    sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
                }
                r = mServiceMap.getServiceByName(name, userId);
                if (r == null) {
                if (r == null && createIfNeeded) {
                    Intent.FilterComparison filter = new Intent.FilterComparison(
                            service.cloneFilter());
                    ServiceRestarter res = new ServiceRestarter();
@@ -897,13 +847,11 @@ public class ActiveServices {
        boolean canceled = false;

        final long now = SystemClock.uptimeMillis();
        long minDuration = SERVICE_RESTART_DURATION;
        long resetTime = SERVICE_RESET_RUN_DURATION;

        if ((r.serviceInfo.applicationInfo.flags
                &ApplicationInfo.FLAG_PERSISTENT) != 0) {
            minDuration /= 4;
        }
                &ApplicationInfo.FLAG_PERSISTENT) == 0) {
            long minDuration = SERVICE_RESTART_DURATION;
            long resetTime = SERVICE_RESET_RUN_DURATION;

            // Any delivered but not yet finished starts should be put back
            // on the pending list.
@@ -979,6 +927,15 @@ public class ActiveServices {
                }
            } while (repeat);

        } else {
            // Persistent processes are immediately restrted, so there is no
            // reason to hold of on restarting their services.
            r.totalRestartCount++;
            r.restartCount = 0;
            r.restartDelay = 0;
            r.nextRestartTime = now;
        }

        if (!mRestartingServices.contains(r)) {
            mRestartingServices.add(r);
        }
@@ -1494,6 +1451,7 @@ public class ActiveServices {

    boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
        boolean didSomething = false;
        // Collect any services that are waiting for this process to come up.
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
@@ -1515,6 +1473,22 @@ public class ActiveServices {
                throw e;
            }
        }
        // Also, if there are any services that are waiting to restart and
        // would run in this process, now is a good time to start them.  It would
        // be weird to bring up the process but arbitrarily not let the services
        // run at this point just because their restart time hasn't come up.
        if (mRestartingServices.size() > 0) {
            ServiceRecord sr = null;
            for (int i=0; i<mRestartingServices.size(); i++) {
                sr = mRestartingServices.get(i);
                if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                        || !processName.equals(sr.processName))) {
                    continue;
                }
                mAm.mHandler.removeCallbacks(sr.restarter);
                mAm.mHandler.post(sr.restarter);
            }
        }
        return didSomething;
    }

@@ -1836,7 +1810,8 @@ public class ActiveServices {
        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
        try {
            List<UserInfo> users = mAm.getUserManager().getUsers();
            for (UserInfo user : users) {
            for (int ui=0; ui<users.size(); ui++) {
                final UserInfo user = users.get(ui);
                if (mServiceMap.getAllServices(user.id).size() > 0) {
                    boolean printed = false;
                    long nowReal = SystemClock.elapsedRealtime();
@@ -1852,7 +1827,10 @@ public class ActiveServices {
                            continue;
                        }
                        if (!printed) {
                            pw.println("  Active services:");
                            if (ui > 0) {
                                pw.println();
                            }
                            pw.println("  User " + user.id + " active services:");
                            printed = true;
                        }
                        if (needSep) {
+3 −3
Original line number Diff line number Diff line
@@ -1952,7 +1952,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                mPidsSelfLocked.remove(app.pid);
                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            }
            app.pid = 0;
            app.setPid(0);
        }
        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
@@ -2055,7 +2055,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
            buf.append("}");
            Slog.i(TAG, buf.toString());
            app.pid = startResult.pid;
            app.setPid(startResult.pid);
            app.usingWrapper = startResult.usingWrapper;
            app.removed = false;
            synchronized (mPidsSelfLocked) {
@@ -2067,7 +2067,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
        } catch (RuntimeException e) {
            // XXX do better error recovery.
            app.pid = 0;
            app.setPid(0);
            Slog.e(TAG, "Failure starting process " + app.processName, e);
        }
    }
+1 −2
Original line number Diff line number Diff line
@@ -198,7 +198,6 @@ public class ProviderMap {

    void dumpProvidersLocked(PrintWriter pw, boolean dumpAll) {
        if (mSingletonByClass.size() > 0) {
            pw.println("");
            pw.println("  Published single-user content providers (by class):");
            dumpProvidersByClassLocked(pw, dumpAll, mSingletonByClass);
        }
@@ -206,10 +205,10 @@ public class ProviderMap {
        pw.println("");
        for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
            HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i);
            pw.println("");
            pw.println("  Published user " + mProvidersByClassPerUser.keyAt(i)
                    + " content providers (by class):");
            dumpProvidersByClassLocked(pw, dumpAll, map);
            pw.println(" ");
        }

        if (dumpAll) {