1.简介
上篇主要学习了reset相关的ui,这篇详细学习下3种reset都清除了哪些数据
1.1.reset network
上篇小节3,最终跳转到ResetNetworkConfirm页面处理
- 相关代码见小节2和3
1.2.reset app preference
上篇2.4
- 相关代码见小节4到12
1.3.factory reset
见上篇5.3,最终跳转页面MainClearConfirm,功能代码也在上篇小节10到12分析了,基本交给底层 c库处理了。
2.ResetNetworkConfirm.java
2.1.startMonitorSubscriptionChange
onCreate里会调用,监听sim卡的状态变化
private void startMonitorSubscriptionChange(SubscriptionManager mgr) {
if (mgr == null) {
return;
}
// update monitor listener
mSubscriptionsChangedListener = new OnSubscriptionsChangedListener(
Looper.getMainLooper()) {
@Override
public void onSubscriptionsChanged() {
//先获取我们要reset的sim的相关id
int subId = mResetNetworkRequest.getResetApnSubId();
SubscriptionManager mgr = getSubscriptionManager();
if (isSubscriptionRemainActive(mgr, subId)) {
//sim卡依旧是活动的
return;
}
//要reset的sim已经不再活动了,那么停止监听,关闭页面
stopMonitorSubscriptionChange(mgr);
mActivity.finish();
}
};
mgr.addOnSubscriptionsChangedListener(
mActivity.getMainExecutor(), mSubscriptionsChangedListener);
}
2.1.onClick
public void onClick(View v) {
// abandon execution if subscription no longer active
int subId = mResetNetworkRequest.getResetApnSubId();
if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
说明有选中的sim卡
SubscriptionManager mgr = getSubscriptionManager();
stopMonitorSubscriptionChange(mgr);
if (!isSubscriptionRemainActive(mgr, subId)) {
//sim卡已经不活动了,关闭页面
mActivity.finish();
return;
}
}
//显示loading
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
mProgressDialog = getProgressDialog(mActivity);
mProgressDialog.show();
//开始reset操作,具体见2.3
mResetNetworkTask = new ResetNetworkTask(mActivity);
mResetNetworkTask.execute();
}
2.3.doInBackground
mResetNetworkRequest = new ResetNetworkRequest(args);
protected Boolean doInBackground(Void... params) {
final AtomicBoolean resetEsimSuccess = new AtomicBoolean(true);
String resetEsimPackageName = mResetNetworkRequest.getResetEsimPackageName();
//转换成builder,见3.1
ResetNetworkOperationBuilder builder = mResetNetworkRequest
.toResetNetworkOperationBuilder(mContext, Looper.getMainLooper());
if (resetEsimPackageName != null) {
//有虚拟sim卡的话,添加对应的任务
builder = builder.resetEsim(resetEsimPackageName,
success -> { resetEsimSuccess.set(success); }
);
}
//开始执行所有的任务,见3.3
builder.build().run();
boolean isResetSucceed = resetEsimSuccess.get();
return isResetSucceed;
}
3.ResetNetworkOperationBuilder.java
3.1.ResetNetworkRequest.java
根据请求的option,添加对应的任务,具体任务见3.4到3.10
public ResetNetworkOperationBuilder toResetNetworkOperationBuilder(Context context,
Looper looper) {
// Follow specific order based on previous design within file ResetNetworkConfirm.java
ResetNetworkOperationBuilder builder = new ResetNetworkOperationBuilder(context);
if ((mResetOptions & RESET_CONNECTIVITY_MANAGER) != 0) {
builder.resetConnectivityManager();
}
if ((mResetOptions & RESET_VPN_MANAGER) != 0) {
builder.resetVpnManager();
}
if ((mResetOptions & RESET_WIFI_MANAGER) != 0) {
builder.resetWifiManager();
}
if ((mResetOptions & RESET_WIFI_P2P_MANAGER) != 0) {
builder.resetWifiP2pManager(looper);
}
if (mResetEsimPackageName != null) {
builder.resetEsim(mResetEsimPackageName);
}
if (mResetTelephonyManager != INVALID_SUBSCRIPTION_ID) {
builder.resetTelephonyAndNetworkPolicyManager(mResetTelephonyManager);
}
if ((mResetOptions & RESET_BLUETOOTH_MANAGER) != 0) {
builder.resetBluetoothManager();
}
if (mResetApn != INVALID_SUBSCRIPTION_ID) {
builder.resetApn(mResetApn);
}
return builder;
}
3.2.attachSystemServiceWork
根据服务名字,获取对应的系统服务,然后传递给第二个参数,并把runnable加入集合
protected <T> void attachSystemServiceWork(String serviceName, Consumer<T> serviceAccess) {
T service = (T) mContext.getSystemService(serviceName);
if (service == null) {
return;
}
Runnable runnable = () -> {
if (!DRY_RUN) {
serviceAccess.accept(service);
}
};
//加入集合
mResetSequence.add(runnable);
}
3.3.build
返回一个runnable,里边就是循环3.2方法添加的reset集合,执行对应的run方法
public Runnable build() {
return () -> mResetSequence.forEach(runnable -> runnable.run());
}
下边看下常用的任务都干啥了,可以看到,都是交给对应的Manager处理了,细节不研究了。
3.4.resetConnectivityManager
public ResetNetworkOperationBuilder resetConnectivityManager() {
attachSystemServiceWork(Context.CONNECTIVITY_SERVICE,
(Consumer<ConnectivityManager>) cm -> {
cm.factoryReset();
});
return this;
}
3.5.resetVpnManager
public ResetNetworkOperationBuilder resetVpnManager() {
attachSystemServiceWork(Context.VPN_MANAGEMENT_SERVICE,
(Consumer<VpnManager>) vpnManager -> {
vpnManager.factoryReset();
});
return this;
}
3.6.resetWifiManager
public ResetNetworkOperationBuilder resetWifiManager() {
attachSystemServiceWork(Context.WIFI_SERVICE,
(Consumer<WifiManager>) wifiManager -> {
wifiManager.factoryReset();
});
return this;
}
3.7.resetWifiP2pManager
public ResetNetworkOperationBuilder resetWifiP2pManager(Looper callbackLooper) {
attachSystemServiceWork(Context.WIFI_P2P_SERVICE,
(Consumer<WifiP2pManager>) wifiP2pManager -> {
WifiP2pManager.Channel channel = wifiP2pManager.initialize(
mContext, callbackLooper, null /* listener */);
if (channel != null) {
wifiP2pManager.factoryReset(channel, null /* listener */);
}
});
return this;
}
3.8.resetBluetoothManager
public ResetNetworkOperationBuilder resetBluetoothManager() {
attachSystemServiceWork(Context.BLUETOOTH_SERVICE,
(Consumer<BluetoothManager>) btManager -> {
BluetoothAdapter btAdapter = btManager.getAdapter();
if (btAdapter != null) {
btAdapter.clearBluetooth();
}
});
return this;
}
3.9.resetTelephonyAndNetworkPolicyManager
public ResetNetworkOperationBuilder resetTelephonyAndNetworkPolicyManager(
int subscriptionId) {
final AtomicReference<String> subscriberId = new AtomicReference<String>();
attachSystemServiceWork(Context.TELEPHONY_SERVICE,
(Consumer<TelephonyManager>) tm -> {
TelephonyManager subIdTm = tm.createForSubscriptionId(subscriptionId);
subscriberId.set(subIdTm.getSubscriberId());
subIdTm.resetSettings();
});
attachSystemServiceWork(Context.NETWORK_POLICY_SERVICE,
(Consumer<NetworkPolicyManager>) policyManager -> {
policyManager.factoryReset(subscriberId.get());
});
return this;
}
3.10.resetApn
拼接相应的uri进行删除操作
public ResetNetworkOperationBuilder resetApn(int subscriptionId) {
Runnable runnable = () -> {
//"content://telephony/carriers/restore"
Uri uri = Uri.parse(ApnSettings.RESTORE_CARRIERS_URI);
if (SubscriptionManager.isUsableSubscriptionId(subscriptionId)) {
uri = Uri.withAppendedPath(uri, "subId/" + String.valueOf(subscriptionId));
}
if (!DRY_RUN) {
ContentResolver resolver = mContext.getContentResolver();
resolver.delete(uri, null, null);
}
};
mResetSequence.add(runnable);
return this;
}
4.NotificationManagerService.java
4.1.clearData
- mConditionProviders,mListeners,mAssistants对象都是继承的ManagedServices.java
public void clearData(String packageName, int uid, boolean fromApp) throws RemoteException {
boolean packagesChanged = false;
checkCallerIsSystem();
// Cancel posted notifications
final int userId = UserHandle.getUserId(uid);
//根据包名和用户id删除相关的通知
cancelAllNotificationsInt(MY_UID, MY_PID, packageName, null, 0, 0, true,
UserHandle.getUserId(Binder.getCallingUid()), REASON_CLEAR_DATA, null);
//见补充1
packagesChanged |=
mConditionProviders.resetPackage(packageName, userId);
// 见补充2
ArrayMap<Boolean, ArrayList<ComponentName>> changedListeners =
mListeners.resetComponents(packageName, userId);
packagesChanged |= changedListeners.get(true).size() > 0
|| changedListeners.get(false).size() > 0;
// When a listener is enabled, we enable the dnd package as a secondary
for (int i = 0; i < changedListeners.get(true).size(); i++) {
mConditionProviders.setPackageOrComponentEnabled(
changedListeners.get(true).get(i).getPackageName(),
userId, false, true);
}
// Assistant,见5.1
ArrayMap<Boolean, ArrayList<ComponentName>> changedAssistants =
mAssistants.resetComponents(packageName, userId);
packagesChanged |= changedAssistants.get(true).size() > 0
|| changedAssistants.get(false).size() > 0;
//assitant只enable一个,所以从1开始,把其他的都disable掉
for (int i = 1; i < changedAssistants.get(true).size(); i++) {
mAssistants.setPackageOrComponentEnabled(
changedAssistants.get(true).get(i).flattenToString(),
userId, true, false);
}
// When the default assistant is enabled, we enable the dnd package as a secondary
if (changedAssistants.get(true).size() > 0) {
//we want only one assistant active
mConditionProviders
.setPackageOrComponentEnabled(
changedAssistants.get(true).get(0).getPackageName(),
userId, false, true);
}
// Snoozing ,见补充3,清除snoozing通知
mSnoozeHelper.clearData(UserHandle.getUserId(uid), packageName);
// Reset notification preferences
if (!fromApp) {
//补充4
mPreferencesHelper.clearData(packageName, uid);
}
if (packagesChanged) {
//发送包改变的广播
getContext().sendBroadcastAsUser(new Intent(
ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
.setPackage(packageName)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT),
UserHandle.of(userId), null);
}
handleSavePolicyFile();//补充5
}
>1.resetPackage
重置组件的状态
//ConditionProviders.java
boolean resetPackage(String packageName, int userId) {
boolean isAllowed = super.isPackageOrComponentAllowed(packageName, userId);
boolean isDefault = super.isDefaultComponentOrPackage(packageName);
if (!isAllowed && isDefault) {
//见5.3,使组件可用
setPackageOrComponentEnabled(packageName, userId, true, true);
}
if (isAllowed && !isDefault) {
//使组件不可用
setPackageOrComponentEnabled(packageName, userId, true, false);
}
return !isAllowed && isDefault;
}
>2.resetComponents
见父类5.1
public class NotificationListeners extends ManagedServices {
//..
>3.clearData
SnoozeHelper.java
protected void clearData(int userId, String pkg) {
synchronized (mLock) {
int n = mSnoozedNotifications.size();
for (int i = n - 1; i >= 0; i--) {
final NotificationRecord record = mSnoozedNotifications.valueAt(i);
//包名和userId一样
if (record.getUserId() == userId && record.getSbn().getPackageName().equals(pkg)) {
//移除数据
mSnoozedNotifications.removeAt(i);
String trimmedKey = getTrimmedString(record.getKey());
mPersistedSnoozedNotificationsWithContext.remove(trimmedKey);
mPersistedSnoozedNotifications.remove(trimmedKey);
Runnable runnable = () -> {
final PendingIntent pi = createPendingIntent(record.getKey());
//清除通知
mAm.cancel(pi);
};
runnable.run();
}
}
}
}
>4.PreferencesHelper.java
public void clearData(String pkg, int uid) {
synchronized (mPackagePreferences) {
PackagePreferences p = getPackagePreferencesLocked(pkg, uid);
if (p != null) {
p.channels = new ArrayMap<>();
p.groups = new ArrayMap<>();
p.delegate = null;
p.lockedAppFields = DEFAULT_LOCKED_APP_FIELDS;
p.bubblePreference = DEFAULT_BUBBLE_PREFERENCE;
p.importance = DEFAULT_IMPORTANCE;
p.priority = DEFAULT_PRIORITY;
p.visibility = DEFAULT_VISIBILITY;
p.showBadge = DEFAULT_SHOW_BADGE;
}
}
}
>5.handleSavePolicyFile
mPolicyFile的文件路径如下,/data/system/notification_policy.xml
final File systemDir = new File(Environment.getDataDirectory(), "system");
new File(systemDir, "notification_policy.xml")
最终执行这个runnable,clearData里已经重置了各种设置,这里走后进行保存
private final class SavePolicyFileRunnable implements Runnable {
@Override
public void run() {
synchronized (mPolicyFile) {
final FileOutputStream stream;
try {
stream = mPolicyFile.startWrite();
} catch (IOException e) {
return;
}
try {
//把新的策略写入文件里
writePolicyXml(stream, false /*forBackup*/, UserHandle.USER_ALL);
mPolicyFile.finishWrite(stream);
} catch (IOException e) {
mPolicyFile.failWrite(stream);
}
}
BackupManager.dataChanged(getContext().getPackageName());
}
}
5.ManagedServices.java
5.1.resetComponents
ArrayMap<Boolean, ArrayList<ComponentName>> resetComponents(String packageName, int userId) {
// components that we want to enable
ArrayList<ComponentName> componentsToEnable =
new ArrayList<>(mDefaultComponents.size());
// components that were removed
ArrayList<ComponentName> disabledComponents =
new ArrayList<>(mDefaultComponents.size());
// all components that are enabled now
ArraySet<ComponentName> enabledComponents =
new ArraySet<>(getAllowedComponents(userId));
boolean changed = false;
synchronized (mDefaultsLock) {
// record all components that are enabled but should not be by default
for (int i = 0; i < mDefaultComponents.size() && enabledComponents.size() > 0; i++) {
ComponentName currentDefault = mDefaultComponents.valueAt(i);
if (packageName.equals(currentDefault.getPackageName())
&& !enabledComponents.contains(currentDefault)) {
//找到包名对应的默认组件,不在enable集合里,添加进入
componentsToEnable.add(currentDefault);
}
}
synchronized (mApproved) {
final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(
userId);
if (approvedByType != null) {
final int M = approvedByType.size();
for (int j = 0; j < M; j++) {
final ArraySet<String> approved = approvedByType.valueAt(j);
for (int i = 0; i < enabledComponents.size(); i++) {
ComponentName currentComponent = enabledComponents.valueAt(i);
if (packageName.equals(currentComponent.getPackageName())
&& !mDefaultComponents.contains(currentComponent)) {
//在enabled组件里,不在default组件里
if (approved.remove(currentComponent.flattenToString())) {
//移除组件,加入到disabled集合组件
disabledComponents.add(currentComponent);
//从userSet里移除,见补充1
clearUserSetFlagLocked(currentComponent, userId);
changed = true;
}
}
}
//把enabled组件加入approved集合里
for (int i = 0; i < componentsToEnable.size(); i++) {
ComponentName candidate = componentsToEnable.get(i);
changed |= approved.add(candidate.flattenToString());
}
}
}
}
}
//数据发生变化,重新绑定服务
if (changed) rebindServices(false, USER_ALL);
//封装数据返回
ArrayMap<Boolean, ArrayList<ComponentName>> changes = new ArrayMap<>();
changes.put(true, componentsToEnable);
changes.put(false, disabledComponents);
return changes;
}
>1.clearUserSetFlagLocked
private boolean clearUserSetFlagLocked(ComponentName component, int userId) {
String approvedValue = getApprovedValue(component.flattenToString());
ArraySet<String> userSet = mUserSetServices.get(userId);
return userSet != null && userSet.remove(approvedValue);
}
5.2.rebindServices
- 每当包更改、用户切换或安全设置更改时调用。(例如在我们的广播接收器中响应user_switch)
protected void rebindServices(boolean forceRebind, int userToRebind) {
IntArray userIds = mUserProfiles.getCurrentProfileIds();
if (userToRebind != USER_ALL) {
userIds = new IntArray(1);
userIds.add(userToRebind);
}
final SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
final SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
synchronized (mMutex) {
final SparseArray<ArraySet<ComponentName>> approvedComponentsByUser =
getAllowedComponents(userIds);
final Set<ManagedServiceInfo> removableBoundServices = getRemovableConnectedServices();
//补充3
populateComponentsToBind(componentsToBind, userIds, approvedComponentsByUser);
//补充4
populateComponentsToUnbind(
forceRebind, removableBoundServices, componentsToBind, componentsToUnbind);
}
//补充5
unbindFromServices(componentsToUnbind);
//补充6
bindToServices(componentsToBind);
}
>1.getAllowedComponents
protected SparseArray<ArraySet<ComponentName>> getAllowedComponents(IntArray userIds) {
final int nUserIds = userIds.size();
final SparseArray<ArraySet<ComponentName>> componentsByUser = new SparseArray<>();
for (int i = 0; i < nUserIds; ++i) {
final int userId = userIds.get(i);
synchronized (mApproved) {
final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId);
if (approvedLists != null) {
final int N = approvedLists.size();
for (int j = 0; j < N; j++) {
ArraySet<ComponentName> approvedByUser = componentsByUser.get(userId);
if (approvedByUser == null) {
approvedByUser = new ArraySet<>();
componentsByUser.put(userId, approvedByUser);
}
approvedByUser.addAll(
loadComponentNamesFromValues(approvedLists.valueAt(j), userId));
}
}
}
}
return componentsByUser;
}
>2.getRemovableConnectedServices
获取要移除的已连接服务
protected Set<ManagedServiceInfo> getRemovableConnectedServices() {
final Set<ManagedServiceInfo> removableBoundServices = new ArraySet<>();
for (ManagedServiceInfo service : mServices) {
if (!service.isSystem && !service.isGuest(this)) {
//非系统,这个service就是当前的ManagedServices
removableBoundServices.add(service);
}
}
return removableBoundServices;
}
>3.populateComponentsToBind
获取要绑定的组件
protected void populateComponentsToBind(SparseArray<Set<ComponentName>> componentsToBind,
final IntArray activeUsers,
SparseArray<ArraySet<ComponentName>> approvedComponentsByUser) {
mEnabledServicesForCurrentProfiles.clear();
mEnabledServicesPackageNames.clear();
final int nUserIds = activeUsers.size();
for (int i = 0; i < nUserIds; ++i) {
final int userId = activeUsers.get(i);
final ArraySet<ComponentName> userComponents = approvedComponentsByUser.get(userId);
if (null == userComponents) {
componentsToBind.put(userId, new ArraySet<>());
continue;
}
final Set<ComponentName> add = new HashSet<>(userComponents);
//移除不需要运行的组件
add.removeAll(mSnoozingForCurrentProfiles);
componentsToBind.put(userId, add);
//enabled服务集合添加数据
mEnabledServicesForCurrentProfiles.addAll(userComponents);
for (int j = 0; j < userComponents.size(); j++) {
final ComponentName component = userComponents.valueAt(j);
//添加包名
mEnabledServicesPackageNames.add(component.getPackageName());
}
}
}
>4.populateComponentsToUnbind
获取要解除绑定的组件
protected void populateComponentsToUnbind(
boolean forceRebind,
Set<ManagedServiceInfo> removableBoundServices,
SparseArray<Set<ComponentName>> allowedComponentsToBind,
SparseArray<Set<ComponentName>> componentsToUnbind) {
for (ManagedServiceInfo info : removableBoundServices) {
final Set<ComponentName> allowedComponents = allowedComponentsToBind.get(info.userid);
if (allowedComponents != null) {
//强制重新绑定,或者不在allowed组件里
if (forceRebind || !allowedComponents.contains(info.component)) {
Set<ComponentName> toUnbind =
componentsToUnbind.get(info.userid, new ArraySet<>());
toUnbind.add(info.component);
componentsToUnbind.put(info.userid, toUnbind);
}
}
}
}
>5.unbindFromServices
unbind提供的组件
protected void unbindFromServices(SparseArray<Set<ComponentName>> componentsToUnbind) {
for (int i = 0; i < componentsToUnbind.size(); i++) {
final int userId = componentsToUnbind.keyAt(i);
final Set<ComponentName> removableComponents = componentsToUnbind.get(userId);
for (ComponentName cn : removableComponents) {
//最终就是拿到ServiceConnection,调用context的unbindService方法
unregisterService(cn, userId);
}
}
}
>6.bindToServices
private void bindToServices(SparseArray<Set<ComponentName>> componentsToBind) {
for (int i = 0; i < componentsToBind.size(); i++) {
final int userId = componentsToBind.keyAt(i);
final Set<ComponentName> add = componentsToBind.get(userId);
for (ComponentName component : add) {
try {
ServiceInfo info = mPm.getServiceInfo(component,
PackageManager.GET_META_DATA
| PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
userId);
if (info == null) {
//无法获取服务信息
continue;
}
if (!mConfig.bindPermission.equals(info.permission)) {
//权限问题
continue;
}
registerService(info, userId);//见补充7
}
}
}
}
>7.registerServiceLocked
private void registerServiceLocked(final ComponentName name, final int userid,
final boolean isSystem) {
final Pair<ComponentName, Integer> servicesBindingTag = Pair.create(name, userid);
if (mServicesBound.contains(servicesBindingTag)) {
//组件已经绑定过了
return;
}
//加入集合,方便下次判断
mServicesBound.add(servicesBindingTag);
final int N = mServices.size();
for (int i = N - 1; i >= 0; i--) {
final ManagedServiceInfo info = mServices.get(i);
if (name.equals(info.component)
&& info.userid == userid) {
//移除解绑旧的服务
removeServiceLocked(i);
if (info.connection != null) {
unbindService(info.connection, info.component, info.userid);
}
}
}
Intent intent = new Intent(mConfig.serviceInterface);
intent.setComponent(name);
intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mConfig.clientLabel);
final PendingIntent pendingIntent = PendingIntent.getActivity(
mContext, 0, new Intent(mConfig.settingsAction), PendingIntent.FLAG_IMMUTABLE);
intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);
ApplicationInfo appInfo = null;
try {
appInfo = mContext.getPackageManager().getApplicationInfo(
name.getPackageName(), 0);
}
final int targetSdkVersion =
appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;
final int uid = appInfo != null ? appInfo.uid : -1;
try {
ServiceConnection serviceConnection = new ServiceConnection() {
IInterface mService;
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
boolean added = false;
ManagedServiceInfo info = null;
synchronized (mMutex) {
//从rebinding里移除
mServicesRebinding.remove(servicesBindingTag);
try {
mService = asInterface(binder);
//绑定成功以后,实例化一个serviceInfo对象,加入集合
info = newServiceInfo(mService, name,
userid, isSystem, this, targetSdkVersion, uid);
binder.linkToDeath(info, 0);
added = mServices.add(info);
}
}
if (added) {
onServiceAdded(info);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onBindingDied(ComponentName name) {
//
synchronized (mMutex) {
unbindService(this, name, userid);
if (!mServicesRebinding.contains(servicesBindingTag)) {
//延迟10秒重新注册服务
mServicesRebinding.add(servicesBindingTag);
mHandler.postDelayed(() ->
reregisterService(name, userid),
ON_BINDING_DIED_REBIND_DELAY_MS);
}
}
}
@Override
public void onNullBinding(ComponentName name) {
mContext.unbindService(this);
}
};
//执行bind操作
if (!mContext.bindServiceAsUser(intent,
serviceConnection,
getBindFlags(),
new UserHandle(userid))) {
//绑定失败,移除
mServicesBound.remove(servicesBindingTag);
return;
}
} catch (SecurityException ex) {
//异常,移除
mServicesBound.remove(servicesBindingTag);
}
}
5.3.setPackageOrComponentEnabled
- enabled 为true,添加数据,为false,删除数据
protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
boolean isPrimary, boolean enabled) {
setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled, true);
}
protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
boolean isPrimary, boolean enabled, boolean userSet) {
synchronized (mApproved) {
ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId);
if (allowedByType == null) {
allowedByType = new ArrayMap<>();
mApproved.put(userId, allowedByType);
}
ArraySet<String> approved = allowedByType.get(isPrimary);
if (approved == null) {
approved = new ArraySet<>();
allowedByType.put(isPrimary, approved);
}
String approvedItem = getApprovedValue(pkgOrComponent);
if (approvedItem != null) {
if (enabled) {
approved.add(approvedItem);
} else {
approved.remove(approvedItem);
}
}
ArraySet<String> userSetServices = mUserSetServices.get(userId);
if (userSetServices == null) {
userSetServices = new ArraySet<>();
mUserSetServices.put(userId, userSetServices);
}
if (userSet) {
userSetServices.add(pkgOrComponent);
} else {
userSetServices.remove(pkgOrComponent);
}
}
//见5.2
rebindServices(false, userId);
}
>1.getApprovedValue
private String getApprovedValue(String pkgOrComponent) {
if (mApprovalLevel == APPROVAL_BY_COMPONENT) {
//走这里,验证下是否是 a.b.c/.d 或者a.b.c/a.b.c.d,也就是可以解析出包名和类名的
if(ComponentName.unflattenFromString(pkgOrComponent) != null) {
return pkgOrComponent;
}
return null;
} else {
return getPackageName(pkgOrComponent);
}
}
6.PackageManagerService.java
6.1.IPackageManagerBase.java
public abstract class IPackageManagerBase extends IPackageManager.Stub {
//..
public final void resetApplicationPreferences(int userId) {
mPreferredActivityHelper.resetApplicationPreferences(userId);
}
6.2.PreferredActivityHelper.java
>1.resetApplicationPreferences
public void resetApplicationPreferences(int userId) {
mPm.mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
// writer
try {
final SparseBooleanArray changedUsers = new SparseBooleanArray();
synchronized (mPm.mLock) {//见6.3
mPm.clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
}
if (changedUsers.size() > 0) {//见6.4
mPm.postPreferredActivityChangedBroadcast(userId);
}
synchronized (mPm.mLock) {
//见7.2
mPm.mSettings.applyDefaultPreferredAppsLPw(userId);
//
mPm.mDomainVerificationManager.clearUser(userId);
final int numPackages = mPm.mPackages.size();
for (int i = 0; i < numPackages; i++) {
final AndroidPackage pkg = mPm.mPackages.valueAt(i);
//重置运行权限
mPm.mPermissionManager.resetRuntimePermissions(pkg, userId);
}
}
//见补充2,更新默认的桌面
updateDefaultHomeNotLocked(mPm.snapshotComputer(), userId);
//补充3
resetNetworkPolicies(userId);
//小节6.5
mPm.scheduleWritePackageRestrictions(userId);
}
}
>2.updateDefaultHomeNotLocked
public boolean updateDefaultHomeNotLocked(@NonNull Computer snapshot, @UserIdInt int userId) {
if (!mPm.isSystemReady()) {
return false;
}
//桌面intent
final Intent intent = snapshot.getHomeIntent();
//根据intent查找所有的resolveInfo
final List<ResolveInfo> resolveInfos = snapshot.queryIntentActivitiesInternal(
intent, null, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
//旋转最合适的一个
final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(snapshot,
intent, null, 0, resolveInfos, true, false, false, userId);
//获取对应的包名
final String packageName = preferredResolveInfo != null
&& preferredResolveInfo.activityInfo != null
? preferredResolveInfo.activityInfo.packageName : null;
//获取当前活动的launcher包名
final String currentPackageName = mPm.getActiveLauncherPackageName(userId);
if (TextUtils.equals(currentPackageName, packageName)) {
//默认的launcher和当前的一样,不做处理
return false;
}
final String[] callingPackages = snapshot.getPackagesForUid(Binder.getCallingUid());
if (callingPackages != null && ArrayUtils.contains(callingPackages,
mPm.mRequiredPermissionControllerPackage)) {
// PermissionController manages default home directly.
return false;
}
if (packageName == null) {
return false;
}
//修改为新的launcher
return mPm.setActiveLauncherPackage(packageName, userId,
successful -> {
if (successful) {
mPm.postPreferredActivityChangedBroadcast(userId);
}
});
}
>3.resetNetworkPolicies
private void resetNetworkPolicies(int userId) {
//见8.1
mPm.mInjector.getLocalService(NetworkPolicyManagerInternal.class).resetUserState(userId);
}
6.3.clearPackagePreferredActivitiesLPw
比如我们的包,跳转一个intent,有3个选项,我们可以选择一个作为默认打开的程序,这里就是清除这种数据
void clearPackagePreferredActivitiesLPw(String packageName,
@NonNull SparseBooleanArray outUserChanged, int userId) {
//清除的包的首选活动数据
mSettings.clearPackagePreferredActivities(packageName, outUserChanged, userId);
}
6.4.postPreferredActivityChangedBroadcast
首选意图改变广播
void postPreferredActivityChangedBroadcast(int userId) {
mHandler.post(() -> mBroadcastHelper.sendPreferredActivityChangedBroadcast(userId));
}
>1.BroadcastHelper.java
public void sendPreferredActivityChangedBroadcast(int userId) {
final IActivityManager am = ActivityManager.getService();
if (am == null) {
return;
}
final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
try {
am.broadcastIntentWithFeature(null, null, intent, null, null,
0, null, null, null, null, null, android.app.AppOpsManager.OP_NONE,
null, false, false, userId);
} catch (RemoteException e) {
}
}
6.5.scheduleWritePackageRestrictions
void scheduleWritePackageRestrictions(int userId) {
invalidatePackageInfoCache();
if (userId == UserHandle.USER_ALL) {
synchronized (mDirtyUsers) {
for (int aUserId : mUserManager.getUserIds()) {
mDirtyUsers.add(aUserId);
}
}
} else {
if (!mUserManager.exists(userId)) {
return;
}
synchronized (mDirtyUsers) {
mDirtyUsers.add(userId);
}
}
if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
}
}
交给PackageHandler.java处理,最终又回到这里
void writePendingRestrictions() {
synchronized (mLock) {
mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
synchronized (mDirtyUsers) {
for (int userId : mDirtyUsers) {
//
mSettings.writePackageRestrictionsLPr(userId);
}
mDirtyUsers.clear();
}
}
}
7.Settings.java
7.1.clearPackagePreferredActivities
void clearPackagePreferredActivities(String packageName,
@NonNull SparseBooleanArray outUserChanged, int userId) {
boolean changed = false;
ArrayList<PreferredActivity> removed = null;
for (int i = 0; i < mPreferredActivities.size(); i++) {
final int thisUserId = mPreferredActivities.keyAt(i);
PreferredIntentResolver pir = mPreferredActivities.valueAt(i);
if (userId != UserHandle.USER_ALL && userId != thisUserId) {
continue;
}
Iterator<PreferredActivity> it = pir.filterIterator();
while (it.hasNext()) {
PreferredActivity pa = it.next();
if (packageName == null
|| (pa.mPref.mComponent.getPackageName().equals(packageName)
&& pa.mPref.mAlways)) {
if (removed == null) {
removed = new ArrayList<>();
}
//没有提供具体的包名,或者提供的包名和我们的首选意图解析的包名一样,加入remove集合
removed.add(pa);
}
}
if (removed != null) {
for (int j = 0; j < removed.size(); j++) {
PreferredActivity pa = removed.get(j);
pir.removeFilter(pa);
}
//有要移除的数据,标记
outUserChanged.put(thisUserId, true);
changed = true;
}
}
if (changed) {
onChanged();
}
}
7.2.applyDefaultPreferredAppsLPw
应用默认的首选应用
void applyDefaultPreferredAppsLPw(int userId) {
// First pull data from any pre-installed apps.
final PackageManagerInternal pmInternal =
LocalServices.getService(PackageManagerInternal.class);
for (PackageSetting ps : mPackages.values()) {
//系统包,首选活动过滤不为空
if ((ps.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0 && ps.getPkg() != null
&& !ps.getPkg().getPreferredActivityFilters().isEmpty()) {
List<Pair<String, ParsedIntentInfo>> intents
= ps.getPkg().getPreferredActivityFilters();
for (int i=0; i<intents.size(); i++) {
//首选activity的类名以及解析的intent信息
Pair<String, ParsedIntentInfo> pair = intents.get(i);
//应用
applyDefaultPreferredActivityLPw(pmInternal,
pair.second.getIntentFilter(),
new ComponentName(ps.getPackageName(), pair.first), userId);
}
}
}
// Read preferred apps from .../etc/preferred-apps directories.
//循环所有的系统分区,读取特定位置的配置文件,获取首选app信息
int size = PackageManagerService.SYSTEM_PARTITIONS.size();
for (int index = 0; index < size; index++) {
ScanPartition partition = PackageManagerService.SYSTEM_PARTITIONS.get(index);
File preferredDir = new File(partition.getFolder(), "etc/preferred-apps");
if (!preferredDir.exists() || !preferredDir.isDirectory()) {
continue;
}
if (!preferredDir.canRead()) {
continue;
}
File[] files = preferredDir.listFiles();
if (ArrayUtils.isEmpty(files)) {
continue;
}
//必须有.xml结尾的可读文件
for (File f : files) {
if (!f.getPath().endsWith(".xml")) {
continue;
}
if (!f.canRead()) {
continue;
}
try (InputStream str = new FileInputStream(f)) {
final TypedXmlPullParser parser = Xml.resolvePullParser(str);
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
if (type != XmlPullParser.START_TAG) {
continue;
}
if (!"preferred-activities".equals(parser.getName())) {
continue;
}
//读取并应用数据
readDefaultPreferredActivitiesLPw(parser, userId);
}
}
}
}
7.3.writePackageRestrictionsLPr
void writePackageRestrictionsLPr(int userId) {
invalidatePackageCache();
if (DEBUG_MU) {
Log.i(TAG, "Writing package restrictions for user=" + userId);
}
final long startTime = SystemClock.uptimeMillis();
// Keep the old stopped packages around until we know the new ones have
// been successfully written.
File userPackagesStateFile = getUserPackagesStateFile(userId);
File backupFile = getUserPackagesStateBackupFile(userId);
new File(userPackagesStateFile.getParent()).mkdirs();
>1.getUserPackagesStateFile
private File getUserPackagesStateFile(int userId) {
File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
return new File(userDir, "package-restrictions.xml");
}
8.NetworkPolicyManagerService.java
8.1.NetworkPolicyManagerInternalImpl
private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
@Override
public void resetUserState(int userId) {
synchronized (mUidRulesFirstLock) {
boolean changed = removeUserStateUL(userId, false, true);
changed = addDefaultRestrictBackgroundAllowlistUidsUL(userId) || changed;
if (changed) {
synchronized (mNetworkPoliciesSecondLock) {
writePolicyAL();
}
}
}
}
8.2.getUidsWithPolicy
根据提供的网络策略返回所有支持的uid
public int[] getUidsWithPolicy(int policy) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
int[] uids = new int[0];
synchronized (mUidRulesFirstLock) {
for (int i = 0; i < mUidPolicy.size(); i++) {
final int uid = mUidPolicy.keyAt(i);
final int uidPolicy = mUidPolicy.valueAt(i);
//要查找的和循环的策略都是空,或者循环的策略里包含要查找的策略
if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) ||
(uidPolicy & policy) != 0) {
uids = appendInt(uids, uid);
}
}
}
return uids;
}
8.3.setUidPolicy
设置新的网络策略
public void setUidPolicy(int uid, int policy) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
if (!UserHandle.isApp(uid)) {
throw new IllegalArgumentException("cannot apply policy to UID " + uid);
}
synchronized (mUidRulesFirstLock) {
try {
final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
if (oldPolicy != policy) {
//见8.4.
setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
}
}
}
}
8.4.setUidPolicyUncheckedUL
private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
setUidPolicyUncheckedUL(uid, policy, false);//补充1
final boolean notifyApp;
if (!isUidValidForAllowlistRulesUL(uid)) {//补充2
notifyApp = false;
} else {
final boolean wasDenied = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
final boolean isDenied = policy == POLICY_REJECT_METERED_BACKGROUND;
final boolean wasAllowed = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
final boolean isAllowed = policy == POLICY_ALLOW_METERED_BACKGROUND;
final boolean wasBlocked = wasDenied || (mRestrictBackground && !wasAllowed);
final boolean isBlocked = isDenied || (mRestrictBackground && !isAllowed);
if ((wasAllowed && (!isAllowed || isDenied))
&& mDefaultRestrictBackgroundAllowlistUids.get(uid)
&& !mRestrictBackgroundAllowlistRevokedUids.get(uid)) {
mRestrictBackgroundAllowlistRevokedUids.append(uid, true);
}
notifyApp = wasBlocked != isBlocked;
}
//补充3,策略变化,通知相关的回调,以及发送广播
mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp))
.sendToTarget();
if (persist) {
synchronized (mNetworkPoliciesSecondLock) {
writePolicyAL();
}
}
}
>1.setUidPolicyUncheckedUL
给uid设置对应的策略
private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
if (policy == POLICY_NONE) {
//NONE的话,删除
mUidPolicy.delete(uid);
} else {
//其他的添加
mUidPolicy.put(uid, policy);
}
// uid policy changed, recompute rules and persist policy.
//策略变化了,更新数据使用限制的规则
updateRulesForDataUsageRestrictionsUL(uid);
if (persist) {
synchronized (mNetworkPoliciesSecondLock) {
//需要持久化的,保存数据
writePolicyAL();
}
}
}
>2.isUidValidForAllowlistRulesUL
是普通应用,并且清单文件里有网络权限
private boolean isUidValidForAllowlistRulesUL(int uid) {
return UserHandle.isApp(uid) && hasInternetPermissionUL(uid);
}
public static boolean isApp(int uid) {
if (uid > 0) {
final int appId = getAppId(uid); //10000-19999
return appId >= Process.FIRST_APPLICATION_UID && appId <= Process.LAST_APPLICATION_UID;
} else {
return false;
}
}
>3.MSG_POLICIES_CHANGED
case MSG_POLICIES_CHANGED: {
final int uid = msg.arg1;
final int policy = msg.arg2;
final Boolean notifyApp = (Boolean) msg.obj;
// First notify internal listeners...
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
//循环所有的监听,
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
dispatchUidPoliciesChanged(listener, uid, policy);
}
mListeners.finishBroadcast();
//通知app的话,发送广播
if (notifyApp.booleanValue()) {
broadcastRestrictBackgroundChanged(uid, notifyApp);
}
return true;
}
private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) {
final PackageManager pm = mContext.getPackageManager();
final String[] packages = pm.getPackagesForUid(uid);
if (packages != null) {
final int userId = UserHandle.getUserId(uid);
for (String packageName : packages) {
final Intent intent =
new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
intent.setPackage(packageName);
intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
}
}
}
9.AppOpsService.java
应用操作服务,
public class AppOpsService extends IAppOpsService.Stub {
9.1.AppProtoEnums
code是通过proto文件生成的,路径frameworks/base/core/proto/android/app/enums.proto
syntax = "proto2";
package android.app;
option java_outer_classname = "AppProtoEnums";
option java_multiple_files = true;
//...
// AppOpsManager.java - operation ids for logging
enum AppOpEnum {
APP_OP_NONE = -1;
APP_OP_COARSE_LOCATION = 0;
APP_OP_FINE_LOCATION = 1;
APP_OP_GPS = 2;
APP_OP_VIBRATE = 3;
APP_OP_READ_CONTACTS = 4;
APP_OP_REQUEST_INSTALL_PACKAGES = 66;
//...
9.2.resetAllModes
这里是从上篇的reset apps 那边调用的,第二个参数为空。
- 循环所有的uidState,先获取opModes(SparseIntArray),key就是操作,value是状态
- 先判断对应的key是否允许重置,允许的话
public void resetAllModes(int reqUserId, String reqPackageName) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId,
true, true, "resetAllModes", null);
int reqUid = -1;
//权限检查
enforceManageAppOpsModes(callingPid, callingUid, reqUid);
HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks = null;
ArrayList<ChangeRec> allChanges = new ArrayList<>();
synchronized (this) {
boolean changed = false;
for (int i = mUidStates.size() - 1; i >= 0; i--) {
UidState uidState = mUidStates.valueAt(i);
//key就是9.1里定义的操作,value就是操作的状态,支持的状态见10.1
SparseIntArray opModes = uidState.opModes;
if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) {
final int uidOpCount = opModes.size();
for (int j = uidOpCount - 1; j >= 0; j--) {
final int code = opModes.keyAt(j);
//我们这里是重置操作,所以需要先查看下对应的操作是否支持重置,见10.2
if (AppOpsManager.opAllowsReset(code)) {
int previousMode = opModes.valueAt(j);
opModes.removeAt(j);
if (opModes.size() <= 0) {
uidState.opModes = null;
}
//循环进程里包含的所有包
for (String packageName : getPackagesForUid(uidState.uid)) {
//添加回调,见补充2
callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
previousMode, mOpModeWatchers.get(code));
callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
previousMode, mPackageModeWatchers.get(packageName));
//见补充3,添加数据到集合
allChanges = addChange(allChanges, code, uidState.uid,
packageName, previousMode);
}
}
}
}
if (uidState.pkgOps == null) {
//没有额外的包
continue;
}
if (reqUserId != UserHandle.USER_ALL
&& reqUserId != UserHandle.getUserId(uidState.uid)) {
// 不同的用户
continue;
}
//一个进程下可能有多个包
Map<String, Ops> packages = uidState.pkgOps;
//key就是包名
Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator();
boolean uidChanged = false;
while (it.hasNext()) {
Map.Entry<String, Ops> ent = it.next();
String packageName = ent.getKey();
if (reqPackageName != null && !reqPackageName.equals(packageName)) {
// Skip any ops for a different package
continue;
}
Ops pkgOps = ent.getValue();
for (int j=pkgOps.size()-1; j>=0; j--) {
//一个存储ops数据的对象
Op curOp = pkgOps.valueAt(j);
if (shouldDeferResetOpToDpm(curOp.op)) {
//见补充5
deferResetOpToDpm(curOp.op, reqPackageName, reqUserId);
continue;
}
//对应的op允许reset并且当前的状态和默认状态不一样
if (AppOpsManager.opAllowsReset(curOp.op)
&& curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) {
int previousMode = curOp.mode;
curOp.mode = AppOpsManager.opToDefaultMode(curOp.op);
changed = true;
uidChanged = true;
final int uid = curOp.uidState.uid;
//见补充2
callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
previousMode, mOpModeWatchers.get(curOp.op));
callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
previousMode, mPackageModeWatchers.get(packageName));
//见补充3
allChanges = addChange(allChanges, curOp.op, uid, packageName,
previousMode);
curOp.removeAttributionsWithNoTime();
if (curOp.mAttributions.isEmpty()) {
pkgOps.removeAt(j);
}
}
}
if (pkgOps.size() == 0) {
it.remove();
}
}
//见9.4.1 成了默认状态的话,从集合里移除
if (uidState.isDefault()) {
mUidStates.remove(uidState.uid);
}
if (uidChanged) {
//状态有改变的话,
uidState.evalForegroundOps(mOpModeWatchers);
}
}
if (changed) {
//这个是数据本地保存,文件路径 /data/system/appops.xml
scheduleFastWriteLocked();
}
}
if (callbacks != null) {
for (Map.Entry<ModeCallback, ArrayList<ChangeRec>> ent : callbacks.entrySet()) {
ModeCallback cb = ent.getKey();
ArrayList<ChangeRec> reports = ent.getValue();
for (int i=0; i<reports.size(); i++) {
ChangeRec rep = reports.get(i);
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyOpChanged,
this, cb, rep.op, rep.uid, rep.pkg));
}
}
}
int numChanges = allChanges.size();
for (int i = 0; i < numChanges; i++) {
ChangeRec change = allChanges.get(i);
//op发生改变的,进行相应的操作,见补充4
notifyOpChangedSync(change.op, change.uid, change.pkg,
AppOpsManager.opToDefaultMode(change.op), change.previous_mode);
}
}
>1.watchers集合
用户注册的监听ops的状态改变的回调集合
//数据来源见9.3
final SparseArray<ArraySet<ModeCallback>> mOpModeWatchers = new SparseArray<>();
final ArrayMap<String, ArraySet<ModeCallback>> mPackageModeWatchers = new ArrayMap<>();
>2.addCallbacks
- 最后一个参数cbs就是用户注册的回调观察
- 第一个参数callbacks是布局变量集合,存储对应callback发生的变化内容集合
private static HashMap<ModeCallback, ArrayList<ChangeRec>> addCallbacks(
HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks,
int op, int uid, String packageName, int previousMode, ArraySet<ModeCallback> cbs) {
if (cbs == null) {
//没有要观察的回调集合,那就返回
return callbacks;
}
if (callbacks == null) {
callbacks = new HashMap<>();
}
final int N = cbs.size();
for (int i=0; i<N; i++) {
//循环用户添加的回调
ModeCallback cb = cbs.valueAt(i);
//根据回调获取对应的数据改变的集合
ArrayList<ChangeRec> reports = callbacks.get(cb);
//集合里添加数据
ArrayList<ChangeRec> changed = addChange(reports, op, uid, packageName, previousMode);
if (changed != reports) {
callbacks.put(cb, changed);
}
}
return callbacks;
}
>3.addChange
创建一个数据对象放入集合
private static ArrayList<ChangeRec> addChange(ArrayList<ChangeRec> reports,
int op, int uid, String packageName, int previousMode) {
boolean duplicate = false;
if (reports == null) {
reports = new ArrayList<>();
} else {
final int reportCount = reports.size();
//循环旧数据
for (int j = 0; j < reportCount; j++) {
ChangeRec report = reports.get(j);
//判断op和包名是否一样,一样就认为是重复的
if (report.op == op && report.pkg.equals(packageName)) {
//标记为重复的数据
duplicate = true;
break;
}
}
}
if (!duplicate) {
//没有重复的表明是新的,
reports.add(new ChangeRec(op, uid, packageName, previousMode));
}
return reports;
}
>4.notifyOpChangedSync
private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode,
int previousMode) {
final StorageManagerInternal storageManagerInternal =
LocalServices.getService(StorageManagerInternal.class);
if (storageManagerInternal != null) {
//见9.5
storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode, previousMode);
}
}
>5.shouldDeferResetOpToDpm
是否应该延迟重置op,可以看到交给dpmi处理了,见9.8
@Nullable private final DevicePolicyManagerInternal dpmi =
LocalServices.getService(DevicePolicyManagerInternal.class);
private boolean shouldDeferResetOpToDpm(int op) {
// TODO(b/174582385): avoid special-casing app-op resets by migrating app-op permission
// pre-grants to a role-based mechanism or another general-purpose mechanism.
return dpmi != null && dpmi.supportsResetOp(op);
}
private void deferResetOpToDpm(int op, String packageName, @UserIdInt int userId) {
// TODO(b/174582385): avoid special-casing app-op resets by migrating app-op permission
// pre-grants to a role-based mechanism or another general-purpose mechanism.
dpmi.resetOp(op, packageName, userId);
}
9.3.startWatchingModeWithFlags
监听给定的包的指定的op的flags的改变
public void startWatchingModeWithFlags(int op, String packageName, int flags,
IAppOpsCallback callback) {
//..
if (callback == null) {
return;
}
final boolean mayWatchPackageName =
packageName != null && !filterAppAccessUnlocked(packageName);
synchronized (this) {
int switchOp = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op;
int notifiedOps;
if ((flags & CALL_BACK_ON_SWITCHED_OP) == 0) {
if (op == OP_NONE) {
notifiedOps = ALL_OPS;
} else {
notifiedOps = op;
}
} else {
notifiedOps = switchOp;
}
//先看有没有旧数据
ModeCallback cb = mModeWatchers.get(callback.asBinder());
if (cb == null) {
//没有就创建新的
cb = new ModeCallback(callback, watchedUid, flags, notifiedOps, callingUid,
callingPid);
//这里添加数据
mModeWatchers.put(callback.asBinder(), cb);
}
if (switchOp != AppOpsManager.OP_NONE) {
ArraySet<ModeCallback> cbs = mOpModeWatchers.get(switchOp);
if (cbs == null) {
cbs = new ArraySet<>();
mOpModeWatchers.put(switchOp, cbs);
}
cbs.add(cb);
}
//需要观察包名的
if (mayWatchPackageName) {
ArraySet<ModeCallback> cbs = mPackageModeWatchers.get(packageName);
if (cbs == null) {
//没有旧数据
cbs = new ArraySet<>();
//集合添加数据
mPackageModeWatchers.put(packageName, cbs);
}
cbs.add(cb);
}
evalAllForegroundOpsLocked();
}
}
>1.filterAppAccessUnlocked
- 确定所提供的包是否应该对Binder.getCallingUid()可见。
- 注意:为了避免死锁,在This上同步时不能调用这个函数
private boolean filterAppAccessUnlocked(String packageName) {
final int callingUid = Binder.getCallingUid();
return LocalServices.getService(PackageManagerInternal.class)
.filterAppAccess(packageName, callingUid, UserHandle.getUserId(callingUid));
}
9.4.UidState
>1.isDefault
public boolean isDefault() {
return (pkgOps == null || pkgOps.isEmpty())
&& (opModes == null || opModes.size() <= 0)
&& (state == UID_STATE_CACHED
&& (pendingState == UID_STATE_CACHED));
}
9.5.StorageManagerService.java
>1.onAppOpsChanged
//内部类里的方法
public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode,
int previousMode) {
final long token = Binder.clearCallingIdentity();
try {
// When using FUSE, we may need to kill the app if the op changes
switch(code) {
case OP_REQUEST_INSTALL_PACKAGES:
// In R, we used to kill the app here if it transitioned to/from
// MODE_ALLOWED, to make sure the app had the correct (writable) OBB
// view. But the majority of apps don't handle OBBs anyway, and for those
// that do, they can restart themselves. Therefore, starting from S,
// only kill the app when it transitions away from MODE_ALLOWED (eg,
// when the permission is taken away).
//旧状态是allow,新状态不是
if (previousMode == MODE_ALLOWED && mode != MODE_ALLOWED) {
//见补充2,杀死进程
killAppForOpChange(code, uid);
}
return;
case OP_MANAGE_EXTERNAL_STORAGE:
if (mode != MODE_ALLOWED) {
// Only kill if op is denied, to lose external_storage gid
// Killing when op is granted to pickup the gid automatically,
// results in a bad UX, especially since the gid only gives access
// to unreliable volumes, USB OTGs that are rarely mounted. The app
// will get the external_storage gid on next organic restart.
killAppForOpChange(code, uid);
}
return;
case OP_LEGACY_STORAGE:
updateLegacyStorageApps(packageName, uid, mode == MODE_ALLOWED);
return;
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
>2.killAppForOpChange
private void killAppForOpChange(int code, int uid) {
final IActivityManager am = ActivityManager.getService();
try {//见9.6
am.killUid(UserHandle.getAppId(uid), UserHandle.USER_ALL,
AppOpsManager.opToName(code) + " changed.");
} catch (RemoteException e) {
}
}
9.6.ActivityManagerService.java
>1.killUid
public void killUid(int appId, int userId, String reason) {
enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
synchronized (this) {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mProcLock) {
mProcessList.killPackageProcessesLSP(null /* packageName */, appId, userId,
ProcessList.PERSISTENT_PROC_ADJ, false /* callerWillRestart */,
true /* callerWillRestart */, true /* doit */,
true /* evenPersistent */, false /* setRemoved */,
false /* uninstalling */,
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_KILL_UID,
reason != null ? reason : "kill uid");
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
9.7.ProcessList.java
boolean killPackageProcessesLSP(String packageName, int appId,
//...
final ArrayList<Pair<ProcessRecord, Boolean>> procs = new ArrayList<>();
//循环所有的进程,找到appId相关的进程信息
final int NP = mProcessNames.getMap().size();
for (int ip = 0; ip < NP; ip++) {
SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
//..
//中间就是各种判断,走到最后
procs.add(new Pair<>(app, shouldAllowRestart));
}
}
int N = procs.size();
for (int i=0; i<N; i++) {
final Pair<ProcessRecord, Boolean> proc = procs.get(i);
//杀死进程,补充2
removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second,
reasonCode, subReason, reason);
}
killAppZygotesLocked(packageName, appId, userId, false /* force */);
mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
return N > 0;
}
>2.removeProcessLocked
后边就是调用ProcessRecord的kill方法,如下
boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
//...
app.killLocked(reason, reasonCode, subReason, true);
9.8.DevicePolicyManagerService.java
>1.supportsResetOp
- 可以看到op必须是OP_INTERACT_ACROSS_PROFILES
- 对应的服务不为空,服务注册见补充3
public boolean supportsResetOp(int op) {
return op == AppOpsManager.OP_INTERACT_ACROSS_PROFILES
&& LocalServices.getService(CrossProfileAppsInternal.class) != null;
}
>2.resetOp
- 目前只支持为一个op,不是的话抛出异常
@Override
public void resetOp(int op, String packageName, @UserIdInt int userId) {
if (op != AppOpsManager.OP_INTERACT_ACROSS_PROFILES) {
throw new IllegalArgumentException("Unsupported op for DPM reset: " + op);
}
LocalServices.getService(CrossProfileAppsInternal.class)
.setInteractAcrossProfilesAppOp(//见补充4
packageName, findInteractAcrossProfilesResetMode(packageName), userId);
}
>3.CrossProfileAppsService
public class CrossProfileAppsService extends SystemService {
private CrossProfileAppsServiceImpl mServiceImpl;
public CrossProfileAppsService(Context context) {
super(context);
mServiceImpl = new CrossProfileAppsServiceImpl(context);
}
@Override
public void onStart() {
publishBinderService(Context.CROSS_PROFILE_APPS_SERVICE, mServiceImpl);
//这里注册的
publishLocalService(CrossProfileAppsInternal.class, mServiceImpl.getLocalService());
}
}
>4.setInteractAcrossProfilesAppOp
不看了,这个profile看着晕
private void setInteractAcrossProfilesAppOpUnchecked(
String packageName, @Mode int newMode, @UserIdInt int userId) {
if (newMode == AppOpsManager.MODE_ALLOWED
&& !canConfigureInteractAcrossProfiles(packageName, userId)) {
// The user should not be prompted for apps that cannot request to interact across
// profiles. However, we return early here if required to avoid race conditions.
Slog.e(TAG, "Tried to turn on the appop for interacting across profiles for invalid"
+ " app " + packageName);
return;
}
final int[] profileIds =
mInjector.getUserManager().getProfileIds(userId, /* enabledOnly= */ false);
for (int profileId : profileIds) {
if (!isPackageInstalled(packageName, profileId)) {
continue;
}
// Only log once per profile group by checking against the user ID.
setInteractAcrossProfilesAppOpForProfile(
packageName, newMode, profileId, /* logMetrics= */ profileId == userId);
}
}
class LocalService extends CrossProfileAppsInternal {
//..
public void setInteractAcrossProfilesAppOp(
String packageName, int newMode, @UserIdInt int userId) {
CrossProfileAppsServiceImpl.this.setInteractAcrossProfilesAppOpUnchecked(
packageName, newMode, userId);
}
10.AppOpsManager.java
10.1.MODE_XXX
执行操作的结果
//给定的调用者允许执行给定的操作
public static final int MODE_ALLOWED = 0;
//给定的调用者不允许执行给定的操作,并且操作失败是静默的,不影响app
public static final int MODE_IGNORED = 1;
//给定的调用者不允许执行给定的操作,并且返回安全异常,致命的错误
public static final int MODE_ERRORED = 2;
/**
* Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
* use its default security check. This mode is not normally used; it should only be used
* with appop permissions, and callers must explicitly check for it and deal with it.
*/
//给定的调用者使用默认的安全检查,这个mode不常用,只应该用来权限检查
public static final int MODE_DEFAULT = 3;
/**
* Special mode that means "allow only when app is in foreground." This is <b>not</b>
* returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather,
* {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
* possible for it to be ultimately allowed, depending on the app's background state),
* and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
* being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
*
* <p>The only place you will this normally see this value is through
* {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because
* you can't know the current state of the app being checked (and it can change at any
* point), you can only treat the result here as an indication that it will vary between
* {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
* state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do
* the actual check for access to the op.</p>
*/
//只允许前台应用,
public static final int MODE_FOREGROUND = 4;
10.2.opAllowsReset
对应的op是否允许重置,默认状态都在数组里存着了
public static boolean opAllowsReset(int op) {
return !sOpDisableReset[op];
}
10.3.opToDefaultMode
对应的op的默认状态,默认状态都在数组里存着了
public static @Mode int opToDefaultMode(int op) {
return sOpDefaultMode[op];
}
11.BatteryOptimizeUtils.java
11.1.resetAppOptimizationMode
public static void resetAppOptimizationMode(
Context context, IPackageManager ipm, AppOpsManager aom) {
resetAppOptimizationMode(context, ipm, aom,
PowerAllowlistBackend.getInstance(context), BatteryUtils.getInstance(context));
}
static void resetAppOptimizationMode(
Context context, IPackageManager ipm, AppOpsManager aom,
PowerAllowlistBackend allowlistBackend, BatteryUtils batteryUtils) {
//获取安装的应用,不包括用户disable的
final ArraySet<ApplicationInfo> applications = getInstalledApplications(context, ipm);
if (applications == null || applications.isEmpty()) {
return;
}
//见12.1
allowlistBackend.refreshList();
//
for (ApplicationInfo info : applications) {
final int mode = aom.checkOpNoThrow(
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, info.uid, info.packageName);
@OptimizationMode //见补充1
final int optimizationMode = getAppOptimizationMode(
mode, allowlistBackend.isAllowlisted(info.packageName));//见12.2
// Ignores default optimized/unknown state or system/default apps.
if (optimizationMode == MODE_OPTIMIZED
|| optimizationMode == MODE_UNKNOWN //见补充2
|| isSystemOrDefaultApp(allowlistBackend, info.packageName)) {
continue;
}
// Resets to the default mode: MODE_OPTIMIZED.
setAppUsageStateInternal(MODE_OPTIMIZED, info.uid, info.packageName, batteryUtils,
allowlistBackend);
}
}
>1.getAppOptimizationMode
根据app的操作结果mode,以及app是否在白名单里,返回优化模式
public static int getAppOptimizationMode(int mode, boolean isAllowListed) {
if (!isAllowListed && mode == AppOpsManager.MODE_IGNORED) {
//不在白名单,受限
return MODE_RESTRICTED;
} else if (isAllowListed && mode == AppOpsManager.MODE_ALLOWED) {
//在白名单的,不受限
return MODE_UNRESTRICTED;
} else if (!isAllowListed && mode == AppOpsManager.MODE_ALLOWED) {
//不在白名单的,优化
return MODE_OPTIMIZED;
} else {
return MODE_UNKNOWN;
}
}
>2.isSystemOrDefaultApp
在系统白名单里,或者是默认的激活应用
private static boolean isSystemOrDefaultApp(
PowerAllowlistBackend powerAllowlistBackend, String packageName) {
return powerAllowlistBackend.isSysAllowlisted(packageName)
|| powerAllowlistBackend.isDefaultActiveApp(packageName);
}
>3.setAppUsageStateInternal
private static void setAppUsageStateInternal(
@OptimizationMode int mode, int uid, String packageName, BatteryUtils batteryUtils,
PowerAllowlistBackend powerAllowlistBackend) {
if (mode == MODE_UNKNOWN) {
return;
}
// MODE_RESTRICTED = AppOpsManager.MODE_IGNORED + !allowListed
// MODE_UNRESTRICTED = AppOpsManager.MODE_ALLOWED + allowListed
// MODE_OPTIMIZED = AppOpsManager.MODE_ALLOWED + !allowListed
final int appOpsManagerMode =
mode == MODE_RESTRICTED ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
final boolean allowListed = mode == MODE_UNRESTRICTED;
setAppOptimizationModeInternal(appOpsManagerMode, allowListed, uid, packageName,
batteryUtils, powerAllowlistBackend);
}
//
private static void setAppOptimizationModeInternal(
int appStandbyMode, boolean allowListed, int uid, String packageName,
BatteryUtils batteryUtils, PowerAllowlistBackend powerAllowlistBackend) {
try {//见11.2
batteryUtils.setForceAppStandby(uid, packageName, appStandbyMode);
//更新白名单
if (allowListed) {
powerAllowlistBackend.addApp(packageName);
} else {
powerAllowlistBackend.removeApp(packageName);
}
}
}
11.2.BatteryUtils
>1.setForceAppStandby
public void setForceAppStandby(int uid, String packageName,
int mode) {
// Control whether app could run jobs in the background
//设置app是否可以在后台运行job的mode
mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);
ThreadUtils.postOnBackgroundThread(() -> {
final BatteryDatabaseManager batteryDatabaseManager = BatteryDatabaseManager
.getInstance(mContext);
//更新数据库
if (mode == AppOpsManager.MODE_IGNORED) {
batteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
uid, packageName, System.currentTimeMillis());
} else if (mode == AppOpsManager.MODE_ALLOWED) {
batteryDatabaseManager.deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
uid, packageName);
}
});
}
12.PowerAllowlistBackend
12.1.refreshList
public void refreshList() {
mSysAllowlistedApps.clear();
mAllowlistedApps.clear();
mDefaultActiveApps.clear();
if (mDeviceIdleService == null) {
return;
}
try {
//所有的白名单,包括系统设置的,用户设置的,
final String[] allowlistedApps = mDeviceIdleService.getFullPowerWhitelist();
for (String app : allowlistedApps) {
mAllowlistedApps.add(app);
}
//系统设置的白名单,所有模式下退出省电模式
final String[] sysAllowlistedApps = mDeviceIdleService.getSystemPowerWhitelist();
for (String app : sysAllowlistedApps) {
mSysAllowlistedApps.add(app);
}
final boolean hasTelephony = mAppContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TELEPHONY);
final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext,
true /* updateIfNeeded */);
final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(
mAppContext);
if (hasTelephony) {
//有语音通话功能,添加默认的短信以及拨号应用
if (defaultSms != null) {
mDefaultActiveApps.add(defaultSms.getPackageName());
}
if (!TextUtils.isEmpty(defaultDialer)) {
mDefaultActiveApps.add(defaultDialer);
}
}
}
}
>1.DeviceIdleController.java
/**
* Package names the system has white-listed to opt out of power save restrictions for
* all modes.
*/
private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();
/**
* Package names the user has white-listed to opt out of power save restrictions.
*/
private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
12.2.isAllowlisted
在白名单里,或者是默认的活动应用
public boolean isAllowlisted(String pkg) {
if (mAllowlistedApps.contains(pkg)) {
return true;
}
if (isDefaultActiveApp(pkg)) {
return true;
}
return false;
}