auto import from //depot/cupcake/@136745
This commit is contained in:
@@ -75,6 +75,8 @@ public class Am {
|
||||
runInstrument();
|
||||
} else if (op.equals("broadcast")) {
|
||||
sendBroadcast();
|
||||
} else if (op.equals("profile")) {
|
||||
runProfile();
|
||||
} else {
|
||||
System.err.println("Error: Unknown command: " + op);
|
||||
showUsage();
|
||||
@@ -423,6 +425,49 @@ public class Am {
|
||||
}
|
||||
}
|
||||
|
||||
private void runProfile() {
|
||||
String profileFile = null;
|
||||
boolean start = false;
|
||||
|
||||
String process = nextArg();
|
||||
if (process == null) {
|
||||
System.err.println("Error: No profile process supplied");
|
||||
showUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
String cmd = nextArg();
|
||||
if ("start".equals(cmd)) {
|
||||
start = true;
|
||||
profileFile = nextArg();
|
||||
if (profileFile == null) {
|
||||
System.err.println("Error: No profile file path supplied");
|
||||
showUsage();
|
||||
return;
|
||||
}
|
||||
} else if (!"stop".equals(cmd)) {
|
||||
System.err.println("Error: Profile command " + cmd + " not valid");
|
||||
showUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!mAm.profileControl(process, start, profileFile)) {
|
||||
System.out.println("PROFILE FAILED on process " + process);
|
||||
return;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("PROFILE FAILED: " + e.getMessage());
|
||||
return;
|
||||
} catch (IllegalStateException e) {
|
||||
System.out.println("PROFILE FAILED: " + e.getMessage());
|
||||
return;
|
||||
} catch (RemoteException e) {
|
||||
System.out.println("PROFILE FAILED: activity manager gone");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private String nextOption() {
|
||||
if (mNextArg >= mArgs.length) {
|
||||
return null;
|
||||
@@ -470,11 +515,12 @@ public class Am {
|
||||
}
|
||||
|
||||
private void showUsage() {
|
||||
System.err.println("usage: am [start|broadcast|instrument]");
|
||||
System.err.println("usage: am [start|broadcast|instrument|profile]");
|
||||
System.err.println(" am start -D INTENT");
|
||||
System.err.println(" am broadcast INTENT");
|
||||
System.err.println(" am instrument [-r] [-e <ARG_NAME> <ARG_VALUE>] [-p <PROF_FILE>]");
|
||||
System.err.println(" [-w] <COMPONENT> ");
|
||||
System.err.println(" am profile <PROCESS> [start <PROF_FILE>|stop]");
|
||||
System.err.println("");
|
||||
System.err.println(" INTENT is described with:");
|
||||
System.err.println(" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]");
|
||||
|
||||
@@ -979,6 +979,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
return true;
|
||||
}
|
||||
|
||||
case PROFILE_CONTROL_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
String process = data.readString();
|
||||
boolean start = data.readInt() != 0;
|
||||
String path = data.readString();
|
||||
boolean res = profileControl(process, start, path);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(res ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
case PEEK_SERVICE_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
Intent service = Intent.CREATOR.createFromParcel(data);
|
||||
@@ -2131,5 +2142,23 @@ class ActivityManagerProxy implements IActivityManager
|
||||
data.recycle();
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean profileControl(String process, boolean start,
|
||||
String path) throws RemoteException
|
||||
{
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
data.writeString(process);
|
||||
data.writeInt(start ? 1 : 0);
|
||||
data.writeString(path);
|
||||
mRemote.transact(PROFILE_CONTROL_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
boolean res = reply.readInt() != 0;
|
||||
reply.recycle();
|
||||
data.recycle();
|
||||
return res;
|
||||
}
|
||||
|
||||
private IBinder mRemote;
|
||||
}
|
||||
|
||||
@@ -1449,6 +1449,10 @@ public final class ActivityThread {
|
||||
}
|
||||
}
|
||||
|
||||
public void profilerControl(boolean start, String path) {
|
||||
queueOrSendMessage(H.PROFILER_CONTROL, path, start ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
long nativeMax = Debug.getNativeHeapSize() / 1024;
|
||||
@@ -1641,6 +1645,7 @@ public final class ActivityThread {
|
||||
public static final int LOW_MEMORY = 124;
|
||||
public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
|
||||
public static final int RELAUNCH_ACTIVITY = 126;
|
||||
public static final int PROFILER_CONTROL = 127;
|
||||
String codeToString(int code) {
|
||||
if (localLOGV) {
|
||||
switch (code) {
|
||||
@@ -1671,6 +1676,7 @@ public final class ActivityThread {
|
||||
case LOW_MEMORY: return "LOW_MEMORY";
|
||||
case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
|
||||
case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
|
||||
case PROFILER_CONTROL: return "PROFILER_CONTROL";
|
||||
}
|
||||
}
|
||||
return "(unknown)";
|
||||
@@ -1770,6 +1776,9 @@ public final class ActivityThread {
|
||||
case ACTIVITY_CONFIGURATION_CHANGED:
|
||||
handleActivityConfigurationChanged((IBinder)msg.obj);
|
||||
break;
|
||||
case PROFILER_CONTROL:
|
||||
handleProfilerControl(msg.arg1 != 0, (String)msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3432,6 +3441,21 @@ public final class ActivityThread {
|
||||
performConfigurationChanged(r.activity, mConfiguration);
|
||||
}
|
||||
|
||||
final void handleProfilerControl(boolean start, String path) {
|
||||
if (start) {
|
||||
File file = new File(path);
|
||||
file.getParentFile().mkdirs();
|
||||
try {
|
||||
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(TAG, "Profiling failed on path " + path
|
||||
+ " -- can the process access this path?");
|
||||
}
|
||||
} else {
|
||||
Debug.stopMethodTracing();
|
||||
}
|
||||
}
|
||||
|
||||
final void handleLowMemory() {
|
||||
ArrayList<ComponentCallbacks> callbacks
|
||||
= new ArrayList<ComponentCallbacks>();
|
||||
|
||||
@@ -322,6 +322,15 @@ public abstract class ApplicationThreadNative extends Binder
|
||||
requestPss();
|
||||
return true;
|
||||
}
|
||||
|
||||
case PROFILER_CONTROL_TRANSACTION:
|
||||
{
|
||||
data.enforceInterface(IApplicationThread.descriptor);
|
||||
boolean start = data.readInt() != 0;
|
||||
String path = data.readString();
|
||||
profilerControl(start, path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.onTransact(code, data, reply, flags);
|
||||
@@ -654,5 +663,14 @@ class ApplicationThreadProxy implements IApplicationThread {
|
||||
data.recycle();
|
||||
}
|
||||
|
||||
public void profilerControl(boolean start, String path) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
data.writeInterfaceToken(IApplicationThread.descriptor);
|
||||
data.writeInt(start ? 1 : 0);
|
||||
data.writeString(path);
|
||||
mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null,
|
||||
IBinder.FLAG_ONEWAY);
|
||||
data.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -221,6 +221,10 @@ public interface IActivityManager extends IInterface {
|
||||
// Get device configuration
|
||||
public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
|
||||
|
||||
// Turn on/off profiling in a particular process.
|
||||
public boolean profileControl(String process, boolean start,
|
||||
String path) throws RemoteException;
|
||||
|
||||
/*
|
||||
* Private non-Binder interfaces
|
||||
*/
|
||||
@@ -365,4 +369,5 @@ public interface IActivityManager extends IInterface {
|
||||
int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
|
||||
int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
|
||||
int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
|
||||
int PROFILE_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+85;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ public interface IApplicationThread extends IInterface {
|
||||
void scheduleLowMemory() throws RemoteException;
|
||||
void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
|
||||
void requestPss() throws RemoteException;
|
||||
void profilerControl(boolean start, String path) throws RemoteException;
|
||||
|
||||
String descriptor = "android.app.IApplicationThread";
|
||||
|
||||
@@ -115,4 +116,5 @@ public interface IApplicationThread extends IInterface {
|
||||
int SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+24;
|
||||
int SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
|
||||
int REQUEST_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26;
|
||||
int PROFILER_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import java.util.List;
|
||||
*/
|
||||
public class BluetoothA2dp {
|
||||
private static final String TAG = "BluetoothA2dp";
|
||||
private static final boolean DBG = false;
|
||||
|
||||
/** int extra for SINK_STATE_CHANGED_ACTION */
|
||||
public static final String SINK_STATE =
|
||||
@@ -103,6 +104,7 @@ public class BluetoothA2dp {
|
||||
* @hide
|
||||
*/
|
||||
public int connectSink(String address) {
|
||||
if (DBG) log("connectSink(" + address + ")");
|
||||
try {
|
||||
return mService.connectSink(address);
|
||||
} catch (RemoteException e) {
|
||||
@@ -119,6 +121,7 @@ public class BluetoothA2dp {
|
||||
* @hide
|
||||
*/
|
||||
public int disconnectSink(String address) {
|
||||
if (DBG) log("disconnectSink(" + address + ")");
|
||||
try {
|
||||
return mService.disconnectSink(address);
|
||||
} catch (RemoteException e) {
|
||||
@@ -133,6 +136,7 @@ public class BluetoothA2dp {
|
||||
* @hide
|
||||
*/
|
||||
public boolean isSinkConnected(String address) {
|
||||
if (DBG) log("isSinkConnected(" + address + ")");
|
||||
int state = getSinkState(address);
|
||||
return state == STATE_CONNECTED || state == STATE_PLAYING;
|
||||
}
|
||||
@@ -142,6 +146,7 @@ public class BluetoothA2dp {
|
||||
* @hide
|
||||
*/
|
||||
public List<String> listConnectedSinks() {
|
||||
if (DBG) log("listConnectedSinks()");
|
||||
try {
|
||||
return mService.listConnectedSinks();
|
||||
} catch (RemoteException e) {
|
||||
@@ -156,6 +161,7 @@ public class BluetoothA2dp {
|
||||
* @hide
|
||||
*/
|
||||
public int getSinkState(String address) {
|
||||
if (DBG) log("getSinkState(" + address + ")");
|
||||
try {
|
||||
return mService.getSinkState(address);
|
||||
} catch (RemoteException e) {
|
||||
@@ -177,6 +183,7 @@ public class BluetoothA2dp {
|
||||
* @return Result code, negative indicates an error
|
||||
*/
|
||||
public int setSinkPriority(String address, int priority) {
|
||||
if (DBG) log("setSinkPriority(" + address + ", " + priority + ")");
|
||||
try {
|
||||
return mService.setSinkPriority(address, priority);
|
||||
} catch (RemoteException e) {
|
||||
@@ -191,6 +198,7 @@ public class BluetoothA2dp {
|
||||
* @return non-negative priority, or negative error code on error.
|
||||
*/
|
||||
public int getSinkPriority(String address) {
|
||||
if (DBG) log("getSinkPriority(" + address + ")");
|
||||
try {
|
||||
return mService.getSinkPriority(address);
|
||||
} catch (RemoteException e) {
|
||||
@@ -244,4 +252,8 @@ public class BluetoothA2dp {
|
||||
return "<unknown state " + state + ">";
|
||||
}
|
||||
}
|
||||
|
||||
private static void log(String msg) {
|
||||
Log.d(TAG, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ public class BluetoothHeadset {
|
||||
* are ok.
|
||||
*/
|
||||
public synchronized void close() {
|
||||
if (DBG) log("close()");
|
||||
if (mConnection != null) {
|
||||
mContext.unbindService(mConnection);
|
||||
mConnection = null;
|
||||
@@ -138,6 +139,7 @@ public class BluetoothHeadset {
|
||||
* object is currently not connected to the Headset service.
|
||||
*/
|
||||
public int getState() {
|
||||
if (DBG) log("getState()");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getState();
|
||||
@@ -156,6 +158,7 @@ public class BluetoothHeadset {
|
||||
* service.
|
||||
*/
|
||||
public String getHeadsetAddress() {
|
||||
if (DBG) log("getHeadsetAddress()");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getHeadsetAddress();
|
||||
@@ -180,6 +183,7 @@ public class BluetoothHeadset {
|
||||
* will be expected.
|
||||
*/
|
||||
public boolean connectHeadset(String address) {
|
||||
if (DBG) log("connectHeadset(" + address + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
if (mService.connectHeadset(address)) {
|
||||
@@ -199,6 +203,7 @@ public class BluetoothHeadset {
|
||||
* if not currently connected to the headset service.
|
||||
*/
|
||||
public boolean isConnected(String address) {
|
||||
if (DBG) log("isConnected(" + address + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.isConnected(address);
|
||||
@@ -216,6 +221,7 @@ public class BluetoothHeadset {
|
||||
* not currently connected to the Headset service.
|
||||
*/
|
||||
public boolean disconnectHeadset() {
|
||||
if (DBG) log("disconnectHeadset()");
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.disconnectHeadset();
|
||||
@@ -235,6 +241,7 @@ public class BluetoothHeadset {
|
||||
* error.
|
||||
*/
|
||||
public boolean startVoiceRecognition() {
|
||||
if (DBG) log("startVoiceRecognition()");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.startVoiceRecognition();
|
||||
@@ -252,6 +259,7 @@ public class BluetoothHeadset {
|
||||
* headset is not in voice recognition mode, or on error.
|
||||
*/
|
||||
public boolean stopVoiceRecognition() {
|
||||
if (DBG) log("stopVoiceRecognition()");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.stopVoiceRecognition();
|
||||
@@ -282,6 +290,7 @@ public class BluetoothHeadset {
|
||||
* @return True if successful, false if there was some error.
|
||||
*/
|
||||
public boolean setPriority(String address, int priority) {
|
||||
if (DBG) log("setPriority(" + address + ", " + priority + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.setPriority(address, priority);
|
||||
@@ -299,6 +308,7 @@ public class BluetoothHeadset {
|
||||
* @return non-negative priority, or negative error code on error.
|
||||
*/
|
||||
public int getPriority(String address) {
|
||||
if (DBG) log("getPriority(" + address + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getPriority(address);
|
||||
@@ -350,4 +360,8 @@ public class BluetoothHeadset {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static void log(String msg) {
|
||||
Log.d(TAG, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +295,8 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
new ArrayList<String>(Arrays.asList(
|
||||
"00:02:C7", "00:16:FE", "00:19:C1", "00:1B:FB", "00:1E:3D", //ALPS
|
||||
"00:21:4F", "00:23:06", "00:24:33", "00:A0:79", // ALPS
|
||||
"00:0E:6D", "00:13:E0", "00:21:E8", "00:60:57"// Murata for Prius 2007
|
||||
"00:0E:6D", "00:13:E0", "00:21:E8", "00:60:57",// Murata for Prius 2007
|
||||
"00:0E:9F" // TEMIC SDS for Porsche
|
||||
));
|
||||
|
||||
public synchronized void loadBondState() {
|
||||
|
||||
@@ -499,13 +499,10 @@ public class GestureDetector {
|
||||
// Finally, give the up event of the double-tap
|
||||
handled |= mDoubleTapListener.onDoubleTapEvent(ev);
|
||||
mIsDoubleTapping = false;
|
||||
break;
|
||||
} else if (mInLongPress) {
|
||||
mHandler.removeMessages(TAP);
|
||||
mInLongPress = false;
|
||||
break;
|
||||
}
|
||||
if (mAlwaysInTapRegion) {
|
||||
} else if (mAlwaysInTapRegion) {
|
||||
handled = mListener.onSingleTapUp(ev);
|
||||
} else {
|
||||
|
||||
|
||||
@@ -11823,6 +11823,56 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
}
|
||||
}
|
||||
|
||||
public boolean profileControl(String process, boolean start,
|
||||
String path) throws RemoteException {
|
||||
|
||||
synchronized (this) {
|
||||
// note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
|
||||
// its own permission.
|
||||
if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
throw new SecurityException("Requires permission "
|
||||
+ android.Manifest.permission.SET_ACTIVITY_WATCHER);
|
||||
}
|
||||
|
||||
ProcessRecord proc = null;
|
||||
try {
|
||||
int pid = Integer.parseInt(process);
|
||||
synchronized (mPidsSelfLocked) {
|
||||
proc = mPidsSelfLocked.get(pid);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
|
||||
if (proc == null) {
|
||||
HashMap<String, SparseArray<ProcessRecord>> all
|
||||
= mProcessNames.getMap();
|
||||
SparseArray<ProcessRecord> procs = all.get(process);
|
||||
if (procs != null && procs.size() > 0) {
|
||||
proc = procs.valueAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (proc == null || proc.thread == null) {
|
||||
throw new IllegalArgumentException("Unknown process: " + process);
|
||||
}
|
||||
|
||||
boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
|
||||
if (isSecure) {
|
||||
if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
|
||||
throw new SecurityException("Process not debuggable: " + proc);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
proc.thread.profilerControl(start, path);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("Process disappeared");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** In this method we try to acquire our lock to make sure that we have not deadlocked */
|
||||
public void monitor() {
|
||||
synchronized (this) { }
|
||||
|
||||
Reference in New Issue
Block a user