auto import from //branches/cupcake_rel/...@138607

This commit is contained in:
The Android Open Source Project
2009-03-13 13:04:19 -07:00
parent 243d18eb22
commit 59008ebc2c
31 changed files with 1540 additions and 580 deletions

View File

@@ -481,6 +481,12 @@
style="push"
toolbarPath="android_project"
tooltip="Opens a wizard to help create a new Android XML file">
<enablement>
<objectState
name="projectNature"
value="com.android.ide.eclipse.adt.AndroidNature">
</objectState>
</enablement>
</action>
<action
class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"

View File

@@ -966,9 +966,10 @@ public class ApkBuilder extends BaseBuilder {
* @param javaProject the javaProject object.
* @param referencedJavaProjects the java projects that this project references.
* @throws IOException
* @throws CoreException
*/
private void writeStandardResources(SignedJarBuilder jarBuilder, IJavaProject javaProject,
IJavaProject[] referencedJavaProjects) throws IOException {
IJavaProject[] referencedJavaProjects) throws IOException, CoreException {
IWorkspace ws = ResourcesPlugin.getWorkspace();
IWorkspaceRoot wsRoot = ws.getRoot();
@@ -978,7 +979,9 @@ public class ApkBuilder extends BaseBuilder {
writeStandardProjectResources(jarBuilder, javaProject, wsRoot, list);
for (IJavaProject referencedJavaProject : referencedJavaProjects) {
writeStandardProjectResources(jarBuilder, referencedJavaProject, wsRoot, list);
if (referencedJavaProject.getProject().hasNature(AndroidConstants.NATURE)) {
writeStandardProjectResources(jarBuilder, referencedJavaProject, wsRoot, list);
}
}
}
@@ -1067,7 +1070,9 @@ public class ApkBuilder extends BaseBuilder {
}
/**
* Returns the list of the output folders for the specified {@link IJavaProject} objects.
* Returns the list of the output folders for the specified {@link IJavaProject} objects, if
* they are Android projects.
*
* @param referencedJavaProjects the java projects.
* @return an array, always. Can be empty.
* @throws CoreException
@@ -1079,19 +1084,21 @@ public class ApkBuilder extends BaseBuilder {
IWorkspaceRoot wsRoot = ws.getRoot();
for (IJavaProject javaProject : referencedJavaProjects) {
// get the output folder
IPath path = null;
try {
path = javaProject.getOutputLocation();
} catch (JavaModelException e) {
continue;
}
IResource outputResource = wsRoot.findMember(path);
if (outputResource != null && outputResource.getType() == IResource.FOLDER) {
String outputOsPath = outputResource.getLocation().toOSString();
list.add(outputOsPath);
if (javaProject.getProject().hasNature(AndroidConstants.NATURE)) {
// get the output folder
IPath path = null;
try {
path = javaProject.getOutputLocation();
} catch (JavaModelException e) {
continue;
}
IResource outputResource = wsRoot.findMember(path);
if (outputResource != null && outputResource.getType() == IResource.FOLDER) {
String outputOsPath = outputResource.getLocation().toOSString();
list.add(outputOsPath);
}
}
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 2009 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.launch;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.MultiLineReceiver;
import com.android.ide.eclipse.adt.AdtPlugin;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Output receiver for am process (Activity Manager)
*
* Monitors adb output for am errors, and retries launch as appropriate.
*/
public class AMReceiver extends MultiLineReceiver {
private static final int MAX_ATTEMPT_COUNT = 5;
private static final Pattern sAmErrorType = Pattern.compile("Error type (\\d+)"); //$NON-NLS-1$
private final DelayedLaunchInfo mLaunchInfo;
private final IDevice mDevice;
private final ILaunchController mLaunchController;
/**
* Basic constructor.
*
* @param launchInfo the {@link DelayedLaunchInfo} associated with the am process.
* @param device the Android device on which the launch is done.
* @param launchController the {@link ILaunchController} that is managing the launch
*/
public AMReceiver(DelayedLaunchInfo launchInfo, IDevice device,
ILaunchController launchController) {
mLaunchInfo = launchInfo;
mDevice = device;
mLaunchController = launchController;
}
/**
* Monitors the am process for error messages. If an error occurs, will reattempt launch up to
* <code>MAX_ATTEMPT_COUNT</code> times.
*
* @param lines a portion of the am output
*
* @see MultiLineReceiver#processNewLines(String[])
*/
@Override
public void processNewLines(String[] lines) {
// first we check if one starts with error
ArrayList<String> array = new ArrayList<String>();
boolean error = false;
boolean warning = false;
for (String s : lines) {
// ignore empty lines.
if (s.length() == 0) {
continue;
}
// check for errors that output an error type, if the attempt count is still
// valid. If not the whole text will be output in the console
if (mLaunchInfo.getAttemptCount() < MAX_ATTEMPT_COUNT &&
mLaunchInfo.isCancelled() == false) {
Matcher m = sAmErrorType.matcher(s);
if (m.matches()) {
// get the error type
int type = Integer.parseInt(m.group(1));
final int waitTime = 3;
String msg;
switch (type) {
case 1:
/* Intended fall through */
case 2:
msg = String.format(
"Device not ready. Waiting %1$d seconds before next attempt.",
waitTime);
break;
case 3:
msg = String.format(
"New package not yet registered with the system. Waiting %1$d seconds before next attempt.",
waitTime);
break;
default:
msg = String.format(
"Device not ready (%2$d). Waiting %1$d seconds before next attempt.",
waitTime, type);
break;
}
AdtPlugin.printToConsole(mLaunchInfo.getProject(), msg);
// launch another thread, that waits a bit and attempts another launch
new Thread("Delayed Launch attempt") {
@Override
public void run() {
try {
sleep(waitTime * 1000);
} catch (InterruptedException e) {
// ignore
}
mLaunchController.launchApp(mLaunchInfo, mDevice);
}
}.start();
// no need to parse the rest
return;
}
}
// check for error if needed
if (error == false && s.startsWith("Error:")) { //$NON-NLS-1$
error = true;
}
if (warning == false && s.startsWith("Warning:")) { //$NON-NLS-1$
warning = true;
}
// add the line to the list
array.add("ActivityManager: " + s); //$NON-NLS-1$
}
// then we display them in the console
if (warning || error) {
AdtPlugin.printErrorToConsole(mLaunchInfo.getProject(), array.toArray());
} else {
AdtPlugin.printToConsole(mLaunchInfo.getProject(), array.toArray());
}
// if error then we cancel the launch, and remove the delayed info
if (error) {
mLaunchController.stopLaunch(mLaunchInfo);
}
}
/**
* Returns true if launch has been cancelled
*/
public boolean isCancelled() {
return mLaunchInfo.isCancelled();
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2009 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.launch;
import com.android.ddmlib.IDevice;
import com.android.ide.eclipse.adt.AdtPlugin;
import java.io.IOException;
/**
* Launches the given activity
*/
public class ActivityLaunchAction implements IAndroidLaunchAction {
private final String mActivity;
private final ILaunchController mLaunchController;
/**
* Creates a ActivityLaunchAction
*
* @param activity fully qualified activity name to launch
* @param controller the {@link ILaunchController} that performs launch
*/
public ActivityLaunchAction(String activity, ILaunchController controller) {
mActivity = activity;
mLaunchController = controller;
}
/**
* Launches the activity on targeted device
*
* @param info the {@link DelayedLaunchInfo} that contains launch details
* @param device the Android device to perform action on
*
* @see IAndroidLaunchAction#doLaunchAction(DelayedLaunchInfo, IDevice)
*/
public boolean doLaunchAction(DelayedLaunchInfo info, IDevice device) {
try {
String msg = String.format("Starting activity %1$s on device ", mActivity,
device);
AdtPlugin.printToConsole(info.getProject(), msg);
// In debug mode, we need to add the info to the list of application monitoring
// client changes.
// increment launch attempt count, to handle retries and timeouts
info.incrementAttemptCount();
// now we actually launch the app.
device.executeShellCommand("am start" //$NON-NLS-1$
+ (info.isDebugMode() ? " -D" //$NON-NLS-1$
: "") //$NON-NLS-1$
+ " -n " //$NON-NLS-1$
+ info.getPackageName() + "/" //$NON-NLS-1$
+ mActivity.replaceAll("\\$", "\\\\\\$"), //$NON-NLS-1$ //$NON-NLS-2$
new AMReceiver(info, device, mLaunchController));
// if the app is not a debug app, we need to do some clean up, as
// the process is done!
if (info.isDebugMode() == false) {
// stop the launch object, since there's no debug, and it can't
// provide any control over the app
return false;
}
} catch (IOException e) {
// something went wrong trying to launch the app.
// lets stop the Launch
AdtPlugin.printErrorToConsole(info.getProject(),
String.format("Launch error: %s", e.getMessage()));
return false;
}
return true;
}
/**
* Returns a description of the activity being launched
*
* @see IAndroidLaunchAction#getLaunchDescription()
*/
public String getLaunchDescription() {
return String.format("%1$s activity launch", mActivity);
}
}

View File

@@ -26,7 +26,7 @@ import org.eclipse.debug.core.model.ISourceLocator;
* Custom implementation of Launch to allow access to the LaunchManager
*
*/
class AndroidLaunch extends Launch {
public class AndroidLaunch extends Launch {
/**
* Basic constructor does nothing special

View File

@@ -0,0 +1,133 @@
/*
* Copyright (C) 2009 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.launch;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
/**
* Launch configuration data. This stores the result of querying the
* {@link ILaunchConfiguration} so that it's only done once.
*/
public class AndroidLaunchConfiguration {
/**
* Launch action. See {@link LaunchConfigDelegate#ACTION_DEFAULT},
* {@link LaunchConfigDelegate#ACTION_ACTIVITY},
* {@link LaunchConfigDelegate#ACTION_DO_NOTHING}
*/
public int mLaunchAction = LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION;
public static final boolean AUTO_TARGET_MODE = true;
/**
* Target selection mode.
* <ul>
* <li><code>true</code>: automatic mode, see {@link #AUTO_TARGET_MODE}</li>
* <li><code>false</code>: manual mode</li>
* </ul>
*/
public boolean mTargetMode = LaunchConfigDelegate.DEFAULT_TARGET_MODE;
/**
* Indicates whether the emulator should be called with -wipe-data
*/
public boolean mWipeData = LaunchConfigDelegate.DEFAULT_WIPE_DATA;
/**
* Indicates whether the emulator should be called with -no-boot-anim
*/
public boolean mNoBootAnim = LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM;
/**
* AVD Name.
*/
public String mAvdName = null;
public String mNetworkSpeed = EmulatorConfigTab.getSpeed(
LaunchConfigDelegate.DEFAULT_SPEED);
public String mNetworkDelay = EmulatorConfigTab.getDelay(
LaunchConfigDelegate.DEFAULT_DELAY);
/**
* Optional custom command line parameter to launch the emulator
*/
public String mEmulatorCommandLine;
/**
* Initialized the structure from an ILaunchConfiguration object.
* @param config
*/
public void set(ILaunchConfiguration config) {
try {
mLaunchAction = config.getAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION,
mLaunchAction);
} catch (CoreException e1) {
// nothing to be done here, we'll use the default value
}
try {
mTargetMode = config.getAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
mTargetMode);
} catch (CoreException e) {
// nothing to be done here, we'll use the default value
}
try {
mAvdName = config.getAttribute(LaunchConfigDelegate.ATTR_AVD_NAME, mAvdName);
} catch (CoreException e) {
// ignore
}
int index = LaunchConfigDelegate.DEFAULT_SPEED;
try {
index = config.getAttribute(LaunchConfigDelegate.ATTR_SPEED, index);
} catch (CoreException e) {
// nothing to be done here, we'll use the default value
}
mNetworkSpeed = EmulatorConfigTab.getSpeed(index);
index = LaunchConfigDelegate.DEFAULT_DELAY;
try {
index = config.getAttribute(LaunchConfigDelegate.ATTR_DELAY, index);
} catch (CoreException e) {
// nothing to be done here, we'll use the default value
}
mNetworkDelay = EmulatorConfigTab.getDelay(index);
try {
mEmulatorCommandLine = config.getAttribute(
LaunchConfigDelegate.ATTR_COMMANDLINE, ""); //$NON-NLS-1$
} catch (CoreException e) {
// lets not do anything here, we'll use the default value
}
try {
mWipeData = config.getAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA, mWipeData);
} catch (CoreException e) {
// nothing to be done here, we'll use the default value
}
try {
mNoBootAnim = config.getAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM,
mNoBootAnim);
} catch (CoreException e) {
// nothing to be done here, we'll use the default value
}
}
}

View File

@@ -0,0 +1,226 @@
/*
* Copyright (C) 2009 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.launch;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import com.android.ddmlib.IDevice;
/**
* A delayed launch waiting for a device to be present or ready before the
* application is launched.
*/
public final class DelayedLaunchInfo {
/**
* Used to indicate behavior when Android app already exists
*/
enum InstallRetryMode {
NEVER, ALWAYS, PROMPT;
}
/** The device on which to launch the app */
private IDevice mDevice = null;
/** The eclipse project */
private final IProject mProject;
/** Package name */
private final String mPackageName;
/** IFile to the package (.apk) file */
private final IFile mPackageFile;
/** debuggable attribute of the manifest file. */
private final Boolean mDebuggable;
/** Required ApiVersionNumber by the app. 0 means no requirements */
private final int mRequiredApiVersionNumber;
private InstallRetryMode mRetryMode = InstallRetryMode.NEVER;
/** Launch action. */
private final IAndroidLaunchAction mLaunchAction;
/** the launch object */
private final AndroidLaunch mLaunch;
/** the monitor object */
private final IProgressMonitor mMonitor;
/** debug mode flag */
private boolean mDebugMode;
/** current number of launch attempts */
private int mAttemptCount = 0;
/** cancellation state of launch */
private boolean mCancelled = false;
/**
* Basic constructor with activity and package info.
*
* @param project the eclipse project that corresponds to Android app
* @param packageName package name of Android app
* @param launchAction action to perform after app install
* @param pack IFile to the package (.apk) file
* @param debuggable debuggable attribute of the app's manifest file.
* @param requiredApiVersionNumber required SDK version by the app. 0 means no requirements.
* @param launch the launch object
* @param monitor progress monitor for launch
*/
public DelayedLaunchInfo(IProject project, String packageName,
IAndroidLaunchAction launchAction, IFile pack, Boolean debuggable,
int requiredApiVersionNumber, AndroidLaunch launch, IProgressMonitor monitor) {
mProject = project;
mPackageName = packageName;
mPackageFile = pack;
mLaunchAction = launchAction;
mLaunch = launch;
mMonitor = monitor;
mDebuggable = debuggable;
mRequiredApiVersionNumber = requiredApiVersionNumber;
}
/**
* @return the device on which to launch the app
*/
public IDevice getDevice() {
return mDevice;
}
/**
* Set the device on which to launch the app
*/
public void setDevice(IDevice device) {
mDevice = device;
}
/**
* @return the eclipse project that corresponds to Android app
*/
public IProject getProject() {
return mProject;
}
/**
* @return the package name of the Android app
*/
public String getPackageName() {
return mPackageName;
}
/**
* @return the application package file
*/
public IFile getPackageFile() {
return mPackageFile;
}
/**
* @return true if Android app is marked as debuggable in its manifest
*/
public Boolean getDebuggable() {
return mDebuggable;
}
/**
* @return the required api version number for the Android app
*/
public int getRequiredApiVersionNumber() {
return mRequiredApiVersionNumber;
}
/**
* @param retryMode the install retry mode to set
*/
public void setRetryMode(InstallRetryMode retryMode) {
this.mRetryMode = retryMode;
}
/**
* @return the installation retry mode
*/
public InstallRetryMode getRetryMode() {
return mRetryMode;
}
/**
* @return the launch action
*/
public IAndroidLaunchAction getLaunchAction() {
return mLaunchAction;
}
/**
* @return the launch
*/
public AndroidLaunch getLaunch() {
return mLaunch;
}
/**
* @return the launch progress monitor
*/
public IProgressMonitor getMonitor() {
return mMonitor;
}
/**
* @param debugMode the debug mode to set
*/
public void setDebugMode(boolean debugMode) {
this.mDebugMode = debugMode;
}
/**
* @return true if this is a debug launch
*/
public boolean isDebugMode() {
return mDebugMode;
}
/**
* Increases the number of launch attempts
*/
public void incrementAttemptCount() {
mAttemptCount++;
}
/**
* @return the number of launch attempts made
*/
public int getAttemptCount() {
return mAttemptCount;
}
/**
* Set if launch has been cancelled
*/
public void setCancelled(boolean cancelled) {
this.mCancelled = cancelled;
}
/**
* @return true if launch has been cancelled
*/
public boolean isCancelled() {
return mCancelled;
}
}

View File

@@ -231,9 +231,9 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
public static class DeviceChooserResponse {
private AvdInfo mAvdToLaunch;
private Device mDeviceToUse;
private IDevice mDeviceToUse;
public void setDeviceToUse(Device d) {
public void setDeviceToUse(IDevice d) {
mDeviceToUse = d;
mAvdToLaunch = null;
}
@@ -243,7 +243,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
mDeviceToUse = null;
}
public Device getDeviceToUse() {
public IDevice getDeviceToUse() {
return mDeviceToUse;
}
@@ -737,3 +737,4 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
mDisableAvdSelectionChange = false;
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2009 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.launch;
import com.android.ddmlib.IDevice;
import com.android.ide.eclipse.adt.AdtPlugin;
/**
* A launch action that does nothing after the application has been installed
*/
public class EmptyLaunchAction implements IAndroidLaunchAction {
public boolean doLaunchAction(DelayedLaunchInfo info, IDevice device) {
// we're not supposed to do anything, just return;
String msg = String.format("%1$s installed on device",
info.getPackageFile().getFullPath().toOSString());
AdtPlugin.printToConsole(info.getProject(), msg, "Done!");
// return false so launch controller will not wait for debugger to attach
return false;
}
public String getLaunchDescription() {
return "sync";
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2009 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.launch;
import com.android.ddmlib.IDevice;
import com.android.ide.eclipse.adt.launch.DelayedLaunchInfo;
/**
* An action to perform after performing a launch of an Android application
*/
public interface IAndroidLaunchAction {
/**
* Do the launch
*
* @param info the {@link DelayedLaunchInfo} that contains launch details
* @param device the Android device to perform action on
* @returns true if launch was successfully, and controller should wait for debugger to attach
* (if applicable)
*/
boolean doLaunchAction(DelayedLaunchInfo info, IDevice device);
/**
* Return a description of launch, to be used for logging and error messages
*/
String getLaunchDescription();
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2009 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.launch;
import com.android.ddmlib.IDevice;
/**
* Interface for managing Android launches
*/
public interface ILaunchController {
/**
* Launches an application on a device or emulator
*
* @param launchInfo the {@link DelayedLaunchInfo} that indicates the launch action
* @param device the device or emulator to launch the application on
*/
public void launchApp(DelayedLaunchInfo launchInfo, IDevice device);
/**
* Cancels a launch
*
* @param launchInfo the {@link DelayedLaunchInfo} to cancel
*/
void stopLaunch(DelayedLaunchInfo launchInfo);
}

View File

@@ -18,7 +18,6 @@ package com.android.ide.eclipse.adt.launch;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.launch.AndroidLaunchController.AndroidLaunchConfiguration;
import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
@@ -233,7 +232,16 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate {
return;
}
String activityName = null;
doLaunch(configuration, mode, monitor, project, androidLaunch, config, controller,
applicationPackage, manifestParser);
}
protected void doLaunch(ILaunchConfiguration configuration, String mode,
IProgressMonitor monitor, IProject project, AndroidLaunch androidLaunch,
AndroidLaunchConfiguration config, AndroidLaunchController controller,
IFile applicationPackage, AndroidManifestParser manifestParser) {
String activityName = null;
if (config.mLaunchAction == ACTION_ACTIVITY) {
// Get the activity name defined in the config
@@ -292,11 +300,16 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate {
}
}
IAndroidLaunchAction launchAction = new EmptyLaunchAction();
if (activityName != null) {
launchAction = new ActivityLaunchAction(activityName, controller);
}
// everything seems fine, we ask the launch controller to handle
// the rest
controller.launch(project, mode, applicationPackage, manifestParser.getPackage(),
manifestParser.getDebuggable(), manifestParser.getApiLevelRequirement(),
activityName, config, androidLaunch, monitor);
launchAction, config, androidLaunch, monitor);
}
@Override

View File

@@ -400,6 +400,9 @@ public final class ProjectHelper {
try {
parser = AndroidManifestParser.parseForData(manifestFile);
} catch (CoreException e) {
// ignore, handled below.
}
if (parser == null) {
// skip this project.
continue;
}

View File

@@ -253,8 +253,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
if (markerMessage != null) {
// log the error and put the marker on the project if we can.
if (outputToConsole) {
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_ALWAYS, iProject,
markerMessage);
AdtPlugin.printErrorToConsole(iProject, markerMessage);
}
try {

View File

@@ -36,7 +36,6 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
@@ -823,12 +822,7 @@ public class NewProjectCreationPage extends WizardPage {
Path path = new Path(f.getPath());
String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
AndroidManifestParser manifestData = null;
try {
manifestData = AndroidManifestParser.parseForData(osPath);
} catch (CoreException e1) {
// ignore any parsing issue
}
AndroidManifestParser manifestData = AndroidManifestParser.parseForData(osPath);
if (manifestData == null) {
return;
}
@@ -1096,10 +1090,8 @@ public class NewProjectCreationPage extends WizardPage {
}
// Parse it and check the important fields.
AndroidManifestParser manifestData;
try {
manifestData = AndroidManifestParser.parseForData(osPath);
} catch (CoreException e) {
AndroidManifestParser manifestData = AndroidManifestParser.parseForData(osPath);
if (manifestData == null) {
return setStatus(
String.format("File %1$s could not be parsed.", osPath),
MSG_ERROR);

View File

@@ -686,7 +686,8 @@ public class AndroidManifestParser {
* Parses the manifest file, and collects data.
* @param manifestFile The manifest file to parse.
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
* @throws CoreException for example the file does not exist in the workspace or
* the workspace needs to be refreshed.
*/
public static AndroidManifestParser parseForData(IFile manifestFile) throws CoreException {
return parse(null /* javaProject */, manifestFile, null /* errorListener */,
@@ -698,11 +699,15 @@ public class AndroidManifestParser {
*
* @param osManifestFilePath The OS path of the manifest file to parse.
* @return an {@link AndroidManifestParser} or null if the parsing failed.
* @throws CoreException
*/
public static AndroidManifestParser parseForData(String osManifestFilePath)
throws CoreException {
return parse(new File(osManifestFilePath));
public static AndroidManifestParser parseForData(String osManifestFilePath) {
try {
return parse(new File(osManifestFilePath));
} catch (CoreException e) {
// Ignore workspace errors (unlikely to happen since this parses an actual file,
// not a workspace resource).
return null;
}
}
/**

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2009 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.editors.layout;
import com.android.ide.eclipse.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
import com.android.ide.eclipse.editors.layout.parts.ElementCreateCommand;
import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;
import org.eclipse.gef.ui.parts.SelectionSynchronizer;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.ui.IWorkbenchPart;
/**
* Abstract GraphicalLayoutEditor.
*/
/*package*/ abstract class AbstractGraphicalLayoutEditor extends GraphicalEditorWithPalette
implements IWorkbenchPart, ILayoutReloadListener {
/**
* Sets the UI for the edition of a new file.
* @param configuration the configuration of the new file.
*/
abstract void editNewFile(FolderConfiguration configuration);
/**
* Reloads this editor, by getting the new model from the {@link LayoutEditor}.
*/
abstract void reloadEditor();
/**
* Callback for XML model changed. Only update/recompute the layout if the editor is visible
*/
abstract void onXmlModelChanged();
/**
* Responds to a page change that made the Graphical editor page the activated page.
*/
abstract void activated();
/**
* Responds to a page change that made the Graphical editor page the deactivated page
*/
abstract void deactivated();
/**
* Used by LayoutEditor.UiEditorActions.selectUiNode to select a new UI Node
* created by {@link ElementCreateCommand#execute()}.
*
* @param uiNodeModel The {@link UiElementNode} to select.
*/
abstract void selectModel(UiElementNode uiNodeModel);
/**
* Returns the selection synchronizer object.
* The synchronizer can be used to sync the selection of 2 or more EditPartViewers.
* <p/>
* This is changed from protected to public so that the outline can use it.
*
* @return the synchronizer
*/
@Override
public SelectionSynchronizer getSelectionSynchronizer() {
return super.getSelectionSynchronizer();
}
/**
* Returns the edit domain.
* <p/>
* This is changed from protected to public so that the outline can use it.
*
* @return the edit domain
*/
@Override
public DefaultEditDomain getEditDomain() {
return super.getEditDomain();
}
abstract void reloadPalette();
abstract void recomputeLayout();
abstract UiDocumentNode getModel();
abstract LayoutEditor getLayoutEditor();
abstract Clipboard getClipboard();
}

View File

@@ -86,8 +86,6 @@ import org.eclipse.gef.dnd.TemplateTransferDropTargetListener;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;
import org.eclipse.gef.ui.parts.SelectionSynchronizer;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
@@ -141,7 +139,7 @@ import java.util.Set;
* <p/>
* To understand Drag'n'drop: http://www.eclipse.org/articles/Article-Workbench-DND/drag_drop.html
*/
public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor
implements ILayoutReloadListener {
private final static String THEME_SEPARATOR = "----------"; //$NON-NLS-1$
@@ -595,6 +593,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
return mPaletteRoot;
}
@Override
public Clipboard getClipboard() {
return mClipboard;
}
@@ -716,7 +715,8 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
*
* @param uiNodeModel The {@link UiElementNode} to select.
*/
public void selectModel(UiElementNode uiNodeModel) {
@Override
void selectModel(UiElementNode uiNodeModel) {
GraphicalViewer viewer = getGraphicalViewer();
// Give focus to the graphical viewer (in case the outline has it)
@@ -734,6 +734,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
// Local methods
//--------------
@Override
public LayoutEditor getLayoutEditor() {
return mLayoutEditor;
}
@@ -863,7 +864,8 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
* Sets the UI for the edition of a new file.
* @param configuration the configuration of the new file.
*/
public void editNewFile(FolderConfiguration configuration) {
@Override
void editNewFile(FolderConfiguration configuration) {
// update the configuration UI
setConfiguration(configuration);
@@ -1015,6 +1017,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
/**
* Reloads this editor, by getting the new model from the {@link LayoutEditor}.
*/
@Override
void reloadEditor() {
GraphicalViewer viewer = getGraphicalViewer();
viewer.setContents(getModel());
@@ -1036,6 +1039,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
/**
* Callback for XML model changed. Only update/recompute the layout if the editor is visible
*/
@Override
void onXmlModelChanged() {
if (mLayoutEditor.isGraphicalEditorActive()) {
doXmlReload(true /* force */);
@@ -1265,10 +1269,12 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
mCurrentLayoutLabel.setText(current != null ? current : "(Default)");
}
@Override
UiDocumentNode getModel() {
return mLayoutEditor.getUiRootNode();
}
@Override
void reloadPalette() {
PaletteFactory.createPaletteRoot(mPaletteRoot, mLayoutEditor.getTargetData());
}
@@ -1667,6 +1673,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
/**
* Recomputes the layout with the help of layoutlib.
*/
@Override
@SuppressWarnings("deprecation")
void recomputeLayout() {
doXmlReload(false /* force */);
@@ -1968,6 +1975,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
/**
* Responds to a page change that made the Graphical editor page the activated page.
*/
@Override
void activated() {
if (mNeedsRecompute || mNeedsXmlReload) {
recomputeLayout();
@@ -1977,6 +1985,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
/**
* Responds to a page change that made the Graphical editor page the deactivated page
*/
@Override
void deactivated() {
// nothing to be done here for now.
}
@@ -2233,31 +2242,6 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
return mConfiguredFrameworkRes;
}
/**
* Returns the selection synchronizer object.
* The synchronizer can be used to sync the selection of 2 or more EditPartViewers.
* <p/>
* This is changed from protected to public so that the outline can use it.
*
* @return the synchronizer
*/
@Override
public SelectionSynchronizer getSelectionSynchronizer() {
return super.getSelectionSynchronizer();
}
/**
* Returns the edit domain.
* <p/>
* This is changed from protected to public so that the outline can use it.
*
* @return the edit domain
*/
@Override
public DefaultEditDomain getEditDomain() {
return super.getEditDomain();
}
/**
* Creates a new layout file from the specificed {@link FolderConfiguration}.
*/

View File

@@ -55,7 +55,7 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa
/** Root node of the UI element hierarchy */
private UiDocumentNode mUiRootNode;
private GraphicalLayoutEditor mGraphicalEditor;
private AbstractGraphicalLayoutEditor mGraphicalEditor;
private int mGraphicalEditorIndex;
/** Implementation of the {@link IContentOutlinePage} for this editor */
private UiContentOutlinePage mOutline;

View File

@@ -70,7 +70,7 @@ import java.util.List;
*/
class UiContentOutlinePage extends ContentOutlinePage {
private GraphicalLayoutEditor mEditor;
private AbstractGraphicalLayoutEditor mEditor;
private Action mAddAction;
private Action mDeleteAction;
@@ -79,7 +79,7 @@ class UiContentOutlinePage extends ContentOutlinePage {
private UiOutlineActions mUiActions = new UiOutlineActions();
public UiContentOutlinePage(GraphicalLayoutEditor editor, final EditPartViewer viewer) {
public UiContentOutlinePage(AbstractGraphicalLayoutEditor editor, final EditPartViewer viewer) {
super(viewer);
mEditor = editor;
IconFactory factory = IconFactory.getInstance();

View File

@@ -18,7 +18,6 @@ package com.android.ide.eclipse.editors.layout.descriptors;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
import com.android.ide.eclipse.common.resources.ResourceType;
import com.android.ide.eclipse.common.resources.ViewClassInfo;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
@@ -27,7 +26,6 @@ import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
import com.android.ide.eclipse.editors.descriptors.ReferenceAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
import com.android.sdklib.SdkConstants;

View File

@@ -217,8 +217,10 @@ public final class CompiledResourcesMonitor implements IFileListener, IProjectLi
try {
IFile manifestFile = AndroidManifestParser.getManifest(project);
AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile);
String javaPackage = data.getPackage();
return javaPackage + ".R"; //$NON-NLS-1$
if (data != null) {
String javaPackage = data.getPackage();
return javaPackage + ".R"; //$NON-NLS-1$
}
} catch (CoreException e) {
// This will typically happen either because the manifest file is not present
// and/or the workspace needs to be refreshed.
@@ -227,8 +229,8 @@ public final class CompiledResourcesMonitor implements IFileListener, IProjectLi
"Failed to find the package of the AndroidManifest of project %1$s. Reason: %2$s",
project.getName(),
e.getMessage());
return null;
}
return null;
}
}

View File

@@ -158,6 +158,35 @@ public class UiResourceAttributeNode extends UiTextAttributeNode {
return null;
}
/**
* Gets all the values one could use to auto-complete a "resource" value in an XML
* content assist.
* <p/>
* Typically the user is editing the value of an attribute in a resource XML, e.g.
* <pre> "&lt;Button android:test="@string/my_[caret]_string..." </pre>
* <p/>
*
* "prefix" is the value that the user has typed so far (or more exactly whatever is on the
* left side of the insertion point). In the example above it would be "@style/my_".
* <p/>
*
* To avoid a huge long list of values, the completion works on two levels:
* <ul>
* <li> If a resource type as been typed so far (e.g. "@style/"), then limit the values to
* the possible completions that match this type.
* <li> If no resource type as been typed so far, then return the various types that could be
* completed. So if the project has only strings and layouts resources, for example,
* the returned list will only include "@string/" and "@layout/".
* </ul>
*
* Finally if anywhere in the string we find the special token "android:", we use the
* current framework system resources rather than the project resources.
* This works for both "@android:style/foo" and "@style/android:foo" conventions even though
* the reconstructed name will always be of the former form.
*
* Note that "android:" here is a keyword specific to Android resources and should not be
* mixed with an XML namespace for an XML attribute name.
*/
@Override
public String[] getPossibleValues(String prefix) {
IResourceRepository repository = null;
@@ -174,6 +203,8 @@ public class UiResourceAttributeNode extends UiTextAttributeNode {
}
} else {
// If there's a prefix with "android:" in it, use the system resources
//
// TODO find a way to only list *public* framework resources here.
AndroidTargetData data = editor.getTargetData();
repository = data.getSystemResources();
isSystem = true;