Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ build/
/x/
local.properties
/scrcpy-server
/.vscode/*
/.cache/*
*.DS_Store
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ documented in the following pages:
- [Camera](doc/camera.md)
- [Video4Linux](doc/v4l2.md)
- [Shortcuts](doc/shortcuts.md)
- [Get app icon](doc/get_app_icon.md)


## Resources
Expand Down
34 changes: 34 additions & 0 deletions app/src/adb/adb.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,40 @@ sc_adb_push(struct sc_intr *intr, const char *serial, const char *local,
return process_check_success_intr(intr, pid, "adb push", flags);
}

bool
sc_adb_pull(struct sc_intr *intr, const char *serial, const char *remote,
const char *local, unsigned flags) {
assert(serial);

#ifdef __WINDOWS__
// Windows will parse the string, so the paths must be quoted
// (see sys/win/command.c)
local = sc_str_quote(local);
if (!local) {
LOG_OOM();
return false;
}
remote = sc_str_quote(remote);
if (!remote) {
LOG_OOM();
free((void *) local);
return false;
}
#endif

const char *const argv[] =
SC_ADB_COMMAND("-s", serial, "pull", remote, local);

sc_pid pid = sc_adb_execute(argv, flags);

#ifdef __WINDOWS__
free((void *) local);
free((void *) remote);
#endif

return process_check_success_intr(intr, pid, "adb pull", flags);
}

bool
sc_adb_install(struct sc_intr *intr, const char *serial, const char *local,
unsigned flags) {
Expand Down
4 changes: 4 additions & 0 deletions app/src/adb/adb.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ bool
sc_adb_push(struct sc_intr *intr, const char *serial, const char *local,
const char *remote, unsigned flags);

bool
sc_adb_pull(struct sc_intr *intr, const char *serial, const char *remote,
const char *local, unsigned flags);

bool
sc_adb_install(struct sc_intr *intr, const char *serial, const char *local,
unsigned flags);
Expand Down
27 changes: 27 additions & 0 deletions app/src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ enum {
OPT_GAMEPAD,
OPT_NEW_DISPLAY,
OPT_LIST_APPS,
OPT_GET_APP_ICON,
OPT_START_APP,
OPT_SCREEN_OFF_TIMEOUT,
OPT_CAPTURE_ORIENTATION,
Expand Down Expand Up @@ -511,6 +512,29 @@ static const struct sc_option options[] = {
.longopt = "list-apps",
.text = "List Android apps installed on the device.",
},
{
.longopt_id = OPT_GET_APP_ICON,
.longopt = "get-app-icon",
.argdesc = "package_names[:path]",
.text = "Get the icon of an Android app installed on the device."
"The required argument is a comma-separated list of package names"
" (e.g. \"com.android.chrome,org.mozilla.firefox\").\n"
"Optionally, each package name may be followed by ':path' to "
"specify where to save the icon (default is the current "
"directory).\n"
"The icon is saved as a PNG file, named <package_name>.png by "
"default, or <path> if specified.\n"
"If 'all' is provided instead of a package name, then the "
"icon of all installed apps is extracted.\n"
"Examples:\n"
" scrcpy --get-app-icon=com.android.chrome\n"
" scrcpy --get-app-icon=com.android.chrome:~/Pictures/\n"
" scrcpy --get-app-icon=all:~/Pictures/scrcpy-icons/\n"
" scrcpy --get-app-icon=com.android.chrome,org.mozilla.firefox\n"
" scrcpy --get-app-icon=com.android.chrome,org.mozilla.firefox:~/Pictures/\n"
"If multiple package names are provided, and some cannot be "
"found, then their icons are simply skipped (no error).",
},
{
.longopt_id = OPT_LIST_CAMERAS,
.longopt = "list-cameras",
Expand Down Expand Up @@ -2721,6 +2745,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
case OPT_LIST_APPS:
opts->list |= SC_OPTION_LIST_APPS;
break;
case OPT_GET_APP_ICON:
opts->get_app_icon = optarg;
break;
case OPT_REQUIRE_AUDIO:
opts->require_audio = true;
break;
Expand Down
1 change: 1 addition & 0 deletions app/src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const struct scrcpy_options scrcpy_options_default = {
.audio_dup = false,
.new_display = NULL,
.start_app = NULL,
.get_app_icon = NULL,
.angle = NULL,
.vd_destroy_content = true,
.vd_system_decorations = true,
Expand Down
2 changes: 2 additions & 0 deletions app/src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,12 +319,14 @@ struct scrcpy_options {
#define SC_OPTION_LIST_CAMERAS 0x4
#define SC_OPTION_LIST_CAMERA_SIZES 0x8
#define SC_OPTION_LIST_APPS 0x10
#define SC_OPTION_GET_APP_ICON 0x20
uint8_t list;
bool window;
bool mouse_hover;
bool audio_dup;
const char *new_display; // [<width>x<height>][/<dpi>] parsed by the server
const char *start_app;
const char *get_app_icon; // package name for app icon
bool vd_destroy_content;
bool vd_system_decorations;
};
Expand Down
3 changes: 2 additions & 1 deletion app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ scrcpy(struct scrcpy_options *options) {
.vd_destroy_content = options->vd_destroy_content,
.vd_system_decorations = options->vd_system_decorations,
.list = options->list,
.get_app_icon = options->get_app_icon,
};

static const struct sc_server_callbacks cbs = {
Expand All @@ -497,7 +498,7 @@ scrcpy(struct scrcpy_options *options) {

server_started = true;

if (options->list) {
if (options->list || options->get_app_icon) {
bool ok = await_for_server(NULL);
ret = ok ? SCRCPY_EXIT_SUCCESS : SCRCPY_EXIT_FAILURE;
goto end;
Expand Down
Loading