标签:
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<String, SharedUserSetting> mSharedUsers = new HashMap<String, SharedUserSetting>(); 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<UserInfo>(); //如果/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)) { //读取<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<UserInfo> CREATOR = new Parcelable.Creator<UserInfo>() { 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> <!--为指定group 的gid分配相应的权限--> <!--为指定gid为net_bt_admin分配 BLUETOOTH_ADMIN权限--> <permission name="android.permission.BLUETOOTH_ADMIN" > <group gid="net_bt_admin" /> </permission> <permission name="android.permission.BLUETOOTH" > <group gid="net_bt" /> </permission> <permission name="android.permission.BLUETOOTH_STACK" > <group gid="net_bt_stack" /> </permission> <!--为指定的uid分配相应的权限--> <!--为指定uid为 shell 分配WRITE_EXTERNAL_STORAGE权限--> <assign-permission name="android.permission.WRITE_EXTERNAL_STORAGE" uid="shell" /> <assign-permission name="android.permission.SEND_SMS" uid="shell" /> <assign-permission name="android.permission.CALL_PHONE" uid="shell" /> <assign-permission name="android.permission.READ_CONTACTS" uid="shell" /> <assign-permission name="android.permission.WRITE_CONTACTS" uid="shell" /> <!--连接库--> <library name="android.test.runner" file="/system/framework/android.test.runner.jar" /> <library name="javax.obex" file="/system/framework/javax.obex.jar"/> </permissions>
<permissions> <feature name="android.hardware.wifi" /> </permissions>
permissions> <feature name="android.software.live_wallpaper" /> </permissions>
int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX; if (mNoDexOpt) { scanMode |= SCAN_NO_DEX;//不需要DEX优化 } final HashSet<String> libFiles = new HashSet<String>(); 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<paths.length; i++) { try { //判断是否需要dex优化,如果需要则加入到libFiles中 if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) { libFiles.add(paths[i]); mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true); didDexOpt = true; } } catch (FileNotFoundException e) { } catch (IOException e) { } } } else { } //在platform.xml文件中存储library 标签的变量 if (mSharedLibraries.size() > 0) { Iterator<String> 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<frameworkFiles.length; i++) { ..... } } if (didDexOpt) {//如果didDexOpt为true,则说明优化成功 //mDalvikCacheDir代表 /data/dalvik-cache String[] files = mDalvikCacheDir.list(); if (files != null) { for (int i=0; i<files.length; i++) { String fn = files[i]; //删除data@app@ 或者data@app-private@的文件 if (fn.startsWith("data@app@")|| fn.startsWith("data@app-private@")) { (new File(mDalvikCacheDir, fn)).delete();//删除缓存数据 } } } }
<span style="white-space:pre"> </span> //监控 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<PackageSetting> 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; }
标签:
原文地址:http://blog.csdn.net/yujun411522/article/details/46469087