/**
   * Check if any error occurred during initialization. If it did, display an error message.
   *
   * @return True if an error occurred, false if we should continue.
   */
  public boolean checkIfInitFailed() {
    if (mAvdManagerInitError != null) {
      String example;
      if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
        example = "%USERPROFILE%"; // $NON-NLS-1$
      } else {
        example = "~"; // $NON-NLS-1$
      }

      String error =
          String.format(
              "The AVD manager normally uses the user's profile directory to store "
                  + "AVD files. However it failed to find the default profile directory. "
                  + "\n"
                  + "To fix this, please set the environment variable ANDROID_SDK_HOME to "
                  + "a valid path such as \"%s\".",
              example);

      // We may not have any UI. Only display a dialog if there's a window shell available.
      if (mWindowShell != null && !mWindowShell.isDisposed()) {
        MessageDialog.openError(mWindowShell, "Android Virtual Devices Manager", error);
      } else {
        mSdkLog.error(null /* Throwable */, "%s", error); // $NON-NLS-1$
      }

      return true;
    }
    return false;
  }
 /**
  * Reloads the AVDs.
  *
  * <p>This does not notify the listeners.
  */
 public void reloadAvds() {
   // reload AVDs
   if (mAvdManager != null) {
     try {
       mAvdManager.reloadAvds(mSdkLog);
     } catch (AndroidLocationException e) {
       mSdkLog.error(e, null);
     }
   }
 }
  /**
   * Initializes the {@link SdkManager} and the {@link AvdManager}. Extracted so that we can
   * override this in unit tests.
   */
  @VisibleForTesting(visibility = Visibility.PRIVATE)
  protected void initSdk() {
    setSdkManager(SdkManager.createManager(mOsSdkRoot, mSdkLog));
    try {
      mAvdManager = null;
      mAvdManager = AvdManager.getInstance(mSdkManager, mSdkLog);
    } catch (AndroidLocationException e) {
      mSdkLog.error(e, "Unable to read AVDs: " + e.getMessage()); // $NON-NLS-1$

      // Note: we used to continue here, but the thing is that
      // mAvdManager==null so nothing is really going to work as
      // expected. Let's just display an error later in checkIfInitFailed()
      // and abort right there. This step is just too early in the SWT
      // setup process to display a message box yet.

      mAvdManagerInitError = e;
    }

    // notify listeners.
    broadcastOnSdkReload();
  }
  /**
   * Tries to update all the *existing* local packages. This version is intended to run without a
   * GUI and only outputs to the current {@link ILogger}.
   *
   * @param pkgFilter A list of {@link SdkRepoConstants#NODES} or {@link Package#installId()} or
   *     package indexes to limit the packages we can update or install. A null or empty list means
   *     to update everything possible.
   * @param includeAll True to list and install all packages, including obsolete ones.
   * @param dryMode True to check what would be updated/installed but do not actually download or
   *     install anything.
   * @return A list of archives that have been installed. Can be null if nothing was done.
   */
  public List<Archive> updateOrInstallAll_NoGUI(
      Collection<String> pkgFilter, boolean includeAll, boolean dryMode) {

    List<ArchiveInfo> archives = getRemoteArchives_NoGUI(includeAll);

    // Filter the selected archives to only keep the ones matching the filter
    if (pkgFilter != null && pkgFilter.size() > 0 && archives != null && archives.size() > 0) {
      // Map filter types to an SdkRepository Package type,
      // e.g. create a map "platform" => PlatformPackage.class
      HashMap<String, Class<? extends Package>> pkgMap =
          new HashMap<String, Class<? extends Package>>();

      mapFilterToPackageClass(pkgMap, SdkRepoConstants.NODES);
      mapFilterToPackageClass(pkgMap, SdkAddonConstants.NODES);

      // Prepare a map install-id => package instance
      HashMap<String, Package> installIdMap = new HashMap<String, Package>();
      for (ArchiveInfo ai : archives) {
        Archive a = ai.getNewArchive();
        if (a != null) {
          Package p = a.getParentPackage();
          if (p != null) {
            String id = p.installId();
            if (id != null && id.length() > 0 && !installIdMap.containsKey(id)) {
              installIdMap.put(id, p);
            }
          }
        }
      }

      // Now intersect this with the pkgFilter requested by the user, in order to
      // only keep the classes that the user wants to install.
      // We also create a set with the package indices requested by the user
      // and a set of install-ids requested by the user.

      HashSet<Class<? extends Package>> userFilteredClasses =
          new HashSet<Class<? extends Package>>();
      SparseIntArray userFilteredIndices = new SparseIntArray();
      Set<String> userFilteredInstallIds = new HashSet<String>();

      for (String type : pkgFilter) {
        if (installIdMap.containsKey(type)) {
          userFilteredInstallIds.add(type);

        } else if (type.replaceAll("[0-9]+", "").length() == 0) { // $NON-NLS-1$ //$NON-NLS-2$
          // An all-digit number is a package index requested by the user.
          int index = Integer.parseInt(type);
          userFilteredIndices.put(index, index);

        } else if (pkgMap.containsKey(type)) {
          userFilteredClasses.add(pkgMap.get(type));

        } else {
          // This should not happen unless there's a mismatch in the package map.
          mSdkLog.error(null, "Ignoring unknown package filter '%1$s'", type);
        }
      }

      // we don't need the maps anymore
      pkgMap = null;
      installIdMap = null;

      // Now filter the remote archives list to keep:
      // - any package which class matches userFilteredClasses
      // - any package index which matches userFilteredIndices
      // - any package install id which matches userFilteredInstallIds

      int index = 1;
      for (Iterator<ArchiveInfo> it = archives.iterator(); it.hasNext(); ) {
        boolean keep = false;
        ArchiveInfo ai = it.next();
        Archive a = ai.getNewArchive();
        if (a != null) {
          Package p = a.getParentPackage();
          if (p != null) {
            if (userFilteredInstallIds.contains(p.installId())
                || userFilteredClasses.contains(p.getClass())
                || userFilteredIndices.get(index) > 0) {
              keep = true;
            }

            index++;
          }
        }

        if (!keep) {
          it.remove();
        }
      }

      if (archives.size() == 0) {
        mSdkLog.info(
            LineUtil.reflowLine(
                "Warning: The package filter removed all packages. There is nothing to install.\nPlease consider trying to update again without a package filter.\n"));
        return null;
      }
    }

    if (archives != null && archives.size() > 0) {
      if (dryMode) {
        mSdkLog.info("Packages selected for install:\n");
        for (ArchiveInfo ai : archives) {
          Archive a = ai.getNewArchive();
          if (a != null) {
            Package p = a.getParentPackage();
            if (p != null) {
              mSdkLog.info("- %1$s\n", p.getShortDescription());
            }
          }
        }
        mSdkLog.info("\nDry mode is on so nothing is actually being installed.\n");
      } else {
        return installArchives(archives, NO_TOOLS_MSG);
      }
    } else {
      mSdkLog.info("There is nothing to install or update.\n");
    }

    return null;
  }
  /**
   * Reads the public.xml file in data/res/values/ for a given resource folder and builds up a map
   * of public resources.
   *
   * <p>This map is a subset of the full resource map that only contains framework resources that
   * are public.
   *
   * @param logger a logger to report issues to
   */
  public void loadPublicResources(@Nullable ILogger logger) {
    IAbstractFolder valueFolder = getResFolder().getFolder(SdkConstants.FD_RES_VALUES);
    if (valueFolder.exists() == false) {
      return;
    }

    IAbstractFile publicXmlFile = valueFolder.getFile("public.xml"); // $NON-NLS-1$
    if (publicXmlFile.exists()) {
      Reader reader = null;
      try {
        reader =
            new BufferedReader(new InputStreamReader(publicXmlFile.getContents(), Charsets.UTF_8));
        KXmlParser parser = new KXmlParser();
        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
        parser.setInput(reader);

        ResourceType lastType = null;
        String lastTypeName = "";
        while (true) {
          int event = parser.next();
          if (event == XmlPullParser.START_TAG) {
            // As of API 15 there are a number of "java-symbol" entries here
            if (!parser.getName().equals("public")) { // $NON-NLS-1$
              continue;
            }

            String name = null;
            String typeName = null;
            for (int i = 0, n = parser.getAttributeCount(); i < n; i++) {
              String attribute = parser.getAttributeName(i);

              if (attribute.equals("name")) { // $NON-NLS-1$
                name = parser.getAttributeValue(i);
                if (typeName != null) {
                  // Skip id attribute processing
                  break;
                }
              } else if (attribute.equals("type")) { // $NON-NLS-1$
                typeName = parser.getAttributeValue(i);
              }
            }

            if (name != null && typeName != null) {
              ResourceType type = null;
              if (typeName.equals(lastTypeName)) {
                type = lastType;
              } else {
                type = ResourceType.getEnum(typeName);
                lastType = type;
                lastTypeName = typeName;
              }
              if (type != null) {
                ResourceItem match = null;
                Map<String, ResourceItem> map = mResourceMap.get(type);
                if (map != null) {
                  match = map.get(name);
                }

                if (match != null) {
                  List<ResourceItem> publicList = mPublicResourceMap.get(type);
                  if (publicList == null) {
                    // Pick initial size for the list to hold the public
                    // resources. We could just use map.size() here,
                    // but they're usually much bigger; for example,
                    // in one platform version, there are 1500 drawables
                    // and 1200 strings but only 175 and 25 public ones
                    // respectively.
                    int size;
                    switch (type) {
                      case STYLE:
                        size = 500;
                        break;
                      case ATTR:
                        size = 1000;
                        break;
                      case DRAWABLE:
                        size = 200;
                        break;
                      case ID:
                        size = 50;
                        break;
                      case LAYOUT:
                      case COLOR:
                      case STRING:
                      case ANIM:
                      case INTERPOLATOR:
                        size = 30;
                        break;
                      default:
                        size = 10;
                        break;
                    }
                    publicList = new ArrayList<ResourceItem>(size);
                    mPublicResourceMap.put(type, publicList);
                  }

                  publicList.add(match);
                } else {
                  // log that there's a public resource that doesn't actually
                  // exist?
                }
              } else {
                // log that there was a reference to a typo that doesn't actually
                // exist?
              }
            }
          } else if (event == XmlPullParser.END_DOCUMENT) {
            break;
          }
        }
      } catch (Exception e) {
        if (logger != null) {
          logger.error(e, "Can't read and parse public attribute list");
        }
      } finally {
        if (reader != null) {
          try {
            reader.close();
          } catch (IOException e) {
            // Nothing to be done here - we don't care if it closed or not.
          }
        }
      }
    }

    // put unmodifiable list for all res type in the public resource map
    // this will simplify access
    for (ResourceType type : ResourceType.values()) {
      List<ResourceItem> list = mPublicResourceMap.get(type);
      if (list == null) {
        list = Collections.emptyList();
      } else {
        list = Collections.unmodifiableList(list);
      }

      // put the new list in the map
      mPublicResourceMap.put(type, list);
    }
  }
 @Override
 public void error(@Nullable Throwable t, @Nullable String msgFormat, Object... args) {
   mLogger.error(t, mGradleMessageRewriter.rewriteMessages(Strings.nullToEmpty(msgFormat)), args);
 }
Example #7
0
 protected void displayInitError(String error) {
   mSdkLog.error(null /* Throwable */, "%s", error); // $NON-NLS-1$
 }