All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.sdklib.repository.targets.SystemImageManager Maven / Gradle / Ivy

package com.android.sdklib.repository.targets;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.repository.api.LocalPackage;
import com.android.repository.api.RepoManager;
import com.android.repository.impl.meta.TypeDetails;
import com.android.repository.io.FileOp;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.ISystemImage;
import com.android.sdklib.repository.IdDisplay;
import com.android.sdklib.repository.PackageParserUtils;
import com.android.sdklib.repository.meta.DetailsTypes;
import com.android.sdklib.repository.meta.SysImgFactory;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Table;

import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * {@code SystemImageManager} finds {@link SystemImage}s in the sdk, using a {@link RepoManager}
 */
public class SystemImageManager {

    private final FileOp mFop;

    private final RepoManager mRepoManager;

    /**
     * Used to validate ABI types.
     */
    private final DetailsTypes.SysImgDetailsType mValidator;

    private static final String SYS_IMG_NAME = "system.img";

    /**
     * How far down the directory hierarchy we'll search for system images (starting from a
     * package root).
     */
    private static final int MAX_DEPTH = 4;

    /**
     * Map of packages to the images they contain
     */
    private Multimap mPackageToImage;

    /**
     * Map of directories containing {@code system.img} files to {@link SystemImage}s.
     */
    private Map mPathToImage;

    /**
     * Map of tag, version, and vendor to set of system image, for convenient lookup.
     */
    private Table> mValuesToImage;

    /**
     * Create a new {@link SystemImageManager} using the given {@link RepoManager}.
{@code * factory} is used to enable validation. */ public SystemImageManager(@NonNull RepoManager mgr, @NonNull SysImgFactory factory, @NonNull FileOp fop) { mFop = fop; mRepoManager = mgr; mValidator = factory.createSysImgDetailsType(); } /** * Gets all the {@link SystemImage}s. */ @NonNull public Collection getImages() { if (mPackageToImage == null) { init(); } return mPackageToImage.values(); } /** * Gets a map from all our {@link SystemImage}s to their containing {@link LocalPackage}s. */ public Multimap getImageMap() { if (mPackageToImage == null) { init(); } return mPackageToImage; } /** * Lookup all the {@link SystemImage} with the given property values. */ @NonNull public Collection lookup(@NonNull IdDisplay tag, @NonNull AndroidVersion version, @Nullable IdDisplay vendor) { if (mValuesToImage == null) { init(); } Multimap m = mValuesToImage.get(tag, version); return m == null ? ImmutableList.of() : m.get(vendor); } private void init() { Multimap images = buildImageMap(); Table> valuesToImage = HashBasedTable.create(); Map pathToImages = Maps.newHashMap(); for (SystemImage img : images.values()) { IdDisplay vendor = img.getAddonVendor(); IdDisplay tag = img.getTag(); AndroidVersion version = img.getAndroidVersion(); Multimap vendorImageMap = valuesToImage.get(tag, version); if (vendorImageMap == null) { vendorImageMap = HashMultimap.create(); valuesToImage.put(tag, version, vendorImageMap); } vendorImageMap.put(vendor, img); pathToImages.put(img.getLocation(), img); } mValuesToImage = valuesToImage; mPackageToImage = images; mPathToImage = pathToImages; } @NonNull private Multimap buildImageMap() { Multimap result = HashMultimap.create(); Map platformSkins = Maps.newHashMap(); Collection packages = mRepoManager.getPackages().getLocalPackages().values(); for (LocalPackage p : packages) { if (p.getTypeDetails() instanceof DetailsTypes.PlatformDetailsType) { File skinDir = new File(p.getLocation(), SdkConstants.FD_SKINS); if (mFop.exists(skinDir)) { platformSkins.put(((DetailsTypes.PlatformDetailsType) p.getTypeDetails()) .getAndroidVersion(), skinDir); } } } for (LocalPackage p : packages) { TypeDetails typeDetails = p.getTypeDetails(); if (typeDetails instanceof DetailsTypes.SysImgDetailsType || typeDetails instanceof DetailsTypes.PlatformDetailsType || typeDetails instanceof DetailsTypes.AddonDetailsType) { collectImages(p.getLocation(), p, 0, platformSkins, result); } } return result; } private void collectImages(File dir, LocalPackage p, int depth, Map platformSkins, Multimap collector) { for (File f : mFop.listFiles(dir)) { // Instead of just f.getName().equals, we first check f.getPath().endsWith, // because getPath() is a simpler getter whereas getName() computes a new // string on each call if (f.getPath().endsWith(SYS_IMG_NAME) && f.getName().equals(SYS_IMG_NAME)) { collector.put(p, createSysImg(p, dir, platformSkins)); } if (depth < MAX_DEPTH && mFop.isDirectory(f)) { String name = f.getName(); if (name.equals(SdkConstants.FD_DATA) || name.equals(SdkConstants.FD_SAMPLES) || name.equals(SdkConstants.FD_SKINS)) { // Not containers for system images, but have a lot of files continue; } collectImages(f, p, depth + 1, platformSkins, collector); } } } private SystemImage createSysImg(LocalPackage p, File dir, Map platformSkins) { String containingDir = dir.getName(); String abi; TypeDetails details = p.getTypeDetails(); AndroidVersion version = null; if (details instanceof DetailsTypes.ApiDetailsType) { version = ((DetailsTypes.ApiDetailsType) details).getAndroidVersion(); } if (details instanceof DetailsTypes.SysImgDetailsType) { abi = ((DetailsTypes.SysImgDetailsType) details).getAbi(); } else if (mValidator.isValidAbi(containingDir)) { abi = containingDir; } else { abi = SdkConstants.ABI_ARMEABI; } IdDisplay tag; IdDisplay vendor = null; if (details instanceof DetailsTypes.AddonDetailsType) { vendor = ((DetailsTypes.AddonDetailsType) details).getVendor(); } else if (details instanceof DetailsTypes.SysImgDetailsType) { vendor = ((DetailsTypes.SysImgDetailsType) details).getVendor(); } if (details instanceof DetailsTypes.SysImgDetailsType) { tag = ((DetailsTypes.SysImgDetailsType) details).getTag(); } else if (details instanceof DetailsTypes.AddonDetailsType) { tag = ((DetailsTypes.AddonDetailsType) details).getTag(); } else { tag = SystemImage.DEFAULT_TAG; } File skinDir = new File(dir, SdkConstants.FD_SKINS); if (!mFop.exists(skinDir) && version != null) { skinDir = platformSkins.get(version); } File[] skins; if (skinDir != null) { List skinList = PackageParserUtils.parseSkinFolder(skinDir, mFop); skins = skinList.toArray(new File[skinList.size()]); } else { skins = new File[0]; } return new SystemImage(dir, tag, vendor, abi, skins, p); } @Nullable public ISystemImage getImageAt(@NonNull File imageDir) { if (mPathToImage == null) { init(); } return mPathToImage.get(imageDir); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy