1. 程式人生 > >彈出SD卡導致的重啟問題分析

彈出SD卡導致的重啟問題分析

2018-10-10

 

在Android8.0上,安裝SD卡,設定為內部儲存,然後把安裝的應用move到SD卡上,開啟應用,然後在setting裡彈出(reject)SD卡,會發生重啟。

log

01-01 21:04:55.321858 1050 1081 D PackageManager: Unloaded packages [ApplicationInfo{7df5ec0 com.tencent.mm} ]

 01-01 21:04:55.322845 1050 1067 I ActivityManager: Force stopping com.tencent.mm appid=10179 user=-1: unloadPrivatePackagesInner

 01-01 21:04:55.322844 1050 1068 W Looper : Dispatch took 299ms on android.ui, h=Handler (com.android.server.am.ActivityManagerService$UiHandler) {a45381f} cb=null msg=30

 01-01 21:04:55.323047 1050 1067 I ActivityManager: Killing 9970:com.tencent.mm:push/u0a179 (adj 500): stop com.tencent.mm

 01-01 21:04:55.324681 1050 1067 W ActivityManager: Scheduling restart of crashed service com.tencent.mm/.booter.CoreService in 1000ms

 01-01 21:04:55.328698 1050 1067 I ActivityManager: Killing 9891:com.tencent.mm/u0a179 (adj 700): stop com.tencent.mm

 01-01 21:04:55.329688 448 452 E ProcessKiller: Process system_server (1050) has open file /mnt/expand/fe412b2c-f199-4b78-984e-e33272b9181e/app/com.tencent.mm-44r-mWZ0V21gx7ExIq1UGA==/base.apk

 01-01 21:04:55.329822 448 452 W ProcessKiller: Sending Interrupt to process 1050

 01-01 21:04:55.475353 448 452 E ProcessKiller: Process com.android.nfc (2032) has open file /mnt/expand/fe412b2c-f199-4b78-984e-e33272b9181e/app/com.tencent.mm-44r-mWZ0V21gx7ExIq1UGA==/base.apk

 01-01 21:04:55.475409 448 452 W ProcessKiller: Sending Interrupt to process 2032

 01-01 21:04:55.535982 448 452 E ProcessKiller: Process com.android.launcher3 (2137) has open file /mnt/expand/fe412b2c-f199-4b78-984e-e33272b9181e/app/com.tencent.mm-44r-mWZ0V21gx7ExIq1UGA==/base.apk

 01-01 21:04:55.536086 448 452 W ProcessKiller: Sending Interrupt to process 2137

 

在KillProcessesUsingPath里加sleep,臨時解決重啟問題

 

status_t KillProcessesUsingPath(const std::string& path) {

    const char* cpath = path.c_str();

SLOGD("====vold KillProcessesUsingPath called, path=%s", cpath);

if (cpath != NULL && strstr(cpath, "/mnt/expand") != NULL)

{

SLOGD("====sleep ");

sleep(3);

}

    if (Process::killProcessesWithOpenFiles(cpath, SIGINT) == 0) {

        return OK;

    }

    sleep(5);

 

 

01-01 16:41:20.982   435   439 D VoldCmdListener: volume unmount private:179,130

01-01 16:41:20.982   435   439 D Vold2   : ====vold KillProcessesUsingPath called

 

 

01-01 16:41:20.992  1037  1071 D PackageManager: deletePackageLI: com.tencent.mm user null

01-01 16:41:20.992  1037  1071 D PackageManager: Removing non-system package: com.tencent.mm

01-01 16:41:20.992  1037  1071 D PackageManager: removePackageDataLI: PackageSetting{bf4cb1 com.tencent.mm/10108}

 

01-01 16:41:21.143  1037  1057 D ActivityManager: ===713, forceStopPackageLocked called

01-01 16:41:21.143  1037  1057 I ActivityManager: Force stopping com.tencent.mm appid=10108 user=-1: unloadPrivatePackagesInner

01-01 16:41:21.143  1037  1057 I ActivityManager: Killing 7828:com.tencent.mm:push/u0a108 (adj 500): stop com.tencent.mm

 

 

01-01 16:41:21.714  1037  1045 W asset   : ===713 Destroying SharedZip 0x79814ff260 /mnt/expand/819873b5-dbc1-4ad2-8448-c4213d998b8a/app/com.tencent.mm-nF1YCsQ45suvWQdwOu_8GQ==/base.apk

01-01 16:41:21.714  1037  1045 W asset   : ===713 Closed '/mnt/expand/819873b5-dbc1-4ad2-8448-c4213d998b8a/app/com.tencent.mm-nF1YCsQ45suvWQdwOu_8GQ==/base.apk'

 

 

01-01 16:41:25.983   435   439 I ProcessKiller: killProcessesWithOpenFiles ++, path=/mnt/expand/819873b5-dbc1-4ad2-8448-c4213d998b8a, signal=2

01-01 16:41:26.884   435   439 E ProcessKiller: Process com.android.nfc (7490) has open file /mnt/expand/819873b5-dbc1-4ad2-8448-c4213d998b8a/app/com.tencent.mm-nF1YCsQ45suvWQdwOu_8GQ==/base.apk

01-01 16:41:26.884   435   439 W ProcessKiller: Sending Interrupt to process 7490

01-01 16:41:26.897   435   439 I ProcessKiller: killProcessesWithOpenFiles --, path=/mnt/expand/819873b5-dbc1-4ad2-8448-c4213d998b8a, signal=2

 

reject的處理

/packages/apps/Settings/src/com/android/settings/deviceinfo/PrivateVolumeUnmount.java

 

64    private final OnClickListener mConfirmListener = new OnClickListener() {
65        @Override
66        public void onClick(View v) {
67            new UnmountTask(getActivity(), mVolume).execute();
68            getActivity().finish();
69        }
70    };

 

 

frameworks/base$ vi ./services/core/java/com/android/server/StorageManagerService.java

unmount(

1777    public void unmount(String volId) {
1778        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
1779        waitForReady();
1780
1781        final VolumeInfo vol = findVolumeByIdOrThrow(volId);
1782
1783        // TODO: expand PMS to know about multiple volumes
1784        if (vol.isPrimaryPhysical()) {
1785            final long ident = Binder.clearCallingIdentity();
1786            try {
1787                synchronized (mUnmountLock) {
1788                    mUnmountSignal = new CountDownLatch(1);
1789                    mPms.updateExternalMediaStatus(false, true);
1790                    waitForLatch(mUnmountSignal, "mUnmountSignal");
1791                    mUnmountSignal = null;
1792                }
1793            } finally {
1794                Binder.restoreCallingIdentity(ident);
1795            }
1796        }
1797
1798        try {
1799            mConnector.execute("volume", "unmount", vol.id);
1800        } catch (NativeDaemonConnectorException e) {
1801            throw e.rethrowAsParcelableException();
1802        }
1803    }

 

 

frameworks/base$ vi ./services/core/java/com/android/server/pm/PackageManagerService.java

 

處理流程有問題,

進行了unmount操作後,vold會執行KillProcessesUsingPath進行kill操作

然後

01-01 12:10:44.910  1037  1201 D VoldConnector: RCV <- {651 private:179,130 5}

01-01 12:10:44.910  1037  1062 D StorageManagerService: VOLUME_STATE_CHANGED

01-01 12:10:44.911  1037  1201 D VoldConnector: RCV <- {651 emulated:179,130 5}

vold向StorageManagerService傳送訊號,呼叫起PMS的unloadPrivatePackagesInner方法,進行解除安裝清理操作

 

這個執行順序有問題,PMS的解除安裝操作還沒有完成,KillProcessesUsingPath會把system_server程序kill掉,導致了重啟

 

可以在unmount操作裡執行

               mPms.updateExternalMediaStatus(false, true);

 

後再呼叫      mConnector.execute("volume", "unmount", vol.id);