Compare commits
39 Commits
v4l2_sink
...
nosecurefl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01199084ad | ||
|
|
41a0383d7c | ||
|
|
d39161f753 | ||
|
|
5af9d0ee0f | ||
|
|
fd0dc6c0cd | ||
|
|
151bc16644 | ||
|
|
ffc00210e9 | ||
|
|
243854a408 | ||
|
|
8b90dc61b9 | ||
|
|
2a5dfc1c17 | ||
|
|
e3fccc5a5e | ||
|
|
0541f1bff2 | ||
|
|
0272e6dc77 | ||
|
|
2a94a2b119 | ||
|
|
e91acdb0c4 | ||
|
|
6f5ad21f57 | ||
|
|
08b3086ffc | ||
|
|
deab7da761 | ||
|
|
f7a1b67d66 | ||
|
|
cbed38799e | ||
|
|
5beb7d6c02 | ||
|
|
5980183a33 | ||
|
|
fe8de893ca | ||
|
|
a974483c15 | ||
|
|
1b072a24c4 | ||
|
|
08f1fd46c8 | ||
|
|
2ddf760c09 | ||
|
|
5d9e96dc4e | ||
|
|
de9b79ec2d | ||
|
|
55806e7d31 | ||
|
|
21b590b766 | ||
|
|
d7e6589677 | ||
|
|
b4ee9f27ce | ||
|
|
6fa63cf6f8 | ||
|
|
50eecdab28 | ||
|
|
9576283907 | ||
|
|
66c581851f | ||
|
|
bb4614d558 | ||
|
|
aaf7875d92 |
27
README.md
27
README.md
@@ -301,7 +301,7 @@ vlc v4l2:///dev/videoN # VLC might add some buffering delay
|
||||
|
||||
For example, you could capture the video within [OBS].
|
||||
|
||||
[OBS]: https://obsproject.com/
|
||||
[OBS]: https://obsproject.com/fr
|
||||
|
||||
|
||||
### Connection
|
||||
@@ -741,10 +741,10 @@ _<kbd>[Super]</kbd> is typically the <kbd>Windows</kbd> or <kbd>Cmd</kbd> key._
|
||||
| Rotate display left | <kbd>MOD</kbd>+<kbd>←</kbd> _(left)_
|
||||
| Rotate display right | <kbd>MOD</kbd>+<kbd>→</kbd> _(right)_
|
||||
| Resize window to 1:1 (pixel-perfect) | <kbd>MOD</kbd>+<kbd>g</kbd>
|
||||
| Resize window to remove black borders | <kbd>MOD</kbd>+<kbd>w</kbd> \| _Double-click¹_
|
||||
| Resize window to remove black borders | <kbd>MOD</kbd>+<kbd>w</kbd> \| _Double-left-click¹_
|
||||
| Click on `HOME` | <kbd>MOD</kbd>+<kbd>h</kbd> \| _Middle-click_
|
||||
| Click on `BACK` | <kbd>MOD</kbd>+<kbd>b</kbd> \| _Right-click²_
|
||||
| Click on `APP_SWITCH` | <kbd>MOD</kbd>+<kbd>s</kbd>
|
||||
| Click on `APP_SWITCH` | <kbd>MOD</kbd>+<kbd>s</kbd> \| _4th-click³_
|
||||
| Click on `MENU` (unlock screen) | <kbd>MOD</kbd>+<kbd>m</kbd>
|
||||
| Click on `VOLUME_UP` | <kbd>MOD</kbd>+<kbd>↑</kbd> _(up)_
|
||||
| Click on `VOLUME_DOWN` | <kbd>MOD</kbd>+<kbd>↓</kbd> _(down)_
|
||||
@@ -753,18 +753,27 @@ _<kbd>[Super]</kbd> is typically the <kbd>Windows</kbd> or <kbd>Cmd</kbd> key._
|
||||
| Turn device screen off (keep mirroring) | <kbd>MOD</kbd>+<kbd>o</kbd>
|
||||
| Turn device screen on | <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd>
|
||||
| Rotate device screen | <kbd>MOD</kbd>+<kbd>r</kbd>
|
||||
| Expand notification panel | <kbd>MOD</kbd>+<kbd>n</kbd>
|
||||
| Collapse notification panel | <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>n</kbd>
|
||||
| Copy to clipboard³ | <kbd>MOD</kbd>+<kbd>c</kbd>
|
||||
| Cut to clipboard³ | <kbd>MOD</kbd>+<kbd>x</kbd>
|
||||
| Synchronize clipboards and paste³ | <kbd>MOD</kbd>+<kbd>v</kbd>
|
||||
| Expand notification panel | <kbd>MOD</kbd>+<kbd>n</kbd> \| _5th-click³_
|
||||
| Expand settings panel | <kbd>MOD</kbd>+<kbd>n</kbd>+<kbd>n</kbd> \| _Double-5th-click³_
|
||||
| Collapse panels | <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>n</kbd>
|
||||
| Copy to clipboard⁴ | <kbd>MOD</kbd>+<kbd>c</kbd>
|
||||
| Cut to clipboard⁴ | <kbd>MOD</kbd>+<kbd>x</kbd>
|
||||
| Synchronize clipboards and paste⁴ | <kbd>MOD</kbd>+<kbd>v</kbd>
|
||||
| Inject computer clipboard text | <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>v</kbd>
|
||||
| Enable/disable FPS counter (on stdout) | <kbd>MOD</kbd>+<kbd>i</kbd>
|
||||
| Pinch-to-zoom | <kbd>Ctrl</kbd>+_click-and-move_
|
||||
|
||||
_¹Double-click on black borders to remove them._
|
||||
_²Right-click turns the screen on if it was off, presses BACK otherwise._
|
||||
_³Only on Android >= 7._
|
||||
_³4th and 5th mouse buttons, if your mouse has them._
|
||||
_⁴Only on Android >= 7._
|
||||
|
||||
Shortcuts with repeated keys are executted by releasing and pressing the key a
|
||||
second time. For example, to execute "Expand settings panel":
|
||||
|
||||
1. Press and keep pressing <kbd>MOD</kbd>.
|
||||
2. Then double-press <kbd>n</kbd>.
|
||||
3. Finally, release <kbd>MOD</kbd>.
|
||||
|
||||
All <kbd>Ctrl</kbd>+_key_ shortcuts are forwarded to the device, so they are
|
||||
handled by the active application.
|
||||
|
||||
@@ -186,7 +186,7 @@ Enable "show touches" on start, restore the initial value on exit.
|
||||
It only shows physical touches (not clicks from scrcpy).
|
||||
|
||||
.TP
|
||||
.BI "\-\-v4l2-sink " /dev/videoN
|
||||
.BI "\-\-v4l2_sink " /dev/videoN
|
||||
Output to v4l2loopback device.
|
||||
|
||||
It requires to lock the video orientation (see --lock-video-orientation).
|
||||
|
||||
@@ -177,7 +177,7 @@ scrcpy_print_usage(const char *arg0) {
|
||||
" It only shows physical touches (not clicks from scrcpy).\n"
|
||||
"\n"
|
||||
#ifdef HAVE_V4L2
|
||||
" --v4l2-sink /dev/videoN\n"
|
||||
" --v4l2_sink /dev/videoN\n"
|
||||
" Output to v4l2loopback device.\n"
|
||||
" It requires to lock the video orientation (see\n"
|
||||
" --lock-video-orientation).\n"
|
||||
@@ -726,7 +726,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||
{"stay-awake", no_argument, NULL, 'w'},
|
||||
{"turn-screen-off", no_argument, NULL, 'S'},
|
||||
#ifdef HAVE_V4L2
|
||||
{"v4l2-sink", required_argument, NULL, OPT_V4L2_SINK},
|
||||
{"v4l2_sink", required_argument, NULL, OPT_V4L2_SINK},
|
||||
#endif
|
||||
{"verbosity", required_argument, NULL, 'V'},
|
||||
{"version", no_argument, NULL, 'v'},
|
||||
@@ -926,7 +926,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||
#ifdef HAVE_V4L2
|
||||
if (!opts->display && !opts->record_filename && !opts->v4l2_device) {
|
||||
LOGE("-N/--no-display requires either screen recording (-r/--record)"
|
||||
" or sink to v4l2loopback device (--v4l2-sink)");
|
||||
" or sink to v4l2loopback device (--v4l2_sink)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,8 @@ control_msg_serialize(const struct control_msg *msg, unsigned char *buf) {
|
||||
buf[1] = msg->set_screen_power_mode.mode;
|
||||
return 2;
|
||||
case CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL:
|
||||
case CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL:
|
||||
case CONTROL_MSG_TYPE_EXPAND_SETTINGS_PANEL:
|
||||
case CONTROL_MSG_TYPE_COLLAPSE_PANELS:
|
||||
case CONTROL_MSG_TYPE_GET_CLIPBOARD:
|
||||
case CONTROL_MSG_TYPE_ROTATE_DEVICE:
|
||||
// no additional data
|
||||
|
||||
@@ -27,7 +27,8 @@ enum control_msg_type {
|
||||
CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT,
|
||||
CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON,
|
||||
CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL,
|
||||
CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL,
|
||||
CONTROL_MSG_TYPE_EXPAND_SETTINGS_PANEL,
|
||||
CONTROL_MSG_TYPE_COLLAPSE_PANELS,
|
||||
CONTROL_MSG_TYPE_GET_CLIPBOARD,
|
||||
CONTROL_MSG_TYPE_SET_CLIPBOARD,
|
||||
CONTROL_MSG_TYPE_SET_SCREEN_POWER_MODE,
|
||||
|
||||
@@ -72,6 +72,10 @@ input_manager_init(struct input_manager *im,
|
||||
im->sdl_shortcut_mods.count = shortcut_mods->count;
|
||||
|
||||
im->vfinger_down = false;
|
||||
|
||||
im->last_keycode = SDLK_UNKNOWN;
|
||||
im->last_mod = 0;
|
||||
im->key_repeat = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -179,9 +183,19 @@ expand_notification_panel(struct controller *controller) {
|
||||
}
|
||||
|
||||
static void
|
||||
collapse_notification_panel(struct controller *controller) {
|
||||
expand_settings_panel(struct controller *controller) {
|
||||
struct control_msg msg;
|
||||
msg.type = CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL;
|
||||
msg.type = CONTROL_MSG_TYPE_EXPAND_SETTINGS_PANEL;
|
||||
|
||||
if (!controller_push_msg(controller, &msg)) {
|
||||
LOGW("Could not request 'expand settings panel'");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
collapse_panels(struct controller *controller) {
|
||||
struct control_msg msg;
|
||||
msg.type = CONTROL_MSG_TYPE_COLLAPSE_PANELS;
|
||||
|
||||
if (!controller_push_msg(controller, &msg)) {
|
||||
LOGW("Could not request 'collapse notification panel'");
|
||||
@@ -384,16 +398,27 @@ input_manager_process_key(struct input_manager *im,
|
||||
// control: indicates the state of the command-line option --no-control
|
||||
bool control = im->control;
|
||||
|
||||
bool smod = is_shortcut_mod(im, event->keysym.mod);
|
||||
|
||||
struct controller *controller = im->controller;
|
||||
|
||||
SDL_Keycode keycode = event->keysym.sym;
|
||||
uint16_t mod = event->keysym.mod;
|
||||
bool down = event->type == SDL_KEYDOWN;
|
||||
bool ctrl = event->keysym.mod & KMOD_CTRL;
|
||||
bool shift = event->keysym.mod & KMOD_SHIFT;
|
||||
bool repeat = event->repeat;
|
||||
|
||||
bool smod = is_shortcut_mod(im, mod);
|
||||
|
||||
if (down && !repeat) {
|
||||
if (keycode == im->last_keycode && mod == im->last_mod) {
|
||||
++im->key_repeat;
|
||||
} else {
|
||||
im->key_repeat = 0;
|
||||
im->last_keycode = keycode;
|
||||
im->last_mod = mod;
|
||||
}
|
||||
}
|
||||
|
||||
// The shortcut modifier is pressed
|
||||
if (smod) {
|
||||
int action = down ? ACTION_DOWN : ACTION_UP;
|
||||
@@ -498,9 +523,11 @@ input_manager_process_key(struct input_manager *im,
|
||||
case SDLK_n:
|
||||
if (control && !repeat && down) {
|
||||
if (shift) {
|
||||
collapse_notification_panel(controller);
|
||||
} else {
|
||||
collapse_panels(controller);
|
||||
} else if (im->key_repeat == 0) {
|
||||
expand_notification_panel(controller);
|
||||
} else {
|
||||
expand_settings_panel(controller);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -666,7 +693,11 @@ input_manager_process_mouse_button(struct input_manager *im,
|
||||
return;
|
||||
}
|
||||
if (control && event->button == SDL_BUTTON_X2 && down) {
|
||||
expand_notification_panel(im->controller);
|
||||
if (event->clicks < 2) {
|
||||
expand_notification_panel(im->controller);
|
||||
} else {
|
||||
expand_settings_panel(im->controller);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (control && event->button == SDL_BUTTON_RIGHT) {
|
||||
|
||||
@@ -33,6 +33,13 @@ struct input_manager {
|
||||
} sdl_shortcut_mods;
|
||||
|
||||
bool vfinger_down;
|
||||
|
||||
// Tracks the number of identical consecutive shortcut key down events.
|
||||
// Not to be confused with event->repeat, which counts the number of
|
||||
// system-generated repeated key presses.
|
||||
unsigned key_repeat;
|
||||
SDL_Keycode last_keycode;
|
||||
uint16_t last_mod;
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@@ -58,7 +58,7 @@ get_server_path(void) {
|
||||
LOGE("Could not get executable path, "
|
||||
"using " SERVER_FILENAME " from current directory");
|
||||
// not found, use current directory
|
||||
return SERVER_FILENAME;
|
||||
return strdup(SERVER_FILENAME);
|
||||
}
|
||||
char *dir = dirname(executable_path);
|
||||
size_t dirlen = strlen(dir);
|
||||
@@ -70,7 +70,7 @@ get_server_path(void) {
|
||||
LOGE("Could not alloc server path string, "
|
||||
"using " SERVER_FILENAME " from current directory");
|
||||
free(executable_path);
|
||||
return SERVER_FILENAME;
|
||||
return strdup(SERVER_FILENAME);
|
||||
}
|
||||
|
||||
memcpy(server_path, dir, dirlen);
|
||||
|
||||
@@ -177,9 +177,9 @@ static void test_serialize_expand_notification_panel(void) {
|
||||
assert(!memcmp(buf, expected, sizeof(expected)));
|
||||
}
|
||||
|
||||
static void test_serialize_collapse_notification_panel(void) {
|
||||
static void test_serialize_expand_settings_panel(void) {
|
||||
struct control_msg msg = {
|
||||
.type = CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL,
|
||||
.type = CONTROL_MSG_TYPE_EXPAND_SETTINGS_PANEL,
|
||||
};
|
||||
|
||||
unsigned char buf[CONTROL_MSG_MAX_SIZE];
|
||||
@@ -187,7 +187,22 @@ static void test_serialize_collapse_notification_panel(void) {
|
||||
assert(size == 1);
|
||||
|
||||
const unsigned char expected[] = {
|
||||
CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL,
|
||||
CONTROL_MSG_TYPE_EXPAND_SETTINGS_PANEL,
|
||||
};
|
||||
assert(!memcmp(buf, expected, sizeof(expected)));
|
||||
}
|
||||
|
||||
static void test_serialize_collapse_panels(void) {
|
||||
struct control_msg msg = {
|
||||
.type = CONTROL_MSG_TYPE_COLLAPSE_PANELS,
|
||||
};
|
||||
|
||||
unsigned char buf[CONTROL_MSG_MAX_SIZE];
|
||||
size_t size = control_msg_serialize(&msg, buf);
|
||||
assert(size == 1);
|
||||
|
||||
const unsigned char expected[] = {
|
||||
CONTROL_MSG_TYPE_COLLAPSE_PANELS,
|
||||
};
|
||||
assert(!memcmp(buf, expected, sizeof(expected)));
|
||||
}
|
||||
@@ -274,7 +289,8 @@ int main(int argc, char *argv[]) {
|
||||
test_serialize_inject_scroll_event();
|
||||
test_serialize_back_or_screen_on();
|
||||
test_serialize_expand_notification_panel();
|
||||
test_serialize_collapse_notification_panel();
|
||||
test_serialize_expand_settings_panel();
|
||||
test_serialize_collapse_panels();
|
||||
test_serialize_get_clipboard();
|
||||
test_serialize_set_clipboard();
|
||||
test_serialize_set_screen_power_mode();
|
||||
|
||||
@@ -11,11 +11,12 @@ public final class ControlMessage {
|
||||
public static final int TYPE_INJECT_SCROLL_EVENT = 3;
|
||||
public static final int TYPE_BACK_OR_SCREEN_ON = 4;
|
||||
public static final int TYPE_EXPAND_NOTIFICATION_PANEL = 5;
|
||||
public static final int TYPE_COLLAPSE_NOTIFICATION_PANEL = 6;
|
||||
public static final int TYPE_GET_CLIPBOARD = 7;
|
||||
public static final int TYPE_SET_CLIPBOARD = 8;
|
||||
public static final int TYPE_SET_SCREEN_POWER_MODE = 9;
|
||||
public static final int TYPE_ROTATE_DEVICE = 10;
|
||||
public static final int TYPE_EXPAND_SETTINGS_PANEL = 6;
|
||||
public static final int TYPE_COLLAPSE_PANELS = 7;
|
||||
public static final int TYPE_GET_CLIPBOARD = 8;
|
||||
public static final int TYPE_SET_CLIPBOARD = 9;
|
||||
public static final int TYPE_SET_SCREEN_POWER_MODE = 10;
|
||||
public static final int TYPE_ROTATE_DEVICE = 11;
|
||||
|
||||
private int type;
|
||||
private String text;
|
||||
|
||||
@@ -77,7 +77,8 @@ public class ControlMessageReader {
|
||||
msg = parseSetScreenPowerMode();
|
||||
break;
|
||||
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
|
||||
case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL:
|
||||
case ControlMessage.TYPE_EXPAND_SETTINGS_PANEL:
|
||||
case ControlMessage.TYPE_COLLAPSE_PANELS:
|
||||
case ControlMessage.TYPE_GET_CLIPBOARD:
|
||||
case ControlMessage.TYPE_ROTATE_DEVICE:
|
||||
msg = ControlMessage.createEmpty(type);
|
||||
|
||||
@@ -107,7 +107,10 @@ public class Controller {
|
||||
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
|
||||
Device.expandNotificationPanel();
|
||||
break;
|
||||
case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL:
|
||||
case ControlMessage.TYPE_EXPAND_SETTINGS_PANEL:
|
||||
Device.expandSettingsPanel();
|
||||
break;
|
||||
case ControlMessage.TYPE_COLLAPSE_PANELS:
|
||||
Device.collapsePanels();
|
||||
break;
|
||||
case ControlMessage.TYPE_GET_CLIPBOARD:
|
||||
|
||||
@@ -230,6 +230,10 @@ public final class Device {
|
||||
SERVICE_MANAGER.getStatusBarManager().expandNotificationsPanel();
|
||||
}
|
||||
|
||||
public static void expandSettingsPanel() {
|
||||
SERVICE_MANAGER.getStatusBarManager().expandSettingsPanel();
|
||||
}
|
||||
|
||||
public static void collapsePanels() {
|
||||
SERVICE_MANAGER.getStatusBarManager().collapsePanels();
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
||||
}
|
||||
|
||||
private static IBinder createDisplay() {
|
||||
return SurfaceControl.createDisplay("scrcpy", true);
|
||||
return SurfaceControl.createDisplay("scrcpy", false);
|
||||
}
|
||||
|
||||
private static void configure(MediaCodec codec, MediaFormat format) {
|
||||
|
||||
@@ -14,7 +14,7 @@ public class ActivityManager {
|
||||
|
||||
private final IInterface manager;
|
||||
private Method getContentProviderExternalMethod;
|
||||
private boolean getContentProviderExternalMethodLegacy;
|
||||
private boolean getContentProviderExternalMethodNewVersion = true;
|
||||
private Method removeContentProviderExternalMethod;
|
||||
|
||||
public ActivityManager(IInterface manager) {
|
||||
@@ -29,7 +29,7 @@ public class ActivityManager {
|
||||
} catch (NoSuchMethodException e) {
|
||||
// old version
|
||||
getContentProviderExternalMethod = manager.getClass().getMethod("getContentProviderExternal", String.class, int.class, IBinder.class);
|
||||
getContentProviderExternalMethodLegacy = true;
|
||||
getContentProviderExternalMethodNewVersion = false;
|
||||
}
|
||||
}
|
||||
return getContentProviderExternalMethod;
|
||||
@@ -46,7 +46,7 @@ public class ActivityManager {
|
||||
try {
|
||||
Method method = getGetContentProviderExternalMethod();
|
||||
Object[] args;
|
||||
if (!getContentProviderExternalMethodLegacy) {
|
||||
if (getContentProviderExternalMethodNewVersion) {
|
||||
// new version
|
||||
args = new Object[]{name, ServiceManager.USER_ID, token, null};
|
||||
} else {
|
||||
|
||||
@@ -11,6 +11,8 @@ public class StatusBarManager {
|
||||
|
||||
private final IInterface manager;
|
||||
private Method expandNotificationsPanelMethod;
|
||||
private Method expandSettingsPanelMethod;
|
||||
private boolean expandSettingsPanelMethodNewVersion = true;
|
||||
private Method collapsePanelsMethod;
|
||||
|
||||
public StatusBarManager(IInterface manager) {
|
||||
@@ -24,6 +26,20 @@ public class StatusBarManager {
|
||||
return expandNotificationsPanelMethod;
|
||||
}
|
||||
|
||||
private Method getExpandSettingsPanel() throws NoSuchMethodException {
|
||||
if (expandSettingsPanelMethod == null) {
|
||||
try {
|
||||
// Since Android 7: https://android.googlesource.com/platform/frameworks/base.git/+/a9927325eda025504d59bb6594fee8e240d95b01%5E%21/
|
||||
expandSettingsPanelMethod = manager.getClass().getMethod("expandSettingsPanel", String.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// old version
|
||||
expandSettingsPanelMethod = manager.getClass().getMethod("expandSettingsPanel");
|
||||
expandSettingsPanelMethodNewVersion = false;
|
||||
}
|
||||
}
|
||||
return expandSettingsPanelMethod;
|
||||
}
|
||||
|
||||
private Method getCollapsePanelsMethod() throws NoSuchMethodException {
|
||||
if (collapsePanelsMethod == null) {
|
||||
collapsePanelsMethod = manager.getClass().getMethod("collapsePanels");
|
||||
@@ -40,6 +56,21 @@ public class StatusBarManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void expandSettingsPanel() {
|
||||
try {
|
||||
Method method = getExpandSettingsPanel();
|
||||
if (expandSettingsPanelMethodNewVersion) {
|
||||
// new version
|
||||
method.invoke(manager, (Object) null);
|
||||
} else {
|
||||
// old version
|
||||
method.invoke(manager);
|
||||
}
|
||||
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
||||
Ln.e("Could not invoke method", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void collapsePanels() {
|
||||
try {
|
||||
Method method = getCollapsePanelsMethod();
|
||||
|
||||
@@ -182,19 +182,35 @@ public class ControlMessageReaderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCollapseNotificationPanelEvent() throws IOException {
|
||||
public void testParseExpandSettingsPanelEvent() throws IOException {
|
||||
ControlMessageReader reader = new ControlMessageReader();
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
DataOutputStream dos = new DataOutputStream(bos);
|
||||
dos.writeByte(ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL);
|
||||
dos.writeByte(ControlMessage.TYPE_EXPAND_SETTINGS_PANEL);
|
||||
|
||||
byte[] packet = bos.toByteArray();
|
||||
|
||||
reader.readFrom(new ByteArrayInputStream(packet));
|
||||
ControlMessage event = reader.next();
|
||||
|
||||
Assert.assertEquals(ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL, event.getType());
|
||||
Assert.assertEquals(ControlMessage.TYPE_EXPAND_SETTINGS_PANEL, event.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCollapsePanelsEvent() throws IOException {
|
||||
ControlMessageReader reader = new ControlMessageReader();
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
DataOutputStream dos = new DataOutputStream(bos);
|
||||
dos.writeByte(ControlMessage.TYPE_COLLAPSE_PANELS);
|
||||
|
||||
byte[] packet = bos.toByteArray();
|
||||
|
||||
reader.readFrom(new ByteArrayInputStream(packet));
|
||||
ControlMessage event = reader.next();
|
||||
|
||||
Assert.assertEquals(ControlMessage.TYPE_COLLAPSE_PANELS, event.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user