http://blog.csdn.net/yujun411522/article/details/46226001
本文出自:【yujun411522的博客】
public static final IPackageManager main(Context context, boolean factoryTest,
boolean onlyCore) {
PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
ServiceManager.addService("package", m);//添加java系统服务的功能
return m;
}
mSettings = new Settings();
mSettings.addSharedUserLPw("android.uid.system",
Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.phone",
MULTIPLE_APPLICATION_UIDS
? RADIO_UID : FIRST_APPLICATION_UID,
ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.log",
MULTIPLE_APPLICATION_UIDS
? LOG_UID : FIRST_APPLICATION_UID,
ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.nfc",
MULTIPLE_APPLICATION_UIDS
? NFC_UID : FIRST_APPLICATION_UID,
ApplicationInfo.FLAG_SYSTEM);
Settings() {
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
FileUtils.setPermissions(systemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
//packages.xml 记录系统所有安装apk的信息
mSettingsFilename = new File(systemDir, "packages.xml");
//packages-backup.xml 是packages.xml备份文件,在安装或者卸载apk是更新packages.xml文件就会用backup备份
mBackupSettingsFilename = new File(systemDir, "packages-backup.xml");
//packages.list 所有已安装apk的简要信息
mPackageListFilename = new File(systemDir, "packages.list");
// packages-stopped.xml 强制stop的apk信息
mStoppedPackagesFilename = new File(systemDir, "packages-stopped.xml");
//packages-stopped.xml的备份文件
mBackupStoppedPackagesFilename = new File(systemDir, "packages-stopped-backup.xml");
}
//定义了一个HashMap存储sharedUsers信息
final HashMap mSharedUsers =
new HashMap();
SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
//先在mSharedUsers中找有没有name对应的value。
SharedUserSetting s = mSharedUsers.get(name);//
if (s != null) {
if (s.userId == uid) {//和传入的uid一样就直接返回
return s;
}
..如果s.userId != ui ,返回null
return null;
}
//如果没有在mSharedUsers 找到该name对应的value值,则创建一个新的SharedUserSetting 对象
s = new SharedUserSetting(name, pkgFlags);
s.userId = uid;
//调用addUserIdLPw
if (addUserIdLPw(uid, s, name)) {
mSharedUsers.put(name, s);//添加到mSharedUsers 中
return s;//返回创建的SharedUserSetting 对象
}
return null;//addUserIdLPw 添加失败就返回null
}
private boolean addUserIdLPw(int uid, Object obj, Object name) {
// 三个参数分别为 uid=1000
// obj= new SharedUserSetting("android.uid.system",ApplicationInfo.FLAG_SYSTEM),
// name = "android.uid.system"
// PackageManagerService.FIRST_APPLICATION_UID值为 10000
//PackageManagerService.MAX_APPLICATION_UIDS 值1000
//这里不能uid不能超过10000+1000=11000
//系统版本不一样这里的实现不一样
if (uid >= PackageManagerService.FIRST_APPLICATION_UID + PackageManagerService.MAX_APPLICATION_UIDS) {
return false;
}
//uid>=10000时
if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
int N = mUserIds.size();
final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
while (index >= N) {
mUserIds.add(null);
N++;
}
//可以看出mUserIds 中第i个位置,它存放的是uid=PackageManagerService.FIRST_APPLICATION_UID +i的SharedUserSetting 对象,如果没
//有就设为null。
if (mUserIds.get(index) != null) {//该位置已经设置过了
return false;//返回false
}
mUserIds.set(index, obj);//该位置为null,可以插入,返回true
} else {
//uid<10000时
if (mOtherUserIds.get(uid) != null) {同理这里也是只不过是存储小于10000的SharedUserSetting 对象
return false;
}
mOtherUserIds.put(uid, obj);
}
return true;
}
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread.getLooper());
public void handleMessage(Message msg) {
try {
doHandleMessage(msg);//调用了doHandleMessage方法
} finally {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
}
}
void doHandleMessage(Message msg) {
switch (msg.what) {
case INIT_COPY:
......
case CHECK_PENDING_VERIFICATION:
case PACKAGE_VERIFIED:
}
}
mInstaller = new Installer();
mUserAppDataDir = new File(dataDir, "user");
mUserManager = new UserManager(mInstaller, mUserAppDataDir);
public UserManager(Installer installer, File baseUserPath) {
this(Environment.getDataDirectory(), baseUserPath);
mInstaller = installer;
}
UserManager(File dataDir, File baseUserPath) {
//USER_INFO_DIR 为"system/users";
mUsersDir = new File(dataDir, USER_INFO_DIR);
//创建/data/system/users 目录
mUsersDir.mkdirs();
mBaseUserPath = baseUserPath;
FileUtils.setPermissions(mUsersDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
// 指向/data/system/users userlist.xml文件
mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
readUserList();//调用readUserList函数
}
private void readUserList() {
mUsers = new SparseArray();
//如果/data/system/users userlist.xml文件 不存在
if (!mUserListFile.exists()) {
fallbackToSingleUser();
return;
}
FileInputStream fis = null;
try {
fis = new FileInputStream(mUserListFile);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(fis, null);
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
//TAG_USER 为"user"
if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
//读取标签中的id属性
String id = parser.getAttributeValue(null, ATTR_ID);
UserInfo user = readUser(Integer.parseInt(id));//根据id在读取xml构造成一个UserInfo实体
if (user != null) {
mUsers.put(user.id, user);//添加到mUsers
}
}
}
updateUserIds();
} catch (IOException ioe) {
fallbackToSingleUser();
} catch (XmlPullParserException pe) {
fallbackToSingleUser();
}
}
private UserInfo readUser(int id) {
int flags = 0;
String name = null;
FileInputStream fis = null;
try {
File userFile = new File(mUsersDir, Integer.toString(id) + ".xml");
fis = new FileInputStream(userFile);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(fis, null);
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
if (type != XmlPullParser.START_TAG) {
Slog.e(LOG_TAG, "Unable to read user " + id);
return null;
}
if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
String storedId = parser.getAttributeValue(null, ATTR_ID);
if (Integer.parseInt(storedId) != id) {
Slog.e(LOG_TAG, "User id does not match the file name");
return null;
}
String flagString = parser.getAttributeValue(null, ATTR_FLAGS);
flags = Integer.parseInt(flagString);
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
}
if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_NAME)) {
type = parser.next();
if (type == XmlPullParser.TEXT) {
name = parser.getText();
}
}
}
fis.close();
UserInfo userInfo = new UserInfo(id, name, flags);
return userInfo;
} catch (IOException ioe) {
} catch (XmlPullParserException pe) {
}
return null;
}
public class UserInfo implements Parcelable {
public static final int FLAG_PRIMARY = 0x00000001;
public static final int FLAG_ADMIN = 0x00000002;
public static final int FLAG_GUEST = 0x00000004;
public int id;//用户id
public String name;//用户名称
public int flags;//用户标记,是primary,admin,guest等等
public UserInfo(int id, String name, int flags) {
this.id = id;
this.name = name;
this.flags = flags;
}
public boolean isPrimary() {
return (flags & FLAG_PRIMARY) == FLAG_PRIMARY;
}
public boolean isAdmin() {
return (flags & FLAG_ADMIN) == FLAG_ADMIN;
}
public boolean isGuest() {
return (flags & FLAG_GUEST) == FLAG_GUEST;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int parcelableFlags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeInt(flags);
}
public static final Parcelable.Creator CREATOR
= new Parcelable.Creator() {
public UserInfo createFromParcel(Parcel source) {
return new UserInfo(source);
}
public UserInfo[] newArray(int size) {
return new UserInfo[size];
}
};
private UserInfo(Parcel source) {
id = source.readInt();
name = source.readString();
flags = source.readInt();
}
}
void readPermissions() {
// 指向etc/permissions 文件
File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
..
// Iterate over the files in the directory and scan .xml files
for (File f : libraryDir.listFiles()) {
//不处理etc/permissions/platform.xml
if (f.getPath().endsWith("etc/permissions/platform.xml")) {
continue;
}
//处理.xml文件
if (!f.getPath().endsWith(".xml")) {
continue;
}
//处理刻度的
if (!f.canRead()) {
continue;
}
readPermissionsFromXml(f);
}
// Read permissions from .../etc/permissions/platform.xml last so it will take precedence
最后解析etc/permissions/platform.xm 文件
final File permFile = new File(Environment.getRootDirectory(),"etc/permissions/platform.xml");
readPermissionsFromXml(permFile);
}
permissions>
int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX;
if (mNoDexOpt) {
scanMode |= SCAN_NO_DEX;//不需要DEX优化
}
final HashSet libFiles = new HashSet();
mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
mDalvikCacheDir = new File(dataDir, "dalvik-cache");
boolean didDexOpt = false;
String bootClassPath = System.getProperty("java.boot.class.path");
if (bootClassPath != null) {
String[] paths = splitString(bootClassPath, ':');
for (int i=0; i 0) {
Iterator libs = mSharedLibraries.values().iterator();
while (libs.hasNext()) {
String lib = libs.next();
try {
//判断是否需要dex优化
if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
libFiles.add(lib);
mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
}
//对于framework-res.apk直接添加到libFiles中
libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
//mFrameworkDir代表 /system/frameworks目录,优化里面的apk和jar文件
String[] frameworkFiles = mFrameworkDir.list();
if (frameworkFiles != null) {
for (int i=0; i
//监控 system/framework目录
mFrameworkInstallObserver = new AppDirObserver(mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
mFrameworkInstallObserver.startWatching();
scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR,scanMode | SCAN_NO_DEX, 0);
//监控 system/app目录
mSystemAppDir = new File(Environment.getRootDirectory(), "app");
mSystemInstallObserver = new AppDirObserver(mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
mSystemInstallObserver.startWatching();
scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
//监控 /vendor/app目录
mVendorAppDir = new File("/vendor/app");
mVendorInstallObserver = new AppDirObserver(mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
mVendorInstallObserver.startWatching();
scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
mInstaller.moveFiles();
...
mAppInstallDir = new File(dataDir, "app");
//look for any incomplete package installations
ArrayList deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
//clean up list
for(int i = 0; i < deletePkgsList.size(); i++) {
cleanupInstallFailedPackage(deletePkgsList.get(i));
}
deleteTempPackageFiles();
if (!mOnlyCore) {
mAppInstallObserver = new AppDirObserver(mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
mAppInstallObserver.startWatching();
scanDirLI(mAppInstallDir, 0, scanMode, 0);
mDrmAppInstallObserver = new AppDirObserver(mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
mDrmAppInstallObserver.startWatching();
scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,scanMode, 0);
} else {
mAppInstallObserver = null;
mDrmAppInstallObserver = null;
}
public int install(String name, int uid, int gid) {
StringBuilder builder = new StringBuilder("install");
builder.append(' ');
builder.append(name);
builder.append(' ');
builder.append(uid);
builder.append(' ');
builder.append(gid);
return execute(builder.toString());
}
private int execute(String cmd) {
String res = transaction(cmd);//调用transaction 方法
try {
return Integer.parseInt(res);
} catch (NumberFormatException ex) {
return -1;
}
}
private synchronized String transaction(String cmd) {
if (!connect()) {//连接installd服务
Slog.e(TAG, "connection failed");
return "-1";
}
if (!writeCommand(cmd)) {//向installd发送命令
Slog.e(TAG, "write command failed? reconnect!");
if (!connect() || !writeCommand(cmd)) {
return "-1";
}
}
if (LOCAL_DEBUG) {
Slog.i(TAG, "send: '" + cmd + "'");
}
if (readReply()) {//读取返回的数据
String s = new String(buf, 0, buflen);
if (LOCAL_DEBUG) {
Slog.i(TAG, "recv: '" + s + "'");
}
return s;
} else {
if (LOCAL_DEBUG) {
Slog.i(TAG, "fail");
}
return "-1";
}
}
struct cmdinfo {
const char *name; //命令名称
unsigned numargs; //参数个数
int (*func)(char **arg, char reply[REPLY_MAX]); //该命令对应的函数
};
struct cmdinfo cmds[] = {
{ "ping", 0, do_ping },
{ "install", 3, do_install },
{ "dexopt", 3, do_dexopt },
{ "movedex", 2, do_move_dex },
{ "rmdex", 1, do_rm_dex },
{ "remove", 2, do_remove },
{ "rename", 2, do_rename },
{ "freecache", 1, do_free_cache },
{ "rmcache", 1, do_rm_cache },
{ "protect", 2, do_protect },
{ "getsize", 4, do_get_size },
{ "rmuserdata", 2, do_rm_user_data },
{ "movefiles", 0, do_movefiles },
{ "linklib", 2, do_linklib },
{ "unlinklib", 1, do_unlinklib },
{ "mkuserdata", 3, do_mk_user_data },
{ "rmuser", 1, do_rm_user },
};
int install(const char *pkgname, uid_t uid, gid_t gid)
{
char pkgdir[PKG_PATH_MAX];
char libdir[PKG_PATH_MAX];
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
LOGE("invalid uid/gid: %d %d\n", uid, gid);
return -1;
}
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
LOGE("cannot create package path\n");
return -1;
}
if (create_pkg_path(libdir, pkgname, PKG_LIB_POSTFIX, 0)) {
LOGE("cannot create package lib path\n");
return -1;
}
if (mkdir(pkgdir, 0751) < 0) {
LOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
return -errno;
}
if (chmod(pkgdir, 0751) < 0) {
LOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
unlink(pkgdir);
return -errno;
}
if (chown(pkgdir, uid, gid) < 0) {
LOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
unlink(pkgdir);
return -errno;
}
if (mkdir(libdir, 0755) < 0) {
LOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
unlink(pkgdir);
return -errno;
}
if (chmod(libdir, 0755) < 0) {
LOGE("cannot chmod dir '%s': %s\n", libdir, strerror(errno));
unlink(libdir);
unlink(pkgdir);
return -errno;
}
if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
LOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
unlink(libdir);
unlink(pkgdir);
return -errno;
}
return 0;
}