/**
  * Returns the lastest build tools that's at least the passed version.
  *
  * @param fullRevision the minimum required build tools version.
  * @return the latest build tools.
  * @throws RuntimeException if the latest build tools is older than fullRevision.
  */
 static File getAapt(FullRevision fullRevision) {
   ILogger logger = new StdLogger(StdLogger.Level.VERBOSE);
   SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), logger);
   assert sdkManager != null;
   BuildToolInfo buildToolInfo = sdkManager.getLatestBuildTool();
   if (buildToolInfo == null || buildToolInfo.getRevision().compareTo(fullRevision) < 0) {
     throw new RuntimeException("Test requires build-tools " + fullRevision.toShortString());
   }
   return new File(buildToolInfo.getPath(BuildToolInfo.PathId.AAPT));
 }
Example #2
0
File: Main.java Project: MIPS/sdk
  /** Does the basic SDK parsing required for all actions */
  private void parseSdk() {
    mSdkManager = SdkManager.createManager(mOsSdkFolder, mSdkLog);

    if (mSdkManager == null) {
      errorAndExit("Unable to parse SDK content.");
    }
  }
Example #3
0
File: Main.java Project: MIPS/sdk
  /**
   * Converts a symbolic target name (such as those accepted by --target on the command-line) to an
   * internal target index id. A valid target name is either a numeric target id (> 0) or a target
   * hash string.
   *
   * <p>If the given target can't be mapped, {@link #INVALID_TARGET_ID} (0) is returned. It's up to
   * the caller to output an error.
   *
   * <p>On success, returns a value > 0.
   */
  private int resolveTargetName(String targetName) {

    if (targetName == null) {
      return INVALID_TARGET_ID;
    }

    targetName = targetName.trim();

    // Case of an integer number
    if (targetName.matches("[0-9]*")) {
      try {
        int n = Integer.parseInt(targetName);
        return n < 1 ? INVALID_TARGET_ID : n;
      } catch (NumberFormatException e) {
        // Ignore. Should not happen.
      }
    }

    // Let's try to find a platform or addon name.
    IAndroidTarget[] targets = mSdkManager.getTargets();
    for (int i = 0; i < targets.length; i++) {
      if (targetName.equals(targets[i].hashString())) {
        return i + 1;
      }
    }

    return INVALID_TARGET_ID;
  }
Example #4
0
File: Main.java Project: MIPS/sdk
  /**
   * Updates an existing Android project based on command-line parameters
   *
   * @param library whether the project is a library project.
   */
  private void updateProject(boolean library) {
    // get the target and try to resolve it.
    IAndroidTarget target = null;
    String targetStr = mSdkCommandLine.getParamTargetId();
    // For "update project" the target parameter is optional so having null is acceptable.
    // However if there's a value, it must be valid.
    if (targetStr != null) {
      IAndroidTarget[] targets = mSdkManager.getTargets();
      int targetId = resolveTargetName(targetStr);
      if (targetId == INVALID_TARGET_ID || targetId > targets.length) {
        errorAndExit(
            "Target id '%1$s' is not valid. Use '%2$s list targets' to get the target ids.",
            targetStr, SdkConstants.androidCmdName());
      }
      target = targets[targetId - 1]; // target id is 1-based
    }

    ProjectCreator creator = getProjectCreator();

    String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());

    String libraryPath =
        library ? null : mSdkCommandLine.getParamProjectLibrary(SdkCommandLine.OBJECT_PROJECT);

    creator.updateProject(projectDir, target, mSdkCommandLine.getParamName(), libraryPath);

    if (library == false) {
      boolean doSubProjects = mSdkCommandLine.getParamSubProject();
      boolean couldHaveDone = false;

      // If there are any sub-folders with a manifest, try to update them as projects
      // too. This will take care of updating any underlying test project even if the
      // user changed the folder name.
      File[] files = new File(projectDir).listFiles();
      if (files != null) {
        for (File dir : files) {
          if (dir.isDirectory() && new File(dir, SdkConstants.FN_ANDROID_MANIFEST_XML).isFile()) {
            if (doSubProjects) {
              creator.updateProject(
                  dir.getPath(), target, mSdkCommandLine.getParamName(), null /*libraryPath*/);
            } else {
              couldHaveDone = true;
            }
          }
        }
      }

      if (couldHaveDone) {
        mSdkLog.printf(
            "It seems that there are sub-projects. If you want to update them\nplease use the --%1$s parameter.\n",
            SdkCommandLine.KEY_SUBPROJECTS);
      }
    }
  }
 @NotNull
 public String getLocation() {
   String location = mySdkManager.getLocation();
   if (location.length() > 0) {
     char lastChar = location.charAt(location.length() - 1);
     if (lastChar == '/' || lastChar == File.separatorChar) {
       return location.substring(0, location.length() - 1);
     }
   }
   return location;
 }
Example #6
0
  /**
   * 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.getLocalSdk(), 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();
  }
 @NotNull
 public IAndroidTarget[] getTargets() {
   if (myTargets == null) {
     IAndroidTarget[] targets = mySdkManager.getTargets();
     if (targets != null) {
       myTargets = new IAndroidTarget[targets.length];
       for (int i = 0; i < targets.length; i++) {
         myTargets[i] = new MyTargetWrapper(targets[i]);
       }
     }
   }
   return myTargets;
 }
Example #8
0
File: Main.java Project: MIPS/sdk
  /** Creates a new Android project based on command-line parameters */
  private void createProject(boolean library) {
    String directObject =
        library ? SdkCommandLine.OBJECT_LIB_PROJECT : SdkCommandLine.OBJECT_PROJECT;

    // get the target and try to resolve it.
    int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
    IAndroidTarget[] targets = mSdkManager.getTargets();
    if (targetId == INVALID_TARGET_ID || targetId > targets.length) {
      errorAndExit(
          "Target id is not valid. Use '%s list targets' to get the target ids.",
          SdkConstants.androidCmdName());
    }
    IAndroidTarget target = targets[targetId - 1]; // target id is 1-based

    ProjectCreator creator = getProjectCreator();

    String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());

    String projectName = mSdkCommandLine.getParamName();
    String packageName = mSdkCommandLine.getParamProjectPackage(directObject);
    String activityName = null;
    if (library == false) {
      activityName = mSdkCommandLine.getParamProjectActivity();
    }

    if (projectName != null && !ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
      errorAndExit(
          "Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
          projectName, ProjectCreator.CHARS_PROJECT_NAME);
      return;
    }

    if (activityName != null && !ProjectCreator.RE_ACTIVITY_NAME.matcher(activityName).matches()) {
      errorAndExit(
          "Activity name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
          activityName, ProjectCreator.CHARS_ACTIVITY_NAME);
      return;
    }

    if (packageName != null && !ProjectCreator.RE_PACKAGE_NAME.matcher(packageName).matches()) {
      errorAndExit(
          "Package name '%1$s' contains invalid characters.\n"
              + "A package name must be constitued of two Java identifiers.\n"
              + "Each identifier allowed characters are: %2$s",
          packageName, ProjectCreator.CHARS_PACKAGE_NAME);
      return;
    }

    creator.createProject(
        projectDir, projectName, packageName, activityName, target, library, null /*pathToMain*/);
  }
Example #9
0
File: Main.java Project: MIPS/sdk
  /** Updates adb with the USB devices declared in the SDK add-ons. */
  private void updateAdb() {
    try {
      mSdkManager.updateAdb();

      mSdkLog.printf(
          "adb has been updated. You must restart adb with the following commands\n"
              + "\tadb kill-server\n"
              + "\tadb start-server\n");
    } catch (AndroidLocationException e) {
      errorAndExit(e.getMessage());
    } catch (IOException e) {
      errorAndExit(e.getMessage());
    }
  }
Example #10
0
  /**
   * Reloads the SDK content (targets).
   *
   * <p>This also reloads the AVDs in case their status changed.
   *
   * <p>This does not notify the listeners ({@link ISdkChangeListener}).
   */
  public void reloadSdk() {
    // reload SDK
    mSdkManager.reloadSdk(mSdkLog);

    // reload AVDs
    if (mAvdManager != null) {
      try {
        mAvdManager.reloadAvds(mSdkLog);
      } catch (AndroidLocationException e) {
        // FIXME
      }
    }

    mLocalSdkParser.clearPackages();

    // notify listeners
    broadcastOnSdkReload();
  }
Example #11
0
File: Main.java Project: MIPS/sdk
  /** Displays the list of available Targets (Platforms and Add-ons) */
  private void displayTargetList() {
    mSdkLog.printf("Available Android targets:\n");

    int index = 1;
    for (IAndroidTarget target : mSdkManager.getTargets()) {
      mSdkLog.printf("id: %1$d or \"%2$s\"\n", index, target.hashString());
      mSdkLog.printf("     Name: %s\n", target.getName());
      if (target.isPlatform()) {
        mSdkLog.printf("     Type: Platform\n");
        mSdkLog.printf("     API level: %s\n", target.getVersion().getApiString());
        mSdkLog.printf("     Revision: %d\n", target.getRevision());
      } else {
        mSdkLog.printf("     Type: Add-On\n");
        mSdkLog.printf("     Vendor: %s\n", target.getVendor());
        mSdkLog.printf("     Revision: %d\n", target.getRevision());
        if (target.getDescription() != null) {
          mSdkLog.printf("     Description: %s\n", target.getDescription());
        }
        mSdkLog.printf(
            "     Based on Android %s (API level %s)\n",
            target.getVersionName(), target.getVersion().getApiString());

        // display the optional libraries.
        IOptionalLibrary[] libraries = target.getOptionalLibraries();
        if (libraries != null) {
          mSdkLog.printf("     Libraries:\n");
          for (IOptionalLibrary library : libraries) {
            mSdkLog.printf("      * %1$s (%2$s)\n", library.getName(), library.getJarName());
            mSdkLog.printf(String.format("          %1$s\n", library.getDescription()));
          }
        }
      }

      // get the target skins
      displaySkinList(target, "     Skins: ");

      if (target.getUsbVendorId() != IAndroidTarget.NO_USB_ID) {
        mSdkLog.printf(
            "     Adds USB support for devices (Vendor: 0x%04X)\n", target.getUsbVendorId());
      }

      index++;
    }
  }
Example #12
0
File: Main.java Project: MIPS/sdk
  /** Creates a new AVD. This is a text based creation with command line prompt. */
  private void createAvd() {
    // find a matching target
    int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
    IAndroidTarget[] targets = mSdkManager.getTargets();

    if (targetId == INVALID_TARGET_ID || targetId > targets.length) {
      errorAndExit(
          "Target id is not valid. Use '%s list targets' to get the target ids.",
          SdkConstants.androidCmdName());
    }

    IAndroidTarget target = targets[targetId - 1]; // target id is 1-based

    try {
      boolean removePrevious = mSdkCommandLine.getFlagForce();
      AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);

      String avdName = mSdkCommandLine.getParamName();

      if (!AvdManager.RE_AVD_NAME.matcher(avdName).matches()) {
        errorAndExit(
            "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
            avdName, AvdManager.CHARS_AVD_NAME);
        return;
      }

      AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/);
      if (info != null) {
        if (removePrevious) {
          mSdkLog.warning(
              "Android Virtual Device '%s' already exists and will be replaced.", avdName);
        } else {
          errorAndExit(
              "Android Virtual Device '%s' already exists.\n"
                  + "Use --force if you want to replace it.",
              avdName);
          return;
        }
      }

      String paramFolderPath = mSdkCommandLine.getParamLocationPath();
      File avdFolder = null;
      if (paramFolderPath != null) {
        avdFolder = new File(paramFolderPath);
      } else {
        avdFolder = AvdManager.AvdInfo.getAvdFolder(avdName);
      }

      // Validate skin is either default (empty) or NNNxMMM or a valid skin name.
      Map<String, String> skinHardwareConfig = null;
      String skin = mSdkCommandLine.getParamSkin();
      if (skin != null && skin.length() == 0) {
        skin = null;
      }

      if (skin != null && target != null) {
        boolean valid = false;
        // Is it a know skin name for this target?
        for (String s : target.getSkins()) {
          if (skin.equalsIgnoreCase(s)) {
            skin = s; // Make skin names case-insensitive.
            valid = true;

            // get the hardware properties for this skin
            File skinFolder = avdManager.getSkinPath(skin, target);
            FileWrapper skinHardwareFile = new FileWrapper(skinFolder, AvdManager.HARDWARE_INI);
            if (skinHardwareFile.isFile()) {
              skinHardwareConfig = ProjectProperties.parsePropertyFile(skinHardwareFile, mSdkLog);
            }
            break;
          }
        }

        // Is it NNNxMMM?
        if (!valid) {
          valid = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin).matches();
        }

        if (!valid) {
          displaySkinList(target, "Valid skins: ");
          errorAndExit("'%s' is not a valid skin name or size (NNNxMMM)", skin);
          return;
        }
      }

      Map<String, String> hardwareConfig = null;
      if (target != null && target.isPlatform()) {
        try {
          hardwareConfig = promptForHardware(target, skinHardwareConfig);
        } catch (IOException e) {
          errorAndExit(e.getMessage());
        }
      }

      @SuppressWarnings("unused") // oldAvdInfo is never read, yet useful for debugging
      AvdInfo oldAvdInfo = null;
      if (removePrevious) {
        oldAvdInfo = avdManager.getAvd(avdName, false /*validAvdOnly*/);
      }

      @SuppressWarnings("unused") // newAvdInfo is never read, yet useful for debugging
      AvdInfo newAvdInfo =
          avdManager.createAvd(
              avdFolder,
              avdName,
              target,
              skin,
              mSdkCommandLine.getParamSdCard(),
              hardwareConfig,
              removePrevious,
              mSdkCommandLine.getFlagSnapshot(),
              mSdkLog);

    } catch (AndroidLocationException e) {
      errorAndExit(e.getMessage());
    }
  }
Example #13
0
File: Main.java Project: MIPS/sdk
  /** Creates a new Android test project based on command-line parameters */
  private void createTestProject() {

    String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());

    // first check the path of the parent project, and make sure it's valid.
    String pathToMainProject = mSdkCommandLine.getParamTestProjectMain();

    File parentProject = new File(pathToMainProject);
    if (parentProject.isAbsolute() == false) {
      // if the path is not absolute, we need to resolve it based on the
      // destination path of the project
      try {
        parentProject = new File(projectDir, pathToMainProject).getCanonicalFile();
      } catch (IOException e) {
        errorAndExit("Unable to resolve Main project's directory: %1$s", pathToMainProject);
        return; // help Eclipse static analyzer understand we'll never execute the rest.
      }
    }

    if (parentProject.isDirectory() == false) {
      errorAndExit("Main project's directory does not exist: %1$s", pathToMainProject);
      return;
    }

    // now look for a manifest in there
    File manifest = new File(parentProject, SdkConstants.FN_ANDROID_MANIFEST_XML);
    if (manifest.isFile() == false) {
      errorAndExit(
          "No AndroidManifest.xml file found in the main project directory: %1$s",
          parentProject.getAbsolutePath());
      return;
    }

    // now query the manifest for the package file.
    XPath xpath = AndroidXPathFactory.newXPath();
    String packageName, activityName;

    try {
      packageName =
          xpath.evaluate("/manifest/@package", new InputSource(new FileInputStream(manifest)));

      mSdkLog.printf("Found main project package: %1$s\n", packageName);

      // now get the name of the first activity we find
      activityName =
          xpath.evaluate(
              "/manifest/application/activity[1]/@android:name",
              new InputSource(new FileInputStream(manifest)));
      // xpath will return empty string when there's no match
      if (activityName == null || activityName.length() == 0) {
        activityName = null;
      } else {
        mSdkLog.printf("Found main project activity: %1$s\n", activityName);
      }
    } catch (FileNotFoundException e) {
      // this shouldn't happen as we test it above.
      errorAndExit("No AndroidManifest.xml file found in main project.");
      return; // this is not strictly needed because errorAndExit will stop the execution,
      // but this makes the java compiler happy, wrt to uninitialized variables.
    } catch (XPathExpressionException e) {
      // looks like the main manifest is not valid.
      errorAndExit("Unable to parse main project manifest to get information.");
      return; // this is not strictly needed because errorAndExit will stop the execution,
      // but this makes the java compiler happy, wrt to uninitialized variables.
    }

    // now get the target hash
    ProjectProperties p =
        ProjectProperties.load(parentProject.getAbsolutePath(), PropertyType.DEFAULT);
    if (p == null) {
      errorAndExit("Unable to load the main project's %1$s", PropertyType.DEFAULT.getFilename());
      return;
    }

    String targetHash = p.getProperty(ProjectProperties.PROPERTY_TARGET);
    if (targetHash == null) {
      errorAndExit("Couldn't find the main project target");
      return;
    }

    // and resolve it.
    IAndroidTarget target = mSdkManager.getTargetFromHashString(targetHash);
    if (target == null) {
      errorAndExit(
          "Unable to resolve main project target '%1$s'. You may want to install the platform in your SDK.",
          targetHash);
      return;
    }

    mSdkLog.printf("Found main project target: %1$s\n", target.getFullName());

    ProjectCreator creator = getProjectCreator();

    String projectName = mSdkCommandLine.getParamName();

    if (projectName != null && !ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
      errorAndExit(
          "Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
          projectName, ProjectCreator.CHARS_PROJECT_NAME);
      return;
    }

    creator.createProject(
        projectDir,
        projectName,
        packageName,
        activityName,
        target,
        false /* library*/,
        pathToMainProject);
  }
 @Nullable
 public IAndroidTarget findTargetByHashString(@NotNull String hashString) {
   final IAndroidTarget target = mySdkManager.getTargetFromHashString(hashString);
   return target != null ? new MyTargetWrapper(target) : null;
 }
  @Override
  public void execute() throws BuildException {
    Project antProject = getProject();

    // get the SDK location
    String sdkLocation = antProject.getProperty(ProjectProperties.PROPERTY_SDK);

    // check if it's valid and exists
    if (sdkLocation == null || sdkLocation.length() == 0) {
      throw new BuildException("SDK Location is not set.");
    }

    File sdk = new File(sdkLocation);
    if (sdk.isDirectory() == false) {
      throw new BuildException(String.format("SDK Location '%s' is not valid.", sdkLocation));
    }

    // get the target property value
    String targetHashString = antProject.getProperty(ProjectProperties.PROPERTY_TARGET);
    if (targetHashString == null) {
      throw new BuildException("Android Target is not set.");
    }

    // load up the sdk targets.
    final ArrayList<String> messages = new ArrayList<String>();
    SdkManager manager =
        SdkManager.createManager(
            sdkLocation,
            new ISdkLog() {
              public void error(Throwable t, String errorFormat, Object... args) {
                if (errorFormat != null) {
                  messages.add(String.format("Error: " + errorFormat, args));
                }
                if (t != null) {
                  messages.add("Error: " + t.getMessage());
                }
              }

              public void printf(String msgFormat, Object... args) {
                messages.add(String.format(msgFormat, args));
              }

              public void warning(String warningFormat, Object... args) {
                messages.add(String.format("Warning: " + warningFormat, args));
              }
            });

    if (manager == null) {
      // since we failed to parse the SDK, lets display the parsing output.
      for (String msg : messages) {
        System.out.println(msg);
      }
      throw new BuildException("Failed to parse SDK content.");
    }

    // resolve it
    IAndroidTarget androidTarget = manager.getTargetFromHashString(targetHashString);

    if (androidTarget == null) {
      throw new BuildException(String.format("Unable to resolve target '%s'", targetHashString));
    }

    // display it
    System.out.println("Project Target: " + androidTarget.getName());
    if (androidTarget.isPlatform() == false) {
      System.out.println("Vendor: " + androidTarget.getVendor());
    }
    System.out.println("Platform Version: " + androidTarget.getApiVersionName());
    System.out.println("API level: " + androidTarget.getApiVersionNumber());

    // sets up the properties to find android.jar/framework.aidl
    String androidJar = androidTarget.getPath(IAndroidTarget.ANDROID_JAR);
    String androidAidl = androidTarget.getPath(IAndroidTarget.ANDROID_AIDL);
    antProject.setProperty(PROPERTY_ANDROID_JAR, androidJar);
    antProject.setProperty(PROPERTY_ANDROID_AIDL, androidAidl);

    // sets up the boot classpath

    // create the Path object
    Path bootclasspath = new Path(antProject);

    // create a PathElement for the framework jar
    PathElement element = bootclasspath.createPathElement();
    element.setPath(androidJar);

    // create PathElement for each optional library.
    IOptionalLibrary[] libraries = androidTarget.getOptionalLibraries();
    if (libraries != null) {
      HashSet<String> visitedJars = new HashSet<String>();
      for (IOptionalLibrary library : libraries) {
        String jarPath = library.getJarPath();
        if (visitedJars.contains(jarPath) == false) {
          visitedJars.add(jarPath);

          element = bootclasspath.createPathElement();
          element.setPath(library.getJarPath());
        }
      }
    }

    // finally sets the path in the project with a reference
    antProject.addReference(REF_CLASSPATH, bootclasspath);

    // find the file to import, and import it.
    String templateFolder = androidTarget.getPath(IAndroidTarget.TEMPLATES);

    // make sure the file exists.
    File templates = new File(templateFolder);
    if (templates.isDirectory() == false) {
      throw new BuildException(
          String.format("Template directory '%s' is missing.", templateFolder));
    }

    // now check the rules file exists.
    File rules = new File(templateFolder, ANDROID_RULES);
    if (rules.isFile() == false) {
      throw new BuildException(String.format("Build rules file '%s' is missing.", templateFolder));
    }

    // set the file location to import
    setFile(rules.getAbsolutePath());

    // and import it
    super.execute();
  }