ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2011年11月23日 星期三

forceStopPackage

ActivityManager.java: 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 殺掉。

沒有留言:

標籤

網誌存檔