OSDN Git Service

ADT NPW: cleanup minSdkVersion resolution for samples.
authorRaphael <raphael@google.com>
Sat, 23 Jan 2010 02:56:10 +0000 (18:56 -0800)
committerRaphael <raphael@google.com>
Sat, 23 Jan 2010 02:56:10 +0000 (18:56 -0800)
This fixes a couple quirks in NPW:
- When you select a sample, its minSdkVersion is now used as-is
  but the currently selected target is not changed to match.
  Otherwise it invalidates the list of samples you're trying to
  import from...
- This allows for samples with no minSdkVersion to properly
  import with an empty field.
- Same issue if you were to manually edit the field after the fact.

Also renamed IAndroidTarget.isCompatibleBaseFor() to
IAndroidTarget.canRunOn(), which is way more readable.

This also "fixes" bug 2346838 -- kind of, the bug was obsolete
since I had added the new sample mode but there was another
quirk instead (it was reverting the target so it invalidated
the sample you were trying to import... see point #1 above.)

Change-Id: If2487632484fa5646bea7fe2625a2a55e5d26c50

eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java
sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java
sdkmanager/libs/sdklib/src/com/android/sdklib/AndroidVersion.java
sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java
sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockAddonPackage.java
sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockPlatformPackage.java
sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java

index 16dad90..4c8621e 100644 (file)
@@ -347,7 +347,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
             AvdInfo preferredAvd = null;
             if (config.mAvdName != null) {
                 preferredAvd = avdManager.getAvd(config.mAvdName, true /*validAvdOnly*/);
-                if (projectTarget.isCompatibleBaseFor(preferredAvd.getTarget()) == false) {
+                if (projectTarget.canRunOn(preferredAvd.getTarget()) == false) {
                     preferredAvd = null;
 
                     AdtPlugin.printErrorToConsole(project, String.format(
@@ -394,7 +394,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
                 String deviceAvd = d.getAvdName();
                 if (deviceAvd != null) { // physical devices return null.
                     AvdInfo info = avdManager.getAvd(deviceAvd, true /*validAvdOnly*/);
-                    if (info != null && projectTarget.isCompatibleBaseFor(info.getTarget())) {
+                    if (info != null && projectTarget.canRunOn(info.getTarget())) {
                         compatibleRunningAvds.put(d, info);
                     }
                 } else {
@@ -547,9 +547,9 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
         AvdInfo[] avds = avdManager.getValidAvds();
         AvdInfo defaultAvd = null;
         for (AvdInfo avd : avds) {
-            if (projectTarget.isCompatibleBaseFor(avd.getTarget())) {
+            if (projectTarget.canRunOn(avd.getTarget())) {
                 // at this point we can ignore the code name issue since
-                // IAndroidTarget.isCompatibleBaseFor() will already have filtered the non
+                // IAndroidTarget.canRunOn() will already have filtered the non
                 // compatible AVDs.
                 if (defaultAvd == null ||
                         avd.getTarget().getVersion().getApiLevel() <
@@ -1212,6 +1212,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
      * @return false if cancelled by the monitor
      * @throws CoreException
      */
+    @SuppressWarnings("deprecation")
     public static boolean connectRemoteDebugger(int debugPort,
             AndroidLaunch launch, IProgressMonitor monitor)
                 throws CoreException {
index 315f456..bb4d580 100644 (file)
@@ -146,7 +146,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
                             if (info == null) {
                                 return mWarningImage;
                             }
-                            return mProjectTarget.isCompatibleBaseFor(info.getTarget()) ?
+                            return mProjectTarget.canRunOn(info.getTarget()) ?
                                     mMatchImage : mNoMatchImage;
                         }
                 }
@@ -687,7 +687,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
         public boolean accept(AvdInfo avd) {
             if (mDevices != null) {
                 for (IDevice d : mDevices) {
-                    if (mProjectTarget.isCompatibleBaseFor(avd.getTarget()) == false ||
+                    if (mProjectTarget.canRunOn(avd.getTarget()) == false ||
                             avd.getName().equals(d.getAvdName())) {
                         return false;
                     }
index bd212cb..d144474 100644 (file)
@@ -923,6 +923,15 @@ public class NewProjectCreationPage extends WizardPage {
 
         String minSdkVersion = mInfo.getMinSdkVersion();
 
+        // If there's a current target defined, we do not allow to change it when
+        // operating in the create-from-sample mode -- since the available sample list
+        // is tied to the current target, so changing it would invalidate the project we're
+        // trying to load in the first place.
+        IAndroidTarget currentTarget = mInfo.getSdkTarget();
+        if (currentTarget != null && mInfo.isCreateFromSample()) {
+            return;
+        }
+
         // Before changing, compare with the currently selected one, if any.
         // There can be multiple targets with the same sdk api version, so don't change
         // it if it's already at the right version.
@@ -1100,44 +1109,51 @@ public class NewProjectCreationPage extends WizardPage {
 
         // Select the target matching the manifest's sdk or build properties, if any
         IAndroidTarget foundTarget = null;
+        // This is the target currently in the UI
         IAndroidTarget currentTarget = mInfo.getSdkTarget();
 
-        ProjectProperties p = ProjectProperties.create(projectLocation, null);
-        if (p != null) {
-            // Check the {build|default}.properties files if present
-            p.merge(PropertyType.BUILD).merge(PropertyType.DEFAULT);
-            String v = p.getProperty(ProjectProperties.PROPERTY_TARGET);
-            IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString(v);
-            // We can change the current target if:
-            // - we found a new target
-            // - there is no current target
-            // - there is a current target but the new target is not <= to the current one.
-            if (target != null &&
-                    (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
-                foundTarget = target;
+        // If there's a current target defined, we do not allow to change it when
+        // operating in the create-from-sample mode -- since the available sample list
+        // is tied to the current target, so changing it would invalidate the project we're
+        // trying to load in the first place.
+        if (currentTarget == null || !mInfo.isCreateFromSample()) {
+            ProjectProperties p = ProjectProperties.create(projectLocation, null);
+            if (p != null) {
+                // Check the {build|default}.properties files if present
+                p.merge(PropertyType.BUILD).merge(PropertyType.DEFAULT);
+                String v = p.getProperty(ProjectProperties.PROPERTY_TARGET);
+                IAndroidTarget desiredTarget = Sdk.getCurrent().getTargetFromHashString(v);
+                // We can change the current target if:
+                // - we found a new desired target
+                // - there is no current target
+                // - or the current target can't run the desired target
+                if (desiredTarget != null &&
+                        (currentTarget == null || !desiredTarget.canRunOn(currentTarget))) {
+                    foundTarget = desiredTarget;
+                }
             }
-        }
 
-        if (foundTarget == null && minSdkVersion != null) {
-            // Otherwise try to match the requested sdk version
-            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-                if (target != null &&
-                        target.getVersion().equals(minSdkVersion) &&
-                        (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
-                    foundTarget = target;
-                    break;
+            if (foundTarget == null && minSdkVersion != null) {
+                // Otherwise try to match the requested min-sdk-version if we find an
+                // exact match, regardless of the currently selected target.
+                for (IAndroidTarget existingTarget : mSdkTargetSelector.getTargets()) {
+                    if (existingTarget != null &&
+                            existingTarget.getVersion().equals(minSdkVersion)) {
+                        foundTarget = existingTarget;
+                        break;
+                    }
                 }
             }
-        }
 
-        if (foundTarget == null) {
-            // Or last attemp, try to match a sample project location
-            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-                if (target != null &&
-                        projectLocation.startsWith(target.getLocation()) &&
-                        (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
-                    foundTarget = target;
-                    break;
+            if (foundTarget == null) {
+                // Or last attempt, try to match a sample project location and use it
+                // if we find an exact match, regardless of the currently selected target.
+                for (IAndroidTarget existingTarget : mSdkTargetSelector.getTargets()) {
+                    if (existingTarget != null &&
+                            projectLocation.startsWith(existingTarget.getLocation())) {
+                        foundTarget = existingTarget;
+                        break;
+                    }
                 }
             }
         }
@@ -1146,9 +1162,8 @@ public class NewProjectCreationPage extends WizardPage {
             mSdkTargetSelector.setSelection(foundTarget);
         } else {
             mInternalMinSdkVersionUpdate = true;
-            if (minSdkVersion != null) {
-                mMinSdkVersionField.setText(minSdkVersion);
-            }
+            // It's OK for an import to not a minSdkVersion and we should respect it.
+            mMinSdkVersionField.setText(minSdkVersion == null ? "" : minSdkVersion);  //$NON-NLS-1$
             mInternalMinSdkVersionUpdate = false;
         }
     }
index 9184099..2a55a68 100644 (file)
@@ -212,7 +212,7 @@ final class AddOnTarget implements IAndroidTarget {
         return mVendorId;
     }
 
-    public boolean isCompatibleBaseFor(IAndroidTarget target) {
+    public boolean canRunOn(IAndroidTarget target) {
         // basic test
         if (target == this) {
             return true;
@@ -228,7 +228,7 @@ final class AddOnTarget implements IAndroidTarget {
         // The receiver is an add-on. There are 2 big use cases: The add-on has libraries
         // or the add-on doesn't (in which case we consider it a platform).
         if (mLibraries == null || mLibraries.length == 0) {
-            return mBasePlatform.isCompatibleBaseFor(target);
+            return mBasePlatform.canRunOn(target);
         } else {
             // the only targets that can run the receiver are the same add-on in the same or later
             // versions.
@@ -241,7 +241,7 @@ final class AddOnTarget implements IAndroidTarget {
             // now check the version. At this point since we checked the add-on part,
             // we can revert to the basic check on version/codename which are done by the
             // base platform already.
-            return mBasePlatform.isCompatibleBaseFor(target);
+            return mBasePlatform.canRunOn(target);
         }
 
     }
index 9315c7d..7674e76 100644 (file)
@@ -161,7 +161,7 @@ public final class AndroidVersion implements Comparable<AndroidVersion> {
      * <p/>
      * Be aware that this is not a perfect test, as other properties could break compatibility
      * despite this method returning true. For a more comprehensive test, see
-     * {@link IAndroidTarget#isCompatibleBaseFor(IAndroidTarget)}.
+     * {@link IAndroidTarget#canRunOn(IAndroidTarget)}.
      * <p/>
      * Nevertheless, when testing if an application can run on a device (where there is no
      * access to the list of optional libraries), this method can give a good indication of whether
index 095a593..2bc250c 100644 (file)
@@ -180,12 +180,17 @@ public interface IAndroidTarget extends Comparable<IAndroidTarget> {
 
     /**
      * Returns whether the given target is compatible with the receiver.
-     * <p/>A target is considered compatible if applications developed for the receiver can run on
-     * the given target.
+     * <p/>
+     * This means that a project using the receiver's target can run on the given target.
+     * <br/>
+     * Example:
+     * <pre>
+     * CupcakeTarget.canRunOn(DonutTarget) == true
+     * </pre>.
      *
      * @param target the IAndroidTarget to test.
      */
-    boolean isCompatibleBaseFor(IAndroidTarget target);
+    boolean canRunOn(IAndroidTarget target);
 
     /**
      * Returns a string able to uniquely identify a target.
index 035df21..63a117d 100644 (file)
@@ -191,7 +191,7 @@ final class PlatformTarget implements IAndroidTarget {
         return NO_USB_ID;
     }
 
-    public boolean isCompatibleBaseFor(IAndroidTarget target) {
+    public boolean canRunOn(IAndroidTarget target) {
         // basic test
         if (target == this) {
             return true;
index 4d4199f..5ed9751 100755 (executable)
@@ -123,7 +123,7 @@ public class MockAddonPackage extends AddonPackage {
             return false;\r
         }\r
 \r
-        public boolean isCompatibleBaseFor(IAndroidTarget target) {\r
+        public boolean canRunOn(IAndroidTarget target) {\r
             throw new UnsupportedOperationException("Implement this as needed for tests");\r
         }\r
 \r
index b840b82..8453e4e 100755 (executable)
@@ -156,7 +156,7 @@ public class MockPlatformPackage extends PlatformPackage {
             return true;\r
         }\r
 \r
-        public boolean isCompatibleBaseFor(IAndroidTarget target) {\r
+        public boolean canRunOn(IAndroidTarget target) {\r
             throw new UnsupportedOperationException("Implement this as needed for tests");\r
         }\r
 \r
index b97d8fb..91ada7e 100644 (file)
@@ -169,7 +169,7 @@ public final class AvdSelector {
 
         public boolean accept(AvdInfo avd) {
             if (avd != null) {
-                return mTarget.isCompatibleBaseFor(avd.getTarget());
+                return mTarget.canRunOn(avd.getTarget());
             }
 
             return false;