@@ -2128,6 +2128,19 @@ void list_bundle_id(AMDeviceRef device)
21282128 CFDictionaryRef result = nil ;
21292129 check_error (AMDeviceLookupApplications (device, options, &result));
21302130
2131+ if (bundle_id != NULL ) {
2132+ CFStringRef cf_bundle_id = CFAutorelease (CFStringCreateWithCString (NULL , bundle_id, kCFStringEncodingUTF8 ));
2133+ CFDictionaryRef app_dict = CFRetain (CFDictionaryGetValue (result, cf_bundle_id));
2134+
2135+ CFRelease (result);
2136+ result = CFAutorelease (CFDictionaryCreateMutable (NULL , 0 , &kCFTypeDictionaryKeyCallBacks , &kCFTypeDictionaryValueCallBacks ));
2137+
2138+ if (app_dict != NULL ) {
2139+ CFDictionaryAddValue ((CFMutableDictionaryRef)result, cf_bundle_id, app_dict);
2140+ CFRelease (app_dict);
2141+ }
2142+ }
2143+
21312144 if (_json_output) {
21322145 NSLogJSON (@{@" Event" : @" ListBundleId" ,
21332146 @" Apps" : (NSDictionary *)result});
@@ -3041,12 +3054,40 @@ void instruments_connect_service(AMDeviceRef device) {
30413054 check_error (AMDeviceDisconnect (device));
30423055}
30433056
3044- void list_processes (AMDeviceRef device) {
3045- if (!instruments_available_channels) {
3046- instruments_connect_service (device);
3047- instruments_perform_handshake ();
3057+ NSNumber * pid_for_bundle_id (NSString * bundle_id) {
3058+ int32_t channel = instruments_make_channel (@" com.apple.instruments.server.services.processcontrol" );
3059+
3060+ id pid = instruments_perform_selector (channel, @" processIdentifierForBundleIdentifier:" , @[instruments_object_argument (bundle_id)]);
3061+
3062+ if (pid != nil && ![pid isKindOfClass: NSNumber .class]) {
3063+ on_error (@" Error: did not get valid response from processIdentifierForBundleIdentifier:" );
30483064 }
30493065
3066+ // Return -1 if pid is not found
3067+ return (pid == nil || [pid isEqualToNumber: @0 ]) ? @-1 : pid;
3068+ }
3069+
3070+ void get_pid (AMDeviceRef device) {
3071+ if (bundle_id == NULL ) {
3072+ on_error (@" Error: bundle id required, please specify with --bundle_id." );
3073+ }
3074+
3075+ instruments_connect_service (device);
3076+ instruments_perform_handshake ();
3077+
3078+ CFStringRef cf_bundle_id = CFAutorelease (CFStringCreateWithCString (NULL , bundle_id, kCFStringEncodingUTF8 ));
3079+
3080+ NSNumber * pid = pid_for_bundle_id ((NSString *)cf_bundle_id);
3081+
3082+ NSLogOut (@" pid: %@ " , pid);
3083+ NSLogJSON (@{@" Event" : @" GetPid" ,
3084+ @" pid" : pid});
3085+ }
3086+
3087+ void list_processes (AMDeviceRef device) {
3088+ instruments_connect_service (device);
3089+ instruments_perform_handshake ();
3090+
30503091 int32_t channel = instruments_make_channel (@" com.apple.instruments.server.services.deviceinfo" );
30513092
30523093 id processes = instruments_perform_selector (channel, @" runningProcesses" , nil /* args */ );
@@ -3055,6 +3096,25 @@ void list_processes(AMDeviceRef device) {
30553096 on_error (@" Error: could not retrieve return value for runningProcesses" );
30563097 }
30573098
3099+ if (bundle_id != NULL ) {
3100+ CFStringRef cf_bundle_id = CFAutorelease (CFStringCreateWithCString (NULL , bundle_id, kCFStringEncodingUTF8 ));
3101+ NSNumber * pid = pid_for_bundle_id ((NSString *)cf_bundle_id);
3102+
3103+ NSMutableArray * filteredProcesses = NSMutableArray .array ;
3104+
3105+ if (pid > 0 ) {
3106+ for (NSDictionary * proc in processes) {
3107+ NSNumber * procPid = proc[@" pid" ];
3108+ if (procPid == pid) {
3109+ [filteredProcesses addObject: proc];
3110+ }
3111+ }
3112+ }
3113+
3114+ [processes release ];
3115+ processes = filteredProcesses;
3116+ }
3117+
30583118 if (_json_output) {
30593119 // NSDate cannot be serialized to JSON as is, manually convert it it NSString
30603120 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc ] init ];
@@ -3148,6 +3208,8 @@ void handle_device(AMDeviceRef device) {
31483208 list_bundle_id (device);
31493209 } else if (strcmp (" list_processes" , command) == 0 ) {
31503210 list_processes (device);
3211+ } else if (strcmp (" get_pid" , command) == 0 ) {
3212+ get_pid (device);
31513213 } else if (strcmp (" get_battery_level" , command) == 0 ) {
31523214 get_battery_level (device);
31533215 } else if (strcmp (" symbols" , command) == 0 ) {
@@ -3444,6 +3506,7 @@ void usage(const char* app) {
34443506 @" -e, --exists check if the app with given bundle_id is installed or not \n "
34453507 @" -B, --list_bundle_id list bundle_id \n "
34463508 @" --list_processes list running processes \n "
3509+ @" --get_pid get process id for the bundle. must specify --bundle_id\n "
34473510 @" -W, --no-wifi ignore wifi devices\n "
34483511 @" -C, --get_battery_level get battery current capacity \n "
34493512 @" -O, --output <file> write stdout to this file\n "
@@ -3536,6 +3599,7 @@ int main(int argc, char *argv[]) {
35363599 { " check-developer-mode" , no_argument, NULL , 1008 },
35373600#endif
35383601 { " list_processes" , no_argument, NULL , 1009 },
3602+ { " get_pid" , no_argument, NULL , 1010 },
35393603 { NULL , 0 , NULL , 0 },
35403604 };
35413605 int ch;
@@ -3657,6 +3721,10 @@ int main(int argc, char *argv[]) {
36573721 command_only = true ;
36583722 command = " list_processes" ;
36593723 break ;
3724+ case 1010 :
3725+ command_only = true ;
3726+ command = " get_pid" ;
3727+ break ;
36603728 case ' W' :
36613729 no_wifi = true ;
36623730 break ;
0 commit comments