Android 恢复系统调用流程

作者: NiceDream | 来源:发表于2017-06-14 08:43 被阅读126次

    com.android.settings.MasterClear

    private void showFinalConfirmation() {
            Preference preference = new Preference(getActivity());
            preference.setFragment(MasterClearConfirm.class.getName());
            preference.setTitle(R.string.master_clear_confirm_title);
            preference.getExtras().putBoolean(ERASE_EXTERNAL_EXTRA, mExternalStorage.isChecked());
            ((SettingsActivity) getActivity()).onPreferenceStartFragment(null, preference);
        }
    

    MasterClearConfirm.java

    Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);

        private void doMasterClear() {
            if (mEraseSdCard) {
                Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
                intent.putExtra(Intent.EXTRA_REASON, "WipeAllFlash");
                intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
                getActivity().startService(intent);
            } else {
                Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
                intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
                getActivity().sendBroadcast(intent);
                // Intent handling is asynchronous -- assume it will happen soon.
            }
        }
    

    core/res/AndroidManifest.xml: <receiver android:name="com.android.server.MasterClearReceiver"

    系统注册一个receiver

    <receiver android:name="com.android.server.MasterClearReceiver"
                android:permission="android.permission.MASTER_CLEAR">
                <intent-filter
                        android:priority="100" >
                    <!-- For Checkin, Settings, etc.: action=MASTER_CLEAR -->
                    <action android:name="android.intent.action.MASTER_CLEAR" />
    
                    <!-- MCS always uses REMOTE_INTENT: category=MASTER_CLEAR -->
                    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                    <category android:name="android.intent.category.MASTER_CLEAR" />
                </intent-filter>
            </receiver>
    

    services/core/java/com/android/server/MasterClearReceiver.java

    Thread thr = new Thread("Reboot") {
                @Override
                public void run() {
                    try {
                        RecoverySystem.rebootWipeUserData(context, shutdown, reason);
                        Log.wtf(TAG, "Still running after master clear?!");
                    } catch (IOException e) {
                        Slog.e(TAG, "Can't perform master clear/factory reset", e);
                    } catch (SecurityException e) {
                        Slog.e(TAG, "Can't perform master clear/factory reset", e);
                    }
                }
            };
            thr.start();
    

    格式化sdcard,执行umount命令

    core/res/AndroidManifest.xml: <service android:name="com.android.internal.os.storage.ExternalStorageFormatter“

    <service android:name="com.android.internal.os.storage.ExternalStorageFormatter"
                android:permission="android.permission.MASTER_CLEAR"
                android:exported="true" />
    

    services/core/java/com/android/server/MountService.java

    public void unmountVolume(String path, boolean force, boolean removeEncryption) {
            validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
            waitForReady();
    
            String volState = getVolumeState(path);
            if (DEBUG_UNMOUNT) {
                Slog.i(TAG, "Unmounting " + path
                        + " force = " + force
                        + " removeEncryption = " + removeEncryption);
            }
            if (Environment.MEDIA_UNMOUNTED.equals(volState) ||
                    Environment.MEDIA_REMOVED.equals(volState) ||
                    Environment.MEDIA_SHARED.equals(volState) ||
                    Environment.MEDIA_UNMOUNTABLE.equals(volState)) {
                // Media already unmounted or cannot be unmounted.
                // TODO return valid return code when adding observer call back.
                return;
            }
            UnmountCallBack ucb = new UnmountCallBack(path, force, removeEncryption);
            mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb));
        }
        
        private int doUnmountVolume(String path, boolean force, boolean removeEncryption) {
            if (!getVolumeState(path).equals(Environment.MEDIA_MOUNTED)) {
                return VoldResponseCode.OpFailedVolNotMounted;
            }
    
            /*
             * Force a GC to make sure AssetManagers in other threads of the
             * system_server are cleaned up. We have to do this since AssetManager
             * instances are kept as a WeakReference and it's possible we have files
             * open on the external storage.
             */
            Runtime.getRuntime().gc();
    
            // Redundant probably. But no harm in updating state again.
            if (path.equals(mExternalStoragePath)) //only flash
            {
                mPms.updateExternalMediaStatus(false, false);
            }
            try {
                final Command cmd = new Command("volume", "unmount", path);
                if (removeEncryption) {
                    cmd.appendArg("force_and_revert");
                } else if (force) {
                    cmd.appendArg("force");
                }
                mConnector.execute(cmd);
                // We unmounted the volume. None of the asec containers are available now.
                synchronized (mAsecMountSet) {
                    mAsecMountSet.clear();
                }
                return StorageResultCode.OperationSucceeded;
            } catch (NativeDaemonConnectorException e) {
                // Don't worry about mismatch in PackageManager since the
                // call back will handle the status changes any way.
                int code = e.getCode();
                if (code == VoldResponseCode.OpFailedVolNotMounted) {
                    return StorageResultCode.OperationFailedStorageNotMounted;
                } else if (code == VoldResponseCode.OpFailedStorageBusy) {
                    return StorageResultCode.OperationFailedStorageBusy;
                } else {
                    return StorageResultCode.OperationFailedInternalError;
                }
            }
        }
    

    相关文章

      网友评论

        本文标题:Android 恢复系统调用流程

        本文链接:https://www.haomeiwen.com/subject/wiqsqxtx.html