当前位置: 移动技术网 > IT编程>移动开发>Android > Android多用户之UserManagerService源码分析

Android多用户之UserManagerService源码分析

2018年04月21日  | 移动技术网IT编程  | 我要评论

项羽真名,北京物资学院教务系统,兰普提

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状态

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网