Android 5.0 idmap管理

base/core/java/android/app/LoadedApk.java

 

 

135    public LoadedApk(ActivityThreadactivityThread, ApplicationInfo aInfo,

 136            CompatibilityInfo compatInfo, ClassLoader baseLoader,

 137            boolean securityViolation, boolean includeCode, boolean registerPackage){

 138        final int myUid = Process.myUid();

 139        aInfo = adjustNativeLibraryPaths(aInfo);

 140

 141        mActivityThread = activityThread;

 142         mApplicationInfo = aInfo;

 143        mPackageName = aInfo.packageName;

 144        mAppDir = aInfo.sourceDir;

 145        mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;

 146        mSplitAppDirs = aInfo.splitSourceDirs;

 147         mSplitResDirs = aInfo.uid == myUid ?aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;

 148        mOverlayDirs = aInfo.resourceDirs;

 149        if (!UserHandle.isSameUser(aInfo.uid, myUid) &&!Process.isIsolated()) {

 150            aInfo.dataDir =PackageManager.getDataDirForUser(UserHandle.getUserId(myUid),

 151                     mPackageName);

 152        }

 153        mSharedLibraries = aInfo.sharedLibraryFiles;

 154        mDataDir = aInfo.dataDir;

 155        mDataDirFile = mDataDir != null ? new File(mDataDir) : null;

 156        mLibDir = aInfo.nativeLibraryDir;

 157        mBaseClassLoader = baseLoader;

 158        mSecurityViolation = securityViolation;

 159        mIncludeCode = includeCode;

 160        mRegisterPackage = registerPackage;

 161        mDisplayAdjustments.setCompatibilityInfo(compatInfo);

 162    }

 

 

 

 

542    public Resources getResources(ActivityThreadmainThread) {

 543        if (mResources == null) {

 544            mResources = mainThread.getTopLevelResources(mResDir,mSplitResDirs, mOverlayDirs,

 545                    mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null,this);

 546        }  

 547        return mResources;

 548    } 

 

 

 

 

base/core/java/android/app/ActivityThread.java

 

 

1784    Resources getTopLevelResources(StringresDir, String[] splitResDirs, String[] overlayDirs,

1785             String[] libDirs, int displayId,Configuration overrideConfiguration,

1786             LoadedApk pkgInfo) {

1787        return mResourcesManager.getTopLevelResources(resDir,splitResDirs, overlayDirs, libDirs,

1788                 displayId,overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);

1789    }   

 

 

base/core/java/android/app/ResourcesManager.java

 

152    public Resources getTopLevelResources(StringresDir, String[] splitResDirs,

153             String[] overlayDirs, String[]libDirs, int displayId,

154             ConfigurationoverrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {

155        final float scale = compatInfo.applicationScale;

156        ResourcesKey key = new ResourcesKey(resDir, displayId,overrideConfiguration, scale, token);

157        Resources r;

158        synchronized (this) {

159             // Resources is app scaledependent.

160             if (false) {

161                 Slog.w(TAG,"getTopLevelResources: " + resDir + " / " + scale);

162             }

163             WeakReference<Resources> wr= mActiveResources.get(key);

164             r = wr != null ? wr.get() : null;

165             //if (r != null) Slog.i(TAG,"isUpToDate " + resDir + ": " +r.getAssets().isUpToDate());

166             if (r != null &&r.getAssets().isUpToDate()) {

167                 if (false) {

168                     Slog.w(TAG,"Returning cached resources " + r + " " + resDir

169                             + ":appScale=" + r.getCompatibilityInfo().applicationScale);

170                 }

171                 return r;

172            }

173        }

174

175        //if (r != null) {

176        //    Slog.w(TAG, "Throwingaway out-of-date resources!!!! "

177        //            + r + " "+ resDir);

178        //}

179

180        AssetManager assets = new AssetManager();

181        // resDir can be null if the 'android' package is creating a newResources object.

182        // This is fine, since each AssetManager automatically loads the'android' package

183        // already.

184        if (resDir != null) {

185            if(assets.addAssetPath(resDir) == 0) {

186                 return null;

187             }

188        }

189

190        if (splitResDirs != null) {

191             for (String splitResDir :splitResDirs) {

192                 if (assets.addAssetPath(splitResDir)== 0) {

193                     return null;

194                 }

195             }

196        }

197

198         if (overlayDirs != null) {

199             for (String idmapPath :overlayDirs) {

200                 assets.addOverlayPath(idmapPath);

201             }

202        }

 

 

base/services/core/java/com/android/server/pm/PackageManagerService.java

 

 

4450    private boolean createIdmapForPackagePairLI(PackageParser.Packagepkg,

 4451             PackageParser.Package opkg) {

 4452        if (!opkg.mTrustedOverlay) {

 4453             Slog.w(TAG, "Skipping targetand overlay pair " + pkg.baseCodePath + " and " +

 4454                     opkg.baseCodePath +": overlay not trusted");

 4455             return false;

 4456        }

 4457        HashMap<String, PackageParser.Package> overlaySet =mOverlays.get(pkg.packageName);

 4458        if (overlaySet == null) {

 4459             Slog.e(TAG, "was about tocreate idmap for " + pkg.baseCodePath + " and " +

 4460                     opkg.baseCodePath + " but targetpackage has no known overlays");

 4461             return false;

 4462        }

 4463        final int sharedGid =UserHandle.getSharedAppGid(pkg.applicationInfo.uid);

 4464        // TODO: generate idmap for split APKs

 4465        if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) !=0) {

 4466             Slog.e(TAG, "Failed togenerate idmap for " + pkg.baseCodePath + " and "

 4467                     + opkg.baseCodePath);

 4468             return false;

 4469        }

 4470        PackageParser.Package[] overlayArray =

 4471             overlaySet.values().toArray(newPackageParser.Package[0]);

 4472        Comparator<PackageParser.Package> cmp = newComparator<PackageParser.Package>() {

 4473             public intcompare(PackageParser.Package p1, PackageParser.Package p2) {

 4474                 return p1.mOverlayPriority -p2.mOverlayPriority;

 4475             }

 4476        };

 4477        Arrays.sort(overlayArray, cmp);

 4478      

 4479         pkg.applicationInfo.resourceDirs = newString[overlayArray.length];

 4480        int i = 0;

 4481        for (PackageParser.Package p : overlayArray) {

 4482            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;

 4483        }

 4484        return true;

 4485    }

 

 

5634    private PackageParser.Package scanPackageDirtyLI(PackageParser.Packagepkg, int parseFlags,

 5635             int scanFlags, long currentTime,UserHandle user) throws PackageManagerException {

 5636        final File scanFile = new File(pkg.codePath);

 5637        if (pkg.applicationInfo.getCodePath() == null ||

 5638                pkg.applicationInfo.getResourcePath() == null) {

 5639             // Bail out. The resource and codepaths haven't been set.

 5640             throw newPackageManagerException(INSTALL_FAILED_INVALID_APK,

 5641                     "Code and resourcepaths haven't been set correctly");

 5642        }

 

……

 

6780             // Create idmap files for pairs of(packages, overlay packages).

 6781             // Note: "android", ieframework-res.apk, is handled by native layers.

 6782             if (pkg.mOverlayTarget != null) {

 6783                 // This is an overlay package.

 6784                 if (pkg.mOverlayTarget != null&& !pkg.mOverlayTarget.equals("android")) {

 6785                     if(!mOverlays.containsKey(pkg.mOverlayTarget)) {

 6786                        mOverlays.put(pkg.mOverlayTarget,

 6787                                 new HashMap<String,PackageParser.Package>());

 6788                     }

 6789                     HashMap<String,PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);

 6790                     map.put(pkg.packageName,pkg);

 6791                     PackageParser.Package orig= mPackages.get(pkg.mOverlayTarget);

 6792                     if (orig != null&& !createIdmapForPackagePairLI(orig, pkg)){

 6793                         throw newPackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,

 6794                                "scanPackageLI failed to createIdmap");

 6795                     }

 6796                 }

 6797             } else if(mOverlays.containsKey(pkg.packageName) &&

 6798                     !pkg.packageName.equals("android")){

 6799                 // This is a regular package,with one or more known overlay packages.

 6800                 createIdmapsForPackageLI(pkg);

 6801             }

 

 


 

base/core/java/android/content/pm/PackageParser.java

 

 

1429    private Package parseBaseApk(Resourcesres, XmlResourceParser parser, int flags,

1430             String[] outError) throwsXmlPullParserException, IOException {

1431        final boolean trustedOverlay = (flags & PARSE_TRUSTED_OVERLAY) != 0;

1432

1433        AttributeSet attrs = parser;

1434

1435        mParseInstrumentationArgs = null;

1436        mParseActivityArgs = null;

1437        mParseServiceArgs = null;

1438        mParseProviderArgs = null;

1439

1440        final String pkgName;

1441        final String splitName;

 

1538             } else if(tagName.equals("overlay")) {

1539                 pkg.mTrustedOverlay =trustedOverlay;

1540

1541                 sa =res.obtainAttributes(attrs,

1542                         com.android.internal.R.styleable.AndroidManifestResourceOverlay);

1543                 pkg.mOverlayTarget =sa.getString(

1544                        com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage);

1545                 pkg.mOverlayPriority =sa.getInt(

1546                        com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority,

1547                         -1);

1548                 sa.recycle();

1549

1550                 if (pkg.mOverlayTarget ==null) {

1551                     outError[0] ="<overlay> does not specify a target package";

1552                     mParseError =PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;

1553                     return null;

1554                 }

1555                 if (pkg.mOverlayPriority < 0 ||pkg.mOverlayPriority > 9999) {

1556                     outError[0] ="<overlay> priority must be between 0 and 9999";

1557                     mParseError =

1558                         PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;

1559                     return null;

1560                 }

1561                XmlUtils.skipCurrentTag(parser);

 

 

 

 

 

base/core/jni/android_util_AssetManager.cpp

 

1928 static void android_content_AssetManager_init(JNIEnv*env, jobject clazz, jboolean isSystem)

1929 {          

1930    if (isSystem) {

1931        verifySystemIdmaps();

1932    }          

1933    AssetManager* am = new AssetManager();

1934    if (am == NULL) {

1935        jniThrowException(env, "java/lang/OutOfMemoryError","");

1936        return;

1937    }          

1938                

1939     am->addDefaultAssets();

1940                

1941    ALOGV("Created AssetManager %p for Java object %p\n", am,clazz);

1942    env->SetLongField(clazz, gAssetManagerOffsets.mObject,reinterpret_cast<jlong>(am));

1943 }

 

338bool AssetManager::addDefaultAssets()

 339{

 340    const char* root = getenv("ANDROID_ROOT");

 341    LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");

 342

 343    ///M:add for CIP feature @{

 344    String8 pathCip(root);

 345    pathCip.appendPath(kCIPSystemAssets);

 346    FILE *fp;

 347    ALOGW("AssetManager-->addDefaultAssets 1");

 348    if((fp= fopen(pathCip,"w+"))!= NULL) {

 349

 350       ALOGW("AssetManager-->addDefaultAssets CIP path exsit!");

 351       bool isOK1 = addAssetPath(pathCip, NULL);

 352       if(!isOK1){

 353           ALOGW("AssetManager-->addDefaultAssets CIP path isok1 isfalse");

 354       }

 355       String8 pathCip2(root);

 356       pathCip2.appendPath(kCIPMediatekAssets);

 357       bool isOK2 = addAssetPath(pathCip2, NULL);

 

186 bool AssetManager::addAssetPath(constString8& path, int32_t* cookie)

 187{

 188    AutoMutex _l(mLock);

 189

 190    asset_path ap;

 191

 192    String8 realPath(path);

 193    if (kAppZipName) {

 

232     mAssetPaths.add(ap);

 

 

124 // This is called by zygote (running asuser root) as part of preloadResources.

 

 

 125 static void verifySystemIdmaps()

 126{

 127    pid_t pid;

 128    char system_id[10];

 129

 130    snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);

 131

 132    switch (pid = fork()) {

 133        case -1:

 134            ALOGE("failed to fork for idmap: %s", strerror(errno));

 135            break;

 136        case 0: // child

 137            {

 138                 struct__user_cap_header_struct capheader;

 139                 struct __user_cap_data_structcapdata;

 140

 141                 memset(&capheader, 0,sizeof(capheader));

 142                 memset(&capdata, 0,sizeof(capdata));

 143

 144                 capheader.version =_LINUX_CAPABILITY_VERSION;

 145                 capheader.pid = 0;

 146

 147                 if (capget(&capheader,&capdata) != 0) {

 148                    ALOGE("capget:%s\n", strerror(errno));

 149                     exit(1);

 150                 }

 151

 152                 capdata.effective =capdata.permitted;

 153                 if (capset(&capheader,&capdata) != 0) {

 154                     ALOGE("capset: %s\n",strerror(errno));

 155                     exit(1);

 156                 }

 157

 158                 if (setgid(AID_SYSTEM) != 0) {

 159                     ALOGE("setgid:%s\n", strerror(errno));

 160                     exit(1);

 161                 }

 162

 163                 if (setuid(AID_SYSTEM) != 0) {

 164                     ALOGE("setuid:%s\n", strerror(errno));

 165                     exit(1);

 166                 }

 167

 168                 execl(AssetManager::IDMAP_BIN,AssetManager::IDMAP_BIN, "--scan",

 169                        AssetManager::OVERLAY_DIR, AssetManager::TARGET_PACKAGE_NAME,

 170                        AssetManager::TARGET_APK_PATH, AssetManager::IDMAP_DIR, (char*)NULL);

 171                 ALOGE("failed to execlfor idmap: %s", strerror(errno));

 172                 exit(1); // should never gethere

 173            }

 174            break;

 

 

 

 

 

 

base/libs/androidfw/AssetManager.cpp

753const ResTable* AssetManager::getResTable(bool required) const

 754{

 755    ResTable* rt = mResources;

 756    if (rt) {

 757        return rt;

 758    }

 

781    for (size_t i=0; i<N; i++) {

 782        bool empty = appendPathToResTable(mAssetPaths.itemAt(i));

 783        onlyEmptyResources = onlyEmptyResources && empty;

 784    }

 

 

663 boolAssetManager::appendPathToResTable(const asset_path& ap) const {

 664    Asset* ass = NULL;

 665    ResTable* sharedRes = NULL;

 

705 #ifdef HAVE_ANDROID_OS

 706                 const char* data =getenv("ANDROID_DATA");

 707                 LOG_ALWAYS_FATAL_IF(data ==NULL, "ANDROID_DATA not set");

 708                 String8overlaysListPath(data);

 709                overlaysListPath.appendPath(kResourceCache);

 710                overlaysListPath.appendPath("overlays.list");

 711                addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes,nextEntryIdx);

 712#endif

 

 

 

 

 

 

 

base/cmds/idmap/scan.cpp

 

192int idmap_scan(const char *overlay_dir, const char *target_package_name,

193         const char *target_apk_path, constchar *idmap_dir)

194 {

195    String8 filename = String8(idmap_dir);

196    filename.appendPath("overlays.list");

197    if (unlink(filename.string()) != 0 && errno != ENOENT) {

198        return EXIT_FAILURE;

199    }           

200

201    DIR *dir = opendir(overlay_dir);

202    if (dir == NULL) {

203        return EXIT_FAILURE;

204    }           

205

206    SortedVector<Overlay> overlayVector;

207     struct dirent *dirent;

208    while ((dirent = readdir(dir)) != NULL) {

209        struct stat st;

210        char overlay_apk_path[PATH_MAX + 1];

211        snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir,dirent->d_name);

212        if (stat(overlay_apk_path, &st) < 0) {

213             continue;   

214        }       

215        if (!S_ISREG(st.st_mode)) {

216             continue;

217        }   

218

219        int priority = parse_apk(overlay_apk_path, target_package_name);

220        if (priority < 0) {

221             continue;

222        }

223

224        String8 idmap_path(idmap_dir);

225        idmap_path.appendPath(flatten_path(overlay_apk_path + 1));

226        idmap_path.append("@idmap");

227

228        if (idmap_create_path(target_apk_path, overlay_apk_path,idmap_path.string()) != 0) {

229             ALOGE("error: failed tocreate idmap for target=%s overlay=%s idmap=%s\n",

230                     target_apk_path,overlay_apk_path, idmap_path.string());

231             continue;

232        }

233

234        Overlay overlay(String8(overlay_apk_path), idmap_path, priority);

235        overlayVector.add(overlay);

236    }

237

238    closedir(dir);

239

240     if (!writePackagesList(filename.string(),overlayVector)) {

241        return EXIT_FAILURE;

242    }

 

 

35     bool writePackagesList(const char*filename, const SortedVector<Overlay>&overlayVector)

 36     {

 37        FILE* fout = fopen(filename, "w");

 38        if (fout == NULL) {

 39             return false;

 40        }

 41

 42        for (size_t i = 0; i < overlayVector.size(); ++i) {

 43            const Overlay& overlay = overlayVector[i];

 44            fprintf(fout, "%s %s\n", overlay.apk_path.string(),overlay.idmap_path.string());

 45        }

 46

 47        fclose(fout);

 48

 49        // Make file world readable since Zygote (running as root) will read

 50        // it when creating the initial AssetManger object

 51        const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644

 52        if (chmod(filename, mode) == -1) {

 53            unlink(filename);

 54            return false;

 55        }

 56

 57        return true;

 58     }

 

 

base/cmds/idmap/idmap.cpp

 

 

maybe_scan –> idmap_scan ->

 

 

206int main(int argc, char **argv)

207 {  

208 #if 0  

209    {  

210        char buf[1024];

211        buf[0] = '\0';

212        for (int i = 0; i < argc; ++i) {

213             strncat(buf, argv[i], sizeof(buf)- 1);

214             strncat(buf, " ",sizeof(buf) - 1);

215        }  

216        ALOGD("%s:%d: uid=%d gid=%d argv=%s\n", __FILE__, __LINE__,getuid(), getgid(), buf);

217    }

218 #endif

219

220    if (argc == 2 && !strcmp(argv[1], "--help")) {

221        printf("%s\n", usage);

222        return 0;

223    }

224

225    if (argc == 5 && !strcmp(argv[1], "--fd")) {

226        return maybe_create_fd(argv[2], argv[3], argv[4]);

227    }

228

229    if (argc == 5 && !strcmp(argv[1], "--path")) {

230        return maybe_create_path(argv[2], argv[3], argv[4]);

231    }

232

233     if (argc == 6&& !strcmp(argv[1], "--scan")) {

234         returnmaybe_scan(argv[2], argv[3], argv[4], argv[5]);

235     }

236

237    if (argc == 3 && !strcmp(argv[1], "--inspect")) {

238        return maybe_inspect(argv[2]);

239    }

240

241    fprintf(stderr, "Usage: don't use this (cf dexopt usage).\n");

242    return EXIT_FAILURE;

243 }

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章