1. 程式人生 > >Settings中“清除資料”流程

Settings中“清除資料”流程

1、具體觸發類:

src/com/android/settings/applications/AppStorageSettings.java

 

2、具體按鈕:

mClearDataButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_DATA))
                .findViewById(R.id.button);

 

3、具體回撥: 

@Override
    public void onClick(View v) {

。。。

else if (v == mClearDataButton) {
            if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) {
                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
                        getActivity(), mAppsControlDisallowedAdmin);
            } else if (mAppEntry.info.manageSpaceActivityName != null) {
                if (!Utils.isMonkeyRunning()) {
                    Intent intent = new Intent(Intent.ACTION_DEFAULT);
                    intent.setClassName(mAppEntry.info.packageName,
                            mAppEntry.info.manageSpaceActivityName);
                    startActivityForResult(intent, REQUEST_MANAGE_SPACE);
                }
            } else {
                showDialogInner(DLG_CLEAR_DATA, 0);
            }
        } 

。。。

 

4、彈出dialog:

showDialogInner(DLG_CLEAR_DATA, 0);

 

5、彈dialog方法:

 @Override
    protected AlertDialog createDialog(int id, int errorCode) {
        switch (id) {
            case DLG_CLEAR_DATA:
                return new AlertDialog.Builder(getActivity())
                        .setTitle(getActivity().getText(R.string.clear_data_dlg_title))
                        .setMessage(getActivity().getText(R.string.clear_data_dlg_text))
                        .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                // Clear user data here
                                initiateClearUserData();
                            }
                        })
                        .setNegativeButton(R.string.dlg_cancel, null)
                        .create();

 

6、具體清除方法:

private void initiateClearUserData() {
        mClearDataButton.setEnabled(false);
        // Invoke uninstall or clear user data based on sysPackage
        String packageName = mAppEntry.info.packageName;
        Log.i(TAG, "Clearing user data for package : " + packageName);
        if (mClearDataObserver == null) {
            mClearDataObserver = new ClearUserDataObserver();
        }
        ActivityManager am = (ActivityManager)
                getActivity().getSystemService(Context.ACTIVITY_SERVICE);
        boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
        if (!res) {
            // Clearing data failed for some obscure reason. Just log error for now
            Log.i(TAG, "Couldnt clear application user data for package:"+packageName);
            showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
        } else {
            mClearDataButton.setText(R.string.recompute_size);
        }
    }

 

7、呼叫ActivityManager clearApplicationUserData方法時傳了個mClearDataObserver,該Observer會在清除完成後發一個msg給handler,handler裡會呼叫 processClearMsg

    private void processClearMsg(Message msg) {
        int result = msg.arg1;
        String packageName = mAppEntry.info.packageName;
        mClearDataButton.setText(R.string.clear_user_data_text);
        if (result == OP_SUCCESSFUL) {
            Log.i(TAG, "Cleared user data for package : "+packageName);
            mState.requestSize(mPackageName, mUserId);
            /// M ALPS00235193: send the clear success broadcast { @
            Intent packageDataCleared = new Intent(Intent.ACTION_SETTINGS_PACKAGE_DATA_CLEARED);
            packageDataCleared.putExtra("packageName", packageName);
            getActivity().sendBroadcast(packageDataCleared);
           /// @ }
        } else {
            mClearDataButton.setEnabled(true);
        }
    }

清除ok,傳送一個廣播,先不管。。。

 

8、跟蹤到framework ams中:

am.clearApplicationUserData(packageName, mClearDataObserver);

方法具體行數如下:

 6026     public boolean clearApplicationUserData(final String packageName,
 6027             final IPackageDataObserver observer, int userId) {

        enforceNotIsolatedCaller("clearApplicationUserData");
        int uid = Binder.getCallingUid();
        int pid = Binder.getCallingPid();
        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
                ALLOW_FULL_ONLY, "clearApplicationUserData", null);


android.util.Log.d("jackpeng","clear pkg is "+packageName+"----uid is "+uid+"---pid is "+pid);
        long callingId = Binder.clearCallingIdentity();
        try {
            IPackageManager pm = AppGlobals.getPackageManager();
            int pkgUid = -1;
            synchronized(this) {
                if (getPackageManagerInternalLocked().canPackageBeWiped(
                        userId, packageName)) {
android.util.Log.d("jackpeng","throw exception");
                    throw new SecurityException(
                            "Cannot clear data for a device owner or a profile owner");
                }


                try {
                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
                } catch (RemoteException e) {
                }
                if (pkgUid == -1) {
                    Slog.w(TAG, "Invalid packageName: " + packageName);
                    if (observer != null) {
                        try {
                            observer.onRemoveCompleted(packageName, false);
                        } catch (RemoteException e) {
                            Slog.i(TAG, "Observer no longer exists.");
                        }
                    }
                    return false;
                }
                if (uid == pkgUid || checkComponentPermission(
                        android.Manifest.permission.CLEAR_APP_USER_DATA,
                        pid, uid, -1, true)
                        == PackageManager.PERMISSION_GRANTED) {
android.util.Log.d("jackpeng","permission is granted and uid is matched ");
                    forceStopPackageLocked(packageName, pkgUid, "clear data");
                } else {
                    throw new SecurityException("PID " + pid + " does not have permission "
                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
                                    + " of package " + packageName);
                }


                // Remove all tasks match the cleared application package and user
                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
                    final TaskRecord tr = mRecentTasks.get(i);
                    final String taskPackageName =
                            tr.getBaseIntent().getComponent().getPackageName();
                    if (tr.userId != userId) continue;
                    if (!taskPackageName.equals(packageName)) continue;
                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
                }
            }


            final int pkgUidF = pkgUid;
            final int userIdF = userId;
            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
                @Override
                public void onRemoveCompleted(String packageName, boolean succeeded)
                        throws RemoteException {
                    synchronized (ActivityManagerService.this) {
                        finishForceStopPackageLocked(packageName, pkgUidF);
                    }


                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
                            Uri.fromParts("package", packageName, null));
                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
                            null, null, 0, null, null, null, null, false, false, userIdF);


                    if (observer != null) {
                        observer.onRemoveCompleted(packageName, succeeded);
                    }
                }
            };


            try {
                // Clear application user data
                pm.clearApplicationUserData(packageName, localObserver, userId);


                synchronized(this) {
                    // Remove all permissions granted from/to this package
android.util.Log.d("jackpeng","remove permiison start ");
                    removeUriPermissionsForPackageLocked(packageName, userId, true);
                }


                // Remove all zen rules created by this package; revoke it's zen access.
                INotificationManager inm = NotificationManager.getService();
                inm.removeAutomaticZenRules(packageName);
                inm.setNotificationPolicyAccessGranted(packageName, false);


            } catch (RemoteException e) {
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
        return true;
    }