1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 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.googlecode.android_scripting.facade; 18 19 import android.app.ActivityManager; 20 import android.app.ActivityManager.RunningAppProcessInfo; 21 import android.app.Service; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.pm.PackageManager; 25 import android.content.pm.ResolveInfo; 26 27 import com.googlecode.android_scripting.Log; 28 import com.googlecode.android_scripting.jsonrpc.RpcReceiver; 29 import com.googlecode.android_scripting.rpc.Rpc; 30 import com.googlecode.android_scripting.rpc.RpcParameter; 31 import com.googlecode.android_scripting.rpc.RpcOptional; 32 33 import java.util.ArrayList; 34 import java.util.Arrays; 35 import java.util.HashMap; 36 import java.util.HashSet; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.Set; 40 41 import org.json.JSONException; 42 import org.json.JSONObject; 43 44 /** 45 * Facade for managing Applications. 46 * 47 */ 48 public class ApplicationManagerFacade extends RpcReceiver { 49 50 private final Service mService; 51 private final AndroidFacade mAndroidFacade; 52 private final ActivityManager mActivityManager; 53 private final PackageManager mPackageManager; 54 ApplicationManagerFacade(FacadeManager manager)55 public ApplicationManagerFacade(FacadeManager manager) { 56 super(manager); 57 mService = manager.getService(); 58 mAndroidFacade = manager.getReceiver(AndroidFacade.class); 59 mActivityManager = (ActivityManager) mService.getSystemService(Context.ACTIVITY_SERVICE); 60 mPackageManager = mService.getPackageManager(); 61 } 62 63 @Rpc(description = "Returns a list of all launchable application class names.") getLaunchableApplications()64 public Map<String, String> getLaunchableApplications() { 65 Intent intent = new Intent(Intent.ACTION_MAIN); 66 intent.addCategory(Intent.CATEGORY_LAUNCHER); 67 List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent, 0); 68 Map<String, String> applications = new HashMap<String, String>(); 69 for (ResolveInfo info : resolveInfos) { 70 applications.put(info.loadLabel(mPackageManager).toString(), info.activityInfo.name); 71 } 72 return applications; 73 } 74 75 @Rpc(description = "Start activity with the given class name.") launch(@pcParametername = "className") String className)76 public void launch(@RpcParameter(name = "className") String className) { 77 Intent intent = new Intent(Intent.ACTION_MAIN); 78 String packageName = className.substring(0, className.lastIndexOf(".")); 79 intent.setClassName(packageName, className); 80 mAndroidFacade.startActivity(intent); 81 } 82 83 @Rpc(description = "Start activity with the given class name with result") launchForResult(@pcParametername = "className") String className)84 public Intent launchForResult(@RpcParameter(name = "className") String className) { 85 Intent intent = new Intent(Intent.ACTION_MAIN); 86 String packageName = className.substring(0, className.lastIndexOf(".")); 87 intent.setClassName(packageName, className); 88 return mAndroidFacade.startActivityForResult(intent); 89 } 90 91 @Rpc(description = "Launch the specified app.") appLaunch(@pcParametername = "name") String name)92 public void appLaunch(@RpcParameter(name = "name") String name) { 93 Intent LaunchIntent = mPackageManager.getLaunchIntentForPackage(name); 94 mService.startActivity(LaunchIntent); 95 } 96 97 @Rpc(description = "Launch activity for result with intent") launchForResultWithIntent( @pcParametername = "intent") Intent intent, @RpcParameter(name = "extras")@RpcOptional JSONObject extras)98 public Intent launchForResultWithIntent( 99 @RpcParameter(name = "intent") Intent intent, 100 @RpcParameter(name = "extras")@RpcOptional JSONObject extras) 101 throws JSONException { 102 if(extras != null) { 103 mAndroidFacade.putExtrasFromJsonObject(extras, intent); 104 } 105 return mAndroidFacade.startActivityForResult(intent); 106 } 107 108 @Rpc(description = "Create intent given the class name") createIntentForClassName( @pcParametername = "className") String className)109 public Intent createIntentForClassName( 110 @RpcParameter(name = "className") String className) { 111 Intent intent = new Intent(Intent.ACTION_MAIN); 112 String packageName = className.substring(0, className.lastIndexOf(".")); 113 intent.setClassName(packageName, className); 114 return intent; 115 } 116 117 @Rpc(description = "Get UID of a package") getUidForPackage( @pcParametername = "className") String className)118 public int getUidForPackage( 119 @RpcParameter(name = "className") String className) { 120 String packageName = className.substring(0, className.lastIndexOf(".")); 121 try { 122 return mPackageManager.getApplicationInfo(packageName, 0).uid; 123 } catch (PackageManager.NameNotFoundException e) { 124 Log.e("Package not found", e); 125 } 126 return 0; 127 } 128 129 @Rpc(description = "Kill the specified app.") appKill(@pcParametername = "name") String name)130 public Boolean appKill(@RpcParameter(name = "name") String name) { 131 for (RunningAppProcessInfo info : mActivityManager.getRunningAppProcesses()) { 132 if (info.processName.contains(name)) { 133 Log.d("Killing " + info.processName); 134 android.os.Process.killProcess(info.pid); 135 android.os.Process.sendSignal(info.pid, android.os.Process.SIGNAL_KILL); 136 mActivityManager.killBackgroundProcesses(info.processName); 137 return true; 138 } 139 } 140 return false; 141 } 142 143 @Rpc(description = "Returns a list of packages running activities or services.", 144 returns = "List of packages running activities.") getRunningPackages()145 public List<String> getRunningPackages() { 146 Set<String> runningPackages = new HashSet<String>(); 147 List<ActivityManager.RunningAppProcessInfo> appProcesses = 148 mActivityManager.getRunningAppProcesses(); 149 for (ActivityManager.RunningAppProcessInfo info : appProcesses) { 150 runningPackages.addAll(Arrays.asList(info.pkgList)); 151 } 152 List<ActivityManager.RunningServiceInfo> serviceProcesses = 153 mActivityManager.getRunningServices(Integer.MAX_VALUE); 154 for (ActivityManager.RunningServiceInfo info : serviceProcesses) { 155 runningPackages.add(info.service.getPackageName()); 156 } 157 return new ArrayList<String>(runningPackages); 158 } 159 160 /** 161 * Force stops a package. Equivalent to calling `am force-stop "package.name"` as root. 162 * <p> 163 * If you have access to adb, it is preferred to use the above command instead. 164 * 165 * @param packageName the name of the package to force stop 166 */ 167 @Rpc(description = "Force stops a package. Equivalent to `adb shell am force-stop " 168 + "\"package.name\"`. If possible, use that command instead.") forceStopPackage( @pcParametername = "packageName", description = "name of package") String packageName)169 public void forceStopPackage( 170 @RpcParameter(name = "packageName", description = "name of package") String packageName) { 171 mActivityManager.forceStopPackage(packageName); 172 } 173 174 @Override shutdown()175 public void shutdown() { 176 } 177 } 178