PackageManagerService学习笔记二-构造方法

PKMS构造方法部分源码:

/*
Android 4.2.2源码
*/
public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)
{
	/*---省略部分代码---*/
	if(mSdkVersion <= 0)
	{
		Slog.w(TAG, "**** ro.build.version.sdk not set!");
	}

	mContext = context;
    mFactoryTest = factoryTest;
    mOnlyCore = onlyCore;
	/*
	如果是eng版,扫描Package后,不对Package做dex优化
	dex:是android针对java字节码的一种优化技术,课提高运行效率
	*/
    mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
    mMetrics = new DisplayMetrics();
	/*
	Settings: 该类用于存储系统运行过程中的一些配置
	*/
    mSettings = new Settings(context);
    mSettings.addSharedUserLPw("android.uid.system",
           Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
    mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
    mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
    mSettings.addSharedUserLPw("com.tmobile.thememanager", THEME_MAMANER_GUID, ApplicationInfo.FLAG_SYSTEM);
    mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
    mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
	/*---省略部分代码---*/
}


Settings

/*-------------Settings中相关-------------*/
	class GrantedPermissions
	{
		int pkgFlags;
		HashSet<String> grantedpermissions = new HashSet<>(String);
		int[] grds;

		GrantedPermissions(int pkgFlags)
		{
			setFlags(pkgFlags);
		}

		@SuppressWarnings("unchecked")
	    GrantedPermissions(GrantedPermissions base) {
	        pkgFlags = base.pkgFlags;
	        grantedPermissions = (HashSet<String>) base.grantedPermissions.clone();

	        if (base.gids != null) {
	            gids = base.gids.clone();
	        }
	    }

	    void setFlags(int pkgFlags) {
	        this.pkgFlags = pkgFlags
	                & (ApplicationInfo.FLAG_SYSTEM
	                        | ApplicationInfo.FLAG_FORWARD_LOCK
	                        | ApplicationInfo.FLAG_EXTERNAL_STORAGE);
	    }
	}

	/* 
	 Settings data for a particular package we know about.
	*/
	final class PackageSetting extends PackageSettingBase {
	    int appId;
	    PackageParser.Package pkg;
	    SharedUserSetting sharedUser;

	    PackageSetting(String name, String realName, File codePath, File resourcePath,
	            String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
	        super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
	                pkgFlags);
	    }

	    /*
		New instance of PackageSetting replicating the original settings.
	    Note that it keeps the same PackageParser.Package instance.
	    */
	    PackageSetting(PackageSetting orig) {
	        super(orig);

	        appId = orig.appId;
	        pkg = orig.pkg;
	        sharedUser = orig.sharedUser;
	    }

	    @Override
	    public String toString() {
	        return "PackageSetting{"
	            + Integer.toHexString(System.identityHashCode(this))
	            + " " + name + "/" + appId + "}";
	    }
	}

	final class SharedUserSetting extends GrantedPermissions
	{
		final String name;
		int userId;

		/*
		*/
		final HashSet<PackageSetting> packages = new HashSet<PackageSetting>();
		/*
		包签名信息
		*/
		final PackageSignatures signatures = new PackageSignatures();

		SharedUserSetting(String _name, int _pkgFlags)
		{
			super(_pkgFlags);
			name = _name;
		}

	    @Override
	    public String toString() {
	        return "SharedUserSetting{" + Integer.toHexString(System.identityHashCode(this)) + " "
	                + name + "/" + userId + "}";
	    }
	}
	
	/*
	Settings.java
	--Settings中的成员变量
	----mSharedUsers: HashMap<String, SharedUserSetting> 存储的是字符串与SharedUserSetting的键值对
	*/
	SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
		SharedUserSetting s = mSharedUsers.get(name);
		if (s != null) {
			if (s.userId == uid) {
				return s;
			}
			PackageManagerService.reportSettingsProblem(Log.ERROR,
					"Adding duplicate shared user, keeping first: " + name);
			return null;
		}
		s = new SharedUserSetting(name, pkgFlags);
		s.userId = uid;
		if (addUserIdLPw(uid, s, name)) {
			mSharedUsers.put(name, s);
			return s;
		}
		return null;
	}
	
	/*
	Settings.java
	--mUserIds: ArrayList<Object> 以UID为List索引,存放对应的ShardUserSetting对象
	--mOtherUserIds: SparseArray<Object> 以UID为List索引,存放对应的ShardUserSetting对象
	问题:
	--Settings中已经有一个mSharedUsers成员,该成员中存放着name与ShardUserSetting对象的对应关系,为什么还要定义这个变量呢?
	原因:
	--通过id获取数组中的元素要比,通过key从HashMap中获取元素要快。(index = uid-Process.FIRST_APPLICATION_UID)
	*/
	private boolean addUserIdLPw(int uid, Object obj, Object name) {
		/*
		uid不能超出限制。
		*/
		if (uid > Process.LAST_APPLICATION_UID) {
            return false;
        }
		/*
		Process.FIRST_APPLICATION_UID : 10000
		应用APK的uid所在进程uid从10000开始
		*/
        if (uid >= Process.FIRST_APPLICATION_UID) {
            int N = mUserIds.size();
            /*
			通过uid计算索引
            */
            final int index = uid - Process.FIRST_APPLICATION_UID;
            while (index >= N) {
                mUserIds.add(null);
                N++;
            }
            if (mUserIds.get(index) != null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        "Adding duplicate user id: " + uid
                        + " name=" + name);
                return false;
            }
            mUserIds.set(index, obj);
        } else {
            if (mOtherUserIds.get(uid) != null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        "Adding duplicate shared id: " + uid
                        + " name=" + name);
                return false;
            }
            mOtherUserIds.put(uid, obj);
        }
        return true;
    }

Settings中相关类的层次关系


总结:
1. PKMS中的mSettings成员变量中记录着用户进程中的信息
2. Settings中的成员变量
mSharedUsers中记录着string和SharedUserSettings对象的键值对;( “android.uid.system” --------> uid )
/*为了提高运行效率,以空间换时间*/
mSharedUserIds中存储着SharedUserSettings对象;(索引index = uid - PackageManagerService.FIRST_APPLICATION_UID)
mOtherUserIds: 非应用APKSharedUserSettings对象;  


<----------未完待续----------->


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值