public void forceStopPackage(String packageName) {
try {
ActivityManagerNative.getDefault().forceStopPackage(packageName);
} catch (RemoteException e) {
}
}
call 的是ActivivityManagerProxy Implement IActivityManager:
public void forceStopPackage(String packageName) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeString(packageName);
mRemote.transact(FORCE_STOP_PACKAGE_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
mRemote transact 經由 IBinder 傳送 FORCE_STO_PACKAGE_TRANSACTION 需求。
收到並執行的是
在 ActivityManagerNative 的 onTransact():
case FORCE_STOP_PACKAGE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String packageName = data.readString();
forceStopPackage(packageName);
reply.writeNoException();
return true;
}
onTransact 的 case handler
呼叫的是ActivityManagerService 的 forceStopPackage(?):
IPackageManager pm = AppGlobals.getPackageManager();
int pkgUid = pm.getPackageUid(packageName);
forceStopPackageLocked(packageName, pkgUid);
就是從 package manager 找出 packageName 的 pid,然後 call forceStopPackageLocked( ) 結束他。
其中的 forceStopPackageLocked 是:
private void forceStopPackageLocked(final String packageName, int uid) {
forceStopPackageLocked(packageName, uid, false, false, true);
Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
Uri.fromParts("package", packageName, null));
if (!mProcessesReady) {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}
intent.putExtra(Intent.EXTRA_UID, uid);
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null,
false, false, MY_PID, Process.SYSTEM_UID);
}
就是call forceStopPackageLocked( ) 結束他,然後再 broadcast ACTION_PACKAGE_RESTARTED.. (叫他再起來?) Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
while (badApps.hasNext()) {
SparseArray ba = badApps.next();
if (ba.get(uid) != null) {
badApps.remove();
}
}
把 mProcessCrashTime (上次system crash 時的 proces map) 中,同 uid 的 process data 從 record map 中移除。 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
callerWillRestart, doit);
然後 killPackageProcessLocked( ). for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
if (r.packageName.equals(name)) {
if (!doit) {
return true;
}
didSomething = true;
Slog.i(TAG, " Force finishing activity " + r);
if (r.app != null) {
r.app.removed = true;
}
r.app = null;
r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
}
}
然後再從 目前系統 activiry stack (所有執行過的 activity) 中,找出符合name 的package,作 RESULT_CANCELED 的 finishActivityLocked( )。後面看起來會把 activity stack 中 下一個 activity resume 回來 (到 top)。
如果 stack 是空的,就 launch home launcher
trace code 的其中一點,最後是用 kill 把 process 殺掉。
沒有留言:
張貼留言