aboutsummaryrefslogtreecommitdiffstats
path: root/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java
diff options
context:
space:
mode:
Diffstat (limited to 'sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java')
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java493
1 files changed, 0 insertions, 493 deletions
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java
deleted file mode 100755
index 18cccae..0000000
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.sdkuilib.internal.repository.core;
-
-import com.android.sdklib.internal.repository.AddonsListFetcher;
-import com.android.sdklib.internal.repository.AddonsListFetcher.Site;
-import com.android.sdklib.internal.repository.DownloadCache;
-import com.android.sdklib.internal.repository.ITask;
-import com.android.sdklib.internal.repository.ITaskMonitor;
-import com.android.sdklib.internal.repository.NullTaskMonitor;
-import com.android.sdklib.internal.repository.archives.Archive;
-import com.android.sdklib.internal.repository.packages.Package;
-import com.android.sdklib.internal.repository.packages.Package.UpdateInfo;
-import com.android.sdklib.internal.repository.sources.SdkAddonSource;
-import com.android.sdklib.internal.repository.sources.SdkSource;
-import com.android.sdklib.internal.repository.sources.SdkSourceCategory;
-import com.android.sdklib.internal.repository.sources.SdkSources;
-import com.android.sdklib.internal.repository.sources.SdkSysImgSource;
-import com.android.sdklib.repository.SdkAddonsListConstants;
-import com.android.sdklib.repository.SdkRepoConstants;
-import com.android.sdkuilib.internal.repository.UpdaterData;
-
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Loads packages fetched from the remote SDK Repository and keeps track
- * of their state compared with the current local SDK installation.
- */
-public class PackageLoader {
-
- /** The update data context. Never null. */
- private final UpdaterData mUpdaterData;
-
- /**
- * The {@link DownloadCache} override. Can be null, in which case the one from
- * {@link UpdaterData} is used instead.
- * @see #getDownloadCache()
- */
- private final DownloadCache mOverrideCache;
-
- /**
- * 0 = need to fetch remote addons list once..
- * 1 = fetch succeeded, don't need to do it any more.
- * -1= fetch failed, do it again only if the user requests a refresh
- * or changes the force-http setting.
- */
- private int mStateFetchRemoteAddonsList;
-
-
- /**
- * Interface for the callback called by
- * {@link PackageLoader#loadPackages(boolean, ISourceLoadedCallback)}.
- * <p/>
- * After processing each source, the package loader calls {@link #onUpdateSource}
- * with the list of packages found in that source.
- * By returning true from {@link #onUpdateSource}, the client tells the loader to
- * continue and process the next source. By returning false, it tells to stop loading.
- * <p/>
- * The {@link #onLoadCompleted()} method is guaranteed to be called at the end, no
- * matter how the loader stopped, so that the client can clean up or perform any
- * final action.
- */
- public interface ISourceLoadedCallback {
- /**
- * After processing each source, the package loader calls this method with the
- * list of packages found in that source.
- * By returning true from {@link #onUpdateSource}, the client tells
- * the loader to continue and process the next source.
- * By returning false, it tells to stop loading.
- * <p/>
- * <em>Important</em>: This method is called from a sub-thread, so clients which
- * try to access any UI widgets must wrap their calls into
- * {@link Display#syncExec(Runnable)} or {@link Display#asyncExec(Runnable)}.
- *
- * @param packages All the packages loaded from the source. Never null.
- * @return True if the load operation should continue, false if it should stop.
- */
- public boolean onUpdateSource(SdkSource source, Package[] packages);
-
- /**
- * This method is guaranteed to be called at the end, no matter how the
- * loader stopped, so that the client can clean up or perform any final action.
- */
- public void onLoadCompleted();
- }
-
- /**
- * Interface describing the task of installing a specific package.
- * For details on the operation,
- * see {@link PackageLoader#loadPackagesWithInstallTask(int, IAutoInstallTask)}.
- *
- * @see PackageLoader#loadPackagesWithInstallTask(int, IAutoInstallTask)
- */
- public interface IAutoInstallTask {
- /**
- * Invoked by the loader once a source has been loaded and its package
- * definitions are known. The method should return the {@code packages}
- * array and can modify it if necessary.
- * The loader will call {@link #acceptPackage(Package)} on all the packages returned.
- *
- * @param source The source of the packages. Null for the locally installed packages.
- * @param packages The packages found in the source.
- */
- public Package[] filterLoadedSource(SdkSource source, Package[] packages);
-
- /**
- * Called by the install task for every package available (new ones, updates as well
- * as existing ones that don't have a potential update.)
- * The method should return true if this is a package that should be installed.
- * <p/>
- * <em>Important</em>: This method is called from a sub-thread, so clients who try
- * to access any UI widgets must wrap their calls into {@link Display#syncExec(Runnable)}
- * or {@link Display#asyncExec(Runnable)}.
- */
- public boolean acceptPackage(Package pkg);
-
- /**
- * Called when the accepted package has been installed, successfully or not.
- * If an already installed (aka existing) package has been accepted, this will
- * be called with a 'true' success and the actual install paths.
- * <p/>
- * <em>Important</em>: This method is called from a sub-thread, so clients who try
- * to access any UI widgets must wrap their calls into {@link Display#syncExec(Runnable)}
- * or {@link Display#asyncExec(Runnable)}.
- */
- public void setResult(boolean success, Map<Package, File> installPaths);
-
- /**
- * Called when the task is done iterating and completed.
- */
- public void taskCompleted();
- }
-
- /**
- * Creates a new PackageManager associated with the given {@link UpdaterData}
- * and using the {@link UpdaterData}'s default {@link DownloadCache}.
- *
- * @param updaterData The {@link UpdaterData}. Must not be null.
- */
- public PackageLoader(UpdaterData updaterData) {
- mUpdaterData = updaterData;
- mOverrideCache = null;
- }
-
- /**
- * Creates a new PackageManager associated with the given {@link UpdaterData}
- * but using the specified {@link DownloadCache} instead of the one from
- * {@link UpdaterData}.
- *
- * @param updaterData The {@link UpdaterData}. Must not be null.
- * @param cache The {@link DownloadCache} to use instead of the one from {@link UpdaterData}.
- */
- public PackageLoader(UpdaterData updaterData, DownloadCache cache) {
- mUpdaterData = updaterData;
- mOverrideCache = cache;
- }
-
- /**
- * Loads all packages from the remote repository.
- * This runs in an {@link ITask}. The call is blocking.
- * <p/>
- * The callback is called with each set of {@link PkgItem} found in each source.
- * The caller is responsible to accumulate the packages given to the callback
- * after each source is finished loaded. In return the callback tells the loader
- * whether to continue loading sources.
- * <p/>
- * Normally this method doesn't access the remote source if it's already
- * been loaded in the in-memory source (e.g. don't fetch twice).
- *
- * @param overrideExisting Set this to true when the caller wants to
- * check for updates and discard any existing source already
- * loaded in memory. It should be false for normal use.
- * @param sourceLoadedCallback The callback to invoke for each loaded source.
- */
- public void loadPackages(
- final boolean overrideExisting,
- final ISourceLoadedCallback sourceLoadedCallback) {
- try {
- if (mUpdaterData == null) {
- return;
- }
-
- mUpdaterData.getTaskFactory().start("Loading Sources", new ITask() {
- @Override
- public void run(ITaskMonitor monitor) {
- monitor.setProgressMax(10);
-
- // get local packages and offer them to the callback
- Package[] localPkgs =
- mUpdaterData.getInstalledPackages(monitor.createSubMonitor(1));
- if (localPkgs == null) {
- localPkgs = new Package[0];
- }
- if (!sourceLoadedCallback.onUpdateSource(null, localPkgs)) {
- return;
- }
-
- // get remote packages
- boolean forceHttp =
- mUpdaterData.getSettingsController().getSettings().getForceHttp();
- loadRemoteAddonsList(monitor.createSubMonitor(1));
-
- SdkSource[] sources = mUpdaterData.getSources().getAllSources();
- try {
- if (sources != null && sources.length > 0) {
- ITaskMonitor subMonitor = monitor.createSubMonitor(8);
- subMonitor.setProgressMax(sources.length);
- for (SdkSource source : sources) {
- Package[] pkgs = source.getPackages();
- if (pkgs == null || overrideExisting) {
- source.load(getDownloadCache(),
- subMonitor.createSubMonitor(1),
- forceHttp);
- pkgs = source.getPackages();
- }
- if (pkgs == null) {
- continue;
- }
-
- // Notify the callback a new source has finished loading.
- // If the callback requests so, stop right away.
- if (!sourceLoadedCallback.onUpdateSource(source, pkgs)) {
- return;
- }
- }
- }
- } catch(Exception e) {
- monitor.logError("Loading source failed: %1$s", e.toString());
- } finally {
- monitor.setDescription("Done loading packages.");
- }
- }
- });
- } finally {
- sourceLoadedCallback.onLoadCompleted();
- }
- }
-
- /**
- * Load packages, source by source using
- * {@link #loadPackages(boolean, ISourceLoadedCallback)},
- * and executes the given {@link IAutoInstallTask} on the current package list.
- * That is for each package known, the install task is queried to find if
- * the package is the one to be installed or updated.
- * <p/>
- * - If an already installed package is accepted by the task, it is returned. <br/>
- * - If a new package (remotely available but not installed locally) is accepted,
- * the user will be <em>prompted</em> for permission to install it. <br/>
- * - If an existing package has updates, the install task will be accept if it
- * accepts one of the updating packages, and if yes the the user will be
- * <em>prompted</em> for permission to install it. <br/>
- * <p/>
- * Only one package can be accepted, after which the task is completed.
- * There is no direct return value, {@link IAutoInstallTask#setResult} is called on the
- * result of the accepted package.
- * When the task is completed, {@link IAutoInstallTask#taskCompleted()} is called.
- * <p/>
- * <em>Important</em>: Since some UI will be displayed to install the selected package,
- * the {@link UpdaterData} must have a window {@link Shell} associated using
- * {@link UpdaterData#setWindowShell(Shell)}.
- * <p/>
- * The call is blocking. Although the name says "Task", this is not an {@link ITask}
- * running in its own thread but merely a synchronous call.
- *
- * @param installFlags Flags for installation such as
- * {@link UpdaterData#TOOLS_MSG_UPDATED_FROM_ADT}.
- * @param installTask The task to perform.
- */
- public void loadPackagesWithInstallTask(
- final int installFlags,
- final IAutoInstallTask installTask) {
-
- loadPackages(false /*overrideExisting*/, new ISourceLoadedCallback() {
- List<Archive> mArchivesToInstall = new ArrayList<Archive>();
- Map<Package, File> mInstallPaths = new HashMap<Package, File>();
-
- @Override
- public boolean onUpdateSource(SdkSource source, Package[] packages) {
- packages = installTask.filterLoadedSource(source, packages);
- if (packages == null || packages.length == 0) {
- // Tell loadPackages() to process the next source.
- return true;
- }
-
- for (Package pkg : packages) {
- if (pkg.isLocal()) {
- // This is a local (aka installed) package
- if (installTask.acceptPackage(pkg)) {
- // If the caller is accepting an installed package,
- // return a success and give the package's install path
- Archive[] a = pkg.getArchives();
- // an installed package should have one local compatible archive
- if (a.length == 1 && a[0].isCompatible()) {
- mInstallPaths.put(pkg, new File(a[0].getLocalOsPath()));
- }
- }
-
- } else {
- // This is a remote package
- if (installTask.acceptPackage(pkg)) {
- // The caller is accepting this remote package. We'll install it.
- for (Archive archive : pkg.getArchives()) {
- if (archive.isCompatible()) {
- mArchivesToInstall.add(archive);
- break;
- }
- }
- }
- }
- }
-
- // Tell loadPackages() to process the next source.
- return true;
- }
-
- @Override
- public void onLoadCompleted() {
- if (!mArchivesToInstall.isEmpty()) {
- installArchives(mArchivesToInstall);
- }
- if (mInstallPaths == null) {
- installTask.setResult(false, null);
- } else {
- installTask.setResult(true, mInstallPaths);
- }
-
- installTask.taskCompleted();
- }
-
- /**
- * Shows the UI of the install selector.
- * If the package is then actually installed, refresh the local list and
- * notify the install task of the installation path.
- *
- * @param archivesToInstall The archives to install.
- */
- private void installArchives(final List<Archive> archivesToInstall) {
- // Actually install the new archives that we just found.
- // This will display some UI so we need a shell's sync exec.
-
- final List<Archive> installedArchives = new ArrayList<Archive>();
-
- Shell shell = mUpdaterData.getWindowShell();
- if (shell != null && !shell.isDisposed()) {
- shell.getDisplay().syncExec(new Runnable() {;
- @Override
- public void run() {
- List<Archive> archives =
- mUpdaterData.updateOrInstallAll_WithGUI(
- archivesToInstall,
- true /* includeObsoletes */,
- installFlags);
-
- if (archives != null) {
- installedArchives.addAll(archives);
- }
- }
- });
- }
-
- if (installedArchives.isEmpty()) {
- // We failed to install anything.
- mInstallPaths = null;
- return;
- }
-
- // The local package list has changed, make sure to refresh it
- mUpdaterData.getSdkManager().reloadSdk(mUpdaterData.getSdkLog());
- mUpdaterData.getLocalSdkParser().clearPackages();
- final Package[] localPkgs = mUpdaterData.getInstalledPackages(
- new NullTaskMonitor(mUpdaterData.getSdkLog()));
-
- // Scan the installed package list to find the install paths.
- for (Archive installedArchive : installedArchives) {
- Package pkg = installedArchive.getParentPackage();
-
- for (Package localPkg : localPkgs) {
- if (localPkg.canBeUpdatedBy(pkg) == UpdateInfo.NOT_UPDATE) {
- Archive[] localArchive = localPkg.getArchives();
- if (localArchive.length == 1 && localArchive[0].isCompatible()) {
- mInstallPaths.put(
- localPkg,
- new File(localArchive[0].getLocalOsPath()));
- }
- }
- }
- }
- }
- });
- }
-
-
- /**
- * Loads the remote add-ons list.
- */
- public void loadRemoteAddonsList(ITaskMonitor monitor) {
-
- if (mStateFetchRemoteAddonsList != 0) {
- return;
- }
-
- mUpdaterData.getTaskFactory().start("Load Add-ons List", monitor, new ITask() {
- @Override
- public void run(ITaskMonitor subMonitor) {
- loadRemoteAddonsListInTask(subMonitor);
- }
- });
- }
-
- private void loadRemoteAddonsListInTask(ITaskMonitor monitor) {
- mStateFetchRemoteAddonsList = -1;
-
- String url = SdkAddonsListConstants.URL_ADDON_LIST;
-
- // We override SdkRepoConstants.URL_GOOGLE_SDK_SITE if this is defined
- String baseUrl = System.getenv("SDK_TEST_BASE_URL"); //$NON-NLS-1$
- if (baseUrl != null) {
- if (baseUrl.length() > 0 && baseUrl.endsWith("/")) { //$NON-NLS-1$
- if (url.startsWith(SdkRepoConstants.URL_GOOGLE_SDK_SITE)) {
- url = baseUrl + url.substring(SdkRepoConstants.URL_GOOGLE_SDK_SITE.length());
- }
- } else {
- monitor.logError("Ignoring invalid SDK_TEST_BASE_URL: %1$s", baseUrl); //$NON-NLS-1$
- }
- }
-
- if (mUpdaterData.getSettingsController().getSettings().getForceHttp()) {
- url = url.replaceAll("https://", "http://"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- // Hook to bypass loading 3rd party addons lists.
- boolean fetch3rdParties = System.getenv("SDK_SKIP_3RD_PARTIES") == null;
-
- AddonsListFetcher fetcher = new AddonsListFetcher();
- Site[] sites = fetcher.fetch(url, getDownloadCache(), monitor);
- if (sites != null) {
- SdkSources sources = mUpdaterData.getSources();
- sources.removeAll(SdkSourceCategory.ADDONS_3RD_PARTY);
-
- if (fetch3rdParties) {
- for (Site s : sites) {
- switch (s.getType()) {
- case ADDON_SITE:
- sources.add(SdkSourceCategory.ADDONS_3RD_PARTY,
- new SdkAddonSource(s.getUrl(), s.getUiName()));
- break;
- case SYS_IMG_SITE:
- sources.add(SdkSourceCategory.ADDONS_3RD_PARTY,
- new SdkSysImgSource(s.getUrl(), s.getUiName()));
- break;
- }
- }
- }
-
- sources.notifyChangeListeners();
-
- mStateFetchRemoteAddonsList = 1;
- }
-
- monitor.setDescription("Fetched Add-ons List successfully");
- }
-
- /**
- * Returns the {@link DownloadCache} to use.
- *
- * @return Returns {@link #mOverrideCache} if not null; otherwise returns the
- * one from {@link UpdaterData} is used instead.
- */
- private DownloadCache getDownloadCache() {
- return mOverrideCache != null ? mOverrideCache : mUpdaterData.getDownloadCache();
- }
-}