Author:Kevin Xu
Email:13570805860@163.com
QQ&Wechat:1922656999
Date:2016年11月28日
1.Setup Wizard 调用方法
PackageManager pm = mActivity.getPackageManager();
pm.setComponentEnabledSetting(name,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);
//Kevin Note:此处主要以COMPONENT_ENABLED_STATE_DISABLED 来分析
2.setComponentEnabledSetting 的由来
@File:
MM/frameworks/base/core/java/android/content/pm/PackageManager.java
publicabstractvoid setComponentEnabledSetting(ComponentName componentName,
int newState,int flags);
@file:
MM/frameworks/base/core/java/android/app/ApplicationPackageManager.java
finalclassApplicationPackageManagerextendsPackageManager{
@Override
publicvoid setComponentEnabledSetting(ComponentName componentName,
int newState,int flags){
try{
mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
}catch(RemoteException e){
// Should never happen!
}
}
4.mPM 的本体
@file:
MM/frameworks/base/core/java/android/app/ApplicationPackageManager.java
ApplicationPackageManager(ContextImpl context,
IPackageManager pm){
mContext = context;
mPM = pm;
}
@file:
MM/frameworks/base/core/java/android/app/ContextImpl.java
@Override
publicPackageManager getPackageManager(){
if(mPackageManager !=null){
return mPackageManager;
}
IPackageManager pm =ActivityThread.getPackageManager();
if(pm !=null){
// Doesn't matter if we make more than one instance.
return(mPackageManager =newApplicationPackageManager(this, pm));
}
returnnull;
}
@file:
MM/frameworks/base/core/java/android/app/ActivityThread.java
publicstaticIPackageManager getPackageManager(){
if(sPackageManager !=null){
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
IBinder b =ServiceManager.getService("package");
//Slog.v("PackageManager", "default service binder = " + b);
sPackageManager =IPackageManager.Stub.asInterface(b);
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
如上代码可以看出mPM 是PackageManagerService
5.PackageManagerService 的setComponentEnabledSetting
@file:
MM/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override
publicvoid setComponentEnabledSetting(ComponentName componentName,
int newState,int flags,int userId){
if(!sUserManager.exists(userId))return;
setEnabledSetting(componentName.getPackageName(),
componentName.getClassName(), newState, flags, userId,null);
}
privatevoid setEnabledSetting(finalString packageName,String className,int newState,
finalint flags,int userId,String callingPackage){
...
PackageSetting pkgSetting;
pkgSetting = mSettings.mPackages.get(packageName);
case COMPONENT_ENABLED_STATE_DISABLED:
if(!pkgSetting.disableComponentLPw(className, userId)){
return;
}
break;
scheduleWritePackageRestrictionsLocked(userId);
6. pkgSetting.disableComponentLPw
@File:
MM/frameworks/base/services/core/java/com/android/server/pm/PackageSetting.java
finalclassPackageSettingextendsPackageSettingBase{
@File:
MM/frameworks/base/services/core/java/com/android/server/pm/PackageSettingBase.java
boolean disableComponentLPw(String componentClassName,int userId){
PackageUserState state = modifyUserStateComponents(userId,true,false);
boolean changed = state.enabledComponents !=null
? state.enabledComponents.remove(componentClassName):false;
changed |= state.disabledComponents.add(componentClassName);
return changed;
}
MM/frameworks/base/core/java/android/content/pm/PackageUserState.java
publicArraySet<String> disabledComponents;
@File:
MM/frameworks/base/services/core/java/com/android/server/pm/PackageSettingBase.java
scheduleWritePackageRestrictionsLocked(userId);
void scheduleWritePackageRestrictionsLocked(int userId){
if(!sUserManager.exists(userId))return;
mDirtyUsers.add(userId);
if(!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)){
mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
}
}
case WRITE_PACKAGE_RESTRICTIONS:{
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
synchronized(mPackages){
removeMessages(WRITE_PACKAGE_RESTRICTIONS);
for(int userId : mDirtyUsers){
mSettings.writePackageRestrictionsLPr(userId);
}
mDirtyUsers.clear();
}
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
}break;
@file:
MM/frameworks/base/core/java/com/android/server/pm/Settings.java
void writePackageRestrictionsLPr(int userId){
File userPackagesStateFile = getUserPackagesStateFile(userId);
privateFile getUserPackagesStateFile(int userId){
// TODO: Implement a cleaner solution when adding tests.
// This instead of Environment.getUserSystemDirectory(userId) to support testing.
File userDir =newFile(newFile(mSystemDir,"users"),Integer.toString(userId));
returnnewFile(userDir,"package-restrictions.xml");
//kevin Note:文件路径为/data/system/users/0/package-restrictions.xml
}
经过如上的调用,将对应的数据写入/data/system/users/0/package-restrictions.xml
但是此处会有一个延时,
static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
如果在未写入时,就关机,会产生下次开机还进行设置向导的问题。
解决办法:
在数据设置成功,直接写数据文件。
在如下的位置进行增加:
case COMPONENT_ENABLED_STATE_DISABLED: if (!pkgSetting.disableComponentLPw(className, userId)) { return;
}else{
mSettings.writePackageRestrictionsLPr(userId);
} break;
mSettings.writePackageRestrictionsLPr(userId);
} break;
Author:Kevin Xu
Email:13570805860@163.com
QQ&Wechat:1922656999
Date:2016年11月28日
1.Setup Wizard 调用方法
PackageManager pm = mActivity.getPackageManager();
pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
//Kevin Note:此处主要以COMPONENT_ENABLED_STATE_DISABLED 来分析
2.setComponentEnabledSetting 的由来
@File:
MM/frameworks/base/core/java/android/content/pm/PackageManager.java
public abstract void setComponentEnabledSetting(ComponentName componentName,
int newState, int flags);
@file:
MM/frameworks/base/core/java/android/app/ApplicationPackageManager.java
final class ApplicationPackageManager extends PackageManager {
@Override
public void setComponentEnabledSetting(ComponentName componentName,
int newState, int flags) {
try {
mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
} catch (RemoteException e) {
// Should never happen!
}
}
4.mPM 的本体
@file:
MM/frameworks/base/core/java/android/app/ApplicationPackageManager.java
ApplicationPackageManager(ContextImpl context,
IPackageManager pm) {
mContext = context;
mPM = pm;
}
@file:
MM/frameworks/base/core/java/android/app/ContextImpl.java
@Override
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
@file:
MM/frameworks/base/core/java/android/app/ActivityThread.java
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
//Slog.v("PackageManager", "default service binder = " + b);
sPackageManager = IPackageManager.Stub.asInterface(b);
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
如上代码可以看出mPM 是PackageManagerService
5.PackageManagerService 的setComponentEnabledSetting
@file:
MM/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override
public void setComponentEnabledSetting(ComponentName componentName,
int newState, int flags, int userId) {
if (!sUserManager.exists(userId)) return;
setEnabledSetting(componentName.getPackageName(),
componentName.getClassName(), newState, flags, userId, null);
}
private void setEnabledSetting(final String packageName, String className, int newState,
final int flags, int userId, String callingPackage) {
...
PackageSetting pkgSetting;
pkgSetting = mSettings.mPackages.get(packageName);
case COMPONENT_ENABLED_STATE_DISABLED:
if (!pkgSetting.disableComponentLPw(className, userId)) {
return;
}
break;
scheduleWritePackageRestrictionsLocked(userId);
6. pkgSetting.disableComponentLPw
@File:
MM/frameworks/base/services/core/java/com/android/server/pm/PackageSetting.java
final class PackageSetting extends PackageSettingBase {
@File:
MM/frameworks/base/services/core/java/com/android/server/pm/PackageSettingBase.java
boolean disableComponentLPw(String componentClassName, int userId) {
PackageUserState state = modifyUserStateComponents(userId, true, false);
boolean changed = state.enabledComponents != null
? state.enabledComponents.remove(componentClassName) : false;
changed |= state.disabledComponents.add(componentClassName);
return changed;
}
MM/frameworks/base/core/java/android/content/pm/PackageUserState.java
public ArraySet<String> disabledComponents;
@File:
MM/frameworks/base/services/core/java/com/android/server/pm/PackageSettingBase.java
scheduleWritePackageRestrictionsLocked(userId);
void scheduleWritePackageRestrictionsLocked(int userId) {
if (!sUserManager.exists(userId)) return;
mDirtyUsers.add(userId);
if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
}
}
case WRITE_PACKAGE_RESTRICTIONS: {
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
synchronized (mPackages) {
removeMessages(WRITE_PACKAGE_RESTRICTIONS);
for (int userId : mDirtyUsers) {
mSettings.writePackageRestrictionsLPr(userId);
}
mDirtyUsers.clear();
}
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
} break;
@file:
MM/frameworks/base/core/java/com/android/server/pm/Settings.java
void writePackageRestrictionsLPr(int userId) {
File userPackagesStateFile = getUserPackagesStateFile(userId);
private File getUserPackagesStateFile(int userId) {
// TODO: Implement a cleaner solution when adding tests.
// This instead of Environment.getUserSystemDirectory(userId) to support testing.
File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
return new File(userDir, "package-restrictions.xml");
//kevin Note:文件路径为/data/system/users/0/package-restrictions.xml
}
经过如上的调用,将对应的数据写入/data/system/users/0/package-restrictions.xml
但是此处会有一个延时,
static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
如果在未写入时,就关机,会产生下次开机还进行设置向导的问题。
解决办法:
在数据设置成功,直接写数据文件。
在如下的位置进行增加:
case COMPONENT_ENABLED_STATE_DISABLED: if
(!pkgSetting.disableComponentLPw(className, userId)) { return; }else{
mSettings.writePackageRestrictionsLPr(userId);
} break;
mSettings.writePackageRestrictionsLPr(userId);
} break;