aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--anttasks/src/com/android/ant/AaptExecLoopTask.java61
-rw-r--r--anttasks/src/com/android/ant/ApkBuilderTask.java14
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java51
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java32
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java52
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java111
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java92
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkSettings.java58
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java18
-rw-r--r--sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ApkConfigEditDialog.java177
-rw-r--r--sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ApkConfigWidget.java211
11 files changed, 245 insertions, 632 deletions
diff --git a/anttasks/src/com/android/ant/AaptExecLoopTask.java b/anttasks/src/com/android/ant/AaptExecLoopTask.java
index ef74fe7..47b8f48 100644
--- a/anttasks/src/com/android/ant/AaptExecLoopTask.java
+++ b/anttasks/src/com/android/ant/AaptExecLoopTask.java
@@ -17,6 +17,7 @@
package com.android.ant;
import com.android.sdklib.internal.project.ApkConfigurationHelper;
+import com.android.sdklib.internal.project.ApkSettings;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
@@ -28,7 +29,6 @@ import org.apache.tools.ant.types.Path;
import java.io.File;
import java.util.Map;
-import java.util.Set;
import java.util.Map.Entry;
/**
@@ -38,7 +38,7 @@ import java.util.Map.Entry;
*
*/
public final class AaptExecLoopTask extends Task {
-
+
private String mExecutable;
private String mCommand;
private String mManifest;
@@ -55,7 +55,7 @@ public final class AaptExecLoopTask extends Task {
public void setExecutable(String executable) {
mExecutable = executable;
}
-
+
/**
* Sets the value of the "command" attribute.
* @param command the value.
@@ -63,7 +63,7 @@ public final class AaptExecLoopTask extends Task {
public void setCommand(String command) {
mCommand = command;
}
-
+
/**
* Sets the value of the "manifest" attribute.
* @param manifest the value.
@@ -71,7 +71,7 @@ public final class AaptExecLoopTask extends Task {
public void setManifest(Path manifest) {
mManifest = manifest.toString();
}
-
+
/**
* Sets the value of the "resources" attribute.
* @param resources the value.
@@ -79,7 +79,7 @@ public final class AaptExecLoopTask extends Task {
public void setResources(Path resources) {
mResources = resources.toString();
}
-
+
/**
* Sets the value of the "assets" attribute.
* @param assets the value.
@@ -87,7 +87,7 @@ public final class AaptExecLoopTask extends Task {
public void setAssets(Path assets) {
mAssets = assets.toString();
}
-
+
/**
* Sets the value of the "androidjar" attribute.
* @param androidJar the value.
@@ -95,7 +95,7 @@ public final class AaptExecLoopTask extends Task {
public void setAndroidjar(Path androidJar) {
mAndroidJar = androidJar.toString();
}
-
+
/**
* Sets the value of the "outfolder" attribute.
* @param outFolder the value.
@@ -103,7 +103,7 @@ public final class AaptExecLoopTask extends Task {
public void setOutfolder(Path outFolder) {
mOutFolder = outFolder.toString();
}
-
+
/**
* Sets the value of the "basename" attribute.
* @param baseName the value.
@@ -111,19 +111,19 @@ public final class AaptExecLoopTask extends Task {
public void setBasename(String baseName) {
mBaseName = baseName;
}
-
+
/*
* (non-Javadoc)
- *
+ *
* Executes the loop. Based on the values inside default.properties, this will
* create alternate temporary ap_ files.
- *
+ *
* @see org.apache.tools.ant.Task#execute()
*/
@Override
public void execute() throws BuildException {
Project taskProject = getProject();
-
+
// first do a full resource package
createPackage(null /*configName*/, null /*resourceFilter*/);
@@ -132,12 +132,15 @@ public final class AaptExecLoopTask extends Task {
File baseDir = taskProject.getBaseDir();
ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
PropertyType.DEFAULT);
-
- Map<String, String> apkConfigs = ApkConfigurationHelper.getConfigs(properties);
- if (apkConfigs.size() > 0) {
- Set<Entry<String, String>> entrySet = apkConfigs.entrySet();
- for (Entry<String, String> entry : entrySet) {
- createPackage(entry.getKey(), entry.getValue());
+
+
+ ApkSettings apkSettings = ApkConfigurationHelper.getSettings(properties);
+ if (apkSettings != null) {
+ Map<String, String> apkFilters = apkSettings.getResourceFilters();
+ if (apkFilters.size() > 0) {
+ for (Entry<String, String> entry : apkFilters.entrySet()) {
+ createPackage(entry.getKey(), entry.getValue());
+ }
}
}
}
@@ -164,19 +167,19 @@ public final class AaptExecLoopTask extends Task {
ExecTask task = new ExecTask();
task.setExecutable(mExecutable);
task.setFailonerror(true);
-
+
// aapt command. Only "package" is supported at this time really.
task.createArg().setValue(mCommand);
-
+
// filters if needed
if (configName != null && resourceFilter != null) {
task.createArg().setValue("-c");
task.createArg().setValue(resourceFilter);
}
-
+
// force flag
task.createArg().setValue("-f");
-
+
// manifest location
task.createArg().setValue("-M");
task.createArg().setValue(mManifest);
@@ -187,18 +190,18 @@ public final class AaptExecLoopTask extends Task {
task.createArg().setValue("-S");
task.createArg().setValue(mResources);
}
-
+
// assets location. This may not exists, and aapt doesn't like it, so we check first.
File assets = new File(mAssets);
if (assets.isDirectory()) {
task.createArg().setValue("-A");
task.createArg().setValue(mAssets);
}
-
+
// android.jar
task.createArg().setValue("-I");
task.createArg().setValue(mAndroidJar);
-
+
// out file. This is based on the outFolder, baseName, and the configName (if applicable)
String filename;
if (configName != null && resourceFilter != null) {
@@ -206,15 +209,15 @@ public final class AaptExecLoopTask extends Task {
} else {
filename = mBaseName + ".ap_";
}
-
+
File file = new File(mOutFolder, filename);
task.createArg().setValue("-F");
task.createArg().setValue(file.getAbsolutePath());
-
+
// final setup of the task
task.setProject(taskProject);
task.setOwningTarget(getOwningTarget());
-
+
// execute it.
task.execute();
}
diff --git a/anttasks/src/com/android/ant/ApkBuilderTask.java b/anttasks/src/com/android/ant/ApkBuilderTask.java
index 3a15368..b2c445d 100644
--- a/anttasks/src/com/android/ant/ApkBuilderTask.java
+++ b/anttasks/src/com/android/ant/ApkBuilderTask.java
@@ -20,6 +20,7 @@ import com.android.apkbuilder.ApkBuilder.ApkCreationException;
import com.android.apkbuilder.internal.ApkBuilderImpl;
import com.android.apkbuilder.internal.ApkBuilderImpl.ApkFile;
import com.android.sdklib.internal.project.ApkConfigurationHelper;
+import com.android.sdklib.internal.project.ApkSettings;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
@@ -35,7 +36,6 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Map;
-import java.util.Set;
import java.util.Map.Entry;
public class ApkBuilderTask extends Task {
@@ -214,11 +214,13 @@ public class ApkBuilderTask extends Task {
ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
PropertyType.DEFAULT);
- Map<String, String> apkConfigs = ApkConfigurationHelper.getConfigs(properties);
- if (apkConfigs.size() > 0) {
- Set<Entry<String, String>> entrySet = apkConfigs.entrySet();
- for (Entry<String, String> entry : entrySet) {
- createApk(apkBuilder, entry.getKey(), entry.getValue(), path);
+ ApkSettings apkSettings = ApkConfigurationHelper.getSettings(properties);
+ if (apkSettings != null) {
+ Map<String, String> apkFilters = apkSettings.getResourceFilters();
+ if (apkFilters.size() > 0) {
+ for (Entry<String, String> entry : apkFilters.entrySet()) {
+ createApk(apkBuilder, entry.getKey(), entry.getValue(), path);
+ }
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java
index b49ee6e..1ed5123 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java
@@ -34,6 +34,7 @@ import com.android.jarutils.SignedJarBuilder.IZipEntryFilter;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
+import com.android.sdklib.internal.project.ApkSettings;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@@ -303,11 +304,15 @@ public class ApkBuilder extends BaseBuilder {
return referencedProjects;
}
- // get the extra configs for the project.
- // The map contains (name, filter) where 'name' is a name to be used in the apk filename,
- // and filter is the resource filter to be used in the aapt -c parameters to restrict
- // which resource configurations to package in the apk.
- Map<String, String> configs = Sdk.getCurrent().getProjectApkConfigs(project);
+ // get the APK configs for the project.
+ ApkSettings apkSettings = Sdk.getCurrent().getApkSettings(project);
+ Set<Entry<String, String>> apkfilters = null;
+ if (apkSettings != null) {
+ Map<String, String> filterMap = apkSettings.getResourceFilters();
+ if (filterMap != null && filterMap.size() > 0) {
+ apkfilters = filterMap.entrySet();
+ }
+ }
// do some extra check, in case the output files are not present. This
// will force to recreate them.
@@ -320,19 +325,20 @@ public class ApkBuilder extends BaseBuilder {
mPackageResources = true;
mBuildFinalPackage = true;
} else {
- // if the full package is present, we check the filtered resource packages as well
- if (configs != null) {
- Set<Entry<String, String>> entrySet = configs.entrySet();
-
- for (Entry<String, String> entry : entrySet) {
+ // if the full package is present, we check the filtered resource packages
+ // as well
+ if (apkfilters != null) {
+ for (Entry<String, String> entry : apkfilters) {
String filename = String.format(AndroidConstants.FN_RESOURCES_S_AP_,
entry.getKey());
tmp = outputFolder.findMember(filename);
if (tmp == null || (tmp instanceof IFile &&
tmp.exists() == false)) {
- String msg = String.format(Messages.s_Missing_Repackaging, filename);
- AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
+ String msg = String.format(Messages.s_Missing_Repackaging,
+ filename);
+ AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE,
+ project, msg);
mPackageResources = true;
mBuildFinalPackage = true;
break;
@@ -360,11 +366,9 @@ public class ApkBuilder extends BaseBuilder {
String msg = String.format(Messages.s_Missing_Repackaging, finalPackageName);
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
mBuildFinalPackage = true;
- } else if (configs != null) {
+ } else if (apkfilters != null) {
// if the full apk is present, we check the filtered apk as well
- Set<Entry<String, String>> entrySet = configs.entrySet();
-
- for (Entry<String, String> entry : entrySet) {
+ for (Entry<String, String> entry : apkfilters) {
String filename = ProjectHelper.getApkFilename(project, entry.getKey());
tmp = outputFolder.findMember(filename);
@@ -411,9 +415,8 @@ public class ApkBuilder extends BaseBuilder {
// notified.
finalPackage.delete();
- if (configs != null) {
- Set<Entry<String, String>> entrySet = configs.entrySet();
- for (Entry<String, String> entry : entrySet) {
+ if (apkfilters != null) {
+ for (Entry<String, String> entry : apkfilters) {
String packageFilepath = osBinPath + File.separator +
ProjectHelper.getApkFilename(project, entry.getKey());
@@ -477,9 +480,8 @@ public class ApkBuilder extends BaseBuilder {
}
// now do the same thing for all the configured resource packages.
- if (configs != null) {
- Set<Entry<String, String>> entrySet = configs.entrySet();
- for (Entry<String, String> entry : entrySet) {
+ if (apkfilters != null) {
+ for (Entry<String, String> entry : apkfilters) {
String outPathFormat = osBinPath + File.separator +
AndroidConstants.FN_RESOURCES_S_AP_;
String outPath = String.format(outPathFormat, entry.getKey());
@@ -527,12 +529,11 @@ public class ApkBuilder extends BaseBuilder {
}
// now do the same thing for all the configured resource packages.
- if (configs != null) {
+ if (apkfilters != null) {
String resPathFormat = osBinPath + File.separator +
AndroidConstants.FN_RESOURCES_S_AP_;
- Set<Entry<String, String>> entrySet = configs.entrySet();
- for (Entry<String, String> entry : entrySet) {
+ for (Entry<String, String> entry : apkfilters) {
// make the filename for the resource package.
String resPath = String.format(resPathFormat, entry.getKey());
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java
index 7dc4ae2..a88f864 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java
@@ -18,7 +18,7 @@ package com.android.ide.eclipse.adt.internal.properties;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.IAndroidTarget;
-import com.android.sdkuilib.internal.widgets.ApkConfigWidget;
+import com.android.sdklib.internal.project.ApkSettings;
import com.android.sdkuilib.internal.widgets.SdkTargetSelector;
import org.eclipse.core.resources.IProject;
@@ -27,14 +27,14 @@ 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.Control;
+import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbenchPropertyPage;
import org.eclipse.ui.dialogs.PropertyPage;
-import java.util.Map;
-
/**
* Property page for "Android" project.
* This is accessible from the Package Explorer when right clicking a project and choosing
@@ -45,7 +45,7 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope
private IProject mProject;
private SdkTargetSelector mSelector;
- private ApkConfigWidget mApkConfigWidget;
+ private Button mSplitByDensity;
public AndroidPropertyPage() {
// pass
@@ -72,13 +72,13 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope
mSelector = new SdkTargetSelector(top, targets);
- l = new Label(top, SWT.SEPARATOR | SWT.HORIZONTAL);
- l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- l = new Label(top, SWT.NONE);
- l.setText("Project APK Configurations");
+ Group g = new Group(top, SWT.NONE);
+ g.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ g.setLayout(new GridLayout(1, false));
+ g.setText("APK Generation");
- mApkConfigWidget = new ApkConfigWidget(top);
+ mSplitByDensity = new Button(g, SWT.CHECK);
+ mSplitByDensity.setText("One APK per density");
// fill the ui
Sdk currentSdk = Sdk.getCurrent();
@@ -89,9 +89,9 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope
mSelector.setSelection(target);
}
- // get the apk configurations
- Map<String, String> configs = currentSdk.getProjectApkConfigs(mProject);
- mApkConfigWidget.fillTable(configs);
+ // get the project settings
+ ApkSettings settings = currentSdk.getApkSettings(mProject);
+ mSplitByDensity.setSelection(settings.isSplitByDpi());
}
mSelector.setSelectionListener(new SelectionAdapter() {
@@ -114,8 +114,10 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope
public boolean performOk() {
Sdk currentSdk = Sdk.getCurrent();
if (currentSdk != null) {
- currentSdk.setProject(mProject, mSelector.getSelected(),
- mApkConfigWidget.getApkConfigs());
+ ApkSettings apkSettings = new ApkSettings();
+ apkSettings.setSplitByDensity(mSplitByDensity.getSelection());
+
+ currentSdk.setProject(mProject, mSelector.getSelected(), apkSettings);
}
return true;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
index f2e883d..f93b6c5 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
@@ -30,6 +30,7 @@ import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.internal.project.ApkConfigurationHelper;
+import com.android.sdklib.internal.project.ApkSettings;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
@@ -68,8 +69,8 @@ public class Sdk implements IProjectListener {
new HashMap<IProject, IAndroidTarget>();
private final HashMap<IAndroidTarget, AndroidTargetData> mTargetDataMap =
new HashMap<IAndroidTarget, AndroidTargetData>();
- private final HashMap<IProject, Map<String, String>> mProjectApkConfigMap =
- new HashMap<IProject, Map<String, String>>();
+ private final HashMap<IProject, ApkSettings> mApkSettingsMap =
+ new HashMap<IProject, ApkSettings>();
private final String mDocBaseUrl;
/**
@@ -193,11 +194,9 @@ public class Sdk implements IProjectListener {
* apk configurations should not be updated.
*/
public void setProject(IProject project, IAndroidTarget target,
- Map<String, String> apkConfigMap) {
+ ApkSettings settings) {
synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
boolean resolveProject = false;
- boolean compileProject = false;
- boolean cleanProject = false;
ProjectProperties properties = ProjectProperties.load(
project.getLocation().toOSString(), PropertyType.DEFAULT);
@@ -222,15 +221,17 @@ public class Sdk implements IProjectListener {
}
}
- if (apkConfigMap != null) {
- // save the apk configs in the project persistent property
- cleanProject = ApkConfigurationHelper.setConfigs(properties, apkConfigMap);
+ // if there's no settings, force default values (to reset possibly changed
+ // values in a previous call.
+ if (settings == null) {
+ settings = new ApkSettings();
+ }
- // put it in a local map for easy access.
- mProjectApkConfigMap.put(project, apkConfigMap);
+ // save the project settings into the project persistent property
+ ApkConfigurationHelper.setProperties(properties, settings);
- compileProject = true;
- }
+ // put it in a local map for easy access.
+ mApkSettingsMap.put(project, settings);
// we are done with the modification. Save the property file.
try {
@@ -242,17 +243,14 @@ public class Sdk implements IProjectListener {
if (resolveProject) {
// force a resolve of the project by updating the classpath container.
+ // This will also force a recompile.
IJavaProject javaProject = JavaCore.create(project);
AndroidClasspathContainerInitializer.updateProjects(
new IJavaProject[] { javaProject });
- } else if (compileProject) {
- // If there was removed configs, we clean instead of build
- // (to remove the obsolete ap_ and apk file from removed configs).
+ } else {
+ // always do a full clean/build.
try {
- project.build(cleanProject ?
- IncrementalProjectBuilder.CLEAN_BUILD :
- IncrementalProjectBuilder.FULL_BUILD,
- null);
+ project.build(IncrementalProjectBuilder.CLEAN_BUILD, null);
} catch (CoreException e) {
// failed to build? force resolve instead.
IJavaProject javaProject = JavaCore.create(project);
@@ -316,10 +314,10 @@ public class Sdk implements IProjectListener {
if (sdkStorage != null) {
synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
- Map<String, String> configMap = ApkConfigurationHelper.getConfigs(properties);
+ ApkSettings settings = ApkConfigurationHelper.getSettings(properties);
- if (configMap != null) {
- sdkStorage.mProjectApkConfigMap.put(project, configMap);
+ if (settings != null) {
+ sdkStorage.mApkSettingsMap.put(project, settings);
}
}
}
@@ -392,13 +390,11 @@ public class Sdk implements IProjectListener {
}
/**
- * Returns the configuration map for a given project.
- * <p/>The Map key are name to be used in the apk filename, while the values are comma separated
- * config values. The config value can be passed directly to aapt through the -c option.
+ * Returns the APK settings for a given project.
*/
- public Map<String, String> getProjectApkConfigs(IProject project) {
+ public ApkSettings getApkSettings(IProject project) {
synchronized (AdtPlugin.getDefault().getSdkLockObject()) {
- return mProjectApkConfigMap.get(project);
+ return mApkSettingsMap.get(project);
}
}
@@ -505,7 +501,7 @@ public class Sdk implements IProjectListener {
// now remove the project for the maps.
mProjectTargetMap.remove(project);
- mProjectApkConfigMap.remove(project);
+ mApkSettingsMap.remove(project);
}
}
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
index 0f630c4..5f8a8d5 100644
--- 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
@@ -19,6 +19,7 @@ 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.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.ExportWizardPage;
+import com.android.sdklib.internal.project.ApkSettings;
import org.eclipse.core.resources.IProject;
import org.eclipse.swt.SWT;
@@ -68,17 +69,17 @@ final class KeyCheckPage extends ExportWizardPage {
private Text mDestination;
private boolean mFatalSigningError;
private FormText mDetailText;
- /** The Apk Config map for the current project */
- private Map<String, String> mApkConfig;
private ScrolledComposite mScrolledComposite;
-
+
+ private ApkSettings mApkSettings;
+
private String mKeyDetails;
private String mDestinationDetails;
protected KeyCheckPage(ExportWizard wizard, String pageName) {
super(pageName);
mWizard = wizard;
-
+
setTitle("Destination and key/certificate checks");
setDescription(""); // TODO
}
@@ -93,7 +94,7 @@ final class KeyCheckPage extends ExportWizardPage {
GridLayout gl = new GridLayout(3, false);
gl.verticalSpacing *= 3;
composite.setLayout(gl);
-
+
GridData gd;
new Label(composite, SWT.NONE).setText("Destination APK file:");
@@ -110,26 +111,26 @@ final class KeyCheckPage extends ExportWizardPage {
@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);
@@ -139,18 +140,18 @@ final class KeyCheckPage extends ExportWizardPage {
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();
- mApkConfig = Sdk.getCurrent().getProjectApkConfigs(project);
-
+ mApkSettings = Sdk.getCurrent().getApkSettings(project);
+
String destination = ProjectHelper.loadStringProperty(project,
ExportWizard.PROPERTY_DESTINATION);
String filename = ProjectHelper.loadStringProperty(project,
@@ -159,7 +160,7 @@ final class KeyCheckPage extends ExportWizardPage {
mDestination.setText(destination + File.separator + filename);
}
}
-
+
// if anything change we basically reload the data.
if (mProjectDataChanged != 0) {
mFatalSigningError = false;
@@ -170,7 +171,7 @@ final class KeyCheckPage extends ExportWizardPage {
mPrivateKey = null;
mCertificate = null;
mKeyDetails = null;
-
+
if (mWizard.getKeystoreCreationMode() || mWizard.getKeyCreationMode()) {
int validity = mWizard.getValidity();
StringBuilder sb = new StringBuilder(
@@ -196,13 +197,13 @@ final class KeyCheckPage extends ExportWizardPage {
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) {
@@ -220,33 +221,33 @@ final class KeyCheckPage extends ExportWizardPage {
} 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 + 25 < expirationYear) {
// do nothing
} else {
@@ -258,14 +259,14 @@ final class KeyCheckPage extends ExportWizardPage {
"<p>The Certificate expires in %1$s %2$s.</p>",
count, count == 1 ? "year" : "years"));
}
-
+
sb.append("<p>Make sure the certificate is valid for the planned lifetime of the product.</p>");
sb.append("<p>If the certificate expires, you will be forced to sign your application with a different one.</p>");
sb.append("<p>Applications cannot be upgraded if their certificate changes from one version to another, ");
sb.append("forcing a full uninstall/install, which will make the user lose his/her data.</p>");
sb.append("<p>Android Market currently requires certificates to be valid until 2033.</p>");
}
-
+
mKeyDetails = sb.toString();
}
} else {
@@ -277,7 +278,7 @@ final class KeyCheckPage extends ExportWizardPage {
onDestinationChange(true /*forceDetailUpdate*/);
}
-
+
/**
* Callback for destination field edition
* @param forceDetailUpdate if true, the detail {@link FormText} is updated even if a fatal
@@ -319,12 +320,12 @@ final class KeyCheckPage extends ExportWizardPage {
// display the list of files that will actually be created
Map<String, String[]> apkFileMap = getApkFileMap(file);
-
+
// display them
boolean fileExists = false;
StringBuilder sb = new StringBuilder(String.format(
"<p>This will create the following files:</p>"));
-
+
Set<Entry<String, String[]>> set = apkFileMap.entrySet();
for (Entry<String, String[]> entry : set) {
String[] apkArray = entry.getValue();
@@ -360,7 +361,7 @@ final class KeyCheckPage extends ExportWizardPage {
updateDetailText();
}
}
-
+
/**
* Updates the scrollbar to match the content of the {@link FormText} or the new size
* of the {@link ScrolledComposite}.
@@ -372,41 +373,40 @@ final class KeyCheckPage extends ExportWizardPage {
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();
-
}
/**
* Creates the list of destination filenames based on the content of the destination field
* and the list of APK configurations for the project.
- *
+ *
* @param file File name from the destination field
* @return A list of destination filenames based <code>file</code> and the list of APK
* configurations for the project.
*/
private Map<String, String[]> getApkFileMap(File file) {
String filename = file.getName();
-
+
HashMap<String, String[]> map = new HashMap<String, String[]>();
-
+
// add the default APK filename
String[] apkArray = new String[ExportWizard.APK_COUNT];
apkArray[ExportWizard.APK_FILE_SOURCE] = ProjectHelper.getApkFilename(
@@ -415,29 +415,32 @@ final class KeyCheckPage extends ExportWizardPage {
map.put(null, apkArray);
// add the APKs for each APK configuration.
- if (mApkConfig != null && mApkConfig.size() > 0) {
- // remove the extension.
- int index = filename.lastIndexOf('.');
- String base = filename.substring(0, index);
- String extension = filename.substring(index);
-
- Set<Entry<String, String>> set = mApkConfig.entrySet();
- for (Entry<String, String> entry : set) {
- apkArray = new String[ExportWizard.APK_COUNT];
- apkArray[ExportWizard.APK_FILE_SOURCE] = ProjectHelper.getApkFilename(
- mWizard.getProject(), entry.getKey());
- apkArray[ExportWizard.APK_FILE_DEST] = base + "-" + entry.getKey() + extension;
- map.put(entry.getKey(), apkArray);
+ if (mApkSettings != null) {
+ Map<String, String> apkFilters = mApkSettings.getResourceFilters();
+ if (apkFilters.size() > 0) {
+ // remove the extension from the user-chosen filename
+ int index = filename.lastIndexOf('.');
+ String base = filename.substring(0, index);
+ String extension = filename.substring(index);
+
+ for (Entry<String, String> entry : apkFilters.entrySet()) {
+ apkArray = new String[ExportWizard.APK_COUNT];
+ apkArray[ExportWizard.APK_FILE_SOURCE] = ProjectHelper.getApkFilename(
+ mWizard.getProject(), entry.getKey());
+ apkArray[ExportWizard.APK_FILE_DEST] = base + "-" + //$NON-NLS-1$
+ entry.getKey() + extension;
+ map.put(entry.getKey(), apkArray);
+ }
}
}
-
+
return map;
}
-
+
@Override
protected void onException(Throwable t) {
super.onException(t);
-
+
mKeyDetails = String.format("ERROR: %1$s", ExportWizard.getExceptionMessage(t));
}
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java
index eeab46a..4ba6fa6 100644
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java
@@ -16,91 +16,33 @@
package com.android.sdklib.internal.project;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
/**
* Helper class to read and write Apk Configuration into a {@link ProjectProperties} file.
*/
public class ApkConfigurationHelper {
- /** Prefix for property names for config definition. This prevents having config named
- * after other valid properties such as "target". */
- final static String CONFIG_PREFIX = "apk-config-";
-
/**
- * Reads the Apk Configurations from a {@link ProjectProperties} file and returns them as a map.
- * <p/>If there are no defined configurations, the returned map will be empty.
- * @return a map of apk configurations. The map contains (name, filter) where name is
- * the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of
- * resource configuration to include in the apk (see aapt -c)
+ * Reads the project settings from a {@link ProjectProperties} file and returns them as a
+ * {@link ApkSettings} object.
*/
- public static Map<String, String> getConfigs(ProjectProperties properties) {
- HashMap<String, String> configMap = new HashMap<String, String>();
+ public static ApkSettings getSettings(ProjectProperties properties) {
+ ApkSettings apkSettings = new ApkSettings();
+
+ boolean splitByDensity = Boolean.parseBoolean(properties.getProperty(
+ ProjectProperties.PROPERTY_SPLIT_BY_DENSITY));
+ apkSettings.setSplitByDensity(splitByDensity);
+
- // get the list of configs.
- String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS);
- if (configList != null) {
- // this is a comma separated list
- String[] configs = configList.split(","); //$NON-NLS-1$
-
- // read the value of each config and store it in a map
- for (String config : configs) {
- config = config.trim();
- String configValue = properties.getProperty(CONFIG_PREFIX + config);
- if (configValue != null) {
- configMap.put(config, configValue);
- }
- }
- }
-
- return configMap;
+ return apkSettings;
}
-
+
/**
- * Writes the Apk Configurations from a given map into a {@link ProjectProperties}.
- * @param properties the {@link ProjectProperties} in which to store the apk configurations.
- * @param configMap a map of apk configurations. The map contains (name, filter) where name is
- * the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of
- * resource configuration to include in the apk (see aapt -c)
- * @return true if the {@link ProjectProperties} contained Apk Configuration that were not
- * present in the map.
+ * Sets the content of a {@link ApkSettings} into a {@link ProjectProperties}.
+ * @param properties the {@link ProjectProperties} in which to store the settings.
+ * @param settings the project settings to store.
*/
- public static boolean setConfigs(ProjectProperties properties, Map<String, String> configMap) {
- // load the current configs, in order to remove the value properties for each of them
- // in case a config was removed.
-
- // get the list of configs.
- String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS);
-
- boolean hasRemovedConfig = false;
-
- if (configList != null) {
- // this is a comma separated list
- String[] configs = configList.split(","); //$NON-NLS-1$
-
- for (String config : configs) {
- config = config.trim();
- if (configMap.containsKey(config) == false) {
- hasRemovedConfig = true;
- properties.removeProperty(CONFIG_PREFIX + config);
- }
- }
- }
-
- // now add the properties.
- Set<Entry<String, String>> entrySet = configMap.entrySet();
- StringBuilder sb = new StringBuilder();
- for (Entry<String, String> entry : entrySet) {
- if (sb.length() > 0) {
- sb.append(",");
- }
- sb.append(entry.getKey());
- properties.setProperty(CONFIG_PREFIX + entry.getKey(), entry.getValue());
- }
- properties.setProperty(ProjectProperties.PROPERTY_APK_CONFIGS, sb.toString());
-
- return hasRemovedConfig;
+ public static void setProperties(ProjectProperties properties, ApkSettings settings) {
+ properties.setProperty(ProjectProperties.PROPERTY_SPLIT_BY_DENSITY,
+ Boolean.toString(settings.isSplitByDpi()));
}
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkSettings.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkSettings.java
new file mode 100644
index 0000000..c96e223
--- /dev/null
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkSettings.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 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.android.sdklib.internal.project;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Settings for multiple APK generation.
+ */
+public class ApkSettings {
+ private boolean mSplitByDpi = false;
+
+ public ApkSettings() {
+ }
+
+ /**
+ * Returns a map of configuration filters to be used by the -c option of aapt.
+ * <p/>The map stores (key, value) pairs where the keys is a filename modifier and the value
+ * is the parameter to pass to aapt through the -c option.
+ * @return a map, always. It can however be empty.
+ */
+ public Map<String, String> getResourceFilters() {
+ Map<String, String> map = new HashMap<String, String>();
+ if (mSplitByDpi) {
+ map.put("hdpi", "hdpi,nodpi");
+ map.put("mdpi", "mdpi,nodpi");
+ map.put("ldpi", "ldpi,nodpi");
+ }
+
+ return map;
+ }
+
+ /**
+ * Indicates whether APKs should be generate for each dpi level.
+ */
+ public boolean isSplitByDpi() {
+ return mSplitByDpi;
+ }
+
+ public void setSplitByDensity(boolean split) {
+ mSplitByDpi = split;
+ }
+}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
index b3c172b..5b35d50 100644
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
@@ -35,14 +35,17 @@ import java.util.Map.Entry;
public final class ProjectProperties {
/** The property name for the project target */
public final static String PROPERTY_TARGET = "target";
- public final static String PROPERTY_APK_CONFIGS = "apk.configurations";
+
public final static String PROPERTY_SDK = "sdk.dir";
// LEGACY - compatibility with 1.6 and before
public final static String PROPERTY_SDK_LEGACY = "sdk-location";
+
public final static String PROPERTY_APP_PACKAGE = "application.package";
// LEGACY - compatibility with 1.6 and before
public final static String PROPERTY_APP_PACKAGE_LEGACY = "application-package";
+ public final static String PROPERTY_SPLIT_BY_DENSITY = "split.density";
+
public static enum PropertyType {
BUILD("build.properties", BUILD_HEADER),
DEFAULT("default.properties", DEFAULT_HEADER),
@@ -107,17 +110,8 @@ public final class ProjectProperties {
// 1-------10--------20--------30--------40--------50--------60--------70--------80
COMMENT_MAP.put(PROPERTY_TARGET,
"# Project target.\n");
- COMMENT_MAP.put(PROPERTY_APK_CONFIGS,
- "# apk configurations. This property allows creation of APK files with limited\n" +
- "# resources. For example, if your application contains many locales and\n" +
- "# you wish to release multiple smaller apks instead of a large one, you can\n" +
- "# define configuration to create apks with limited language sets.\n" +
- "# Format is a comma separated list of configuration names. For each\n" +
- "# configuration, a property will declare the resource configurations to\n" +
- "# include. Example:\n" +
- "# " + PROPERTY_APK_CONFIGS +"=european,northamerica\n" +
- "# " + ApkConfigurationHelper.CONFIG_PREFIX + "european=en,fr,it,de,es\n" +
- "# " + ApkConfigurationHelper.CONFIG_PREFIX + "northamerica=en,es\n");
+ COMMENT_MAP.put(PROPERTY_SPLIT_BY_DENSITY,
+ "# Indicates whether an apk should be generated for each density.\n");
COMMENT_MAP.put(PROPERTY_SDK,
"# location of the SDK. This is only used by Ant\n" +
"# For customization when using a Version Control System, please read the\n" +
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ApkConfigEditDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ApkConfigEditDialog.java
deleted file mode 100644
index be241a5..0000000
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ApkConfigEditDialog.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2009 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.android.sdkuilib.internal.widgets;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-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.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Edit dialog to create/edit APK configuration. The dialog displays 2 text fields for the config
- * name and its filter.
- */
-class ApkConfigEditDialog extends Dialog implements ModifyListener, VerifyListener {
-
- private String mName;
- private String mFilter;
- private Text mNameField;
- private Text mFilterField;
- private Button mOkButton;
-
- /**
- * Creates an edit dialog with optional initial values for the name and filter.
- * @param name optional value for the name. Can be null.
- * @param filter optional value for the filter. Can be null.
- * @param parentShell the parent shell.
- */
- protected ApkConfigEditDialog(String name, String filter, Shell parentShell) {
- super(parentShell);
- mName = name;
- mFilter = filter;
- }
-
- /**
- * Returns the name of the config. This is only valid if the user clicked OK and {@link #open()}
- * returned {@link Window#OK}
- */
- public String getName() {
- return mName;
- }
-
- /**
- * Returns the filter for the config. This is only valid if the user clicked OK and
- * {@link #open()} returned {@link Window#OK}
- */
- public String getFilter() {
- return mFilter;
- }
-
- @Override
- protected Control createContents(Composite parent) {
- Control control = super.createContents(parent);
-
- mOkButton = getButton(IDialogConstants.OK_ID);
- validateButtons();
-
- return control;
- }
-
- @Override
- protected Control createDialogArea(Composite parent) {
- Composite composite = new Composite(parent, SWT.NONE);
- GridLayout layout;
- composite.setLayout(layout = new GridLayout(2, false));
- layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
- layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
- layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
- layout.horizontalSpacing = convertHorizontalDLUsToPixels(
- IDialogConstants.HORIZONTAL_SPACING);
-
- composite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- Label l = new Label(composite, SWT.NONE);
- l.setText("Name");
-
- mNameField = new Text(composite, SWT.BORDER);
- mNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mNameField.addVerifyListener(this);
- if (mName != null) {
- mNameField.setText(mName);
- }
- mNameField.addModifyListener(this);
-
- l = new Label(composite, SWT.NONE);
- l.setText("Filter");
-
- mFilterField = new Text(composite, SWT.BORDER);
- mFilterField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- if (mFilter != null) {
- mFilterField.setText(mFilter);
- }
- mFilterField.addVerifyListener(this);
- mFilterField.addModifyListener(this);
-
- applyDialogFont(composite);
- return composite;
- }
-
- /**
- * Validates the OK button based on the content of the 2 text fields.
- */
- private void validateButtons() {
- mOkButton.setEnabled(mNameField.getText().trim().length() > 0 &&
- mFilterField.getText().trim().length() > 0);
- }
-
- @Override
- protected void okPressed() {
- mName = mNameField.getText();
- mFilter = mFilterField.getText().trim();
- super.okPressed();
- }
-
- /**
- * Callback for text modification in the 2 text fields.
- */
- public void modifyText(ModifyEvent e) {
- validateButtons();
- }
-
- /**
- * Callback to ensure the content of the text field are proper.
- */
- public void verifyText(VerifyEvent e) {
- Text source = ((Text)e.getSource());
- if (source == mNameField) {
- // check for a-zA-Z0-9.
- final String text = e.text;
- final int len = text.length();
- for (int i = 0 ; i < len; i++) {
- char letter = text.charAt(i);
- if (letter > 255 || Character.isLetterOrDigit(letter) == false) {
- e.doit = false;
- return;
- }
- }
- } else if (source == mFilterField) {
- // we can't validate the content as its typed, but we can at least ensure the characters
- // are valid. Same as mNameFiled + the comma.
- final String text = e.text;
- final int len = text.length();
- for (int i = 0 ; i < len; i++) {
- char letter = text.charAt(i);
- if (letter > 255 || (Character.isLetterOrDigit(letter) == false && letter != ',')) {
- e.doit = false;
- return;
- }
- }
- }
- }
-}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ApkConfigWidget.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ApkConfigWidget.java
deleted file mode 100644
index a05f9bd..0000000
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ApkConfigWidget.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2009 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.android.sdkuilib.internal.widgets;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-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.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * The APK Configuration widget is a table that is added to the given parent composite.
- * <p/>
- * To use, create it using {@link #ApkConfigWidget(Composite)} then
- * call {@link #fillTable(Map)} to set the initial list of configurations.
- */
-public class ApkConfigWidget {
- private final static int INDEX_NAME = 0;
- private final static int INDEX_FILTER = 1;
-
- private Table mApkConfigTable;
- private Button mEditButton;
- private Button mDelButton;
-
- public ApkConfigWidget(final Composite parent) {
- final Composite apkConfigComp = new Composite(parent, SWT.NONE);
- apkConfigComp.setLayoutData(new GridData(GridData.FILL_BOTH));
- apkConfigComp.setLayout(new GridLayout(2, false));
-
- mApkConfigTable = new Table(apkConfigComp, SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
- mApkConfigTable.setHeaderVisible(true);
- mApkConfigTable.setLinesVisible(true);
-
- GridData data = new GridData();
- data.grabExcessVerticalSpace = true;
- data.grabExcessHorizontalSpace = true;
- data.horizontalAlignment = GridData.FILL;
- data.verticalAlignment = GridData.FILL;
- mApkConfigTable.setLayoutData(data);
-
- // create the table columns
- final TableColumn column0 = new TableColumn(mApkConfigTable, SWT.NONE);
- column0.setText("Name");
- column0.setWidth(100);
- final TableColumn column1 = new TableColumn(mApkConfigTable, SWT.NONE);
- column1.setText("Configuration");
- column1.setWidth(100);
-
- Composite buttonComp = new Composite(apkConfigComp, SWT.NONE);
- buttonComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
- GridLayout gl;
- buttonComp.setLayout(gl = new GridLayout(1, false));
- gl.marginHeight = gl.marginWidth = 0;
-
- Button newButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
- newButton.setText("New...");
- newButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- mEditButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
- mEditButton.setText("Edit...");
- mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- mDelButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
- mDelButton.setText("Delete");
- mDelButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- newButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- ApkConfigEditDialog dlg = new ApkConfigEditDialog(null /*name*/, null /*filter*/,
- apkConfigComp.getShell());
- if (dlg.open() == Dialog.OK) {
- TableItem item = new TableItem(mApkConfigTable, SWT.NONE);
- item.setText(INDEX_NAME, dlg.getName());
- item.setText(INDEX_FILTER, dlg.getFilter());
-
- onSelectionChanged();
- }
- }
- });
-
- mEditButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- // get the current selection (single mode so we don't care about any item beyond
- // index 0).
- TableItem[] items = mApkConfigTable.getSelection();
- if (items.length != 0) {
- ApkConfigEditDialog dlg = new ApkConfigEditDialog(
- items[0].getText(INDEX_NAME), items[0].getText(INDEX_FILTER),
- apkConfigComp.getShell());
- if (dlg.open() == Dialog.OK) {
- items[0].setText(INDEX_NAME, dlg.getName());
- items[0].setText(INDEX_FILTER, dlg.getFilter());
- }
- }
- }
- });
-
- mDelButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- // get the current selection (single mode so we don't care about any item beyond
- // index 0).
- int[] indices = mApkConfigTable.getSelectionIndices();
- if (indices.length != 0) {
- TableItem item = mApkConfigTable.getItem(indices[0]);
- if (MessageDialog.openQuestion(parent.getShell(),
- "Apk Configuration deletion",
- String.format(
- "Are you sure you want to delete configuration '%1$s'?",
- item.getText(INDEX_NAME)))) {
- // delete the item.
- mApkConfigTable.remove(indices[0]);
-
- onSelectionChanged();
- }
- }
- }
- });
-
- // Add a listener to resize the column to the full width of the table
- mApkConfigTable.addControlListener(new ControlAdapter() {
- @Override
- public void controlResized(ControlEvent e) {
- Rectangle r = mApkConfigTable.getClientArea();
- column0.setWidth(r.width * 30 / 100); // 30%
- column1.setWidth(r.width * 70 / 100); // 70%
- }
- });
-
- // add a selection listener on the table, to enable/disable buttons.
- mApkConfigTable.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- onSelectionChanged();
- }
- });
- }
-
- public void fillTable(Map<String, String> apkConfigMap) {
- // get the names in a list so that we can sort them.
- if (apkConfigMap != null) {
- Set<String> keys = apkConfigMap.keySet();
- String[] keyArray = keys.toArray(new String[keys.size()]);
- Arrays.sort(keyArray);
-
- for (String key : keyArray) {
- TableItem item = new TableItem(mApkConfigTable, SWT.NONE);
- item.setText(INDEX_NAME, key);
- item.setText(INDEX_FILTER, apkConfigMap.get(key));
- }
- }
-
- onSelectionChanged();
- }
-
- public Map<String, String> getApkConfigs() {
- // go through all the items from the table and fill a new map
- HashMap<String, String> map = new HashMap<String, String>();
-
- TableItem[] items = mApkConfigTable.getItems();
- for (TableItem item : items) {
- map.put(item.getText(INDEX_NAME), item.getText(INDEX_FILTER));
- }
-
- return map;
- }
-
- /**
- * Handles table selection changes.
- */
- private void onSelectionChanged() {
- if (mApkConfigTable.getSelectionCount() > 0) {
- mEditButton.setEnabled(true);
- mDelButton.setEnabled(true);
- } else {
- mEditButton.setEnabled(false);
- mDelButton.setEnabled(false);
- }
- }
-}