aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.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/KeyCheckPage.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java378
1 files changed, 0 insertions, 378 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java
deleted file mode 100644
index c17f43e38..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java
+++ /dev/null
@@ -1,378 +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.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.widgets.FormText;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.UnrecoverableEntryException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Calendar;
-
-/**
- * Final page of the wizard that checks the key and ask for the ouput location.
- */
-final class KeyCheckPage extends ExportWizardPage {
-
- private static final int REQUIRED_YEARS = 25;
-
- private static final String VALIDITY_WARNING =
- "<p>Make sure the certificate is valid for the planned lifetime of the product.</p>"
- + "<p>If the certificate expires, you will be forced to sign your application with "
- + "a different one.</p>"
- + "<p>Applications cannot be upgraded if their certificate changes from "
- + "one version to another, forcing a full uninstall/install, which will make "
- + "the user lose his/her data.</p>"
- + "<p>Google Play(Android Market) currently requires certificates to be valid "
- + "until 2033.</p>";
-
- private final ExportWizard mWizard;
- private PrivateKey mPrivateKey;
- private X509Certificate mCertificate;
- private Text mDestination;
- private boolean mFatalSigningError;
- private FormText mDetailText;
- private ScrolledComposite mScrolledComposite;
-
- private String mKeyDetails;
- private String mDestinationDetails;
-
- protected KeyCheckPage(ExportWizard wizard, String pageName) {
- super(pageName);
- mWizard = wizard;
-
- setTitle("Destination and key/certificate checks");
- setDescription(""); // TODO
- }
-
- @Override
- public void createControl(Composite parent) {
- setErrorMessage(null);
- setMessage(null);
-
- // build the ui.
- Composite composite = new Composite(parent, SWT.NULL);
- composite.setLayoutData(new GridData(GridData.FILL_BOTH));
- GridLayout gl = new GridLayout(3, false);
- gl.verticalSpacing *= 3;
- composite.setLayout(gl);
-
- GridData gd;
-
- new Label(composite, SWT.NONE).setText("Destination APK file:");
- mDestination = new Text(composite, SWT.BORDER);
- mDestination.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
- mDestination.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- onDestinationChange(false /*forceDetailUpdate*/);
- }
- });
- final Button browseButton = new Button(composite, SWT.PUSH);
- browseButton.setText("Browse...");
- browseButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- FileDialog fileDialog = new FileDialog(browseButton.getShell(), SWT.SAVE);
-
- fileDialog.setText("Destination file name");
- // get a default apk name based on the project
- String filename = ProjectHelper.getApkFilename(mWizard.getProject(),
- null /*config*/);
- fileDialog.setFileName(filename);
-
- String saveLocation = fileDialog.open();
- if (saveLocation != null) {
- mDestination.setText(saveLocation);
- }
- }
- });
-
- mScrolledComposite = new ScrolledComposite(composite, SWT.V_SCROLL);
- mScrolledComposite.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
- gd.horizontalSpan = 3;
- mScrolledComposite.setExpandHorizontal(true);
- mScrolledComposite.setExpandVertical(true);
-
- mDetailText = new FormText(mScrolledComposite, SWT.NONE);
- mScrolledComposite.setContent(mDetailText);
-
- mScrolledComposite.addControlListener(new ControlAdapter() {
- @Override
- public void controlResized(ControlEvent e) {
- updateScrolling();
- }
- });
-
- setControl(composite);
- }
-
- @Override
- void onShow() {
- // fill the texts with information loaded from the project.
- if ((mProjectDataChanged & DATA_PROJECT) != 0) {
- // reset the destination from the content of the project
- IProject project = mWizard.getProject();
-
- String destination = ProjectHelper.loadStringProperty(project,
- ExportWizard.PROPERTY_DESTINATION);
- if (destination != null) {
- mDestination.setText(destination);
- }
- }
-
- // if anything change we basically reload the data.
- if (mProjectDataChanged != 0) {
- mFatalSigningError = false;
-
- // reset the wizard with no key/cert to make it not finishable, unless a valid
- // key/cert is found.
- mWizard.setSigningInfo(null, null);
- mPrivateKey = null;
- mCertificate = null;
- mKeyDetails = null;
-
- if (mWizard.getKeystoreCreationMode() || mWizard.getKeyCreationMode()) {
- int validity = mWizard.getValidity();
- StringBuilder sb = new StringBuilder(
- String.format("<p>Certificate expires in %d years.</p>",
- validity));
-
- if (validity < REQUIRED_YEARS) {
- sb.append(VALIDITY_WARNING);
- }
-
- mKeyDetails = sb.toString();
- } else {
- try {
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream fis = new FileInputStream(mWizard.getKeystore());
- keyStore.load(fis, mWizard.getKeystorePassword().toCharArray());
- fis.close();
- PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(
- mWizard.getKeyAlias(),
- new KeyStore.PasswordProtection(
- mWizard.getKeyPassword().toCharArray()));
-
- if (entry != null) {
- mPrivateKey = entry.getPrivateKey();
- mCertificate = (X509Certificate)entry.getCertificate();
- } else {
- setErrorMessage("Unable to find key.");
-
- setPageComplete(false);
- }
- } catch (FileNotFoundException e) {
- // this was checked at the first previous step and will not happen here, unless
- // the file was removed during the export wizard execution.
- onException(e);
- } catch (KeyStoreException e) {
- onException(e);
- } catch (NoSuchAlgorithmException e) {
- onException(e);
- } catch (UnrecoverableEntryException e) {
- onException(e);
- } catch (CertificateException e) {
- onException(e);
- } catch (IOException e) {
- onException(e);
- }
-
- if (mPrivateKey != null && mCertificate != null) {
- Calendar expirationCalendar = Calendar.getInstance();
- expirationCalendar.setTime(mCertificate.getNotAfter());
- Calendar today = Calendar.getInstance();
-
- if (expirationCalendar.before(today)) {
- mKeyDetails = String.format(
- "<p>Certificate expired on %s</p>",
- mCertificate.getNotAfter().toString());
-
- // fatal error = nothing can make the page complete.
- mFatalSigningError = true;
-
- setErrorMessage("Certificate is expired.");
- setPageComplete(false);
- } else {
- // valid, key/cert: put it in the wizard so that it can be finished
- mWizard.setSigningInfo(mPrivateKey, mCertificate);
-
- StringBuilder sb = new StringBuilder(String.format(
- "<p>Certificate expires on %s.</p>",
- mCertificate.getNotAfter().toString()));
-
- int expirationYear = expirationCalendar.get(Calendar.YEAR);
- int thisYear = today.get(Calendar.YEAR);
-
- if (thisYear + REQUIRED_YEARS < expirationYear) {
- // do nothing
- } else {
- if (expirationYear == thisYear) {
- sb.append("<p>The certificate expires this year.</p>");
- } else {
- int count = expirationYear-thisYear;
- sb.append(String.format(
- "<p>The Certificate expires in %1$s %2$s.</p>",
- count, count == 1 ? "year" : "years"));
- }
- sb.append(VALIDITY_WARNING);
- }
-
- // show certificate fingerprints
- String sha1 = mWizard.getCertSha1Fingerprint();
- String md5 = mWizard.getCertMd5Fingerprint();
-
- sb.append("<p></p>" /*blank line*/);
- sb.append("<p>Certificate fingerprints:</p>");
- sb.append(String.format("<li>MD5 : %s</li>", md5));
- sb.append(String.format("<li>SHA1: %s</li>", sha1));
- sb.append("<p></p>" /*blank line*/);
-
- mKeyDetails = sb.toString();
- }
- } else {
- // fatal error = nothing can make the page complete.
- mFatalSigningError = true;
- }
- }
- }
-
- onDestinationChange(true /*forceDetailUpdate*/);
- }
-
- /**
- * Callback for destination field edition
- * @param forceDetailUpdate if true, the detail {@link FormText} is updated even if a fatal
- * error has happened in the signing.
- */
- private void onDestinationChange(boolean forceDetailUpdate) {
- if (mFatalSigningError == false) {
- // reset messages for now.
- setErrorMessage(null);
- setMessage(null);
-
- String path = mDestination.getText().trim();
-
- if (path.length() == 0) {
- setErrorMessage("Enter destination for the APK file.");
- // reset canFinish in the wizard.
- mWizard.resetDestination();
- setPageComplete(false);
- return;
- }
-
- File file = new File(path);
- if (file.isDirectory()) {
- setErrorMessage("Destination is a directory.");
- // reset canFinish in the wizard.
- mWizard.resetDestination();
- setPageComplete(false);
- return;
- }
-
- File parentFolder = file.getParentFile();
- if (parentFolder == null || parentFolder.isDirectory() == false) {
- setErrorMessage("Not a valid directory.");
- // reset canFinish in the wizard.
- mWizard.resetDestination();
- setPageComplete(false);
- return;
- }
-
- if (file.isFile()) {
- mDestinationDetails = "<li>WARNING: destination file already exists</li>";
- setMessage("Destination file already exists.", WARNING);
- }
-
- // no error, set the destination in the wizard.
- mWizard.setDestination(file);
- setPageComplete(true);
-
- updateDetailText();
- } else if (forceDetailUpdate) {
- updateDetailText();
- }
- }
-
- /**
- * Updates the scrollbar to match the content of the {@link FormText} or the new size
- * of the {@link ScrolledComposite}.
- */
- private void updateScrolling() {
- if (mDetailText != null) {
- Rectangle r = mScrolledComposite.getClientArea();
- mScrolledComposite.setMinSize(mDetailText.computeSize(r.width, SWT.DEFAULT));
- mScrolledComposite.layout();
- }
- }
-
- private void updateDetailText() {
- StringBuilder sb = new StringBuilder("<form>");
- if (mKeyDetails != null) {
- sb.append(mKeyDetails);
- }
-
- if (mDestinationDetails != null && mFatalSigningError == false) {
- sb.append(mDestinationDetails);
- }
-
- sb.append("</form>");
-
- mDetailText.setText(sb.toString(), true /* parseTags */,
- true /* expandURLs */);
-
- mDetailText.getParent().layout();
-
- updateScrolling();
- }
-
- @Override
- protected void onException(Throwable t) {
- super.onException(t);
-
- mKeyDetails = String.format("ERROR: %1$s", ExportWizard.getExceptionMessage(t));
- }
-}