Skip to content

Commit

Permalink
Add a command to check whether a device has enabled developer mode. D…
Browse files Browse the repository at this point in the history
…eveloper mode was introduced in iOS 16. When checking devices on older versions the command will print an unsupported error.

Retry of ios-control#556 that guards the developer mode check by a preprocessor define  so that it is not build by default. Developer mode requires a MobileDevice method introduced with Xcode 14 so including it by default will break builds where Xcode 14 is unavailable.
  • Loading branch information
ivanhernandez13 committed Aug 11, 2022
1 parent 90f9952 commit 978ddb3
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 9 deletions.
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ python -m py_compile src/scripts/*.py && xcodebuild -target ios-deploy && xcodeb
-m, --noinstall directly start debugging without app install (-d not required)
-A, --app_deltas incremental install. must specify a directory to store app deltas to determine what needs to be installed
-p, --port <number> port used for device, default: dynamic
-r, --uninstall uninstall the app before install (do not use with -m; app cache and data are cleared)
-9, --uninstall_only uninstall the app ONLY. Use only with -1 <bundle_id>
-r, --uninstall uninstall the app before install (do not use with -m; app cache and data are cleared)
-9, --uninstall_only uninstall the app ONLY. Use only with -1 <bundle_id>
-1, --bundle_id <bundle id> specify bundle id for list and upload
-l, --list[=<dir>] list all app files or the specified directory
-o, --upload <file> upload file
Expand All @@ -76,18 +76,28 @@ python -m py_compile src/scripts/*.py && xcodebuild -target ios-deploy && xcodeb
-D, --mkdir <dir> make directory on device
-R, --rm <path> remove file or directory on device (directories must be empty)
-X, --rmtree <path> remove directory and all contained files recursively on device
-V, --version print the executable version
-e, --exists check if the app with given bundle_id is installed or not
-B, --list_bundle_id list bundle_id
-V, --version print the executable version
-e, --exists check if the app with given bundle_id is installed or not
-B, --list_bundle_id list bundle_id
-W, --no-wifi ignore wifi devices
-C, --get_battery_level get battery current capacity
-C, --get_battery_level get battery current capacity
-O, --output <file> write stdout to this file
-E, --error_output <file> write stderr to this file
--detect_deadlocks <sec> start printing backtraces for all threads periodically after specific amount of seconds
-f, --file_system specify file system for mkdir / list / upload / download / rm
-k, --key keys for the properties of the bundle. Joined by ',' and used only with -B <list_bundle_id> and -j <json>
-F, --non-recursively specify non-recursively walk directory
-S, --symbols download OS symbols. must specify a directory to store the downloaded symbols
-j, --json format output as JSON
-k, --key keys for the properties of the bundle. Joined by ',' and used only with -B <list_bundle_id> and -j <json>
--custom-script <script> path to custom python script to execute in lldb
--custom-command <command> specify additional lldb commands to execute
--faster-path-search use alternative logic to find the device support paths faster
-P, --list_profiles list all provisioning profiles on device
--profile-uuid <uuid> the UUID of the provisioning profile to target, use with other profile commands
--profile-download <path> download a provisioning profile (requires --profile-uuid)
--profile-install <file> install a provisioning profile
--profile-uninstall uninstall a provisioning profile (requires --profile-uuid <UUID>)
--check-developer-mode checks whether the given device has developer mode enabled

## Examples

Expand Down
53 changes: 51 additions & 2 deletions src/ios-deploy/ios-deploy.m
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
mach_error_t AMDeviceLookupApplications(AMDeviceRef device, CFDictionaryRef options, CFDictionaryRef *result);
int AMDeviceGetInterfaceType(AMDeviceRef device);
AMDeviceRef AMDeviceCopyPairedCompanion(AMDeviceRef device);
#if defined(XCODE_14_OR_NEWER_AVAILABLE)
unsigned int AMDeviceCopyDeveloperModeStatus(AMDeviceRef device, uint32_t error_code);
#endif

int AMDServiceConnectionSend(ServiceConnRef con, const void * data, size_t size);
int AMDServiceConnectionReceive(ServiceConnRef con, void * data, size_t size);
Expand Down Expand Up @@ -2289,6 +2292,34 @@ void uninstall_app(AMDeviceRef device) {
}
}

#if defined(XCODE_14_OR_NEWER_AVAILABLE)
void check_developer_mode(AMDeviceRef device) {
unsigned int error_code = 0;
bool is_enabled = AMDeviceCopyDeveloperModeStatus(device, &error_code);

if (error_code) {
const char *mobdev_error = get_error_message(error_code);
NSString *error_description = mobdev_error ? [NSString stringWithUTF8String:mobdev_error] : @"unknown.";
if (_json_output) {
NSLogJSON(@{
@"Event": @"DeveloperMode",
@"IsEnabled": @(is_enabled),
@"Code": @(error_code),
@"Status": error_description,
});
} else {
NSLogOut(@"Encountered error checking developer mode status: %@", error_description);
}
} else {
if (_json_output) {
NSLogJSON(@{@"Event": @"DeveloperMode", @"IsEnabled": @(is_enabled)});
} else {
NSLogOut(@"Developer mode is%s enabled.", is_enabled ? "" : " not");
}
}
}
#endif

void start_symbols_service_with_command(AMDeviceRef device, uint32_t command) {
connect_and_start_session(device);
check_error(AMDeviceSecureStartService(device, symbols_service_name,
Expand Down Expand Up @@ -2608,7 +2639,11 @@ void handle_device(AMDeviceRef device) {
uninstall_provisioning_profile(device);
} else if (strcmp("download_profile", command) == 0) {
download_provisioning_profile(device);
}
#if defined(XCODE_14_OR_NEWER_AVAILABLE)
} else if (strcmp("check_developer_mode", command) == 0) {
check_developer_mode(device);
#endif
}
exit(0);
}

Expand Down Expand Up @@ -2874,7 +2909,12 @@ void usage(const char* app) {
@" --profile-uuid <uuid> the UUID of the provisioning profile to target, use with other profile commands\n"
@" --profile-download <path> download a provisioning profile (requires --profile-uuid)\n"
@" --profile-install <file> install a provisioning profile\n"
@" --profile-uninstall uninstall a provisioning profile (requires --profile-uuid <UUID>)\n",
@" --profile-uninstall uninstall a provisioning profile (requires --profile-uuid <UUID>)\n"
#if defined(XCODE_14_OR_NEWER_AVAILABLE)
@" --check-developer-mode checks whether the given device has developer mode enabled\n",
#else
,
#endif
[NSString stringWithUTF8String:app]);
}

Expand Down Expand Up @@ -2940,6 +2980,9 @@ int main(int argc, char *argv[]) {
{ "profile-uninstall", no_argument, NULL, 1005},
{ "profile-download", required_argument, NULL, 1006},
{ "profile-uuid", required_argument, NULL, 1007},
#if defined(XCODE_14_OR_NEWER_AVAILABLE)
{ "check-developer-mode", no_argument, NULL, 1008},
#endif
{ NULL, 0, NULL, 0 },
};
int ch;
Expand Down Expand Up @@ -3115,6 +3158,12 @@ int main(int argc, char *argv[]) {
case 1007:
profile_uuid = optarg;
break;
#if defined(XCODE_14_OR_NEWER_AVAILABLE)
case 1008:
command_only = true;
command = "check_developer_mode";
break;
#endif
case 'P':
command_only = true;
command = "list_profiles";
Expand Down

0 comments on commit 978ddb3

Please sign in to comment.