Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
6ec6ba526b | |||
5e565497de | |||
4c6ac6476d | |||
434af65816 | |||
7f2f5950f2 | |||
af4b7855e1 | |||
b1d8c72780 | |||
55e65fa270 | |||
69fb5f6ee1 |
13
app/data/scrcpy-console.desktop
Normal file
13
app/data/scrcpy-console.desktop
Normal file
@ -0,0 +1,13 @@
|
||||
[Desktop Entry]
|
||||
Name=scrcpy (console)
|
||||
GenericName=Android Remote Control
|
||||
Comment=Display and control your Android device
|
||||
# For some users, the PATH or ADB environment variables are set from the shell
|
||||
# startup file, like .bashrc or .zshrc… Run an interactive shell to get
|
||||
# environment correctly initialized.
|
||||
Exec=/bin/bash -i -c '"$SHELL" -i -c scrcpy || read -p "Press any key to quit..."'
|
||||
Icon=scrcpy
|
||||
Terminal=true
|
||||
Type=Application
|
||||
Categories=Utility;RemoteAccess;
|
||||
StartupNotify=false
|
13
app/data/scrcpy.desktop
Normal file
13
app/data/scrcpy.desktop
Normal file
@ -0,0 +1,13 @@
|
||||
[Desktop Entry]
|
||||
Name=scrcpy
|
||||
GenericName=Android Remote Control
|
||||
Comment=Display and control your Android device
|
||||
# For some users, the PATH or ADB environment variables are set from the shell
|
||||
# startup file, like .bashrc or .zshrc… Run an interactive shell to get
|
||||
# environment correctly initialized.
|
||||
Exec=/bin/sh -c '"$SHELL" -i -c scrcpy'
|
||||
Icon=scrcpy
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Utility;RemoteAccess;
|
||||
StartupNotify=false
|
@ -223,14 +223,26 @@ executable('scrcpy', src,
|
||||
install: true,
|
||||
c_args: [])
|
||||
|
||||
# <https://mesonbuild.com/Builtin-options.html#directories>
|
||||
datadir = get_option('datadir') # by default 'share'
|
||||
|
||||
install_man('scrcpy.1')
|
||||
install_data('data/icon.png',
|
||||
rename: 'scrcpy.png',
|
||||
install_dir: 'share/icons/hicolor/256x256/apps')
|
||||
install_dir: join_paths(datadir, 'icons/hicolor/256x256/apps'))
|
||||
install_data('data/zsh-completion/_scrcpy',
|
||||
install_dir: 'share/zsh/site-functions')
|
||||
install_dir: join_paths(datadir, 'zsh/site-functions'))
|
||||
install_data('data/bash-completion/scrcpy',
|
||||
install_dir: 'share/bash-completion/completions')
|
||||
install_dir: join_paths(datadir, 'bash-completion/completions'))
|
||||
|
||||
# Desktop entry file for application launchers
|
||||
if host_machine.system() == 'linux'
|
||||
# Install a launcher (ex: /usr/local/share/applications/scrcpy.desktop)
|
||||
install_data('data/scrcpy.desktop',
|
||||
install_dir: join_paths(datadir, 'applications'))
|
||||
install_data('data/scrcpy-console.desktop',
|
||||
install_dir: join_paths(datadir, 'applications'))
|
||||
endif
|
||||
|
||||
|
||||
### TESTS
|
||||
|
@ -712,48 +712,3 @@ sc_adb_get_device_ip(struct sc_intr *intr, const char *serial, unsigned flags) {
|
||||
|
||||
return sc_adb_parse_device_ip(buf);
|
||||
}
|
||||
|
||||
char *
|
||||
sc_adb_get_installed_apk_path(struct sc_intr *intr, const char *serial,
|
||||
unsigned flags) {
|
||||
assert(serial);
|
||||
const char *const argv[] =
|
||||
SC_ADB_COMMAND("-s", serial, "shell", "pm", "list", "package", "-f",
|
||||
SC_ANDROID_PACKAGE);
|
||||
|
||||
sc_pipe pout;
|
||||
sc_pid pid = sc_adb_execute_p(argv, flags, &pout);
|
||||
if (pid == SC_PROCESS_NONE) {
|
||||
LOGD("Could not execute \"pm list packages\"");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// "pm list packages -f <package>" output should contain only one line, so
|
||||
// the output should be short
|
||||
char buf[1024];
|
||||
ssize_t r = sc_pipe_read_all_intr(intr, pid, pout, buf, sizeof(buf) - 1);
|
||||
sc_pipe_close(pout);
|
||||
|
||||
bool ok = process_check_success_intr(intr, pid, "pm list packages", flags);
|
||||
if (!ok) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (r == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert((size_t) r < sizeof(buf));
|
||||
if (r == sizeof(buf) - 1) {
|
||||
// The implementation assumes that the output of "ip route" fits in the
|
||||
// buffer in a single pass
|
||||
LOGW("Result of \"pm list package\" does not fit in 1Kb. "
|
||||
"Please report an issue.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// It is parsed as a NUL-terminated string
|
||||
buf[r] = '\0';
|
||||
|
||||
return sc_adb_parse_installed_apk_path(buf);
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
|
||||
#define SC_ADB_SILENT (SC_ADB_NO_STDOUT | SC_ADB_NO_STDERR | SC_ADB_NO_LOGERR)
|
||||
|
||||
#define SC_ANDROID_PACKAGE "com.genymobile.scrcpy"
|
||||
|
||||
const char *
|
||||
sc_adb_get_executable(void);
|
||||
|
||||
@ -116,11 +114,4 @@ sc_adb_getprop(struct sc_intr *intr, const char *serial, const char *prop,
|
||||
char *
|
||||
sc_adb_get_device_ip(struct sc_intr *intr, const char *serial, unsigned flags);
|
||||
|
||||
/**
|
||||
* Return the path of the installed APK for com.genymobile.scrcpy (if any)
|
||||
*/
|
||||
char *
|
||||
sc_adb_get_installed_apk_path(struct sc_intr *intr, const char *serial,
|
||||
unsigned flags);
|
||||
|
||||
#endif
|
||||
|
@ -225,31 +225,3 @@ sc_adb_parse_device_ip(char *str) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
sc_adb_parse_installed_apk_path(char *str) {
|
||||
// str is expected to look like:
|
||||
// "package:/data/app/.../base.apk=com.genymobile.scrcpy"
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^
|
||||
// We want to extract the path (which may contain '=', even in practice)
|
||||
|
||||
if (strncmp(str, "package:", 8)) {
|
||||
// Does not start with "package:"
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *s = str + 8;
|
||||
size_t len = strcspn(s, " \r\n");
|
||||
s[len] = '\0';
|
||||
|
||||
char *p = strrchr(s, '=');
|
||||
if (!p) {
|
||||
// No '=' found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Truncate at the last '='
|
||||
*p = '\0';
|
||||
|
||||
return strdup(s);
|
||||
}
|
||||
|
@ -27,15 +27,4 @@ sc_adb_parse_devices(char *str, struct sc_vec_adb_devices *out_vec);
|
||||
char *
|
||||
sc_adb_parse_device_ip(char *str);
|
||||
|
||||
/**
|
||||
* Parse the package path from the output of
|
||||
* `adb shell pm list packages -f <package>`
|
||||
*
|
||||
* The parameter must be a NUL-terminated string.
|
||||
*
|
||||
* Warning: this function modifies the buffer for optimization purposes.
|
||||
*/
|
||||
char *
|
||||
sc_adb_parse_installed_apk_path(char *str);
|
||||
|
||||
#endif
|
||||
|
@ -1,51 +0,0 @@
|
||||
#ifndef STREAM_H
|
||||
#define STREAM_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
#include "trait/packet_sink.h"
|
||||
#include "util/net.h"
|
||||
#include "util/thread.h"
|
||||
|
||||
#define STREAM_MAX_SINKS 2
|
||||
|
||||
struct stream {
|
||||
sc_socket socket;
|
||||
sc_thread thread;
|
||||
|
||||
struct sc_packet_sink *sinks[STREAM_MAX_SINKS];
|
||||
unsigned sink_count;
|
||||
|
||||
AVCodecContext *codec_ctx;
|
||||
AVCodecParserContext *parser;
|
||||
// successive packets may need to be concatenated, until a non-config
|
||||
// packet is available
|
||||
AVPacket *pending;
|
||||
|
||||
const struct stream_callbacks *cbs;
|
||||
void *cbs_userdata;
|
||||
};
|
||||
|
||||
struct stream_callbacks {
|
||||
void (*on_eos)(struct stream *stream, void *userdata);
|
||||
};
|
||||
|
||||
void
|
||||
stream_init(struct stream *stream, sc_socket socket,
|
||||
const struct stream_callbacks *cbs, void *cbs_userdata);
|
||||
|
||||
void
|
||||
stream_add_sink(struct stream *stream, struct sc_packet_sink *sink);
|
||||
|
||||
bool
|
||||
stream_start(struct stream *stream);
|
||||
|
||||
void
|
||||
stream_join(struct stream *stream);
|
||||
|
||||
#endif
|
@ -241,28 +241,6 @@ static void test_get_ip_truncated(void) {
|
||||
assert(!ip);
|
||||
}
|
||||
|
||||
static void test_apk_path(void) {
|
||||
char str[] = "package:/data/app/~~71mguyc6p-kNjQdNaNkToA==/com.genymobile."
|
||||
"scrcpy-l6fiqqUSU7Ok7QLg-rIyJA==/base.apk=com.genymobile."
|
||||
"scrcpy\n";
|
||||
|
||||
const char *expected = "/data/app/~~71mguyc6p-kNjQdNaNkToA==/com.genymobile"
|
||||
".scrcpy-l6fiqqUSU7Ok7QLg-rIyJA==/base.apk";
|
||||
char *path = sc_adb_parse_installed_apk_path(str);
|
||||
assert(!strcmp(path, expected));
|
||||
free(path);
|
||||
}
|
||||
|
||||
static void test_apk_path_invalid(void) {
|
||||
// Does not start with "package:"
|
||||
char str[] = "garbage:/data/app/~~71mguyc6p-kNjQdNaNkToA==/com.genymobile."
|
||||
"scrcpy-l6fiqqUSU7Ok7QLg-rIyJA==/base.apk=com.genymobile."
|
||||
"scrcpy\n";
|
||||
|
||||
char *path = sc_adb_parse_installed_apk_path(str);
|
||||
assert(!path);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
@ -285,8 +263,5 @@ int main(int argc, char *argv[]) {
|
||||
test_get_ip_no_wlan_without_eol();
|
||||
test_get_ip_truncated();
|
||||
|
||||
test_apk_path();
|
||||
test_apk_path_invalid();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
testImplementation 'junit:junit:4.13.1'
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user