From 7c25a8f17349b29e4545183363092d88eb5567d5 Mon Sep 17 00:00:00 2001 From: Chavi Weingarten Date: Thu, 25 Aug 2022 21:47:13 +0000 Subject: [PATCH] Move create and destroy display APIs into server. Move the SurfaceFlinger create and destroy APIs into display server package to remove confusion about who can create a display in SF. SF already guards the API call so only system and shell can create displays, but we'd like to route all display creations through DMS going forward. There were a few places that were calling createDisplay directly through the hidden API to call into SF that were running as Shell. This makes it difficult to make SF updates since it forces backwards compatibility on unsupported APIs. The SurfaceControl APIs will still be around temporarily because they are being called from external places. They will be replaced with calls into DisplayManger in later changes. Test: Displays are created Bug: 237664947 Change-Id: I212437242665f1ebfb2d041d5b91235e7820a45a --- .../server/display/DisplayControl.java | 55 +++++++++++++++++++ .../server/display/OverlayDisplayAdapter.java | 4 +- .../server/display/VirtualDisplayAdapter.java | 5 +- .../server/display/WifiDisplayAdapter.java | 4 +- services/core/jni/Android.bp | 1 + ..._android_server_display_DisplayControl.cpp | 52 ++++++++++++++++++ services/core/jni/onload.cpp | 2 + 7 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 services/core/java/com/android/server/display/DisplayControl.java create mode 100644 services/core/jni/com_android_server_display_DisplayControl.cpp diff --git a/services/core/java/com/android/server/display/DisplayControl.java b/services/core/java/com/android/server/display/DisplayControl.java new file mode 100644 index 0000000000000..e9640cf6b4d5a --- /dev/null +++ b/services/core/java/com/android/server/display/DisplayControl.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import android.os.IBinder; + +import java.util.Objects; + +/** + * Calls into SurfaceFlinger for Display creation and deletion. + */ +public class DisplayControl { + private static native IBinder nativeCreateDisplay(String name, boolean secure); + private static native void nativeDestroyDisplay(IBinder displayToken); + + /** + * Create a display in SurfaceFlinger. + * + * @param name The name of the display + * @param secure Whether this display is secure. + * @return The token reference for the display in SurfaceFlinger. + */ + public static IBinder createDisplay(String name, boolean secure) { + Objects.requireNonNull(name, "name must not be null"); + return nativeCreateDisplay(name, secure); + } + + /** + * Destroy a display in SurfaceFlinger. + * + * @param displayToken The display token for the display to be destroyed. + */ + public static void destroyDisplay(IBinder displayToken) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + + nativeDestroyDisplay(displayToken); + } + +} diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index 330379cf58eb4..b0de844389b65 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -305,7 +305,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { mSurface.release(); mSurface = null; } - SurfaceControl.destroyDisplay(getDisplayTokenLocked()); + DisplayControl.destroyDisplay(getDisplayTokenLocked()); } @Override @@ -460,7 +460,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate, long presentationDeadlineNanos, int state) { synchronized (getSyncRoot()) { - IBinder displayToken = SurfaceControl.createDisplay(mName, mFlags.mSecure); + IBinder displayToken = DisplayControl.createDisplay(mName, mFlags.mSecure); mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode, DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos, mFlags, state, surfaceTexture, mNumber) { diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 479629eae7ac1..38728ce106af0 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -82,8 +82,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter { // Called with SyncRoot lock held. public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context, Handler handler, Listener listener) { - this(syncRoot, context, handler, listener, - (String name, boolean secure) -> SurfaceControl.createDisplay(name, secure)); + this(syncRoot, context, handler, listener, DisplayControl::createDisplay); } @VisibleForTesting @@ -296,7 +295,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter { mSurface.release(); mSurface = null; } - SurfaceControl.destroyDisplay(getDisplayTokenLocked()); + DisplayControl.destroyDisplay(getDisplayTokenLocked()); if (mProjection != null && mMediaProjectionCallback != null) { try { mProjection.unregisterCallback(mMediaProjectionCallback); diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java index d632ee3d021c5..146b003650acb 100644 --- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java @@ -388,7 +388,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { String name = display.getFriendlyDisplayName(); String address = display.getDeviceAddress(); - IBinder displayToken = SurfaceControl.createDisplay(name, secure); + IBinder displayToken = DisplayControl.createDisplay(name, secure); mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height, refreshRate, deviceFlags, address, surface); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED); @@ -621,7 +621,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { mSurface.release(); mSurface = null; } - SurfaceControl.destroyDisplay(getDisplayTokenLocked()); + DisplayControl.destroyDisplay(getDisplayTokenLocked()); } public void setNameLocked(String name) { diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 40789964f4e1d..068bcd8fb3717 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -37,6 +37,7 @@ cc_library_static { "com_android_server_ConsumerIrService.cpp", "com_android_server_companion_virtual_InputController.cpp", "com_android_server_devicepolicy_CryptoTestHelper.cpp", + "com_android_server_display_DisplayControl.cpp", "com_android_server_connectivity_Vpn.cpp", "com_android_server_gpu_GpuService.cpp", "com_android_server_HardwarePropertiesManagerService.cpp", diff --git a/services/core/jni/com_android_server_display_DisplayControl.cpp b/services/core/jni/com_android_server_display_DisplayControl.cpp new file mode 100644 index 0000000000000..61f2b1411a0b0 --- /dev/null +++ b/services/core/jni/com_android_server_display_DisplayControl.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +namespace android { + +static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj, jboolean secure) { + ScopedUtfChars name(env, nameObj); + sp token(SurfaceComposerClient::createDisplay(String8(name.c_str()), bool(secure))); + return javaObjectForIBinder(env, token); +} + +static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { + sp token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + SurfaceComposerClient::destroyDisplay(token); +} + +// ---------------------------------------------------------------------------- + +static const JNINativeMethod sDisplayMethods[] = { + // clang-format off + {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;", + (void*)nativeCreateDisplay }, + {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V", + (void*)nativeDestroyDisplay }, + // clang-format on +}; + +int register_com_android_server_display_DisplayControl(JNIEnv* env) { + return jniRegisterNativeMethods(env, "com/android/server/display/DisplayControl", + sDisplayMethods, NELEM(sDisplayMethods)); +} + +} // namespace android diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 0cd949457cd18..00bef09353084 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -64,6 +64,7 @@ int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env); int register_android_server_companion_virtual_InputController(JNIEnv* env); int register_android_server_app_GameManagerService(JNIEnv* env); int register_com_android_server_wm_TaskFpsCallbackController(JNIEnv* env); +int register_com_android_server_display_DisplayControl(JNIEnv* env); }; using namespace android; @@ -120,5 +121,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_companion_virtual_InputController(env); register_android_server_app_GameManagerService(env); register_com_android_server_wm_TaskFpsCallbackController(env); + register_com_android_server_display_DisplayControl(env); return JNI_VERSION_1_4; }