Esempio n. 1
0
  private int getApiVersion(Element usesSdk, String attribute, int defaultApiLevel) {
    String valueString = null;
    if (usesSdk.hasAttributeNS(NS_RESOURCES, attribute)) {
      valueString = usesSdk.getAttributeNS(NS_RESOURCES, attribute);
    }

    if (valueString != null) {
      int apiLevel = -1;
      try {
        apiLevel = Integer.valueOf(valueString);
      } catch (NumberFormatException e) {
        // Handle codename
        if (Sdk.getCurrent() != null) {
          IAndroidTarget target =
              Sdk.getCurrent().getTargetFromHashString("android-" + valueString); // $NON-NLS-1$
          if (target != null) {
            // codename future API level is current api + 1
            apiLevel = target.getVersion().getApiLevel() + 1;
          }
        }

        if (usesSdk.getTagName().equals(ATTRIBUTE_MIN_SDK_VERSION)) {
          mMinSdkName = valueString;
        }
      }

      return apiLevel;
    }

    return defaultApiLevel;
  }
      // The default attributes must be determined dynamically since whether
      // we use match_parent or fill_parent depends on the API level of the
      // project
      @Override
      String getDefaultAttrs(IProject project, String root) {
        Sdk currentSdk = Sdk.getCurrent();
        String fill = VALUE_FILL_PARENT;
        if (currentSdk != null) {
          IAndroidTarget target = currentSdk.getTarget(project);
          // fill_parent was renamed match_parent in API level 8
          if (target != null && target.getVersion().getApiLevel() >= 8) {
            fill = VALUE_MATCH_PARENT;
          }
        }

        // Only set "vertical" orientation of LinearLayouts by default;
        // for GridLayouts for example we want to rely on the real default
        // of the layout
        String size =
            String.format(
                "android:layout_width=\"%1$s\"\n" //$NON-NLS-1$
                    + "android:layout_height=\"%2$s\"", //$NON-NLS-1$
                fill, fill);
        if (LINEAR_LAYOUT.equals(root)) {
          return "android:orientation=\"vertical\"\n" + size; // $NON-NLS-1$
        } else {
          return size;
        }
      }
Esempio n. 3
0
  private ResourceResolver getResourceResolver(Configuration configuration) {
    ResourceResolver resourceResolver = mResourceResolver.get();
    if (resourceResolver != null) {
      return resourceResolver;
    }

    GraphicalEditorPart graphicalEditor = mCanvas.getEditorDelegate().getGraphicalEditor();
    String theme = configuration.getTheme();
    if (theme == null) {
      return null;
    }

    Map<ResourceType, Map<String, ResourceValue>> configuredFrameworkRes = null;
    Map<ResourceType, Map<String, ResourceValue>> configuredProjectRes = null;

    FolderConfiguration config = configuration.getFullConfig();
    IAndroidTarget target = graphicalEditor.getRenderingTarget();
    ResourceRepository frameworkRes = null;
    if (target != null) {
      Sdk sdk = Sdk.getCurrent();
      if (sdk == null) {
        return null;
      }
      AndroidTargetData data = sdk.getTargetData(target);

      if (data != null) {
        // TODO: SHARE if possible
        frameworkRes = data.getFrameworkResources();
        configuredFrameworkRes = frameworkRes.getConfiguredResources(config);
      } else {
        return null;
      }
    } else {
      return null;
    }
    assert configuredFrameworkRes != null;

    // get the resources of the file's project.
    ProjectResources projectRes =
        ResourceManager.getInstance().getProjectResources(graphicalEditor.getProject());
    configuredProjectRes = projectRes.getConfiguredResources(config);

    if (!theme.startsWith(PREFIX_RESOURCE_REF)) {
      if (frameworkRes.hasResourceItem(ANDROID_STYLE_RESOURCE_PREFIX + theme)) {
        theme = ANDROID_STYLE_RESOURCE_PREFIX + theme;
      } else {
        theme = STYLE_RESOURCE_PREFIX + theme;
      }
    }

    resourceResolver =
        ResourceResolver.create(
            configuredProjectRes,
            configuredFrameworkRes,
            ResourceHelper.styleToTheme(theme),
            ResourceHelper.isProjectStyle(theme));
    mResourceResolver = new SoftReference<ResourceResolver>(resourceResolver);
    return resourceResolver;
  }
Esempio n. 4
0
  private void setExistingProject(IProject project) {
    mValues.testedProject = project;

    // Try to update the application, package, sdk target and minSdkVersion accordingly
    if (project != null
        && (!mValues.applicationNameModifiedByUser
            || !mValues.packageNameModifiedByUser
            || !mValues.targetModifiedByUser
            || !mValues.minSdkModifiedByUser)) {
      ManifestData manifestData = AndroidManifestHelper.parseForData(project);
      if (manifestData != null) {
        String appName = String.format("%1$sTest", project.getName());
        String packageName = manifestData.getPackage();
        String minSdkVersion = manifestData.getMinSdkVersionString();
        IAndroidTarget sdkTarget = null;
        if (Sdk.getCurrent() != null) {
          sdkTarget = Sdk.getCurrent().getTarget(project);
        }

        if (packageName == null) {
          packageName = ""; // $NON-NLS-1$
        }
        mLastExistingPackageName = packageName;

        if (!mValues.projectNameModifiedByUser) {
          mValues.projectName = appName;
        }

        if (!mValues.applicationNameModifiedByUser) {
          mValues.applicationName = appName;
        }

        if (!mValues.packageNameModifiedByUser) {
          packageName += ".test"; // $NON-NLS-1$
          mValues.packageName = packageName;
        }

        if (!mValues.targetModifiedByUser && sdkTarget != null) {
          mValues.target = sdkTarget;
        }

        if (!mValues.minSdkModifiedByUser) {
          if (minSdkVersion != null || sdkTarget != null) {
            mValues.minSdk = minSdkVersion;
          }
          if (sdkTarget == null) {
            mValues.updateSdkTargetToMatchMinSdkVersion();
          }
        }
      }
    }

    updateTestTargetPackageField(mLastExistingPackageName);
  }
Esempio n. 5
0
 /**
  * Returns the Android SDK.
  *
  * @return the SDK instance or null
  */
 public static final Sdk getAndroidSdk() {
   Sdk sdk;
   String s = AdtPlugin.getOsSdkFolder();
   if (s.isEmpty()) {
     return null;
   }
   if (Sdk.getCurrent() == null) {
     sdk = Sdk.loadSdk(s);
   } else {
     sdk = Sdk.getCurrent();
   }
   return sdk;
 }
  /**
   * Validates the fields, displays errors and warnings. Enables the finish button if there are no
   * errors.
   */
  private void validatePage() {
    String error = null;
    String warning = null;

    // -- validate type
    TypeInfo type = mValues.type;
    if (error == null) {
      if (type == null) {
        error = "One of the types must be selected (e.g. layout, values, etc.)";
      }
    }

    // -- validate project
    if (mValues.project == null) {
      error = "Please select an Android project.";
    }

    // -- validate type API level
    if (error == null) {
      IAndroidTarget target = Sdk.getCurrent().getTarget(mValues.project);
      int currentApiLevel = 1;
      if (target != null) {
        currentApiLevel = target.getVersion().getApiLevel();
      }

      assert type != null;
      if (type.getTargetApiLevel() > currentApiLevel) {
        error =
            "The API level of the selected type (e.g. AppWidget, etc.) is not "
                + "compatible with the API level of the project.";
      }
    }

    // -- validate filename
    if (error == null) {
      String fileName = mValues.getFileName();
      assert type != null;
      ResourceFolderType folderType = type.getResFolderType();
      error = ResourceNameValidator.create(true, folderType).isValid(fileName);
    }

    // -- validate destination file doesn't exist
    if (error == null) {
      IFile file = mValues.getDestinationFile();
      if (file != null && file.exists()) {
        warning = "The destination file already exists";
      }
    }

    // -- update UI & enable finish if there's no error
    setPageComplete(error == null);
    if (error != null) {
      setMessage(error, IMessageProvider.ERROR);
    } else if (warning != null) {
      setMessage(warning, IMessageProvider.WARNING);
    } else {
      setErrorMessage(null);
      setMessage(null);
    }
  }
  /* (non-Javadoc)
   * @see org.eclipse.debug.ui.ILaunchShortcut#launch(
   * org.eclipse.jface.viewers.ISelection, java.lang.String)
   */
  @Override
  public void launch(ISelection selection, String mode) {
    if (selection instanceof IStructuredSelection) {

      // get the object and the project from it
      IStructuredSelection structSelect = (IStructuredSelection) selection;
      Object o = structSelect.getFirstElement();

      // get the first (and normally only) element
      if (o instanceof IAdaptable) {
        IResource r = (IResource) ((IAdaptable) o).getAdapter(IResource.class);

        // get the project from the resource
        if (r != null) {
          IProject project = r.getProject();

          if (project != null) {
            ProjectState state = Sdk.getProjectState(project);
            if (state != null && state.isLibrary()) {

              MessageDialog.openError(
                  PlatformUI.getWorkbench().getDisplay().getActiveShell(),
                  "Android Launch",
                  "Android library projects cannot be launched.");
            } else {
              // and launch
              launch(project, mode);
            }
          }
        }
      }
    }
  }
  @Override
  public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    if (pm.isCanceled()) {
      return null;
    }
    if (!getArguments().getUpdateReferences()) {
      return null;
    }
    CompositeChange result = new CompositeChange(getName());
    result.markAsSynthetic();

    addManifestFileChanges(result);

    // Update layout files; we don't just need to react to custom view
    // changes, we need to update fragment references and even tool:context activity
    // references
    addLayoutFileChanges(mProject, result);

    // Also update in dependent projects
    ProjectState projectState = Sdk.getProjectState(mProject);
    if (projectState != null) {
      Collection<ProjectState> parentProjects = projectState.getFullParentProjects();
      for (ProjectState parentProject : parentProjects) {
        IProject project = parentProject.getProject();
        addLayoutFileChanges(project, result);
      }
    }

    return (result.getChildren().length == 0) ? null : result;
  }
Esempio n. 9
0
 /**
  * Returns the target provided by the Google (Google Map implementation included).
  *
  * @param sdk
  * @return
  */
 private static final IAndroidTarget getGoogleTarget(Sdk sdk, int targetNumber) {
   for (IAndroidTarget target : sdk.getTargets()) {
     if (checkTargetNumber(target, targetNumber) && checkGoogleVendor(target)) {
       return target;
     }
   }
   return null;
 }
  @Override
  public void run(IAction action) {
    final Sdk sdk = Sdk.getCurrent();
    if (sdk != null) {
      // Although orthogonal to the avd manager action, this is a good time
      // to check whether the SDK has changed on disk.
      AdtPlugin.getDefault().refreshSdk();

      // Runs the updater window, directing all logs to the ADT console.
      AvdManagerWindow window =
          new AvdManagerWindow(
              AdtPlugin.getDisplay().getActiveShell(),
              new AdtConsoleSdkLog(),
              sdk.getSdkLocation(),
              AvdInvocationContext.IDE);
      window.open();
    } else {
      AdtPlugin.displayError(
          "Android SDK", "Location of the Android SDK has not been setup in the preferences.");
    }
  }
Esempio n. 11
0
  /**
   * Computes the minimum SDK and target SDK versions for the project
   *
   * @param project the project to look up the versions for
   * @return a pair of (minimum SDK, target SDK) versions, never null
   */
  @NonNull
  public static Pair<Integer, Integer> computeSdkVersions(IProject project) {
    int mMinSdkVersion = 1;
    int mTargetSdkVersion = 1;

    IAbstractFile manifestFile = AndroidManifest.getManifest(new IFolderWrapper(project));
    if (manifestFile != null) {
      try {
        Object value = AndroidManifest.getMinSdkVersion(manifestFile);
        mMinSdkVersion = 1; // Default case if missing
        if (value instanceof Integer) {
          mMinSdkVersion = ((Integer) value).intValue();
        } else if (value instanceof String) {
          // handle codename, only if we can resolve it.
          if (Sdk.getCurrent() != null) {
            IAndroidTarget target =
                Sdk.getCurrent().getTargetFromHashString("android-" + value); // $NON-NLS-1$
            if (target != null) {
              // codename future API level is current api + 1
              mMinSdkVersion = target.getVersion().getApiLevel() + 1;
            }
          }
        }

        Integer i = AndroidManifest.getTargetSdkVersion(manifestFile);
        if (i == null) {
          mTargetSdkVersion = mMinSdkVersion;
        } else {
          mTargetSdkVersion = i.intValue();
        }
      } catch (XPathExpressionException e) {
        // do nothing we'll use 1 below.
      } catch (StreamException e) {
        // do nothing we'll use 1 below.
      }
    }

    return Pair.of(mMinSdkVersion, mTargetSdkVersion);
  }
  /**
   * Add the available types in the type combobox, based on whether they are available for the
   * current SDK.
   *
   * <p>A type is available either if: - if mProject is null, API level 1 is considered valid - if
   * mProject is !null, the project->target->API must be >= to the type's API level.
   */
  private void updateAvailableTypes() {
    IProject project = mValues.project;
    IAndroidTarget target = project != null ? Sdk.getCurrent().getTarget(project) : null;
    int currentApiLevel = 1;
    if (target != null) {
      currentApiLevel = target.getVersion().getApiLevel();
    }

    List<String> items = new ArrayList<String>(sTypes.length);
    List<TypeInfo> types = new ArrayList<TypeInfo>(sTypes.length);
    for (int i = 0, n = sTypes.length; i < n; i++) {
      TypeInfo type = sTypes[i];
      if (type.getTargetApiLevel() <= currentApiLevel) {
        items.add(type.getUiName());
        types.add(type);
      }
    }
    mTypeCombo.setItems(items.toArray(new String[items.size()]));
    mTypeCombo.setData(types.toArray(new TypeInfo[types.size()]));
  }
Esempio n. 13
0
  /** Render immediately */
  private void renderSync() {
    GraphicalEditorPart editor = mCanvas.getEditorDelegate().getGraphicalEditor();
    if (editor.getReadyLayoutLib(false /*displayError*/) == null) {
      // Don't attempt to render when there is no ready layout library: most likely
      // the targets are loading/reloading.
      return;
    }

    disposeThumbnail();

    Configuration configuration =
        mAlternateInput != null && mAlternateConfiguration != null
            ? mAlternateConfiguration
            : mConfiguration;
    ResourceResolver resolver = getResourceResolver(configuration);
    RenderService renderService = RenderService.create(editor, configuration, resolver);

    if (mIncludedWithin != null) {
      renderService.setIncludedWithin(mIncludedWithin);
    }

    if (mAlternateInput != null) {
      IAndroidTarget target = editor.getRenderingTarget();
      AndroidTargetData data = null;
      if (target != null) {
        Sdk sdk = Sdk.getCurrent();
        if (sdk != null) {
          data = sdk.getTargetData(target);
        }
      }

      // Construct UI model from XML
      DocumentDescriptor documentDescriptor;
      if (data == null) {
        documentDescriptor = new DocumentDescriptor("temp", null); // $NON-NLS-1$
      } else {
        documentDescriptor = data.getLayoutDescriptors().getDescriptor();
      }
      UiDocumentNode model = (UiDocumentNode) documentDescriptor.createUiNode();
      model.setEditor(mCanvas.getEditorDelegate().getEditor());
      model.setUnknownDescriptorProvider(editor.getModel().getUnknownDescriptorProvider());

      Document document = DomUtilities.getDocument(mAlternateInput);
      if (document == null) {
        mError = "No document";
        createErrorThumbnail();
        return;
      }
      model.loadFromXmlNode(document);
      renderService.setModel(model);
    } else {
      renderService.setModel(editor.getModel());
    }
    RenderLogger log = new RenderLogger(getDisplayName());
    renderService.setLog(log);
    RenderSession session = renderService.createRenderSession();
    Result render = session.render(1000);

    if (DUMP_RENDER_DIAGNOSTICS) {
      if (log.hasProblems() || !render.isSuccess()) {
        AdtPlugin.log(
            IStatus.ERROR,
            "Found problems rendering preview "
                + getDisplayName()
                + ": "
                + render.getErrorMessage()
                + " : "
                + log.getProblems(false));
        Throwable exception = render.getException();
        if (exception != null) {
          AdtPlugin.log(exception, "Failure rendering preview " + getDisplayName());
        }
      }
    }

    if (render.isSuccess()) {
      mError = null;
    } else {
      mError = render.getErrorMessage();
      if (mError == null) {
        mError = "";
      }
    }

    if (render.getStatus() == Status.ERROR_TIMEOUT) {
      // TODO: Special handling? schedule update again later
      return;
    }
    if (render.isSuccess()) {
      BufferedImage image = session.getImage();
      if (image != null) {
        createThumbnail(image);
      }
    }

    if (mError != null) {
      createErrorThumbnail();
    }
  }
  public void run(IAction action) {
    final Sdk sdk = Sdk.getCurrent();
    if (sdk != null) {

      // Runs the updater window, directing all logs to the ADT console.

      SdkUpdaterWindow window =
          new SdkUpdaterWindow(
              AdtPlugin.getDisplay().getActiveShell(),
              new AdtConsoleSdkLog(),
              sdk.getSdkLocation(),
              SdkInvocationContext.IDE);

      ISdkChangeListener listener =
          new ISdkChangeListener() {
            public void onSdkLoaded() {
              // Ignore initial load of the SDK.
            }

            /**
             * Unload all we can from the SDK before new packages are installed. Typically we need
             * to get rid of references to dx from platform-tools and to any platform resource data.
             *
             * <p>{@inheritDoc}
             */
            public void preInstallHook() {

              // TODO we need to unload as much of as SDK as possible. Otherwise
              // on Windows we end up with Eclipse locking some files and we can't
              // replace them.
              //
              // At this point, we know what the user wants to install so it would be
              // possible to pass in flags to know what needs to be unloaded. Typically
              // we need to:
              // - unload dex if platform-tools is going to be updated. There's a vague
              //   attempt below at removing any references to dex and GCing. Seems
              //   to do the trick.
              // - unload any target that is going to be updated since it may have
              //   resource data used by a current layout editor (e.g. data/*.ttf
              //   and various data/res/*.xml).
              //
              // Most important we need to make sure there isn't a build going on
              // and if there is one, either abort it or wait for it to complete and
              // then we want to make sure we don't get any attempt to use the SDK
              // before the postInstallHook is called.

              if (sdk != null) {
                sdk.unloadTargetData(true /*preventReload*/);

                DexWrapper dx = sdk.getDexWrapper();
                dx.unload();
              }
            }

            /**
             * Nothing to do. We'll reparse the SDK later in onSdkReload.
             *
             * <p>{@inheritDoc}
             */
            public void postInstallHook() {}

            /**
             * Reparse the SDK in case anything was add/removed.
             *
             * <p>{@inheritDoc}
             */
            public void onSdkReload() {
              AdtPlugin.getDefault().reparseSdk();
            }
          };

      window.addListener(listener);
      window.open();
    } else {
      AdtPlugin.displayError(
          "Android SDK", "Location of the Android SDK has not been setup in the preferences.");
    }
  }
Esempio n. 15
0
  private Pair<List<String>, List<String>> findViews(final boolean layoutsOnly) {
    final Set<String> customViews = new HashSet<String>();
    final Set<String> thirdPartyViews = new HashSet<String>();

    ProjectState state = Sdk.getProjectState(mProject);
    final List<IProject> libraries =
        state != null ? state.getFullLibraryProjects() : Collections.<IProject>emptyList();

    SearchRequestor requestor =
        new SearchRequestor() {
          @Override
          public void acceptSearchMatch(SearchMatch match) throws CoreException {
            // Ignore matches in comments
            if (match.isInsideDocComment()) {
              return;
            }

            Object element = match.getElement();
            if (element instanceof ResolvedBinaryType) {
              // Third party view
              ResolvedBinaryType type = (ResolvedBinaryType) element;
              IPackageFragment fragment = type.getPackageFragment();
              IPath path = fragment.getPath();
              String last = path.lastSegment();
              // Filter out android.jar stuff
              if (last.equals(FN_FRAMEWORK_LIBRARY)) {
                return;
              }
              if (!isValidView(type, layoutsOnly)) {
                return;
              }

              IProject matchProject = match.getResource().getProject();
              if (mProject == matchProject || libraries.contains(matchProject)) {
                String fqn = type.getFullyQualifiedName();
                thirdPartyViews.add(fqn);
              }
            } else if (element instanceof ResolvedSourceType) {
              // User custom view
              IProject matchProject = match.getResource().getProject();
              if (mProject == matchProject || libraries.contains(matchProject)) {
                ResolvedSourceType type = (ResolvedSourceType) element;
                if (!isValidView(type, layoutsOnly)) {
                  return;
                }
                String fqn = type.getFullyQualifiedName();
                fqn = fqn.replace('$', '.');
                customViews.add(fqn);
              }
            }
          }
        };
    try {
      IJavaProject javaProject = BaseProjectHelper.getJavaProject(mProject);
      if (javaProject != null) {
        String className = layoutsOnly ? CLASS_VIEWGROUP : CLASS_VIEW;
        IType viewType = javaProject.findType(className);
        if (viewType != null) {
          IJavaSearchScope scope = SearchEngine.createHierarchyScope(viewType);
          SearchParticipant[] participants =
              new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()};
          int matchRule = SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE;

          SearchPattern pattern =
              SearchPattern.createPattern(
                  "*", IJavaSearchConstants.CLASS, IJavaSearchConstants.IMPLEMENTORS, matchRule);
          SearchEngine engine = new SearchEngine();
          engine.search(pattern, participants, scope, requestor, new NullProgressMonitor());
        }
      }
    } catch (CoreException e) {
      AdtPlugin.log(e, null);
    }

    List<String> custom = new ArrayList<String>(customViews);
    List<String> thirdParty = new ArrayList<String>(thirdPartyViews);

    if (!layoutsOnly) {
      // Update our cached answers (unless we were filtered on only layouts)
      mCustomViews = custom;
      mThirdPartyViews = thirdParty;
    }

    return Pair.of(custom, thirdParty);
  }
  static void show(final ConfigurationChooser chooser, ToolItem combo) {
    Configuration configuration = chooser.getConfiguration();
    Device current = configuration.getDevice();
    Menu menu = new Menu(chooser.getShell(), SWT.POP_UP);

    List<Device> deviceList = chooser.getDeviceList();
    Sdk sdk = Sdk.getCurrent();
    if (sdk != null) {
      AvdManager avdManager = sdk.getAvdManager();
      if (avdManager != null) {
        boolean separatorNeeded = false;
        AvdInfo[] avds = avdManager.getValidAvds();
        for (AvdInfo avd : avds) {
          for (Device device : deviceList) {
            if (device.getManufacturer().equals(avd.getDeviceManufacturer())
                && device.getName().equals(avd.getDeviceName())) {
              separatorNeeded = true;
              MenuItem item = new MenuItem(menu, SWT.CHECK);
              item.setText(avd.getName());
              item.setSelection(current == device);

              item.addSelectionListener(new DeviceMenuListener(chooser, device));
            }
          }
        }

        if (separatorNeeded) {
          @SuppressWarnings("unused")
          MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
        }
      }
    }

    // Group the devices by manufacturer, then put them in the menu.
    // If we don't have anything but Nexus devices, group them together rather than
    // make many manufacturer submenus.
    boolean haveNexus = false;
    boolean haveNonNexus = false;
    if (!deviceList.isEmpty()) {
      Map<String, List<Device>> manufacturers = new TreeMap<String, List<Device>>();
      for (Device device : deviceList) {
        List<Device> devices;
        if (isNexus(device)) {
          haveNexus = true;
        } else if (!isGeneric(device)) {
          haveNonNexus = true;
        }
        if (manufacturers.containsKey(device.getManufacturer())) {
          devices = manufacturers.get(device.getManufacturer());
        } else {
          devices = new ArrayList<Device>();
          manufacturers.put(device.getManufacturer(), devices);
        }
        devices.add(device);
      }
      if (haveNonNexus) {
        for (List<Device> devices : manufacturers.values()) {
          Menu manufacturerMenu = menu;
          if (manufacturers.size() > 1) {
            MenuItem item = new MenuItem(menu, SWT.CASCADE);
            item.setText(devices.get(0).getManufacturer());
            manufacturerMenu = new Menu(menu);
            item.setMenu(manufacturerMenu);
          }
          for (final Device device : devices) {
            MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.CHECK);
            deviceItem.setText(getGenericLabel(device));
            deviceItem.setSelection(current == device);
            deviceItem.addSelectionListener(new DeviceMenuListener(chooser, device));
          }
        }
      } else {
        List<Device> nexus = new ArrayList<Device>();
        List<Device> generic = new ArrayList<Device>();
        if (haveNexus) {
          // Nexus
          for (List<Device> devices : manufacturers.values()) {
            for (Device device : devices) {
              if (isNexus(device)) {
                if (device.getManufacturer().equals(GENERIC)) {
                  generic.add(device);
                } else {
                  nexus.add(device);
                }
              } else {
                generic.add(device);
              }
            }
          }
        }

        if (!nexus.isEmpty()) {
          sortNexusList(nexus);
          for (final Device device : nexus) {
            MenuItem item = new MenuItem(menu, SWT.CHECK);
            item.setText(getNexusLabel(device));
            item.setSelection(current == device);
            item.addSelectionListener(new DeviceMenuListener(chooser, device));
          }

          @SuppressWarnings("unused")
          MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
        }

        // Generate the generic menu.
        Collections.reverse(generic);
        for (final Device device : generic) {
          MenuItem item = new MenuItem(menu, SWT.CHECK);
          item.setText(getGenericLabel(device));
          item.setSelection(current == device);
          item.addSelectionListener(new DeviceMenuListener(chooser, device));
        }
      }
    }

    @SuppressWarnings("unused")
    MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);

    ConfigurationMenuListener.addTogglePreviewModeAction(
        menu, "Preview All Screens", chooser, RenderPreviewMode.SCREENS);

    Rectangle bounds = combo.getBounds();
    Point location = new Point(bounds.x, bounds.y + bounds.height);
    location = combo.getParent().toDisplay(location);
    menu.setLocation(location.x, location.y);
    menu.setVisible(true);
  }
  /** Initialize the root values of the type infos based on the current framework values. */
  private void initializeRootValues() {
    IProject project = mValues.project;
    for (TypeInfo type : sTypes) {
      // Clear all the roots for this type
      ArrayList<String> roots = type.getRoots();
      if (roots.size() > 0) {
        roots.clear();
      }

      // depending of the type of the seed, initialize the root in different ways
      Object rootSeed = type.getRootSeed();

      if (rootSeed instanceof String) {
        // The seed is a single string, Add it as-is.
        roots.add((String) rootSeed);
      } else if (rootSeed instanceof String[]) {
        // The seed is an array of strings. Add them as-is.
        for (String value : (String[]) rootSeed) {
          roots.add(value);
        }
      } else if (rootSeed instanceof Integer && project != null) {
        // The seed is a descriptor reference defined in AndroidTargetData.DESCRIPTOR_*
        // In this case add all the children element descriptors defined, recursively,
        // and avoid infinite recursion by keeping track of what has already been added.

        // Note: if project is null, the root list will be empty since it has been
        // cleared above.

        // get the AndroidTargetData from the project
        IAndroidTarget target = null;
        AndroidTargetData data = null;

        target = Sdk.getCurrent().getTarget(project);
        if (target == null) {
          // A project should have a target. The target can be missing if the project
          // is an old project for which a target hasn't been affected or if the
          // target no longer exists in this SDK. Simply log the error and dismiss.

          AdtPlugin.log(
              IStatus.INFO,
              "NewXmlFile wizard: no platform target for project %s", //$NON-NLS-1$
              project.getName());
          continue;
        } else {
          data = Sdk.getCurrent().getTargetData(target);

          if (data == null) {
            // We should have both a target and its data.
            // However if the wizard is invoked whilst the platform is still being
            // loaded we can end up in a weird case where we have a target but it
            // doesn't have any data yet.
            // Lets log a warning and silently ignore this root.

            AdtPlugin.log(
                IStatus.INFO,
                "NewXmlFile wizard: no data for target %s, project %s", //$NON-NLS-1$
                target.getName(),
                project.getName());
            continue;
          }
        }

        IDescriptorProvider provider = data.getDescriptorProvider((Integer) rootSeed);
        ElementDescriptor descriptor = provider.getDescriptor();
        if (descriptor != null) {
          HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>();
          initRootElementDescriptor(roots, descriptor, visited);
        }

        // Sort alphabetically.
        Collections.sort(roots);
      }
    }
  }