aboutsummaryrefslogtreecommitdiffstats
path: root/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java')
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java568
1 files changed, 0 insertions, 568 deletions
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java
deleted file mode 100755
index 3ca0ee3..0000000
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import com.android.SdkConstants;
-import com.android.sdklib.internal.repository.DownloadCache;
-import com.android.sdklib.internal.repository.DownloadCache.Strategy;
-import com.android.sdklib.internal.repository.IDescription;
-import com.android.sdklib.internal.repository.archives.Archive;
-import com.android.sdklib.internal.repository.packages.Package;
-import com.android.sdklib.internal.repository.sources.SdkSource;
-import com.android.sdkuilib.internal.repository.UpdaterData;
-import com.android.sdkuilib.internal.repository.core.PackageLoader;
-import com.android.sdkuilib.internal.repository.core.PackageLoader.ISourceLoadedCallback;
-import com.android.sdkuilib.internal.repository.core.PackagesDiffLogic;
-import com.android.sdkuilib.internal.repository.core.PkgCategory;
-import com.android.sdkuilib.internal.repository.core.PkgCategoryApi;
-import com.android.sdkuilib.internal.repository.core.PkgContentProvider;
-import com.android.sdkuilib.internal.repository.core.PkgItem;
-import com.android.sdkuilib.internal.repository.core.PkgItem.PkgState;
-import com.android.sdkuilib.internal.repository.icons.ImageFactory;
-
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.IInputProvider;
-import org.eclipse.jface.viewers.ITableFontProvider;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-
-/**
- * Base class for {@link PackagesPage} that holds most of the logic to display
- * the tree/list of packages. This class holds most of the logic and {@link PackagesPage}
- * holds most of the UI (creating the UI, dealing with menus and buttons and tree
- * selection.) This makes it easier to test the functionality by mocking only a
- * subset of the UI.
- */
-abstract class PackagesPageImpl {
-
- final UpdaterData mUpdaterData;
- final PackagesDiffLogic mDiffLogic;
-
- private ICheckboxTreeViewer mITreeViewer;
- private ITreeViewerColumn mIColumnName;
- private ITreeViewerColumn mIColumnApi;
- private ITreeViewerColumn mIColumnRevision;
- private ITreeViewerColumn mIColumnStatus;
-
- PackagesPageImpl(UpdaterData updaterData) {
- mUpdaterData = updaterData;
- mDiffLogic = new PackagesDiffLogic(updaterData);
- }
-
- /**
- * Utility method that derived classes can override to check whether the UI is disposed.
- * When the UI is disposed, most operations that affect the UI will be bypassed.
- * @return True if UI is not available and should not be touched.
- */
- abstract protected boolean isUiDisposed();
-
- /**
- * Utility method to execute a runnable on the main UI thread.
- * Will do nothing if {@link #isUiDisposed()} returns false.
- * @param runnable The runnable to execute on the main UI thread.
- */
- abstract protected void syncExec(Runnable runnable);
-
- void performFirstLoad() {
- // First a package loader is created that only checks
- // the local cache xml files. It populates the package
- // list based on what the client got last, essentially.
- loadPackages(true /*useLocalCache*/, false /*overrideExisting*/);
-
- // Next a regular package loader is created that will
- // respect the expiration and refresh parameters of the
- // download cache.
- loadPackages(false /*useLocalCache*/, true /*overrideExisting*/);
- }
-
- public void setITreeViewer(ICheckboxTreeViewer iTreeViewer) {
- mITreeViewer = iTreeViewer;
- }
-
- public void setIColumns(
- ITreeViewerColumn columnName,
- ITreeViewerColumn columnApi,
- ITreeViewerColumn columnRevision,
- ITreeViewerColumn columnStatus) {
- mIColumnName = columnName;
- mIColumnApi = columnApi;
- mIColumnRevision = columnRevision;
- mIColumnStatus = columnStatus;
- }
-
- void postCreate() {
- // Caller needs to call setITreeViewer before this.
- assert mITreeViewer != null;
- // Caller needs to call setIColumns before this.
- assert mIColumnApi != null;
- assert mIColumnName != null;
- assert mIColumnStatus != null;
- assert mIColumnRevision != null;
-
- mITreeViewer.setContentProvider(new PkgContentProvider(mITreeViewer));
-
- mIColumnApi.setLabelProvider(
- new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mIColumnApi)));
- mIColumnName.setLabelProvider(
- new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mIColumnName)));
- mIColumnStatus.setLabelProvider(
- new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mIColumnStatus)));
- mIColumnRevision.setLabelProvider(
- new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mIColumnRevision)));
- }
-
- /**
- * Performs a full reload by removing all cached packages data, including the platforms
- * and addons from the sdkmanager instance. This will perform a full local parsing
- * as well as a full reload of the remote data (by fetching all sources again.)
- */
- void fullReload() {
- // Clear all source information, forcing them to be refreshed.
- mUpdaterData.getSources().clearAllPackages();
- // Clear and reload all local data too.
- localReload();
- }
-
- /**
- * Performs a full reload of all the local package information, including the platforms
- * and addons from the sdkmanager instance. This will perform a full local parsing.
- * <p/>
- * This method does NOT force a new fetch of the remote sources.
- *
- * @see #fullReload()
- */
- void localReload() {
- // Clear all source caches, otherwise loading will use the cached data
- mUpdaterData.getLocalSdkParser().clearPackages();
- mUpdaterData.getSdkManager().reloadSdk(mUpdaterData.getSdkLog());
- loadPackages();
- }
-
- /**
- * Performs a "normal" reload of the package information, use the default download
- * cache and refreshing strategy as needed.
- */
- void loadPackages() {
- loadPackages(false /*useLocalCache*/, false /*overrideExisting*/);
- }
-
- /**
- * Performs a reload of the package information.
- *
- * @param useLocalCache When true, the {@link PackageLoader} is switched to use
- * a specific {@link DownloadCache} using the {@link Strategy#ONLY_CACHE}, meaning
- * it will only use data from the local cache. It will not try to fetch or refresh
- * manifests. This is used once the very first time the sdk manager window opens
- * and is typically followed by a regular load with refresh.
- */
- abstract protected void loadPackages(boolean useLocalCache, boolean overrideExisting);
-
- /**
- * Actual implementation of {@link #loadPackages(boolean, boolean)}.
- * Derived implementations must call this to do the actual work after setting up the UI.
- */
- void loadPackagesImpl(final boolean useLocalCache, final boolean overrideExisting) {
- if (mUpdaterData == null) {
- return;
- }
-
- final boolean displaySortByApi = isSortByApi();
-
- PackageLoader packageLoader = getPackageLoader(useLocalCache);
- assert packageLoader != null;
-
- mDiffLogic.updateStart();
- packageLoader.loadPackages(overrideExisting, new ISourceLoadedCallback() {
- @Override
- public boolean onUpdateSource(SdkSource source, Package[] newPackages) {
- // This runs in a thread and must not access UI directly.
- final boolean changed = mDiffLogic.updateSourcePackages(
- displaySortByApi, source, newPackages);
-
- syncExec(new Runnable() {
- @Override
- public void run() {
- if (changed ||
- mITreeViewer.getInput() != mDiffLogic.getCategories(isSortByApi())) {
- refreshViewerInput();
- }
- }
- });
-
- // Return true to tell the loader to continue with the next source.
- // Return false to stop the loader if any UI has been disposed, which can
- // happen if the user is trying to close the window during the load operation.
- return !isUiDisposed();
- }
-
- @Override
- public void onLoadCompleted() {
- // This runs in a thread and must not access UI directly.
- final boolean changed = mDiffLogic.updateEnd(displaySortByApi);
-
- syncExec(new Runnable() {
- @Override
- public void run() {
- if (changed ||
- mITreeViewer.getInput() != mDiffLogic.getCategories(isSortByApi())) {
- try {
- refreshViewerInput();
- } catch (Exception ignore) {}
- }
-
- if (!useLocalCache &&
- mDiffLogic.isFirstLoadComplete() &&
- !isUiDisposed()) {
- // At the end of the first load, if nothing is selected then
- // automatically select all new and update packages.
- Object[] checked = mITreeViewer.getCheckedElements();
- if (checked == null || checked.length == 0) {
- onSelectNewUpdates(
- false, //selectNew
- true, //selectUpdates,
- true); //selectTop
- }
- }
- }
- });
- }
- });
- }
-
- /**
- * Used by {@link #loadPackagesImpl(boolean, boolean)} to get the package
- * loader for the first or second pass update. When starting the manager
- * starts with a first pass that reads only from the local cache, with no
- * extra network access. That's {@code useLocalCache} being true.
- * <p/>
- * Leter it does a second pass with {@code useLocalCache} set to false
- * and actually uses the download cache specified in {@link UpdaterData}.
- *
- * This is extracted so that we can control this cache via unit tests.
- */
- protected PackageLoader getPackageLoader(boolean useLocalCache) {
- if (useLocalCache) {
- return new PackageLoader(mUpdaterData, new DownloadCache(Strategy.ONLY_CACHE));
- } else {
- return mUpdaterData.getPackageLoader();
- }
- }
-
- /**
- * Overridden by the UI to respond to a request to refresh the tree viewer
- * when the input has changed.
- * The implementation must call {@link #setViewerInput()} somehow and will
- * also need to adjust the expand state of the tree items and/or update
- * some buttons or other state.
- */
- abstract protected void refreshViewerInput();
-
- /**
- * Invoked from {@link #refreshViewerInput()} to actually either set the
- * input of the tree viewer or refresh it if it's the <em>same</em> input
- * object.
- */
- protected void setViewerInput() {
- List<PkgCategory> cats = mDiffLogic.getCategories(isSortByApi());
- if (mITreeViewer.getInput() != cats) {
- // set initial input
- mITreeViewer.setInput(cats);
- } else {
- // refresh existing, which preserves the expanded state, the selection
- // and the checked state.
- mITreeViewer.refresh();
- }
- }
-
- /**
- * Overridden by the UI to determine if the tree should display packages sorted
- * by API (returns true) or by repository source (returns false.)
- */
- abstract protected boolean isSortByApi();
-
- /**
- * Checks all PkgItems that are either new or have updates or select top platform
- * for initial run.
- */
- void onSelectNewUpdates(boolean selectNew, boolean selectUpdates, boolean selectTop) {
- // This does not update the tree itself, syncViewerSelection does it in the caller.
- mDiffLogic.checkNewUpdateItems(
- selectNew,
- selectUpdates,
- selectTop,
- SdkConstants.CURRENT_PLATFORM);
- }
-
- /**
- * Deselect all checked PkgItems.
- */
- void onDeselectAll() {
- // This does not update the tree itself, syncViewerSelection does it in the caller.
- mDiffLogic.uncheckAllItems();
- }
-
- // ----------------------
-
- abstract protected Font getTreeFontItalic();
-
- class PkgCellLabelProvider extends ColumnLabelProvider implements ITableFontProvider {
-
- private final ITreeViewerColumn mColumn;
-
- public PkgCellLabelProvider(ITreeViewerColumn column) {
- super();
- mColumn = column;
- }
-
- @Override
- public String getText(Object element) {
-
- if (mColumn == mIColumnName) {
- if (element instanceof PkgCategory) {
- return ((PkgCategory) element).getLabel();
- } else if (element instanceof PkgItem) {
- return getPkgItemName((PkgItem) element);
- } else if (element instanceof IDescription) {
- return ((IDescription) element).getShortDescription();
- }
-
- } else if (mColumn == mIColumnApi) {
- int api = -1;
- if (element instanceof PkgItem) {
- api = ((PkgItem) element).getApi();
- }
- if (api >= 1) {
- return Integer.toString(api);
- }
-
- } else if (mColumn == mIColumnRevision) {
- if (element instanceof PkgItem) {
- PkgItem pkg = (PkgItem) element;
- return pkg.getRevision().toShortString();
- }
-
- } else if (mColumn == mIColumnStatus) {
- if (element instanceof PkgItem) {
- PkgItem pkg = (PkgItem) element;
-
- switch(pkg.getState()) {
- case INSTALLED:
- Package update = pkg.getUpdatePkg();
- if (update != null) {
- return String.format(
- "Update available: rev. %1$s",
- update.getRevision().toShortString());
- }
- return "Installed";
-
- case NEW:
- Package p = pkg.getMainPackage();
- if (p != null && p.hasCompatibleArchive()) {
- return "Not installed";
- } else {
- return String.format("Not compatible with %1$s",
- SdkConstants.currentPlatformName());
- }
- }
- return pkg.getState().toString();
-
- } else if (element instanceof Package) {
- // This is an update package.
- return "New revision " + ((Package) element).getRevision().toShortString();
- }
- }
-
- return ""; //$NON-NLS-1$
- }
-
- private String getPkgItemName(PkgItem item) {
- String name = item.getName().trim();
-
- if (isSortByApi()) {
- // When sorting by API, the package name might contains the API number
- // or the platform name at the end. If we find it, cut it out since it's
- // redundant.
-
- PkgCategoryApi cat = (PkgCategoryApi) findCategoryForItem(item);
- String apiLabel = cat.getApiLabel();
- String platLabel = cat.getPlatformName();
-
- if (platLabel != null && name.endsWith(platLabel)) {
- return name.substring(0, name.length() - platLabel.length());
-
- } else if (apiLabel != null && name.endsWith(apiLabel)) {
- return name.substring(0, name.length() - apiLabel.length());
-
- } else if (platLabel != null && item.isObsolete() && name.indexOf(platLabel) > 0) {
- // For obsolete items, the format is "<base name> <platform name> (Obsolete)"
- // so in this case only accept removing a platform name that is not at
- // the end.
- name = name.replace(platLabel, ""); //$NON-NLS-1$
- }
- }
-
- // Collapse potential duplicated spacing
- name = name.replaceAll(" +", " "); //$NON-NLS-1$ //$NON-NLS-2$
-
- return name;
- }
-
- private PkgCategory findCategoryForItem(PkgItem item) {
- List<PkgCategory> cats = mDiffLogic.getCategories(isSortByApi());
- for (PkgCategory cat : cats) {
- for (PkgItem i : cat.getItems()) {
- if (i == item) {
- return cat;
- }
- }
- }
-
- return null;
- }
-
- @Override
- public Image getImage(Object element) {
- ImageFactory imgFactory = mUpdaterData.getImageFactory();
-
- if (imgFactory != null) {
- if (mColumn == mIColumnName) {
- if (element instanceof PkgCategory) {
- return imgFactory.getImageForObject(((PkgCategory) element).getIconRef());
- } else if (element instanceof PkgItem) {
- return imgFactory.getImageForObject(((PkgItem) element).getMainPackage());
- }
- return imgFactory.getImageForObject(element);
-
- } else if (mColumn == mIColumnStatus && element instanceof PkgItem) {
- PkgItem pi = (PkgItem) element;
- switch(pi.getState()) {
- case INSTALLED:
- if (pi.hasUpdatePkg()) {
- return imgFactory.getImageByName(PackagesPageIcons.ICON_PKG_UPDATE);
- } else {
- return imgFactory.getImageByName(PackagesPageIcons.ICON_PKG_INSTALLED);
- }
- case NEW:
- Package p = pi.getMainPackage();
- if (p != null && p.hasCompatibleArchive()) {
- return imgFactory.getImageByName(PackagesPageIcons.ICON_PKG_NEW);
- } else {
- return imgFactory.getImageByName(PackagesPageIcons.ICON_PKG_INCOMPAT);
- }
- }
- }
- }
- return super.getImage(element);
- }
-
- // -- ITableFontProvider
-
- @Override
- public Font getFont(Object element, int columnIndex) {
- if (element instanceof PkgItem) {
- if (((PkgItem) element).getState() == PkgState.NEW) {
- return getTreeFontItalic();
- }
- } else if (element instanceof Package) {
- // update package
- return getTreeFontItalic();
- }
- return super.getFont(element);
- }
-
- // -- Tooltip support
-
- @Override
- public String getToolTipText(Object element) {
- PkgItem pi = element instanceof PkgItem ? (PkgItem) element : null;
- if (pi != null) {
- element = pi.getMainPackage();
- }
- if (element instanceof IDescription) {
- String s = getTooltipDescription((IDescription) element);
-
- if (pi != null && pi.hasUpdatePkg()) {
- s += "\n-----------------" + //$NON-NLS-1$
- "\nUpdate Available:\n" + //$NON-NLS-1$
- getTooltipDescription(pi.getUpdatePkg());
- }
-
- return s;
- }
- return super.getToolTipText(element);
- }
-
- private String getTooltipDescription(IDescription element) {
- String s = element.getLongDescription();
- if (element instanceof Package) {
- Package p = (Package) element;
-
- if (!p.isLocal()) {
- // For non-installed item, try to find a download size
- for (Archive a : p.getArchives()) {
- if (!a.isLocal() && a.isCompatible()) {
- s += '\n' + a.getSizeDescription();
- break;
- }
- }
- }
-
- // Display info about where this package comes/came from
- SdkSource src = p.getParentSource();
- if (src != null) {
- try {
- URL url = new URL(src.getUrl());
- String host = url.getHost();
- if (p.isLocal()) {
- s += String.format("\nInstalled from %1$s", host);
- } else {
- s += String.format("\nProvided by %1$s", host);
- }
- } catch (MalformedURLException ignore) {
- }
- }
- }
- return s;
- }
-
- @Override
- public Point getToolTipShift(Object object) {
- return new Point(15, 5);
- }
-
- @Override
- public int getToolTipDisplayDelayTime(Object object) {
- return 500;
- }
- }
-
- interface ICheckboxTreeViewer extends IInputProvider {
- void setContentProvider(PkgContentProvider pkgContentProvider);
- void refresh();
- void setInput(List<PkgCategory> cats);
- Object[] getCheckedElements();
- }
-
- interface ITreeViewerColumn {
- void setLabelProvider(ColumnLabelProvider labelProvider);
- }
-}