项羽真名,北京物资学院教务系统,兰普提
Android多用户之UserManagerService源码分析。Android可以支持多个用户使用系统,通常第一个在系统中注册的用户将默认成为系统管理员。
不同用户的设置各不相同,并且不同用户安装的应用及应用数据也不相同。但是系统中和硬件相关的设置则是共用的,如网络设置等。
用户切换后前面用户运行的后台进程还可以继续运行,这样进行用户切换时无须中断一些后台进行的耗时操作(如下载)。
管理用户的系统服务--UserManagerService
UserManagerService的主要功能是创建和删除用户,以及查询用户信息。
1.在PackageManagerService中进行初始化
[java]view plaincopy
finalArrayMapmPackages=
newArrayMap();
publicPackageManagerService(Contextcontext,Installerinstaller,
booleanfactoryTest,booleanonlyCore){
...
synchronized(mInstallLock){
//writer
synchronized(mPackages){
...
sUserManager=newUserManagerService(context,this,mPackages);
...
}//synchronized(mPackages)
}//synchronized(mInstallLock)
...
}
@Override
publicvoidsystemReady(){
...
sUserManager.systemReady();
...
}
UserManagerService的构造方法如下:
[java]view plaincopy
UserManagerService(Contextcontext,PackageManagerServicepm,ObjectpackagesLock){
this(context,pm,packagesLock,Environment.getDataDirectory());
}
调用了另一个构造方法,并多传递了一个参数:/data目录
[java]view plaincopy
privatestaticfinalStringUSER_INFO_DIR="system"+File.separator+"users";
privateUserManagerService(Contextcontext,PackageManagerServicepm,
ObjectpackagesLock,FiledataDir){
mContext=context;
mPm=pm;
mPackagesLock=packagesLock;
mHandler=newMainHandler();
synchronized(mPackagesLock){
///data/system/users
mUsersDir=newFile(dataDir,USER_INFO_DIR);
mUsersDir.mkdirs();
//Makezerothuserdirectory,forservicestomigratetheirfilestothatlocation
FileuserZeroDir=newFile(mUsersDir,String.valueOf(UserHandle.USER_SYSTEM));
//创建第一个用户目录:/data/system/users/0
userZeroDir.mkdirs();
//设置访问文件的权限
FileUtils.setPermissions(mUsersDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1,-1);
///data/system/users/userlist.xml
mUserListFile=newFile(mUsersDir,USER_LIST_FILENAME);
//初始化来宾账户的默认限制条件
initDefaultGuestRestrictions();
//从/data/system/users/userlist.xml文件读取用户信息
readUserListLP();
sInstance=this;
}
mLocalService=newLocalService();
LocalServices.addService(UserManagerInternal.class,mLocalService);
mLockPatternUtils=newLockPatternUtils(mContext);
mUserStates.put(UserHandle.USER_SYSTEM,UserState.STATE_BOOTING);
}
privatefinalBundlemGuestRestrictions=newBundle();
//初始化来宾账户的默认限制条件
privatevoidinitDefaultGuestRestrictions(){
synchronized(mGuestRestrictions){
if(mGuestRestrictions.isEmpty()){
//"no_config_wifi",不允许配置WiFi
mGuestRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI,true);
//"no_install_unknown_sources",不允许安装未知来源的应用
mGuestRestrictions.putBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,true);
//"no_outgoing_calls",不允许呼叫电话
mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS,true);
//"no_sms",不允许收发短信
mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS,true);
}
}
}
先看下/data/system/users/userlist.xml文件的内容,再分析读取过程,文件内容如下:
[html]view plaincopy
[java]view plaincopy
//从/data/system/users/userlist.xml文件读取用户信息
privatefinalSparseArraymUsers=newSparseArray<>();
privatevoidreadUserListLP(){
//如果文件不存在,则创建管理员用户并返回
if(!mUserListFile.exists()){
fallbackToSingleUserLP();
return;
}
FileInputStreamfis=null;
AtomicFileuserListFile=newAtomicFile(mUserListFile);
try{
fis=userListFile.openRead();
XmlPullParserparser=Xml.newPullParser();
parser.setInput(fis,StandardCharsets.UTF_8.name());
inttype;
while((type=parser.next())!=XmlPullParser.START_TAG
&&type!=XmlPullParser.END_DOCUMENT){
//Skip
}
if(type!=XmlPullParser.START_TAG){
Slog.e(LOG_TAG,"Unabletoreaduserlist");
//如果文件异常,则创建管理员用户并返回
fallbackToSingleUserLP();
return;
}
mNextSerialNumber=-1;
//解析文件
if(parser.getName().equals(TAG_USERS)){
StringlastSerialNumber=parser.getAttributeValue(null,ATTR_NEXT_SERIAL_NO);
if(lastSerialNumber!=null){
mNextSerialNumber=Integer.parseInt(lastSerialNumber);
}
StringversionNumber=parser.getAttributeValue(null,ATTR_USER_VERSION);
if(versionNumber!=null){
mUserVersion=Integer.parseInt(versionNumber);
}
}
finalBundlenewDevicePolicyGlobalUserRestrictions=newBundle();
while((type=parser.next())!=XmlPullParser.END_DOCUMENT){
if(type==XmlPullParser.START_TAG){
finalStringname=parser.getName();
if(name.equals(TAG_USER)){
Stringid=parser.getAttributeValue(null,ATTR_ID);
//初始化UserData对象保存从/data/system/users/${id}.xml文件中读取到的用户信息
UserDatauserData=readUserLP(Integer.parseInt(id));
if(userData!=null){
synchronized(mUsersLock){
//把解析到的用户信息保存到mUsers中
mUsers.put(userData.info.id,userData);
if(mNextSerialNumber||mNextSerialNumber<=userData.info.id){
mNextSerialNumber=userData.info.id+1;
}
}
}
}elseif(name.equals(TAG_GUEST_RESTRICTIONS)){
while((type=parser.next())!=XmlPullParser.END_DOCUMENT
&&type!=XmlPullParser.END_TAG){
if(type==XmlPullParser.START_TAG){
if(parser.getName().equals(TAG_RESTRICTIONS)){
synchronized(mGuestRestrictions){
UserRestrictionsUtils
.readRestrictions(parser,mGuestRestrictions);
}
}elseif(parser.getName().equals(TAG_DEVICE_POLICY_RESTRICTIONS)
){
UserRestrictionsUtils.readRestrictions(parser,
newDevicePolicyGlobalUserRestrictions);
}
break;
}
}
}elseif(name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)){
StringownerUserId=parser.getAttributeValue(null,ATTR_ID);
if(ownerUserId!=null){
mGlobalRestrictionOwnerUserId=Integer.parseInt(ownerUserId);
}
}
}
}
synchronized(mRestrictionsLock){
mDevicePolicyGlobalUserRestrictions=newDevicePolicyGlobalUserRestrictions;
}
//解析完文件后,更新用户ID
updateUserIds();
//如果有必要,则升级Version
upgradeIfNecessaryLP();
}catch(IOException|XmlPullParserExceptione){
fallbackToSingleUserLP();
}finally{
IoUtils.closeQuietly(fis);
}
}
//创建管理员用户
privatevoidfallbackToSingleUserLP(){
intflags=UserInfo.FLAG_INITIALIZED;
//Insplitsystemusermode,theadminandprimaryflagsareassignedtothefirsthuman
//user.
if(!UserManager.isSplitSystemUser()){
flags|=UserInfo.FLAG_ADMIN|UserInfo.FLAG_PRIMARY;
}
//Createthesystemuser
UserInfosystem=newUserInfo(UserHandle.USER_SYSTEM,null,null,flags);
UserDatauserData=newUserData();
userData.info=system;
synchronized(mUsersLock){
mUsers.put(system.id,userData);
}
mNextSerialNumber=MIN_USER_ID;
mUserVersion=USER_VERSION;
Bundlerestrictions=newBundle();
synchronized(mRestrictionsLock){
mBaseUserRestrictions.append(UserHandle.USER_SYSTEM,restrictions);
}
//更新用户ID
updateUserIds();
//初始化来宾账户的默认限制条件
initDefaultGuestRestrictions();
/*
*把用户信息写到/data/system/users/${id}.xml文件中,简单的写文件,不再看源码
*Writestheuserfileinthisformat:
*
*
*Primary
*
*/
writeUserLP(userData);
/*
*把用户信息写到/data/system/users/userlist.xml文件中
*Writestheuserlistfileinthisformat:
*
*
*
*
*
*/
writeUserListLP();
}
这样UserManagerService的初始化工作就完成了,主要的工作就是解析userlist.xml文件,并创建了mUsers列表中的UserData对象。
2.UserData的定义
[java]view plaincopy
privatestaticclassUserData{
//Basicuserinformationandproperties
UserInfoinfo;
//Accountnameusedwhenthereisastrongassociationbetweenauserandanaccount
Stringaccount;
//Accountinformationforseedingintoanewlycreateduser.Thiscouldalsobe
//usedforloginvalidationforanexistinguser,forupdatingtheircredentials.
//Inthelattercase,datamaynotneedtobepersistedasitisonlyvalidforthe
//currentloginsession.
StringseedAccountName;
StringseedAccountType;
PersistableBundleseedAccountOptions;
//Whethertoperisttheseedaccountinformationtobeavailableafteraboot
booleanpersistSeedData;
voidclearSeedAccountData(){
seedAccountName=null;
seedAccountType=null;
seedAccountOptions=null;
persistSeedData=false;
}
}
publicclassUserInfoimplementsParcelable{
/**8bitsforusertype用户类型*/
publicstaticfinalintFLAG_MASK_USER_TYPE=0x000000FF;
/**
****************************NOTE***************************
*TheseflagvaluesCANNOTCHANGEbecausetheyarewritten
*directlytostorage.
*/
/**
*Primaryuser.Onlyoneusercanhavethisflagset.Itidentifiesthefirsthumanuser
*onadevice.主用户标志,通常是第一个ID为0的用户
*/
publicstaticfinalintFLAG_PRIMARY=0x00000001;
/**
*Userwithadministrativeprivileges.Suchausercancreateand
*deleteusers.admin用户标志,有此标志才有创建和删除用户的权限
*/
publicstaticfinalintFLAG_ADMIN=0x00000002;
/**
*Indicatesaguestuserthatmaybetransient.guest用户标志
*/
publicstaticfinalintFLAG_GUEST=0x00000004;
/**
*Indicatestheuserhasrestrictionsinprivileges,inadditiontothosefornormalusers.
*ExactmeaningTBD.Forinstance,maybetheycan'tinstallappsoradministerWiFiaccesspts.
*标志权限受限的用户,具体受限功能未定
*/
publicstaticfinalintFLAG_RESTRICTED=0x00000008;
/**
*Indicatesthatthisuserhasgonethroughitsfirst-timeinitialization.
*标志该用户是否已经初始化
*/
publicstaticfinalintFLAG_INITIALIZED=0x00000010;
/**
*Indicatesthatthisuserisaprofileofanotheruser,forexampleholdingausers
*corporatedata.标志该UserInfo是另一个用户的profile
*/
publicstaticfinalintFLAG_MANAGED_PROFILE=0x00000020;
/**
*Indicatesthatthisuserisdisabled.标志该用户已被禁止
*
*
Note:Ifanephemeraluserisdisabled,itshouldn'tbelaterre-enabled.Ephemeralusers
*aredisabledastheirremovalisinprogresstoindicatethattheyshouldn'tbere-entered.
*/
publicstaticfinalintFLAG_DISABLED=0x00000040;
publicstaticfinalintFLAG_QUIET_MODE=0x00000080;
/**
*Indicatesthatthisuserisephemeral.I.e.theuserwillberemovedafterleaving
*theforeground.
*/
publicstaticfinalintFLAG_EPHEMERAL=0x00000100;
publicstaticfinalintNO_PROFILE_GROUP_ID=UserHandle.USER_NULL;
publicintid;//用户ID
publicintserialNumber;//用户的序列号,不会重复
publicStringname;//用户名称
publicStringiconPath;//用户头像路径
publicintflags;//用户标志
publiclongcreationTime;//创建用户的时间
publiclonglastLoggedInTime;//最后一次登录的时间
publicStringlastLoggedInFingerprint;//最后一次用指纹登录的时间
publicintprofileGroupId;//用户profile的groupID
publicintrestrictedProfileParentId;
/**Userisonlypartiallycreated.*/
publicbooleanpartial;//true表示该用户没有创建完成
publicbooleanguestToRemove;
...
}
3.添加用户
UserManagerService中添加用户的方法是createUser():
[java]view plaincopy
@Override
publicUserInfocreateUser(Stringname,intflags){
if(DBG)Slog.i(LOG_TAG,"createUsername"+name);
//检查添加用户的权限
checkManageOrCreateUsersPermission(flags);
returncreateUserInternal(name,flags,UserHandle.USER_NULL);
}
privateUserInfocreateUserInternal(Stringname,intflags,intparentId){
//如果没有添加用户的权限则返回null
if(hasUserRestriction(UserManager.DISALLOW_ADD_USER,UserHandle.getCallingUserId())){
Log.w(LOG_TAG,"Cannotadduser.DISALLOW_ADD_USERisenabled.");
returnnull;
}
returncreateUserInternalUnchecked(name,flags,parentId);
}
privateUserInfocreateUserInternalUnchecked(Stringname,intflags,intparentId){
//如果是一个低内存设备,则返回null
if(ActivityManager.isLowRamDeviceStatic()){
returnnull;
}
finalbooleanisGuest=(flags&UserInfo.FLAG_GUEST)!=0;
finalbooleanisManagedProfile=(flags&UserInfo.FLAG_MANAGED_PROFILE)!=0;
finalbooleanisRestricted=(flags&UserInfo.FLAG_RESTRICTED)!=0;
finallongident=Binder.clearCallingIdentity();
UserInfouserInfo;
UserDatauserData;
finalintuserId;
try{
synchronized(mPackagesLock){
UserDataparent=null;
if(parentId!=UserHandle.USER_NULL){
synchronized(mUsersLock){
//根据userId获取UserData信息
parent=getUserDataLU(parentId);
}
if(parent==null)returnnull;
}
//判断是否可以添加更多profile
if(isManagedProfile&&!canAddMoreManagedProfiles(parentId,false)){
Log.e(LOG_TAG,"Cannotaddmoremanagedprofilesforuser"+parentId);
returnnull;
}
//判断是否达到用户上限
if(!isGuest&&!isManagedProfile&&isUserLimitReached()){
//Ifwe'renotaddingaguestuseroramanagedprofileandthelimithas
//beenreached,cannotaddauser.
returnnull;
}
//Ifwe'readdingaguestandtherealreadyexistsone,bail.
//如果创建的是guest用户且guest用户已经存在则返回
if(isGuest&&findCurrentGuestUser()!=null){
returnnull;
}
//Inlegacymode,restrictedprofile'sparentcanonlybetheowneruser
if(isRestricted&&!UserManager.isSplitSystemUser()
&&(parentId!=UserHandle.USER_SYSTEM)){
Log.w(LOG_TAG,"Cannotaddrestrictedprofile-parentusermustbeowner");
returnnull;
}
if(isRestricted&&UserManager.isSplitSystemUser()){
if(parent==null){
Log.w(LOG_TAG,"Cannotaddrestrictedprofile-parentusermustbe"
+"specified");
returnnull;
}
if(!parent.info.canHaveProfile()){
Log.w(LOG_TAG,"Cannotaddrestrictedprofile-profilescannotbe"
+"createdforthespecifiedparentuserid"+parentId);
returnnull;
}
}
if(!UserManager.isSplitSystemUser()&&(flags&UserInfo.FLAG_EPHEMERAL)!=0){
Log.e(LOG_TAG,
"Ephemeralusersaresupportedonsplit-system-usersystemsonly.");
returnnull;
}
//Insplitsystemusermode,weassignthefirsthumanusertheprimaryflag.
//Andifthereisnodeviceowner,wealsoassigntheadminflagtoprimaryuser.
if(UserManager.isSplitSystemUser()
&&!isGuest&&!isManagedProfile&&getPrimaryUser()==null){
flags|=UserInfo.FLAG_PRIMARY;
synchronized(mUsersLock){
if(!mIsDeviceManaged){
flags|=UserInfo.FLAG_ADMIN;
}
}
}
//获取下一个可用的userId
userId=getNextAvailableId();
//创建/data/system/users/userId文件夹
Environment.getUserSystemDirectory(userId).mkdirs();
booleanephemeralGuests=Resources.getSystem()
.getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
synchronized(mUsersLock){
//Addephemeralflagtoguests/usersifrequired.Alsoinherititfromparent.
if((isGuest&&ephemeralGuests)||mForceEphemeralUsers
||(parent!=null&&parent.info.isEphemeral())){
flags|=UserInfo.FLAG_EPHEMERAL;
}
//初始化新用户
userInfo=newUserInfo(userId,name,null,flags);
userInfo.serialNumber=mNextSerialNumber++;
longnow=System.currentTimeMillis();
userInfo.creationTime=(now>EPOCH_PLUS_30_YEARS)now:0;
//设置partial变量为true,表示用户还没有创建完成
userInfo.partial=true;
userInfo.lastLoggedInFingerprint=Build.FINGERPRINT;
userData=newUserData();
userData.info=userInfo;
mUsers.put(userId,userData);
}
//保存用户信息
writeUserLP(userData);
writeUserListLP();
if(parent!=null){
if(isManagedProfile){
if(parent.info.profileGroupId==UserInfo.NO_PROFILE_GROUP_ID){
parent.info.profileGroupId=parent.info.id;
writeUserLP(parent);
}
userInfo.profileGroupId=parent.info.profileGroupId;
}elseif(isRestricted){
if(parent.info.restrictedProfileParentId==UserInfo.NO_PROFILE_GROUP_ID){
parent.info.restrictedProfileParentId=parent.info.id;
writeUserLP(parent);
}
userInfo.restrictedProfileParentId=parent.info.restrictedProfileParentId;
}
}
}
//为新建用户准备存储区域
finalStorageManagerstorage=mContext.getSystemService(StorageManager.class);
storage.createUserKey(userId,userInfo.serialNumber,userInfo.isEphemeral());
mPm.prepareUserData(userId,userInfo.serialNumber,
StorageManager.FLAG_STORAGE_DE|StorageManager.FLAG_STORAGE_CE);
//保存所有安装应用在新建用户目录下的安装状态
mPm.createNewUser(userId);
//创建完新用户后修改partial变量为false,表示用户创建完成,并重新保存用户信息
userInfo.partial=false;
synchronized(mPackagesLock){
writeUserLP(userData);
}
updateUserIds();
Bundlerestrictions=newBundle();
if(isGuest){
synchronized(mGuestRestrictions){
restrictions.putAll(mGuestRestrictions);
}
}
synchronized(mRestrictionsLock){
mBaseUserRestrictions.append(userId,restrictions);
}
//发送成功添加新用户的广播
IntentaddedIntent=newIntent(Intent.ACTION_USER_ADDED);
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE,userId);
mContext.sendBroadcastAsUser(addedIntent,UserHandle.ALL,
android.Manifest.permission.MANAGE_USERS);
MetricsLogger.count(mContext,isGuestTRON_GUEST_CREATED:TRON_USER_CREATED,1);
}finally{
Binder.restoreCallingIdentity(ident);
}
returnuserInfo;
}
//根据userId获取UserData信息
privateUserDatagetUserDataLU(intuserId){
finalUserDatauserData=mUsers.get(userId);
//Ifitispartialandnotintheprocessofbeingremoved,returnasunknownuser.
if(userData!=null&&userData.info.partial&&!mRemovingUserIds.get(userId)){
returnnull;
}
returnuserData;
}
finalSettingsmSettings;
/**CalledbyUserManagerService*/
//保存所有安装应用在新建用户目录下的安装状态
voidcreateNewUser(intuserId){
synchronized(mInstallLock){
//把所有已安装的应用数据拷贝到新建用户对应目录(/data/user/0/)下
mSettings.createNewUserLI(this,mInstaller,userId);
}
synchronized(mPackages){
//在/data/system/users/0/package-restrictions.xml文件中保存应用的限制信息
scheduleWritePackageRestrictionsLocked(userId);
//更新/data/system/packages.list文件
scheduleWritePackageListLocked(userId);
//保存默认浏览器应用,并更新/data/system/users/0/package-restrictions.xml文件
applyFactoryDefaultBrowserLPw(userId);
//主要域名验证
primeDomainVerificationsLPw(userId);
}
}
/**Mapfrompackagenametosettings每个包名对应一个PackageSetting*/
finalArrayMapmPackages=newArrayMap<>();
//把所有已安装的系统应用数据拷贝到新建用户对应目录下
voidcreateNewUserLI(@NonNullPackageManagerServiceservice,@NonNullInstallerinstaller,
intuserHandle){
String[]volumeUuids;
String[]names;
int[]appIds;
String[]seinfos;
int[]targetSdkVersions;
intpackagesCount;
synchronized(mPackages){
//从map中获取出所有的settings
Collectionpackages=mPackages.values();
packagesCount=packages.size();
volumeUuids=newString[packagesCount];
names=newString[packagesCount];
appIds=newint[packagesCount];
seinfos=newString[packagesCount];
targetSdkVersions=newint[packagesCount];
IteratorpackagesIterator=packages.iterator();
//遍历所有的PackageSetting
for(inti=0;iPackageSettingps=packagesIterator.next();
if(ps.pkg==null||ps.pkg.applicationInfo==null){
continue;
}
//Onlysystemappsareinitiallyinstalled.初始化时只安装系统应用
/**M:[Operator]Operatorpackageshouldalsobeinstalled@{*/
booleancurInstalledStatus=ps.isSystem()
||(ps.pkgFlagsEx&ApplicationInfo.FLAG_EX_OPERATOR)!=0;
//设置每一个应用在新创建用户下的安装状态,系统应用为true
ps.setInstalled(curInstalledStatus,userHandle);
/**@}*/
//Needtocreateadatadirectoryforallappsunderthisuser.Accumulateall
//requiredargsandcalltheinstalleraftermPackageslockhasbeenreleased
volumeUuids[i]=ps.volumeUuid;
names[i]=ps.name;
appIds[i]=ps.appId;
seinfos[i]=ps.pkg.applicationInfo.seinfo;
targetSdkVersions[i]=ps.pkg.applicationInfo.targetSdkVersion;
}
}
for(inti=0;iif(names[i]==null){
continue;
}
//TODO:triageflags!
finalintflags=StorageManager.FLAG_STORAGE_CE|StorageManager.FLAG_STORAGE_DE;
try{
//在新建用户目录(/data/user/0/)下创建每个应用的数据目录(包名命名的文件夹)
installer.createAppData(volumeUuids[i],names[i],userHandle,flags,appIds[i],
seinfos[i],targetSdkVersions[i]);
}catch(InstallerExceptione){
Slog.w(TAG,"Failedtoprepareappdata",e);
}
}
synchronized(mPackages){
//解析"etc/preferred-apps"目录下所有XML文件,XML文件中保存的是设备使用者指定的响应某个Intent
//的最合适的组件信息
applyDefaultPreferredAppsLPw(service,userHandle);
}
}
4.删除用户
[java]view plaincopy
/**
*Removesauserandalldatadirectoriescreatedforthatuser.Thismethodshouldbecalled
*aftertheuser'sprocesseshavebeenterminated.
*@paramuserHandletheuser'sid
*/
@Override
publicbooleanremoveUser(intuserHandle){
//检查调用者是否有删除用户的权限
checkManageOrCreateUsersPermission("Onlythesystemcanremoveusers");
if(getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
UserManager.DISALLOW_REMOVE_USER,false)){
Log.w(LOG_TAG,"Cannotremoveuser.DISALLOW_REMOVE_USERisenabled.");
returnfalse;
}
longident=Binder.clearCallingIdentity();
try{
finalUserDatauserData;
intcurrentUser=ActivityManager.getCurrentUser();
if(currentUser==userHandle){
Log.w(LOG_TAG,"Currentusercannotberemoved");
returnfalse;
}
synchronized(mPackagesLock){
synchronized(mUsersLock){
userData=mUsers.get(userHandle);
if(userHandle==0||userData==null||mRemovingUserIds.get(userHandle)){
returnfalse;
}
//WerememberdeleteduserIDstopreventthemfrombeing
//reusedduringthecurrentboot;theycanstillbereused
//afterareboot.保存要删除的userId,防止重复删除
mRemovingUserIds.put(userHandle,true);
}
try{
mAppOpsService.removeUser(userHandle);
}catch(RemoteExceptione){
Log.w(LOG_TAG,"UnabletonotifyAppOpsServiceofremovinguser",e);
}
//Setthistoapartiallycreateduser,sothattheuserwillbepurged
//onnextstartup,incasetheruntimestopsnowbeforestoppingand
//removingtheusercompletely.
//删除用户并没有删除相关用户文件,只是把partial变量修改为true,
//开机后如果该变量还是true会删除相关文件
userData.info.partial=true;
//Markitasdisabled,sothatitisn'treturnedanymorewhen
//profilesarequeried.
userData.info.flags|=UserInfo.FLAG_DISABLED;
//更新/data/system/users/${id}.xml文件
writeUserLP(userData);
}
if(userData.info.profileGroupId!=UserInfo.NO_PROFILE_GROUP_ID
&&userData.info.isManagedProfile()){
//Sendbroadcasttonotifysystemthattheuserremovedwasa
//manageduser.发送删除用户的广播
sendProfileRemovedBroadcast(userData.info.profileGroupId,userData.info.id);
}
if(DBG)Slog.i(LOG_TAG,"Stoppinguser"+userHandle);
intres;
try{
//停止正在运行的用户
res=ActivityManagerNative.getDefault().stopUser(userHandle,/*force=*/true,
newIStopUserCallback.Stub(){
@Override
publicvoiduserStopped(intuserId){
//删除用户相关应用信息
finishRemoveUser(userId);
}
@Override
publicvoiduserStopAborted(intuserId){
}
});
}catch(RemoteExceptione){
returnfalse;
}
returnres==ActivityManager.USER_OP_SUCCESS;
}finally{
Binder.restoreCallingIdentity(ident);
}
}
5.多用户管理
UserManagerService主要管理用户的账号信息,运行中的用户管理由ActivityManagerService来负责。
用户的状态有5种,定义在UserState类中:
[java]view plaincopy
publicfinalclassUserState{
//Userisfirstcomingup.启动中
publicfinalstaticintSTATE_BOOTING=0;
//Userisinthelockedstate.锁定
publicfinalstaticintSTATE_RUNNING_LOCKED=1;
//Userisintheunlockingstate.未锁定
publicfinalstaticintSTATE_RUNNING_UNLOCKING=2;
//Userisintherunningstate.运行中
publicfinalstaticintSTATE_RUNNING_UNLOCKED=3;
//Userisintheinitialprocessofbeingstopped.停止的初始过程中
publicfinalstaticintSTATE_STOPPING=4;
//Userisinthefinalphafstopping,sendingIntent.ACTION_SHUTDOWN.停止的最后阶段
publicfinalstaticintSTATE_SHUTDOWN=5;
...
}
@Override
publicbooleanswitchUser(finalinttargetUserId){
//检查调用者是否有切换用户的权限
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,targetUserId);
UserInfocurrentUserInfo;
UserInfotargetUserInfo;
synchronized(this){
//获取当用用户的相关信息
intcurrentUserId=mUserController.getCurrentUserIdLocked();
currentUserInfo=mUserController.getUserInfo(currentUserId);
//获取切换目标用户的相关信息
targetUserInfo=mUserController.getUserInfo(targetUserId);
if(targetUserInfo==null){
Slog.w(TAG,"Nouserinfoforuser#"+targetUserId);
returnfalse;
}
//如果目标用户不支持切换,则返回
if(!targetUserInfo.supportsSwitchTo()){
Slog.w(TAG,"CannotswitchtoUser#"+targetUserId+":notsupported");
returnfalse;
}
//如果目标用户是另一个用户的profile,则返回
if(targetUserInfo.isManagedProfile()){
Slog.w(TAG,"CannotswitchtoUser#"+targetUserId+":notafulluser");
returnfalse;
}
mUserController.setTargetUserIdLocked(targetUserId);
}
//发送切换用户的消息
PairuserNames=newPair<>(currentUserInfo,targetUserInfo);
mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG,userNames));
returntrue;
}
finalclassUiHandlerextendsHandler{
publicUiHandler(){
super(com.android.server.UiThread.get().getLooper(),null,true);
}
@Override
publicvoidhandleMessage(Messagemsg){
switch(msg.what){
...
caseSTART_USER_SWITCH_UI_MSG:{
mUserController.showUserSwitchDialog((Pair)msg.obj);
break;
}
...
}
}
}
voidshowUserSwitchDialog(PairfromToUserPair){
//ThedialogwillshowandtheninitiatetheuserswitchbycallingstartUserInForeground
Dialogd=newUserSwitchingDialog(mService,mService.mContext,fromToUserPair.first,
fromToUserPair.second,true/*abovesystem*/);
d.show();
}
@Override
publicvoidshow(){
//Slog.v(TAG,"showcalled");
super.show();
finalViewdecorView=getWindow().getDecorView();
if(decorView!=null){
decorView.getViewTreeObserver().addOnWindowShownListener(this);
}
//Addatimeoutasasafeguard,incasearaceinscreenon/offcausesthewindow
//callbacktonevercome.
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_USER),
WINDOW_SHOWN_TIMEOUT_MS);
}
privatefinalHandlermHandler=newHandler(){
@Override
publicvoidhandleMessage(Messagemsg){
switch(msg.what){
caseMSG_START_USER:
//调用startUser()方法
startUser();
break;
}
}
};
voidstartUser(){
synchronized(this){
if(!mStartedUser){
//调用startUserInForeground方法
mService.mUserController.startUserInForeground(mUserId,this);
mStartedUser=true;
finalViewdecorView=getWindow().getDecorView();
if(decorView!=null){
decorView.getViewTreeObserver().removeOnWindowShownListener(this);
}
mHandler.removeMessages(MSG_START_USER);
}
}
}
/**
*Startuser,ifitsnotalreadyrunning,andbringittoforeground.
*开启用户,如果用户没有在运行,则开启它
*/
booleanstartUserInForeground(finalintuserId,Dialogdlg){
booleanresult=startUser(userId,/*foreground*/true);
dlg.dismiss();
returnresult;
}
/**
*Startuser,ifitsnotalreadyrunning.
*
Theuserwillbebroughttotheforeground,if{@codeforeground}parameterisset.
*Whenstartingtheuser,multipleintentswillbebroadcastinthefollowingorder:
*
*
{@linkIntent#ACTION_USER_STARTED}-senttoregisteredreceiversofthenewuser
*
{@linkIntent#ACTION_USER_BACKGROUND}-senttoregisteredreceiversoftheoutgoing
*userandallprofilesofthisuser.Sentonlyif{@codeforeground}parameteristrue
*
{@linkIntent#ACTION_USER_FOREGROUND}-senttoregisteredreceiversofthenew
*userandallprofilesofthisuser.Sentonlyif{@codeforeground}parameteristrue
*
{@linkIntent#ACTION_USER_SWITCHED}-senttoregisteredreceiversofthenewuser.
*Sentonlyif{@codeforeground}parameteristrue
*
{@linkIntent#ACTION_USER_STARTING}-orderedbroadcastsenttoregisteredreceivers
*ofthenewfguser
*
{@linkIntent#ACTION_LOCKED_BOOT_COMPLETED}-orderedbroadcastsenttoreceiversof
*thenewuser
*
{@linkIntent#ACTION_USER_UNLOCKED}-senttoregisteredreceiversofthenewuser
*
{@linkIntent#ACTION_PRE_BOOT_COMPLETED}-orderedbroadcastsenttoreceiversofthe
*newuser.Sentonlywhentheuserisbootingafterasystemupdate.
*
{@linkIntent#ACTION_USER_INITIALIZE}-orderedbroadcastsenttoreceiversofthe
*newuser.Sentonlythefirsttimeauserisstarting.
*
{@linkIntent#ACTION_BOOT_COMPLETED}-orderedbroadcastsenttoreceiversofthenew
*user.Indicatesthattheuserhasfinishedbooting.
*
*
*@paramuserIdIDoftheusertostart
*@paramforegroundtrueifusershouldbebroughttotheforeground
*@returntrueiftheuserhasbeensuccessfullystarted
*/
booleanstartUser(finalintuserId,finalbooleanforeground){
//检查调用者权限
if(mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
!=PackageManager.PERMISSION_GRANTED){
Stringmsg="PermissionDenial:switchUser()frompid="
+Binder.getCallingPid()
+",uid="+Binder.getCallingUid()
+"requires"+INTERACT_ACROSS_USERS_FULL;
Slog.w(TAG,msg);
thrownewSecurityException(msg);
}
Slog.i(TAG,"Startinguserid:"+userId+"fg:"+foreground);
finallongident=Binder.clearCallingIdentity();
try{
synchronized(mService){
finalintoldUserId=mCurrentUserId;
//如果要开启的用户已经存在,则直接返回true
if(oldUserId==userId){
returntrue;
}
mService.mStackSupervisor.setLockTaskModeLocked(null,
ActivityManager.LOCK_TASK_MODE_NONE,"startUser",false);
//获取目标用户的相关信息
finalUserInfouserInfo=getUserInfo(userId);
if(userInfo==null){
Slog.w(TAG,"Nouserinfoforuser#"+userId);
returnfalse;
}
if(foreground&&userInfo.isManagedProfile()){
Slog.w(TAG,"CannotswitchtoUser#"+userId+":notafulluser");
returnfalse;
}
//如果要把用户切到前台,则播放动画
if(foreground){
mService.mWindowManager.startFreezingScreen(
R.anim.screen_user_exit,R.anim.screen_user_enter);
}
booleanneedStart=false;
//Iftheuserweareswitchingtoisnotcurrentlystarted,then
//weneedtostartitnow.如果目标用户不存在,则修改用户状态为正在开启
//UserState的状态默认值是STATE_BOOTING
if(mStartedUsers.get(userId)==null){
UserStateuserState=newUserState(UserHandle.of(userId));
mStartedUsers.put(userId,userState);
getUserManagerInternal().setUserState(userId,userState.state);
//根据用户状态更新已经开启的用户列表
updateStartedUserArrayLocked();
needStart=true;
}
finalUserStateuss=mStartedUsers.get(userId);
finalIntegeruserIdInt=userId;
mUserLru.remove(userIdInt);
//调整用户在mUserLru中的位置,当前用户位于末尾
mUserLru.add(userIdInt);
if(foreground){
//修改当前用户的Id
mCurrentUserId=userId;
//更新用户配置信息
mService.updateUserConfigurationLocked();
mTargetUserId=UserHandle.USER_NULL;//reset,mCurrentUserIdhascaughtup
//更新与当前用户相关的用户列表
updateCurrentProfileIdsLocked();
mService.mWindowManager.setCurrentUser(userId,mCurrentProfileIds);
//Oncetheinternalnotionoftheactiveuserhasswitched,welockthedevice
//withtheoptiontoshowtheuserswitcheronthekeyguard.
mService.mWindowManager.lockNow(null);
}else{
finalIntegercurrentUserIdInt=mCurrentUserId;
//更新与当前用户相关的用户列表
updateCurrentProfileIdsLocked();
mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
mUserLru.remove(currentUserIdInt);
mUserLru.add(currentUserIdInt);
}
//Makesureuserisinthestartedstate.Ifitiscurrently
//stopping,weneedtoknockthatoff.确保用户处于启动状态,如果处于
//停止的初始阶段,则中止它。如果已经发送过停止运行的广播,则重新设置用户的状态
if(uss.state==UserState.STATE_STOPPING){
//Ifwearestopping,wehaven'tsentACTION_SHUTDOWN,
//sowecanjustfairlysilentlybringtheuserbackfrom
//thealmost-dead.
uss.setState(uss.lastState);
getUserManagerInternal().setUserState(userId,uss.state);
//根据用户状态更新已经开启的用户列表
updateStartedUserArrayLocked();
needStart=true;
}elseif(uss.state==UserState.STATE_SHUTDOWN){
//ThismeansACTION_SHUTDOWNhasbeensent,sowewill
//needtotreatthisasanewbootoftheuser.
uss.setState(UserState.STATE_BOOTING);
getUserManagerInternal().setUserState(userId,uss.state);
//根据用户状态更新已经开启的用户列表
updateStartedUserArrayLocked();
needStart=true;
}
if(uss.state==UserState.STATE_BOOTING){
//Giveusermanagerachancetopropagateuserrestrictions
//tootherservicesandprepareappstorage
//在用户启动之前,先准备相关用户的限制及存储
getUserManager().onBeforeStartUser(userId);
//Bootingupanewuser,needtotellsystemservicesaboutit.
//Notethatthisisonthesamehandlerasschedulingofbroadcasts,
//whichisimportantbecauseitneedstogofirst.
mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG,userId,0));
}
if(foreground){
//发送相关消息
mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG,userId,
oldUserId));
mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
oldUserId,userId,uss));
mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
oldUserId,userId,uss),USER_SWITCH_TIMEOUT);
}
if(needStart){
//SendUSER_STARTEDbroadcast如果需要开启用户,则发送相应广播
//用户切换牵扯到很多模块,如壁纸管理、输入法、账号管理等,都需要收到通知
Intentintent=newIntent(Intent.ACTION_USER_STARTED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
|Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE,userId);
mService.broadcastIntentLocked(null,null,intent,
null,null,0,null,null,null,AppOpsManager.OP_NONE,
null,false,false,MY_PID,SYSTEM_UID,userId);
}
if(foreground){
//把开启的用户设为前台用户
moveUserToForegroundLocked(uss,oldUserId,userId);
}else{
//用户启动结束,则切换用户到STATE_RUNNING_LOCKED状态
mService.mUserController.finishUserBoot(uss);
}
if(needStart){
//如果需要开启用户,则发送相应广播
Intentintent=newIntent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE,userId);
mService.broadcastIntentLocked(null,null,intent,
null,newIIntentReceiver.Stub(){
@Override
publicvoidperformReceive(Intentintent,intresultCode,
Stringdata,Bundleextras,booleanordered,booleansticky,
intsendingUser)throwsRemoteException{
}
},0,null,null,
newString[]{INTERACT_ACROSS_USERS},AppOpsManager.OP_NONE,
null,true,false,MY_PID,SYSTEM_UID,UserHandle.USER_ALL);
}
}
}finally{
Binder.restoreCallingIdentity(ident);
}
returntrue;
}
//根据用户状态更新已经开启的用户列表mStartedUserArray
privatevoidupdateStartedUserArrayLocked(){
intnum=0;
for(inti=0;iUserStateuss=mStartedUsers.valueAt(i);
//Thislistdoesnotincludestoppingusers.
if(uss.state!=UserState.STATE_STOPPING
&&uss.state!=UserState.STATE_SHUTDOWN){
num++;
}
}
mStartedUserArray=newint[num];
num=0;
for(inti=0;iUserStateuss=mStartedUsers.valueAt(i);
if(uss.state!=UserState.STATE_STOPPING
&&uss.state!=UserState.STATE_SHUTDOWN){
mStartedUserArray[num++]=mStartedUsers.keyAt(i);
}
}
}
发送的msg消息是在ActivityManagerService中处理的:
finalclassUiHandlerextendsHandler{
publicUiHandler(){
super(com.android.server.UiThread.get().getLooper(),null,true);
}
@Override
publicvoidhandleMessage(Messagemsg){
switch(msg.what){
...
caseSYSTEM_USER_START_MSG:{
mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
Integer.toString(msg.arg1),msg.arg1);
//新建用户时调用
mSystemServiceManager.startUser(msg.arg1);
break;
}
caseSYSTEM_USER_CURRENT_MSG:{
mBatteryStatsService.noteEvent(
BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
Integer.toString(msg.arg2),msg.arg2);
mBatteryStatsService.noteEvent(
BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
Integer.toString(msg.arg1),msg.arg1);
//切换用户时调用
mSystemServiceManager.switchUser(msg.arg1);
break;
}
caseREPORT_USER_SWITCH_MSG:{
mUserController.dispatchUserSwitch((UserState)msg.obj,msg.arg1,msg.arg2);
break;
}
caseCONTINUE_USER_SWITCH_MSG:{
mUserController.continueUserSwitch((UserState)msg.obj,msg.arg1,msg.arg2);
break;
}
caseUSER_SWITCH_TIMEOUT_MSG:{
mUserController.timeoutUserSwitch((UserState)msg.obj,msg.arg1,msg.arg2);
break;
}
caseREPORT_USER_SWITCH_COMPLETE_MSG:{
mUserController.dispatchUserSwitchComplete(msg.arg1);
break;
}
...
}
};
//该方法主要是调用mUserSwitchObservers列表中的IUserSwitchObserver对象的onUserSwitching方法
//如果想知道用户切换,可以调用AMS的registerUserSwitchObserver()方法来注册一个观察者对象
voiddispatchUserSwitch(finalUserStateuss,finalintoldUserId,finalintnewUserId){
Slog.d(TAG,"DispatchonUserSwitchingoldUser#"+oldUserId+"newUser#"+newUserId);
//获取所有注册回调方法的总数
finalintobserverCount=mUserSwitchObservers.beginBroadcast();
if(observerCount>0){
finalIRemoteCallbackcallback=newIRemoteCallback.Stub(){
intmCount=0;
@Override
publicvoidsendResult(Bundledata)throwsRemoteException{
synchronized(mService){
if(mCurUserSwitchCallback==this){
//收到一条回调,就加一
mCount++;
//所有注册的回调方法都执行了,发送继续处理的消息
if(mCount==observerCount){
sendContinueUserSwitchLocked(uss,oldUserId,newUserId);
}
}
}
}
};
synchronized(mService){
uss.switching=true;
mCurUserSwitchCallback=callback;
}
//遍历调用所有注册回调对象的onUserSwitching方法
for(inti=0;itry{
mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
newUserId,callback);
}catch(RemoteExceptione){
}
}
}else{
synchronized(mService){
//如果没有注册回调方法的,直接调用继续执行用户切换的方法
sendContinueUserSwitchLocked(uss,oldUserId,newUserId);
}
}
mUserSwitchObservers.finishBroadcast();
}
voidsendContinueUserSwitchLocked(UserStateuss,intoldUserId,intnewUserId){
mCurUserSwitchCallback=null;
mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
oldUserId,newUserId,uss));
}
voidcontinueUserSwitch(UserStateuss,intoldUserId,intnewUserId){
Slog.d(TAG,"ContinueuserswitcholdUser#"+oldUserId+",newUser#"+newUserId);
synchronized(mService){
mService.mWindowManager.stopFreezingScreen();
}
uss.switching=false;
//发送完成切换用户的消息
mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
newUserId,0));
//停止切换到后台的Guest或临时用户
stopGuestOrEphemeralUserIfBackground();
//强制停止后台用户
stopBackgroundUsersIfEnforced(oldUserId);
}
/**Calledonhandlerthread*/
voiddispatchUserSwitchComplete(intuserId){
finalintobserverCount=mUserSwitchObservers.beginBroadcast();
for(inti=0;itry{
//遍历调用所有观察者的onUserSwitchComplete方法
mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
}catch(RemoteExceptione){
}
}
mUserSwitchObservers.finishBroadcast();
}
/**
*Stopstheguestorephemeraluserifithasgonetothebackground.
*停止切换到后台的Guest或临时用户
*/
privatevoidstopGuestOrEphemeralUserIfBackground(){
synchronized(mService){
finalintnum=mUserLru.size();
for(inti=0;iIntegeroldUserId=mUserLru.get(i);
UserStateoldUss=mStartedUsers.get(oldUserId);
if(oldUserId==UserHandle.USER_SYSTEM||oldUserId==mCurrentUserId
||oldUss.state==UserState.STATE_STOPPING
||oldUss.state==UserState.STATE_SHUTDOWN){
continue;
}
UserInfouserInfo=getUserInfo(oldUserId);
if(userInfo.isEphemeral()){
LocalServices.getService(UserManagerInternal.class)
.onEphemeralUserStop(oldUserId);
}
if(userInfo.isGuest()||userInfo.isEphemeral()){
//Thisisausertobestopped.
stopUsersLocked(oldUserId,true,null);
break;
}
}
}
}
//强制停止后台用户
privatevoidstopBackgroundUsersIfEnforced(intoldUserId){
//Neverstopsystemuser
if(oldUserId==UserHandle.USER_SYSTEM){
return;
}
//Fornow,onlycheckforuserrestriction.Additionalcheckscanbeaddedhere
booleandisallowRunInBg=hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
oldUserId);
if(!disallowRunInBg){
return;
}
synchronized(mService){
if(DEBUG_MU)Slog.i(TAG,"stopBackgroundUsersIfEnforcedstopping"+oldUserId
+"andrelatedusers");
stopUsersLocked(oldUserId,false,null);
}
}
voidtimeoutUserSwitch(UserStateuss,intoldUserId,intnewUserId){
synchronized(mService){
///M:ChangeSlog.wtftoSlog.wtoavoidhavingWTFeasilyafteraddingnewuser
Slog.w(TAG,"Userswitchtimeout:from"+oldUserId+"to"+newUserId);
sendContinueUserSwitchLocked(uss,oldUserId,newUserId);
}
}
Activity进入Idle状态时会调用activityIdleInternalLocked方法,该方法中会修改用户的状态到STATE_RUNNING_LOCKED状态
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android studio 解决logcat无过滤工具栏的操作
Android Studio 恢复小窗口停靠模式(Docked Mode)
Android studio保存logcat日志到本地的操作
Android Studio快捷键生成TAG、Log.x日志输出介绍
网友评论