mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-03-20 19:14:27 +01:00
Compare commits
13 Commits
issue6156.
...
release
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b4e8e8e59 | ||
|
|
876e42de9b | ||
|
|
afaca80b37 | ||
|
|
8057835a0d | ||
|
|
e47529ab9c | ||
|
|
939c8e7f68 | ||
|
|
eb576c44f8 | ||
|
|
0522d02d40 | ||
|
|
30bfc80f9b | ||
|
|
c3d2ef1b1f | ||
|
|
a79ddc35a7 | ||
|
|
04542a9f58 | ||
|
|
8761dcb7a8 |
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -202,8 +202,7 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install meson ninja nasm libiconv zlib automake autoconf \
|
||||
libtool
|
||||
brew install meson nasm libiconv zlib automake autoconf libtool
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
@@ -245,7 +244,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: brew install meson ninja nasm libiconv zlib automake
|
||||
run: brew install meson nasm libiconv zlib automake
|
||||
# autoconf and libtool are already installed on macos-13
|
||||
|
||||
- name: Build
|
||||
|
||||
@@ -7,7 +7,7 @@ cd "$DEPS_DIR"
|
||||
VERSION=36.0.0
|
||||
FILENAME=platform-tools_r$VERSION-darwin.zip
|
||||
PROJECT_DIR=platform-tools-$VERSION-darwin
|
||||
SHA256SUM=b241878e6ec20650b041bf715ea05f7d5dc73bd24529464bd9cf68946e3132bd
|
||||
SHA256SUM=d3e9fa1df3345cf728586908426615a60863d2632f73f1ce14f0f1349ef000fd
|
||||
|
||||
cd "$SOURCES_DIR"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ cd "$DEPS_DIR"
|
||||
VERSION=36.0.0
|
||||
FILENAME=platform-tools_r$VERSION-win.zip
|
||||
PROJECT_DIR=platform-tools-$VERSION-windows
|
||||
SHA256SUM=24bd8bebbbb58b9870db202b5c6775c4a49992632021c60750d9d8ec8179d5f0
|
||||
SHA256SUM=12c2841f354e92a0eb2fd7bf6f0f9bf8538abce7bd6b060ac8349d6f6a61107c
|
||||
|
||||
cd "$SOURCES_DIR"
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ export CXXFLAGS="$CFLAGS"
|
||||
|
||||
if [[ -d "$DIRNAME" ]]
|
||||
then
|
||||
echo "'$PWD/$HDIRNAME' already exists, not reconfigured"
|
||||
echo "'$PWD/$DIRNAME' already exists, not reconfigured"
|
||||
cd "$DIRNAME"
|
||||
else
|
||||
mkdir "$DIRNAME"
|
||||
|
||||
@@ -13,7 +13,7 @@ BEGIN
|
||||
VALUE "LegalCopyright", "Romain Vimont, Genymobile"
|
||||
VALUE "OriginalFilename", "scrcpy.exe"
|
||||
VALUE "ProductName", "scrcpy"
|
||||
VALUE "ProductVersion", "3.3.1"
|
||||
VALUE "ProductVersion", "3.3.2"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -103,7 +103,7 @@ argv_to_string(const char *const *argv, char *buf, size_t bufsize) {
|
||||
|
||||
static void
|
||||
show_adb_installation_msg(void) {
|
||||
#ifndef __WINDOWS__
|
||||
#ifndef _WIN32
|
||||
static const struct {
|
||||
const char *binary;
|
||||
const char *command;
|
||||
@@ -331,7 +331,7 @@ sc_adb_reverse_remove(struct sc_intr *intr, const char *serial,
|
||||
bool
|
||||
sc_adb_push(struct sc_intr *intr, const char *serial, const char *local,
|
||||
const char *remote, unsigned flags) {
|
||||
#ifdef __WINDOWS__
|
||||
#ifdef _WIN32
|
||||
// Windows will parse the string, so the paths must be quoted
|
||||
// (see sys/win/command.c)
|
||||
local = sc_str_quote(local);
|
||||
@@ -351,7 +351,7 @@ sc_adb_push(struct sc_intr *intr, const char *serial, const char *local,
|
||||
|
||||
sc_pid pid = sc_adb_execute(argv, flags);
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifdef _WIN32
|
||||
free((void *) remote);
|
||||
free((void *) local);
|
||||
#endif
|
||||
@@ -362,7 +362,7 @@ sc_adb_push(struct sc_intr *intr, const char *serial, const char *local,
|
||||
bool
|
||||
sc_adb_install(struct sc_intr *intr, const char *serial, const char *local,
|
||||
unsigned flags) {
|
||||
#ifdef __WINDOWS__
|
||||
#ifdef _WIN32
|
||||
// Windows will parse the string, so the local name must be quoted
|
||||
// (see sys/win/command.c)
|
||||
local = sc_str_quote(local);
|
||||
@@ -377,7 +377,7 @@ sc_adb_install(struct sc_intr *intr, const char *serial, const char *local,
|
||||
|
||||
sc_pid pid = sc_adb_execute(argv, flags);
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifdef _WIN32
|
||||
free((void *) local);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ struct sc_display {
|
||||
|
||||
struct sc_opengl gl;
|
||||
#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE
|
||||
SDL_GLContext *gl_context;
|
||||
SDL_GLContext gl_context;
|
||||
#endif
|
||||
|
||||
bool mipmaps;
|
||||
|
||||
@@ -166,12 +166,6 @@ sc_hid_buttons_from_buttons_state(uint8_t buttons_state) {
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
sc_hid_mouse_init(struct sc_hid_mouse *hid) {
|
||||
hid->residual_hscroll = 0;
|
||||
hid->residual_vscroll = 0;
|
||||
}
|
||||
|
||||
void
|
||||
sc_hid_mouse_generate_input_from_motion(struct sc_hid_input *hid_input,
|
||||
const struct sc_mouse_motion_event *event) {
|
||||
@@ -198,37 +192,22 @@ sc_hid_mouse_generate_input_from_click(struct sc_hid_input *hid_input,
|
||||
data[4] = 0; // no horizontal scrolling
|
||||
}
|
||||
|
||||
static int8_t
|
||||
consume_scroll_integer(float *scroll) {
|
||||
float value = CLAMP(*scroll, -127, 127);
|
||||
int8_t consume = value; // truncate towards 0
|
||||
float residual = value - consume;
|
||||
*scroll = residual;
|
||||
return consume;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_hid_mouse_generate_input_from_scroll(struct sc_hid_mouse *hid,
|
||||
struct sc_hid_input *hid_input,
|
||||
sc_hid_mouse_generate_input_from_scroll(struct sc_hid_input *hid_input,
|
||||
const struct sc_mouse_scroll_event *event) {
|
||||
sc_hid_mouse_input_init(hid_input);
|
||||
|
||||
hid->residual_hscroll += event->hscroll;
|
||||
hid->residual_vscroll += event->vscroll;
|
||||
int8_t hscroll = consume_scroll_integer(&hid->residual_hscroll);
|
||||
int8_t vscroll = consume_scroll_integer(&hid->residual_vscroll);
|
||||
|
||||
if (!hscroll && !vscroll) {
|
||||
// Not enough scrolling to inject a scroll event
|
||||
if (!event->vscroll_int && !event->hscroll_int) {
|
||||
// Need a full integral value for HID
|
||||
return false;
|
||||
}
|
||||
|
||||
sc_hid_mouse_input_init(hid_input);
|
||||
|
||||
uint8_t *data = hid_input->data;
|
||||
data[0] = 0; // buttons state irrelevant (and unknown)
|
||||
data[1] = 0; // no x motion
|
||||
data[2] = 0; // no y motion
|
||||
data[3] = vscroll;
|
||||
data[4] = hscroll;
|
||||
data[3] = CLAMP(event->vscroll_int, -127, 127);
|
||||
data[4] = CLAMP(event->hscroll_int, -127, 127);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,6 @@
|
||||
|
||||
#define SC_HID_ID_MOUSE 2
|
||||
|
||||
struct sc_hid_mouse {
|
||||
float residual_hscroll;
|
||||
float residual_vscroll;
|
||||
};
|
||||
|
||||
void sc_hid_mouse_init(struct sc_hid_mouse *hid);
|
||||
|
||||
void
|
||||
sc_hid_mouse_generate_open(struct sc_hid_open *hid_open);
|
||||
|
||||
@@ -30,8 +23,7 @@ sc_hid_mouse_generate_input_from_click(struct sc_hid_input *hid_input,
|
||||
const struct sc_mouse_click_event *event);
|
||||
|
||||
bool
|
||||
sc_hid_mouse_generate_input_from_scroll(struct sc_hid_mouse *hid,
|
||||
struct sc_hid_input *hid_input,
|
||||
sc_hid_mouse_generate_input_from_scroll(struct sc_hid_input *hid_input,
|
||||
const struct sc_mouse_scroll_event *event);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -393,6 +393,8 @@ struct sc_mouse_scroll_event {
|
||||
struct sc_position position;
|
||||
float hscroll;
|
||||
float vscroll;
|
||||
int32_t hscroll_int;
|
||||
int32_t vscroll_int;
|
||||
uint8_t buttons_state; // bitwise-OR of sc_mouse_button values
|
||||
};
|
||||
|
||||
|
||||
@@ -903,6 +903,8 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
|
||||
.hscroll = event->x,
|
||||
.vscroll = event->y,
|
||||
#endif
|
||||
.hscroll_int = event->x,
|
||||
.vscroll_int = event->y,
|
||||
.buttons_state = im->mouse_buttons_state,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "common.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_V4L2
|
||||
# include <libavdevice/avdevice.h>
|
||||
#endif
|
||||
|
||||
@@ -93,7 +93,7 @@ struct scrcpy {
|
||||
|
||||
#ifdef _WIN32
|
||||
static BOOL WINAPI windows_ctrl_handler(DWORD ctrl_type) {
|
||||
if (ctrl_type == CTRL_C_EVENT) {
|
||||
if (ctrl_type == CTRL_C_EVENT || ctrl_type == CTRL_BREAK_EVENT) {
|
||||
sc_push_event(SDL_QUIT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ sc_screen_render_novideo(struct sc_screen *screen) {
|
||||
(void) res; // any error already logged
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) || defined(__WINDOWS__)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
# define CONTINUOUS_RESIZING_WORKAROUND
|
||||
#endif
|
||||
|
||||
@@ -409,7 +409,7 @@ sc_screen_init(struct sc_screen *screen,
|
||||
} else {
|
||||
// without video, the icon is used as window content, it must be present
|
||||
LOGE("Could not load icon");
|
||||
goto error_destroy_fps_counter;
|
||||
goto error_destroy_window;
|
||||
}
|
||||
|
||||
SDL_Surface *icon_novideo = params->video ? NULL : icon;
|
||||
|
||||
@@ -55,8 +55,7 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
||||
struct sc_mouse_uhid *mouse = DOWNCAST(mp);
|
||||
|
||||
struct sc_hid_input hid_input;
|
||||
if (!sc_hid_mouse_generate_input_from_scroll(&mouse->hid, &hid_input,
|
||||
event)) {
|
||||
if (!sc_hid_mouse_generate_input_from_scroll(&hid_input, event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -66,8 +65,6 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
||||
bool
|
||||
sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
|
||||
struct sc_controller *controller) {
|
||||
sc_hid_mouse_init(&mouse->hid);
|
||||
|
||||
mouse->controller = controller;
|
||||
|
||||
static const struct sc_mouse_processor_ops ops = {
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "controller.h"
|
||||
#include "hid/hid_mouse.h"
|
||||
#include "trait/mouse_processor.h"
|
||||
|
||||
struct sc_mouse_uhid {
|
||||
struct sc_mouse_processor mouse_processor; // mouse processor trait
|
||||
|
||||
struct sc_hid_mouse hid;
|
||||
struct sc_controller *controller;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,8 +42,7 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
||||
struct sc_mouse_aoa *mouse = DOWNCAST(mp);
|
||||
|
||||
struct sc_hid_input hid_input;
|
||||
if (!sc_hid_mouse_generate_input_from_scroll(&mouse->hid, &hid_input,
|
||||
event)) {
|
||||
if (!sc_hid_mouse_generate_input_from_scroll(&hid_input, event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,8 +64,6 @@ sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sc_hid_mouse_init(&mouse->hid);
|
||||
|
||||
static const struct sc_mouse_processor_ops ops = {
|
||||
.process_mouse_motion = sc_mouse_processor_process_mouse_motion,
|
||||
.process_mouse_click = sc_mouse_processor_process_mouse_click,
|
||||
|
||||
@@ -6,13 +6,11 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "usb/aoa_hid.h"
|
||||
#include "hid/hid_mouse.h"
|
||||
#include "trait/mouse_processor.h"
|
||||
|
||||
struct sc_mouse_aoa {
|
||||
struct sc_mouse_processor mouse_processor; // mouse processor trait
|
||||
|
||||
struct sc_hid_mouse hid;
|
||||
struct sc_aoa *aoa;
|
||||
};
|
||||
|
||||
|
||||
@@ -171,6 +171,8 @@ sc_screen_otg_process_mouse_wheel(struct sc_screen_otg *screen,
|
||||
.hscroll = event->x,
|
||||
.vscroll = event->y,
|
||||
#endif
|
||||
.hscroll_int = event->x,
|
||||
.vscroll_int = event->y,
|
||||
.buttons_state = sc_mouse_buttons_state_from_sdl(sdl_buttons_state),
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <ws2tcpip.h>
|
||||
|
||||
@@ -191,7 +191,8 @@ sc_vecdeque_reallocdata_(void *ptr, size_t newcap, size_t item_size,
|
||||
|
||||
size_t right_len = MIN(size, oldcap - oldorigin);
|
||||
assert(right_len);
|
||||
memcpy(newptr, (char *) ptr + (oldorigin * item_size), right_len * item_size);
|
||||
memcpy(newptr, (char *) ptr + (oldorigin * item_size),
|
||||
right_len * item_size);
|
||||
|
||||
if (size > right_len) {
|
||||
memcpy((char *) newptr + (right_len * item_size), ptr,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
project('scrcpy', 'c',
|
||||
version: '3.3.1',
|
||||
version: '3.3.2',
|
||||
meson_version: '>= 0.49',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
|
||||
@@ -7,8 +7,8 @@ android {
|
||||
applicationId "com.genymobile.scrcpy"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 35
|
||||
versionCode 30301
|
||||
versionName "3.3.1"
|
||||
versionCode 30302
|
||||
versionName "3.3.2"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
set -e
|
||||
|
||||
SCRCPY_DEBUG=false
|
||||
SCRCPY_VERSION_NAME=3.3.1
|
||||
SCRCPY_VERSION_NAME=3.3.2
|
||||
|
||||
PLATFORM=${ANDROID_PLATFORM:-35}
|
||||
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-35.0.0}
|
||||
|
||||
@@ -63,4 +63,12 @@ oneway interface IDisplayWindowListener {
|
||||
* Called when the keep clear ares on a display have changed.
|
||||
*/
|
||||
void onKeepClearAreasChanged(int displayId, in List<Rect> restricted, in List<Rect> unrestricted);
|
||||
|
||||
/**
|
||||
* Called when the eligibility of the desktop mode for a display have changed.
|
||||
*/
|
||||
void onDesktopModeEligibleChanged(int displayId);
|
||||
|
||||
void onDisplayAddSystemDecorations(int displayId);
|
||||
void onDisplayRemoveSystemDecorations(int displayId);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.genymobile.scrcpy.wrappers.ServiceManager;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.AttributionSource;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
@@ -91,6 +90,11 @@ public final class FakeContext extends ContextWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context createPackageContext(String packageName, int flags) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentResolver getContentResolver() {
|
||||
return contentResolver;
|
||||
@@ -104,9 +108,11 @@ public final class FakeContext extends ContextWrapper {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Context.CLIPBOARD_SERVICE.equals(name)) {
|
||||
// "semclipboard" is a Samsung-internal service
|
||||
// See <https://github.com/Genymobile/scrcpy/issues/6224>
|
||||
if (Context.CLIPBOARD_SERVICE.equals(name) || "semclipboard".equals(name)) {
|
||||
try {
|
||||
Field field = ClipboardManager.class.getDeclaredField("mContext");
|
||||
Field field = service.getClass().getDeclaredField("mContext");
|
||||
field.setAccessible(true);
|
||||
field.set(service, this);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
package com.genymobile.scrcpy.util;
|
||||
|
||||
import com.genymobile.scrcpy.AndroidVersions;
|
||||
import com.genymobile.scrcpy.wrappers.ContentProvider;
|
||||
import com.genymobile.scrcpy.wrappers.ServiceManager;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class Settings {
|
||||
|
||||
public static final String TABLE_SYSTEM = ContentProvider.TABLE_SYSTEM;
|
||||
@@ -18,66 +13,26 @@ public final class Settings {
|
||||
/* not instantiable */
|
||||
}
|
||||
|
||||
private static void execSettingsPut(String table, String key, String value) throws SettingsException {
|
||||
try {
|
||||
Command.exec("settings", "put", table, key, value);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new SettingsException("put", table, key, value, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String execSettingsGet(String table, String key) throws SettingsException {
|
||||
try {
|
||||
return Command.execReadLine("settings", "get", table, key);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new SettingsException("get", table, key, null, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getValue(String table, String key) throws SettingsException {
|
||||
if (Build.VERSION.SDK_INT <= AndroidVersions.API_30_ANDROID_11) {
|
||||
// on Android >= 12, it always fails: <https://github.com/Genymobile/scrcpy/issues/2788>
|
||||
try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) {
|
||||
return provider.getValue(table, key);
|
||||
} catch (SettingsException e) {
|
||||
Ln.w("Could not get settings value via ContentProvider, fallback to settings process", e);
|
||||
}
|
||||
try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) {
|
||||
return provider.getValue(table, key);
|
||||
}
|
||||
|
||||
return execSettingsGet(table, key);
|
||||
}
|
||||
|
||||
public static void putValue(String table, String key, String value) throws SettingsException {
|
||||
if (Build.VERSION.SDK_INT <= AndroidVersions.API_30_ANDROID_11) {
|
||||
// on Android >= 12, it always fails: <https://github.com/Genymobile/scrcpy/issues/2788>
|
||||
try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) {
|
||||
provider.putValue(table, key, value);
|
||||
} catch (SettingsException e) {
|
||||
Ln.w("Could not put settings value via ContentProvider, fallback to settings process", e);
|
||||
}
|
||||
try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) {
|
||||
provider.putValue(table, key, value);
|
||||
}
|
||||
|
||||
execSettingsPut(table, key, value);
|
||||
}
|
||||
|
||||
public static String getAndPutValue(String table, String key, String value) throws SettingsException {
|
||||
if (Build.VERSION.SDK_INT <= AndroidVersions.API_30_ANDROID_11) {
|
||||
// on Android >= 12, it always fails: <https://github.com/Genymobile/scrcpy/issues/2788>
|
||||
try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) {
|
||||
String oldValue = provider.getValue(table, key);
|
||||
if (!value.equals(oldValue)) {
|
||||
provider.putValue(table, key, value);
|
||||
}
|
||||
return oldValue;
|
||||
} catch (SettingsException e) {
|
||||
Ln.w("Could not get and put settings value via ContentProvider, fallback to settings process", e);
|
||||
try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) {
|
||||
String oldValue = provider.getValue(table, key);
|
||||
if (!value.equals(oldValue)) {
|
||||
provider.putValue(table, key, value);
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
String oldValue = getValue(table, key);
|
||||
if (!value.equals(oldValue)) {
|
||||
putValue(table, key, value);
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,19 @@ public class DisplayWindowListener extends IDisplayWindowListener.Stub {
|
||||
public void onKeepClearAreasChanged(int displayId, List<Rect> restricted, List<Rect> unrestricted) {
|
||||
// empty default implementation
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDesktopModeEligibleChanged(int displayId) {
|
||||
// empty default implementation
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayAddSystemDecorations(int displayId) {
|
||||
// empty default implementation
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayRemoveSystemDecorations(int displayId) {
|
||||
// empty default implementation
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user