/** * Sets up our {@link SchemaModule}s and {@link RepositorySourceProvider}s if they haven't * been yet. * * @param progress Used for error logging. */ public RepoConfig(@NonNull ProgressIndicator progress) { // Schema module for the list of update sites we download SchemaModule<?> addonListModule = new SchemaModule<>( "com.android.sdklib.repository.sources.generated.v%d.ObjectFactory", "sdk-sites-list-%d.xsd", RemoteSiteType.class); try { // Specify what modules are allowed to be used by what sites. Map<Class<? extends RepositorySource>, Collection<SchemaModule<?>>> siteTypes = ImmutableMap.<Class<? extends RepositorySource>, Collection<SchemaModule<?>>>builder() .put(RemoteSiteType.AddonSiteType.class, ImmutableSet.of(ADDON_MODULE)) .put(RemoteSiteType.SysImgSiteType.class, ImmutableSet.of(SYS_IMG_MODULE)).build(); mAddonsListSourceProvider = RemoteListSourceProvider .create(getAddonListUrl(progress), addonListModule, siteTypes); } catch (URISyntaxException e) { progress.logError("Failed to set up addons source provider", e); } String url = String.format(REPO_URL_PATTERN, getBaseUrl(progress), REPOSITORY_MODULE.getNamespaceVersionMap().size()); mRepositorySourceProvider = new ConstantSourceProvider(url, "Android Repository", ImmutableSet.of(REPOSITORY_MODULE, RepoManager.getGenericModule())); }
@NonNull @VisibleForTesting RemoteListSourceProvider getRemoteListSourceProvider(@NonNull ProgressIndicator progress) { return getRepoConfig(progress).getRemoteListSourceProvider(); }
/** * Fetches {@link RepoManager} set up to interact with android SDK repositories. It should not * cached by callers of this method, since any changes to the fundamental properties of the * manager (fallback loaders, local path) will cause a new instance to be created. */ @NonNull public RepoManager getSdkManager(@NonNull ProgressIndicator progress) { RepoManager result = mRepoManager; synchronized (MANAGER_LOCK) { if (result == null) { mSystemImageManager = null; mAndroidTargetManager = null; mLatestBuildTool = null; result = getRepoConfig(progress) .createRepoManager(progress, mLocation, getUserSourceProvider(progress), mFop); // Invalidate system images, targets, the latest build tool, and the legacy local // package manager when local packages change result.registerLocalChangeListener(packages -> { mSystemImageManager = null; mAndroidTargetManager = null; mLatestBuildTool = null; }); mRepoManager = result; } } return mRepoManager; }
/** * Gets the customizable {@link RepositorySourceProvider}. Can be null if there's a problem * with the user's environment. */ @Nullable public LocalSourceProvider getUserSourceProvider(@NonNull ProgressIndicator progress) { if (mUserSourceProvider == null && mAndroidFolder != null) { mUserSourceProvider = RepoConfig.createUserSourceProvider(mFop, mAndroidFolder); synchronized (MANAGER_LOCK) { if (mRepoManager != null) { // If the repo already exists cause it to be reloaded, so the userSourceProvider // can be added to the config. mRepoManager = null; getSdkManager(progress); } } } return mUserSourceProvider; }
@NonNull private static String getAddonListUrl(@NonNull ProgressIndicator progress) { return getBaseUrl(progress) + DEFAULT_SITE_LIST_FILENAME_PATTERN; }
@NonNull private static RepoConfig getRepoConfig(@NonNull ProgressIndicator progress) { if (sRepoConfig == null) { sRepoConfig = new RepoConfig(progress); } return sRepoConfig; }
/** * Add another {@link RepositorySourceProvider}. All existing {@link AndroidSdkHandler}s and * {@link RepoManager}s are invalidated, and all future instances will include the new * provider. */ public static void addCustomSourceProvider(@NonNull RepositorySourceProvider provider, @NonNull ProgressIndicator progress) { getRepoConfig(progress).addCustomSourceProvider(provider); invalidateAll(); }