1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.launch; 18 19 import com.android.ddmlib.AdbCommandRejectedException; 20 import com.android.ddmlib.IDevice; 21 import com.android.ddmlib.ShellCommandUnresponsiveException; 22 import com.android.ddmlib.TimeoutException; 23 import com.android.ide.eclipse.adt.AdtPlugin; 24 25 import java.io.IOException; 26 import java.util.Collection; 27 28 /** 29 * Launches the given activity 30 */ 31 public class ActivityLaunchAction implements IAndroidLaunchAction { 32 33 private final String mActivity; 34 private final ILaunchController mLaunchController; 35 36 /** 37 * Creates a ActivityLaunchAction 38 * 39 * @param activity fully qualified activity name to launch 40 * @param controller the {@link ILaunchController} that performs launch 41 */ 42 public ActivityLaunchAction(String activity, ILaunchController controller) { 43 mActivity = activity; 44 mLaunchController = controller; 45 } 46 47 public boolean doLaunchAction(DelayedLaunchInfo info, IDevice device) { 48 String command = "am start" //$NON-NLS-1$ 49 + (info.isDebugMode() ? " -D" //$NON-NLS-1$ 50 : "") //$NON-NLS-1$ 51 + " -n " //$NON-NLS-1$ 52 + info.getPackageName() + "/" //$NON-NLS-1$ 53 + mActivity.replaceAll("\\$", "\\\\\\$") //$NON-NLS-1$ //$NON-NLS-2$ 54 + " -a android.intent.action.MAIN" //$NON-NLS-1$ 55 + " -c android.intent.category.LAUNCHER"; 56 try { 57 String msg = String.format("Starting activity %1$s on device %2$s", mActivity, 58 device); 59 AdtPlugin.printToConsole(info.getProject(), msg); 60 61 // In debug mode, we need to add the info to the list of application monitoring 62 // client changes. 63 // increment launch attempt count, to handle retries and timeouts 64 info.incrementAttemptCount(); 65 66 // now we actually launch the app. 67 device.executeShellCommand(command, new AMReceiver(info, device, mLaunchController)); 68 69 // if the app is not a debug app, we need to do some clean up, as 70 // the process is done! 71 if (info.isDebugMode() == false) { 72 // stop the launch object, since there's no debug, and it can't 73 // provide any control over the app 74 return false; 75 } 76 } catch (TimeoutException e) { 77 AdtPlugin.printErrorToConsole(info.getProject(), "Launch error: timeout"); 78 return false; 79 } catch (AdbCommandRejectedException e) { 80 AdtPlugin.printErrorToConsole(info.getProject(), String.format( 81 "Launch error: adb rejected command: %1$s", e.getMessage())); 82 return false; 83 } catch (ShellCommandUnresponsiveException e) { 84 // we didn't get the output but that's ok, just log it 85 AdtPlugin.log(e, "No command output when running: '%1$s' on device %2$s", command, 86 device); 87 } catch (IOException e) { 88 // something went wrong trying to launch the app. 89 // lets stop the Launch 90 AdtPlugin.printErrorToConsole(info.getProject(), 91 String.format("Launch error: %s", e.getMessage())); 92 return false; 93 } 94 return true; 95 } 96 97 /** 98 * Launches the activity on targeted device 99 * 100 * @param info the {@link DelayedLaunchInfo} that contains launch details 101 * @param devices list of Android devices on which the activity will be launched 102 */ 103 @Override 104 public boolean doLaunchAction(DelayedLaunchInfo info, Collection<IDevice> devices) { 105 boolean result = true; 106 for (IDevice d : devices) { 107 // Note that this expression should not short circuit - even if an action fails 108 // on a device, it should still be performed on all other devices. 109 result = doLaunchAction(info, d) && result; 110 } 111 112 return result; 113 } 114 115 /** 116 * Returns a description of the activity being launched 117 * 118 * @see IAndroidLaunchAction#getLaunchDescription() 119 */ 120 @Override 121 public String getLaunchDescription() { 122 return String.format("%1$s activity launch", mActivity); 123 } 124 } 125