aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java626
1 files changed, 0 insertions, 626 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java
deleted file mode 100644
index 170da6d33..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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.ide.eclipse.adt.internal.wizards.export;
-
-import com.android.annotations.Nullable;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.internal.utils.FingerprintUtils;
-import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
-import com.android.ide.eclipse.adt.internal.project.ExportHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.BuildToolInfo.PathId;
-import com.android.sdklib.internal.build.DebugKeyProvider.IKeyGenOutput;
-import com.android.sdklib.internal.build.KeystoreHelper;
-import com.android.utils.GrabProcessOutput;
-import com.android.utils.GrabProcessOutput.IProcessOutput;
-import com.android.utils.GrabProcessOutput.Wait;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IExportWizard;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.lang.reflect.InvocationTargetException;
-import java.security.KeyStore;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Export wizard to export an apk signed with a release key/certificate.
- */
-public final class ExportWizard extends Wizard implements IExportWizard {
-
- private static final String PROJECT_LOGO_LARGE = "icons/android-64.png"; //$NON-NLS-1$
-
- private static final String PAGE_PROJECT_CHECK = "Page_ProjectCheck"; //$NON-NLS-1$
- private static final String PAGE_KEYSTORE_SELECTION = "Page_KeystoreSelection"; //$NON-NLS-1$
- private static final String PAGE_KEY_CREATION = "Page_KeyCreation"; //$NON-NLS-1$
- private static final String PAGE_KEY_SELECTION = "Page_KeySelection"; //$NON-NLS-1$
- private static final String PAGE_KEY_CHECK = "Page_KeyCheck"; //$NON-NLS-1$
-
- static final String PROPERTY_KEYSTORE = "keystore"; //$NON-NLS-1$
- static final String PROPERTY_ALIAS = "alias"; //$NON-NLS-1$
- static final String PROPERTY_DESTINATION = "destination"; //$NON-NLS-1$
-
- static final int APK_FILE_SOURCE = 0;
- static final int APK_FILE_DEST = 1;
- static final int APK_COUNT = 2;
-
- /**
- * Base page class for the ExportWizard page. This class add the {@link #onShow()} callback.
- */
- static abstract class ExportWizardPage extends WizardPage {
-
- /** bit mask constant for project data change event */
- protected static final int DATA_PROJECT = 0x001;
- /** bit mask constant for keystore data change event */
- protected static final int DATA_KEYSTORE = 0x002;
- /** bit mask constant for key data change event */
- protected static final int DATA_KEY = 0x004;
-
- protected static final VerifyListener sPasswordVerifier = new VerifyListener() {
- @Override
- public void verifyText(VerifyEvent e) {
- // verify the characters are valid for password.
- int len = e.text.length();
-
- // first limit to 127 characters max
- if (len + ((Text)e.getSource()).getText().length() > 127) {
- e.doit = false;
- return;
- }
-
- // now only take non control characters
- for (int i = 0 ; i < len ; i++) {
- if (e.text.charAt(i) < 32) {
- e.doit = false;
- return;
- }
- }
- }
- };
-
- /**
- * Bit mask indicating what changed while the page was hidden.
- * @see #DATA_PROJECT
- * @see #DATA_KEYSTORE
- * @see #DATA_KEY
- */
- protected int mProjectDataChanged = 0;
-
- ExportWizardPage(String name) {
- super(name);
- }
-
- abstract void onShow();
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- if (visible) {
- onShow();
- mProjectDataChanged = 0;
- }
- }
-
- final void projectDataChanged(int changeMask) {
- mProjectDataChanged |= changeMask;
- }
-
- /**
- * Calls {@link #setErrorMessage(String)} and {@link #setPageComplete(boolean)} based on a
- * {@link Throwable} object.
- */
- protected void onException(Throwable t) {
- String message = getExceptionMessage(t);
-
- setErrorMessage(message);
- setPageComplete(false);
- }
- }
-
- private ExportWizardPage mPages[] = new ExportWizardPage[5];
-
- private IProject mProject;
-
- private String mKeystore;
- private String mKeystorePassword;
- private boolean mKeystoreCreationMode;
-
- private String mKeyAlias;
- private String mKeyPassword;
- private int mValidity;
- private String mDName;
-
- private PrivateKey mPrivateKey;
- private X509Certificate mCertificate;
-
- private File mDestinationFile;
-
- private ExportWizardPage mKeystoreSelectionPage;
- private ExportWizardPage mKeyCreationPage;
- private ExportWizardPage mKeySelectionPage;
- private ExportWizardPage mKeyCheckPage;
-
- private boolean mKeyCreationMode;
-
- private List<String> mExistingAliases;
-
- public ExportWizard() {
- setHelpAvailable(false); // TODO have help
- setWindowTitle("Export Android Application");
- setImageDescriptor();
- }
-
- @Override
- public void addPages() {
- addPage(mPages[0] = new ProjectCheckPage(this, PAGE_PROJECT_CHECK));
- addPage(mKeystoreSelectionPage = mPages[1] = new KeystoreSelectionPage(this,
- PAGE_KEYSTORE_SELECTION));
- addPage(mKeyCreationPage = mPages[2] = new KeyCreationPage(this, PAGE_KEY_CREATION));
- addPage(mKeySelectionPage = mPages[3] = new KeySelectionPage(this, PAGE_KEY_SELECTION));
- addPage(mKeyCheckPage = mPages[4] = new KeyCheckPage(this, PAGE_KEY_CHECK));
- }
-
- @Override
- public boolean performFinish() {
- // save the properties
- ProjectHelper.saveStringProperty(mProject, PROPERTY_KEYSTORE, mKeystore);
- ProjectHelper.saveStringProperty(mProject, PROPERTY_ALIAS, mKeyAlias);
- ProjectHelper.saveStringProperty(mProject, PROPERTY_DESTINATION,
- mDestinationFile.getAbsolutePath());
-
- // run the export in an UI runnable.
- IWorkbench workbench = PlatformUI.getWorkbench();
- final boolean[] result = new boolean[1];
- try {
- workbench.getProgressService().busyCursorWhile(new IRunnableWithProgress() {
- /**
- * Run the export.
- * @throws InvocationTargetException
- * @throws InterruptedException
- */
- @Override
- public void run(IProgressMonitor monitor) throws InvocationTargetException,
- InterruptedException {
- try {
- result[0] = doExport(monitor);
- } finally {
- monitor.done();
- }
- }
- });
- } catch (InvocationTargetException e) {
- return false;
- } catch (InterruptedException e) {
- return false;
- }
-
- return result[0];
- }
-
- private boolean doExport(IProgressMonitor monitor) {
- try {
- // if needed, create the keystore and/or key.
- if (mKeystoreCreationMode || mKeyCreationMode) {
- final ArrayList<String> output = new ArrayList<String>();
- boolean createdStore = KeystoreHelper.createNewStore(
- mKeystore,
- null /*storeType*/,
- mKeystorePassword,
- mKeyAlias,
- mKeyPassword,
- mDName,
- mValidity,
- new IKeyGenOutput() {
- @Override
- public void err(String message) {
- output.add(message);
- }
- @Override
- public void out(String message) {
- output.add(message);
- }
- });
-
- if (createdStore == false) {
- // keystore creation error!
- displayError(output.toArray(new String[output.size()]));
- return false;
- }
-
- // keystore is created, now load the private key and certificate.
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream fis = new FileInputStream(mKeystore);
- keyStore.load(fis, mKeystorePassword.toCharArray());
- fis.close();
- PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(
- mKeyAlias, new KeyStore.PasswordProtection(mKeyPassword.toCharArray()));
-
- if (entry != null) {
- mPrivateKey = entry.getPrivateKey();
- mCertificate = (X509Certificate)entry.getCertificate();
-
- AdtPlugin.printToConsole(mProject,
- String.format("New keystore %s has been created.",
- mDestinationFile.getAbsolutePath()),
- "Certificate fingerprints:",
- String.format(" MD5 : %s", getCertMd5Fingerprint()),
- String.format(" SHA1: %s", getCertSha1Fingerprint()));
-
- } else {
- // this really shouldn't happen since we now let the user choose the key
- // from a list read from the store.
- displayError("Could not find key");
- return false;
- }
- }
-
- // check the private key/certificate again since it may have been created just above.
- if (mPrivateKey != null && mCertificate != null) {
- // check whether we can run zipalign.
- boolean runZipAlign = false;
-
- ProjectState projectState = Sdk.getProjectState(mProject);
- BuildToolInfo buildToolInfo = ExportHelper.getBuildTools(projectState);
-
- String zipAlignPath = buildToolInfo.getPath(PathId.ZIP_ALIGN);
- runZipAlign = zipAlignPath != null && new File(zipAlignPath).isFile();
-
- File apkExportFile = mDestinationFile;
- if (runZipAlign) {
- // create a temp file for the original export.
- apkExportFile = File.createTempFile("androidExport_", ".apk");
- }
-
- // export the signed apk.
- ExportHelper.exportReleaseApk(mProject, apkExportFile,
- mPrivateKey, mCertificate, monitor);
-
- // align if we can
- if (runZipAlign) {
- String message = zipAlign(zipAlignPath, apkExportFile, mDestinationFile);
- if (message != null) {
- displayError(message);
- return false;
- }
- } else {
- AdtPlugin.displayWarning("Export Wizard",
- "The zipalign tool was not found in the SDK.\n\n" +
- "Please update to the latest SDK and re-export your application\n" +
- "or run zipalign manually.\n\n" +
- "Aligning applications allows Android to use application resources\n" +
- "more efficiently.");
- }
-
- return true;
- }
- } catch (Throwable t) {
- displayError(t);
- }
-
- return false;
- }
-
- @Override
- public boolean canFinish() {
- // check if we have the apk to resign, the destination location, and either
- // a private key/certificate or the creation mode. In creation mode, unless
- // all the key/keystore info is valid, the user cannot reach the last page, so there's
- // no need to check them again here.
- return ((mPrivateKey != null && mCertificate != null)
- || mKeystoreCreationMode || mKeyCreationMode) &&
- mDestinationFile != null;
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench,
- * org.eclipse.jface.viewers.IStructuredSelection)
- */
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- // get the project from the selection
- Object selected = selection.getFirstElement();
-
- if (selected instanceof IProject) {
- mProject = (IProject)selected;
- } else if (selected instanceof IAdaptable) {
- IResource r = (IResource)((IAdaptable)selected).getAdapter(IResource.class);
- if (r != null) {
- mProject = r.getProject();
- }
- }
- }
-
- ExportWizardPage getKeystoreSelectionPage() {
- return mKeystoreSelectionPage;
- }
-
- ExportWizardPage getKeyCreationPage() {
- return mKeyCreationPage;
- }
-
- ExportWizardPage getKeySelectionPage() {
- return mKeySelectionPage;
- }
-
- ExportWizardPage getKeyCheckPage() {
- return mKeyCheckPage;
- }
-
- /**
- * Returns an image descriptor for the wizard logo.
- */
- private void setImageDescriptor() {
- ImageDescriptor desc = AdtPlugin.getImageDescriptor(PROJECT_LOGO_LARGE);
- setDefaultPageImageDescriptor(desc);
- }
-
- IProject getProject() {
- return mProject;
- }
-
- void setProject(IProject project) {
- mProject = project;
-
- updatePageOnChange(ExportWizardPage.DATA_PROJECT);
- }
-
- void setKeystore(String path) {
- mKeystore = path;
- mPrivateKey = null;
- mCertificate = null;
-
- updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
- }
-
- String getKeystore() {
- return mKeystore;
- }
-
- void setKeystoreCreationMode(boolean createStore) {
- mKeystoreCreationMode = createStore;
- updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
- }
-
- boolean getKeystoreCreationMode() {
- return mKeystoreCreationMode;
- }
-
-
- void setKeystorePassword(String password) {
- mKeystorePassword = password;
- mPrivateKey = null;
- mCertificate = null;
-
- updatePageOnChange(ExportWizardPage.DATA_KEYSTORE);
- }
-
- String getKeystorePassword() {
- return mKeystorePassword;
- }
-
- void setKeyCreationMode(boolean createKey) {
- mKeyCreationMode = createKey;
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- boolean getKeyCreationMode() {
- return mKeyCreationMode;
- }
-
- void setExistingAliases(List<String> aliases) {
- mExistingAliases = aliases;
- }
-
- List<String> getExistingAliases() {
- return mExistingAliases;
- }
-
- void setKeyAlias(String name) {
- mKeyAlias = name;
- mPrivateKey = null;
- mCertificate = null;
-
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- String getKeyAlias() {
- return mKeyAlias;
- }
-
- void setKeyPassword(String password) {
- mKeyPassword = password;
- mPrivateKey = null;
- mCertificate = null;
-
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- String getKeyPassword() {
- return mKeyPassword;
- }
-
- void setValidity(int validity) {
- mValidity = validity;
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- int getValidity() {
- return mValidity;
- }
-
- void setDName(String dName) {
- mDName = dName;
- updatePageOnChange(ExportWizardPage.DATA_KEY);
- }
-
- String getDName() {
- return mDName;
- }
-
- String getCertSha1Fingerprint() {
- return FingerprintUtils.getFingerprint(mCertificate, "SHA1");
- }
-
- String getCertMd5Fingerprint() {
- return FingerprintUtils.getFingerprint(mCertificate, "MD5");
- }
-
- void setSigningInfo(PrivateKey privateKey, X509Certificate certificate) {
- mPrivateKey = privateKey;
- mCertificate = certificate;
- }
-
- void setDestination(File destinationFile) {
- mDestinationFile = destinationFile;
- }
-
- void resetDestination() {
- mDestinationFile = null;
- }
-
- void updatePageOnChange(int changeMask) {
- for (ExportWizardPage page : mPages) {
- page.projectDataChanged(changeMask);
- }
- }
-
- private void displayError(String... messages) {
- String message = null;
- if (messages.length == 1) {
- message = messages[0];
- } else {
- StringBuilder sb = new StringBuilder(messages[0]);
- for (int i = 1; i < messages.length; i++) {
- sb.append('\n');
- sb.append(messages[i]);
- }
-
- message = sb.toString();
- }
-
- AdtPlugin.displayError("Export Wizard", message);
- }
-
- private void displayError(Throwable t) {
- String message = getExceptionMessage(t);
- displayError(message);
-
- AdtPlugin.log(t, "Export Wizard Error");
- }
-
- /**
- * Executes zipalign
- * @param zipAlignPath location of the zipalign too
- * @param source file to zipalign
- * @param destination where to write the resulting file
- * @return null if success, the error otherwise
- * @throws IOException
- */
- private String zipAlign(String zipAlignPath, File source, File destination) throws IOException {
- // command line: zipaling -f 4 tmp destination
- String[] command = new String[5];
- command[0] = zipAlignPath;
- command[1] = "-f"; //$NON-NLS-1$
- command[2] = "4"; //$NON-NLS-1$
- command[3] = source.getAbsolutePath();
- command[4] = destination.getAbsolutePath();
-
- Process process = Runtime.getRuntime().exec(command);
- final ArrayList<String> output = new ArrayList<String>();
- try {
- final IProject project = getProject();
-
- int status = GrabProcessOutput.grabProcessOutput(
- process,
- Wait.WAIT_FOR_READERS,
- new IProcessOutput() {
- @Override
- public void out(@Nullable String line) {
- if (line != null) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE,
- project, line);
- }
- }
-
- @Override
- public void err(@Nullable String line) {
- if (line != null) {
- output.add(line);
- }
- }
- });
-
- if (status != 0) {
- // build a single message from the array list
- StringBuilder sb = new StringBuilder("Error while running zipalign:");
- for (String msg : output) {
- sb.append('\n');
- sb.append(msg);
- }
-
- return sb.toString();
- }
- } catch (InterruptedException e) {
- // ?
- }
- return null;
- }
-
- /**
- * Returns the {@link Throwable#getMessage()}. If the {@link Throwable#getMessage()} returns
- * <code>null</code>, the method is called again on the cause of the Throwable object.
- * <p/>If no Throwable in the chain has a valid message, the canonical name of the first
- * exception is returned.
- */
- static String getExceptionMessage(Throwable t) {
- String message = t.getMessage();
- if (message == null) {
- // no error info? get the stack call to display it
- // At least that'll give us a better bug report.
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- t.printStackTrace(new PrintStream(baos));
- message = baos.toString();
- }
-
- return message;
- }
-}