summaryrefslogtreecommitdiff
path: root/src/plugins/android/src/com/motorola/studio/android/wizards/installapp/DeployWizardPage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/android/src/com/motorola/studio/android/wizards/installapp/DeployWizardPage.java')
-rw-r--r--src/plugins/android/src/com/motorola/studio/android/wizards/installapp/DeployWizardPage.java430
1 files changed, 430 insertions, 0 deletions
diff --git a/src/plugins/android/src/com/motorola/studio/android/wizards/installapp/DeployWizardPage.java b/src/plugins/android/src/com/motorola/studio/android/wizards/installapp/DeployWizardPage.java
new file mode 100644
index 0000000..53fb85a
--- /dev/null
+++ b/src/plugins/android/src/com/motorola/studio/android/wizards/installapp/DeployWizardPage.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.motorola.studio.android.wizards.installapp;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.DialogPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+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.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.Group;
+import org.eclipse.ui.PlatformUI;
+
+import com.motorola.studio.android.AndroidPlugin;
+import com.motorola.studio.android.common.log.StudioLogger;
+import com.motorola.studio.android.i18n.AndroidNLS;
+import com.motorola.studio.android.wizards.elements.FileChooser;
+import com.motorola.studio.android.wizards.installapp.DeployWizard.INSTALL_TYPE;
+
+/**
+ * Wizard Page used by Deploy Wizard
+ */
+public class DeployWizardPage extends WizardPage
+{
+ private FileChooser fileChooser = null;
+
+ private String initialPackagePath = null;
+
+ private String packageSelectionMessage = null;
+
+ private String packagetext = null;
+
+ private final String packageExtension = "apk";
+
+ private Button overwiteRadio = null;
+
+ private Button uninstallRadio = null;
+
+ private Button doNothingRadio = null;
+
+ private static final String contextId = AndroidPlugin.PLUGIN_ID + ".install_app";
+
+ private static INSTALL_TYPE installType;
+
+ private final String DSA_FILE_EXTENSION = ".DSA";
+
+ private final String RSA_FILE_EXTENSION = ".RSA";
+
+ private final String SF_FILE_EXTENSION = ".SF";
+
+ private static String lastUsedPackage = null;
+
+ /**
+ * Constructor
+ *
+ * @param initialPackagePath
+ * @param selectPCKMessage
+ * Message asking for package selection
+ */
+ public DeployWizardPage(String initialPackagePath, String selectPCKMessage,
+ String browseButtonText, String packagetext)
+ {
+ super("");
+
+ if ((browseButtonText == null) || (packagetext == null) || (selectPCKMessage == null))
+ {
+ throw new IllegalArgumentException("Could not create Deploy Wizard: null argument");
+ }
+
+ if (initialPackagePath == null)
+ {
+ this.initialPackagePath = lastUsedPackage != null ? lastUsedPackage : "";
+ }
+ else
+ {
+ this.initialPackagePath = initialPackagePath;
+ }
+
+ this.packagetext = packagetext;
+ packageSelectionMessage = selectPCKMessage;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets
+ * .Composite)
+ */
+ public void createControl(Composite parent)
+ {
+ // Main composite for the UI
+ Composite mainComposite = new Composite(parent, SWT.FILL);
+
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(mainComposite, contextId);
+
+ mainComposite.setLayout(new GridLayout());
+ mainComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL, GridData.FILL_VERTICAL,
+ true, true));
+
+ // Package group
+ Group packageGroup = new Group(mainComposite, SWT.NONE);
+ packageGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ packageGroup.setLayout(new GridLayout(3, false));
+ packageGroup.setText(packagetext);
+
+ fileChooser = new FileChooser(packageGroup, SWT.NONE, null);
+ fileChooser.setFilterExtensions(new String[]
+ {
+ "*." + packageExtension
+ });
+ fileChooser.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
+ fileChooser.addModifyListener(new ModifyListener()
+ {
+ public void modifyText(ModifyEvent e)
+ {
+ validateSelection();
+ }
+ });
+ createOptionButtons(mainComposite);
+
+ mainComposite.pack();
+
+ setPageComplete(false);
+ loadInitialValues();
+
+ setControl(mainComposite);
+ }
+
+ private void createOptionButtons(Composite mainComposite)
+ {
+
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1);
+ overwiteRadio = new Button(mainComposite, SWT.RADIO);
+ overwiteRadio.setText(AndroidNLS.UI_DeployWizardPage_ReplaceApp);
+ overwiteRadio.setSelection(true);
+ overwiteRadio.setLayoutData(data);
+ overwiteRadio.setData(INSTALL_TYPE.OVERWRITE);
+ overwiteRadio.addSelectionListener(new SelectionAdapter()
+ {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ installType = (INSTALL_TYPE) overwiteRadio.getData();
+ }
+
+ });
+
+ uninstallRadio = new Button(mainComposite, SWT.RADIO);
+ uninstallRadio.setText(AndroidNLS.UI_DeployWizardPage_UninstallApp);
+ uninstallRadio.setSelection(true);
+ uninstallRadio.setLayoutData(data);
+ uninstallRadio.setData(INSTALL_TYPE.UNINSTALL);
+ uninstallRadio.addSelectionListener(new SelectionAdapter()
+ {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ installType = (INSTALL_TYPE) uninstallRadio.getData();
+ }
+
+ });
+
+ doNothingRadio = new Button(mainComposite, SWT.RADIO);
+ doNothingRadio.setText(AndroidNLS.UI_DeployWizardPage_DoNothingApp);
+ doNothingRadio.setSelection(true);
+ doNothingRadio.setLayoutData(data);
+ doNothingRadio.setData(INSTALL_TYPE.DO_NOTHING);
+ doNothingRadio.addSelectionListener(new SelectionAdapter()
+ {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ installType = (INSTALL_TYPE) doNothingRadio.getData();
+ }
+
+ });
+ overwiteRadio.setSelection(true);
+ uninstallRadio.setSelection(false);
+ doNothingRadio.setSelection(false);
+ installType = (INSTALL_TYPE.OVERWRITE);
+
+ }
+
+ /**
+ * Load the initial values to be filled in the wizard
+ */
+ private void loadInitialValues()
+ {
+ if ((initialPackagePath != null) && (initialPackagePath.length() != 0))
+ {
+ fileChooser.setText(initialPackagePath);
+ validateSelection();
+ }
+ else
+ {
+ setMessage(packageSelectionMessage, DialogPage.NONE);
+ }
+ }
+
+ /**
+ * Validates the selected package and device instance setting the
+ * appropriated messages and errors
+ */
+ private synchronized void validateSelection()
+ {
+ String packagePath = fileChooser.getText();
+
+ if (isValidPackage(packagePath))
+ {
+ setErrorMessage(null);
+ setPageComplete(true);
+ }
+ else
+ {
+ setPageComplete(false);
+ }
+ }
+
+ /**
+ * Verify if a package is valid MPKG
+ *
+ * @param packagePath
+ * @return TRUE if the package is valid or FALSE otherwise
+ */
+ private boolean isValidPackage(String packagePath)
+ {
+ boolean result = false;
+ Path path = new Path(packagePath);
+ String extension = path.getFileExtension();
+
+ // testing if the entered path is a folder
+ result = path.toFile().isFile();
+ if (!result)
+ {
+ setErrorMessage(AndroidNLS.UI_DeployWizardPage_PackageIsAFolder);
+ }
+ else
+ {
+ result =
+ ((extension != null) && extension.equals(packageExtension) && path
+ .isValidPath(path.toString()));
+
+ if (!result)
+ {
+ setErrorMessage(AndroidNLS.UI_DeployWizardPage_InvalidPath);
+ }
+ else
+ {
+ // Test if file exists
+ result = path.toFile().exists();
+ if (!result)
+ {
+ setErrorMessage(AndroidNLS.UI_DeployWizardPage_FileDoesNotExist);
+ }
+ }
+ }
+
+ if (result)
+ {
+ setMessage("", DialogPage.NONE);
+
+ //Test if the package is valid
+ result = isPackageSigned(packagePath);
+ if (!result)
+ {
+ setErrorMessage(AndroidNLS.UI_DeployWizardPage_NotSignedMessage);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Verify if the package is signed based on the
+ * existence of an .SF file and a corresponding
+ * DSA or RSA file.
+ *
+ * @param packagePath
+ * @return TRUE if the package is signed
+ */
+ private synchronized boolean isPackageSigned(String packagePath)
+ {
+ // Temporary placeholders for the package entries
+ List<String> SFFiles = new ArrayList<String>();
+ List<String> RSAFiles = new ArrayList<String>();
+ List<String> DSAFiles = new ArrayList<String>();
+
+ //Temporary result
+ boolean result = false;
+ JarFile jar = null;
+ try
+ {
+ jar = new JarFile(packagePath, false);
+ Enumeration<JarEntry> enu = jar.entries();
+
+ //interact over the elements of the package
+ while (enu.hasMoreElements())
+ {
+ JarEntry entry = enu.nextElement();
+ if (entry.getName().toUpperCase().endsWith(SF_FILE_EXTENSION))
+ {
+ // Mounts the list of SF files
+ SFFiles.add(entry.getName().toUpperCase());
+ }
+ else if (entry.getName().toUpperCase().endsWith(RSA_FILE_EXTENSION))
+ {
+ // Mounts the list of RSA files
+ RSAFiles.add(entry.getName().toUpperCase());
+ }
+ else if (entry.getName().toUpperCase().endsWith(DSA_FILE_EXTENSION))
+ {
+ // Mounts the list of DSA files
+ DSAFiles.add(entry.getName().toUpperCase());
+ }
+ }
+
+ if (!SFFiles.isEmpty())
+ {
+ for (String sfFile : SFFiles)
+ {
+ // Interacts over the list of SF files until it ends or until a correspondent DSA or RSA is found
+ Path p = new Path(sfFile);
+ sfFile = p.removeFileExtension().toString();
+ result =
+ (DSAFiles.contains(sfFile + DSA_FILE_EXTENSION) || RSAFiles
+ .contains(sfFile + RSA_FILE_EXTENSION));
+ }
+ }
+
+ }
+ catch (Exception e)
+ {
+ // Could not read the jar file
+ StudioLogger.error(DeployWizardPage.class, "Deploy: Could not verify file "
+ + packagePath, e);
+ }
+ finally
+ {
+ if (jar != null)
+ {
+ try
+ {
+ jar.close();
+ }
+ catch (IOException e)
+ {
+ StudioLogger.error(DeployWizardPage.class,
+ "Error closing package after verification", e);
+ }
+ }
+ }
+
+ return result;
+
+ }
+
+ /**
+ * Gets the selected package path
+ *
+ * @return the package Path
+ */
+ public String getPackagePath()
+ {
+ String packagePath = fileChooser.getText();
+ if (isValidPackage(packagePath))
+ {
+ lastUsedPackage = packagePath;
+ }
+ return packagePath;
+ }
+
+ /**
+ * Return true if the application should be replaced in the case it is
+ * already installed on the device
+ *
+ */
+ public INSTALL_TYPE canOverwrite()
+ {
+ return installType;
+ }
+} \ No newline at end of file