Android13 ActivityManagerService stopServiceToken流程分析

ActivityManagerService的stopServiceToken用于停止一个Service,代码如下:

//frameworks/base/service/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
    final ActiveServices mServices;
    public boolean stopServiceToken(ComponentName className, IBinder token,
            int startId) {
        synchronized(this) {
            return mServices.stopServiceTokenLocked(className, token, startId);
        }
    }
}

ActiveServices stopServiceTokenLocked

调用ActiveServices的stopServiceTokenLocked方法:

//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
    final ActivityManagerService mAm;
    boolean stopServiceTokenLocked(ComponentName className, IBinder token,
            int startId) {
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopServiceToken: " + className
                + " " + token + " startId=" + startId);
        ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
        if (r != null) {
            if (startId >= 0) {
                // Asked to only stop if done with all work.  Note that
                // to avoid leaks, we will take this as dropping all
                // start items up to and including this one.
                ServiceRecord.StartItem si = r.findDeliveredStart(startId, false, false);
                if (si != null) {
                    while (r.deliveredStarts.size() > 0) {
                        ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
                        cur.removeUriPermissionsLocked();
                        if (cur == si) {
                            break;
                        }
                    }
                }


                if (r.getLastStartId() != startId) {
                    return false;
                }


                if (r.deliveredStarts.size() > 0) {
                    Slog.w(TAG, "stopServiceToken startId " + startId
                            + " is last, but have " + r.deliveredStarts.size()
                            + " remaining args");
                }
            }


            final int uid = r.appInfo.uid;
            final String packageName = r.name.getPackageName();
            final String serviceName = r.name.getClassName();
            FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, uid, packageName,
                    serviceName, FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__STOP);
            mAm.mBatteryStatsService.noteServiceStopRunning(uid, packageName, serviceName);
            r.startRequested = false;
            if (r.tracker != null) {
                synchronized (mAm.mProcessStats.mLock) {
                    r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            r.callStart = false;
            final long origId = Binder.clearCallingIdentity();
            bringDownServiceIfNeededLocked(r, false, false, false);
            Binder.restoreCallingIdentity(origId);
            return true;
        }
        return false;
    }
}

调用bringDownServiceIfNeededLocked方法:

//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
    private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
            boolean hasConn, boolean enqueueOomAdj) {
        //Slog.i(TAG, "Bring down service:");
        //r.dump("  ");


        if (isServiceNeededLocked(r, knowConn, hasConn)) {
            return;
        }


        // Are we in the process of launching?
        if (mPendingServices.contains(r)) {
            return;
        }


        bringDownServiceLocked(r, enqueueOomAdj);
    }
}

调用bringDownServiceLocked方法:

//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
    private void bringDownServiceLocked(ServiceRecord r, boolean enqueueOomAdj) {
        //Slog.i(TAG, "Bring down service:");
        //r.dump("  ");


        // Report to all of the connections that the service is no longer
        // available.
        ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
        for (int conni = connections.size() - 1; conni >= 0; conni--) {
            ArrayList<ConnectionRecord> c = connections.valueAt(conni);
            for (int i=0; i<c.size(); i++) {
                ConnectionRecord cr = c.get(i);
                // There is still a connection to the service that is
                // being brought down.  Mark it as dead.
                cr.serviceDead = true;
                cr.stopAssociation();
                final ComponentName clientSideComponentName =
                        cr.aliasComponent != null ? cr.aliasComponent : r.name;
                try {
                    cr.conn.connected(r.name, null, true);
                } catch (Exception e) {
                    Slog.w(TAG, "Failure disconnecting service " + r.shortInstanceName
                          + " to connection " + c.get(i).conn.asBinder()
                          + " (in " + c.get(i).binding.client.processName + ")", e);
                }
            }
        }


        boolean oomAdjusted = false;
        // Tell the service that it has been unbound.
        if (r.app != null && r.app.getThread() != null) {
            for (int i = r.bindings.size() - 1; i >= 0; i--) {
                IntentBindRecord ibr = r.bindings.valueAt(i);
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding " + ibr
                        + ": hasBound=" + ibr.hasBound);
                if (ibr.hasBound) {
                    try {
                        oomAdjusted |= bumpServiceExecutingLocked(r, false, "bring down unbind",
                                OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                        ibr.hasBound = false;
                        ibr.requested = false;
                        r.app.getThread().scheduleUnbindService(r,
                                ibr.intent.getIntent());
                    } catch (Exception e) {
                        Slog.w(TAG, "Exception when unbinding service "
                                + r.shortInstanceName, e);
                        serviceProcessGoneLocked(r, enqueueOomAdj);
                        break;
                    }
                }
            }
        }


        // Check to see if the service had been started as foreground, but being
        // brought down before actually showing a notification.  That is not allowed.
        if (r.fgRequired) {
            Slog.w(TAG_SERVICE, "Bringing down service while still waiting for start foreground: "
                    + r);
            r.fgRequired = false;
            r.fgWaiting = false;
            synchronized (mAm.mProcessStats.mLock) {
                ServiceState stracker = r.getTracker();
                if (stracker != null) {
                    stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            mAm.mAppOpsService.finishOperation(AppOpsManager.getToken(mAm.mAppOpsService),
                    AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
            mAm.mHandler.removeMessages(
                    ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
            if (r.app != null) {
                Message msg = mAm.mHandler.obtainMessage(
                        ActivityManagerService.SERVICE_FOREGROUND_CRASH_MSG);
                SomeArgs args = SomeArgs.obtain();
                args.arg1 = r.app;
                args.arg2 = r.toString();
                args.arg3 = r.getComponentName();


                msg.obj = args;
                mAm.mHandler.sendMessage(msg);
            }
        }


        if (DEBUG_SERVICE) {
            RuntimeException here = new RuntimeException();
            here.fillInStackTrace();
            Slog.v(TAG_SERVICE, "Bringing down " + r + " " + r.intent, here);
        }
        r.destroyTime = SystemClock.uptimeMillis();
        if (LOG_SERVICE_START_STOP) {
            EventLogTags.writeAmDestroyService(
                    r.userId, System.identityHashCode(r), (r.app != null) ? r.app.getPid() : -1);
        }


        final ServiceMap smap = getServiceMapLocked(r.userId);
        ServiceRecord found = smap.mServicesByInstanceName.remove(r.instanceName);


        // Note when this method is called by bringUpServiceLocked(), the service is not found
        // in mServicesByInstanceName and found will be null.
        if (found != null && found != r) {
            // This is not actually the service we think is running...  this should not happen,
            // but if it does, fail hard.
            smap.mServicesByInstanceName.put(r.instanceName, found);
            throw new IllegalStateException("Bringing down " + r + " but actually running "
                    + found);
        }
        smap.mServicesByIntent.remove(r.intent);
        r.totalRestartCount = 0;
        unscheduleServiceRestartLocked(r, 0, true);


        // Also make sure it is not on the pending list.
        for (int i=mPendingServices.size()-1; i>=0; i--) {
            if (mPendingServices.get(i) == r) {
                mPendingServices.remove(i);
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Removed pending: " + r);
            }
        }
        if (mPendingBringups.remove(r) != null) {
            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Removed pending bringup: " + r);
        }


        cancelForegroundNotificationLocked(r);
        final boolean exitingFg = r.isForeground;
        if (exitingFg) {
            decActiveForegroundAppLocked(smap, r);
            synchronized (mAm.mProcessStats.mLock) {
                ServiceState stracker = r.getTracker();
                if (stracker != null) {
                    stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            mAm.mAppOpsService.finishOperation(
                    AppOpsManager.getToken(mAm.mAppOpsService),
                    AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
            unregisterAppOpCallbackLocked(r);
            r.mFgsExitTime = SystemClock.uptimeMillis();
            logFGSStateChangeLocked(r,
                    FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT,
                    r.mFgsExitTime > r.mFgsEnterTime
                            ? (int) (r.mFgsExitTime - r.mFgsEnterTime) : 0,
                    FGS_STOP_REASON_STOP_SERVICE);
            mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
        }


        r.isForeground = false;
        r.mFgsNotificationWasDeferred = false;
        dropFgsNotificationStateLocked(r);
        r.foregroundId = 0;
        r.foregroundNoti = null;
        resetFgsRestrictionLocked(r);
        // Signal FGS observers *after* changing the isForeground state, and
        // only if this was an actual state change.
        if (exitingFg) {
            signalForegroundServiceObserversLocked(r);
        }


        // Clear start entries.
        r.clearDeliveredStartsLocked();
        r.pendingStarts.clear();
        smap.mDelayedStartList.remove(r);


        if (r.app != null) {
            mAm.mBatteryStatsService.noteServiceStopLaunch(r.appInfo.uid, r.name.getPackageName(),
                    r.name.getClassName());
            stopServiceAndUpdateAllowlistManagerLocked(r);
            if (r.app.getThread() != null) {
                // Bump the process to the top of LRU list
                mAm.updateLruProcessLocked(r.app, false, null);
                updateServiceForegroundLocked(r.app.mServices, false);
                try {
                    oomAdjusted |= bumpServiceExecutingLocked(r, false, "destroy",
                            oomAdjusted ? null : OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                    mDestroyingServices.add(r);
                    r.destroying = true;
                    r.app.getThread().scheduleStopService(r);
                } catch (Exception e) {
                    Slog.w(TAG, "Exception when destroying service "
                            + r.shortInstanceName, e);
                    serviceProcessGoneLocked(r, enqueueOomAdj);
                }
            } else {
                if (DEBUG_SERVICE) Slog.v(
                    TAG_SERVICE, "Removed service that has no process: " + r);
            }
        } else {
            if (DEBUG_SERVICE) Slog.v(
                TAG_SERVICE, "Removed service that is not running: " + r);
        }


        if (!oomAdjusted) {
            mAm.enqueueOomAdjTargetLocked(r.app);
            if (!enqueueOomAdj) {
                mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
            }
        }
        if (r.bindings.size() > 0) {
            r.bindings.clear();
        }


        if (r.restarter instanceof ServiceRestarter) {
           ((ServiceRestarter)r.restarter).setService(null);
        }


        synchronized (mAm.mProcessStats.mLock) {
            final int memFactor = mAm.mProcessStats.getMemFactorLocked();
            if (r.tracker != null) {
                final long now = SystemClock.uptimeMillis();
                r.tracker.setStarted(false, memFactor, now);
                r.tracker.setBound(false, memFactor, now);
                if (r.executeNesting == 0) {
                    r.tracker.clearCurrentOwner(r, false);
                    r.tracker = null;
                }
            }
        }


        smap.ensureNotStartingBackgroundLocked(r);
        updateNumForegroundServicesLocked();
    }
}

ApplicationThread scheduleStopService

r.app.getThread()返回IApplicationThread接口,调用IApplicationThread的scheduleStopService方法,IApplicationThread是一个接口由ActivityThread的内部类ApplicationThread实现:

//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    private class ApplicationThread extends IApplicationThread.Stub {
        public final void scheduleStopService(IBinder token) {
            sendMessage(H.STOP_SERVICE, token);
        }
    }
}

发送STOP_SERVICE消息,消息在H的handleMessage中处理:

//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
    class H extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case STOP_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
                    handleStopService((IBinder)msg.obj);
                    schedulePurgeIdler();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
            }
        }
    }
}
ActivityThread handleStopService

调用ActivityThread的handleStopService方法:

Android13 ActivityThread handleStopService流程分析-CSDN博客

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值