Skip to content

Commit 136872d

Browse files
Implement get_pid, respect bundle_id in list_processes and list_bundle_id (#576)
1 parent d0c383a commit 136872d

File tree

1 file changed

+72
-4
lines changed

1 file changed

+72
-4
lines changed

src/ios-deploy/ios-deploy.m

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)