Merge "Generalize physical display management"
This commit is contained in:
committed by
Android (Google) Code Review
commit
9e7dce3833
@@ -252,10 +252,12 @@ status_t BootAnimation::initTexture(FileMap* map, int* width, int* height)
|
||||
status_t BootAnimation::readyToRun() {
|
||||
mAssets.addDefaultAssets();
|
||||
|
||||
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
|
||||
ISurfaceComposer::eDisplayIdMain));
|
||||
mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();
|
||||
if (mDisplayToken == nullptr)
|
||||
return -1;
|
||||
|
||||
DisplayInfo dinfo;
|
||||
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
|
||||
status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo);
|
||||
if (status)
|
||||
return -1;
|
||||
|
||||
@@ -1014,16 +1016,13 @@ void BootAnimation::handleViewport(nsecs_t timestep) {
|
||||
// At the end of the animation, we switch to the viewport that DisplayManager will apply
|
||||
// later. This changes the coordinate system, and means we must move the surface up by
|
||||
// the inset amount.
|
||||
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
|
||||
ISurfaceComposer::eDisplayIdMain));
|
||||
|
||||
Rect layerStackRect(0, 0, mWidth, mHeight - mTargetInset);
|
||||
Rect displayRect(0, mTargetInset, mWidth, mHeight);
|
||||
|
||||
SurfaceComposerClient::Transaction t;
|
||||
t.setPosition(mFlingerSurfaceControl, 0, -mTargetInset)
|
||||
.setCrop(mFlingerSurfaceControl, Rect(0, mTargetInset, mWidth, mHeight));
|
||||
t.setDisplayProjection(dtoken, 0 /* orientation */, layerStackRect, displayRect);
|
||||
t.setDisplayProjection(mDisplayToken, 0 /* orientation */, layerStackRect, displayRect);
|
||||
t.apply();
|
||||
|
||||
mTargetInset = mCurrentInset = 0;
|
||||
|
||||
@@ -171,6 +171,7 @@ private:
|
||||
EGLDisplay mDisplay;
|
||||
EGLDisplay mContext;
|
||||
EGLDisplay mSurface;
|
||||
sp<IBinder> mDisplayToken;
|
||||
sp<SurfaceControl> mFlingerSurfaceControl;
|
||||
sp<Surface> mFlingerSurface;
|
||||
bool mClockEnabled;
|
||||
|
||||
@@ -46,23 +46,22 @@
|
||||
|
||||
using namespace android;
|
||||
|
||||
static uint32_t DEFAULT_DISPLAY_ID = ISurfaceComposer::eDisplayIdMain;
|
||||
|
||||
#define COLORSPACE_UNKNOWN 0
|
||||
#define COLORSPACE_SRGB 1
|
||||
#define COLORSPACE_DISPLAY_P3 2
|
||||
|
||||
static void usage(const char* pname)
|
||||
static void usage(const char* pname, PhysicalDisplayId displayId)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [-hp] [-d display-id] [FILENAME]\n"
|
||||
" -h: this message\n"
|
||||
" -p: save the file as a png.\n"
|
||||
" -d: specify the display id to capture, default %d.\n"
|
||||
" -d: specify the physical display ID to capture (default: %"
|
||||
ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ")\n"
|
||||
" see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n"
|
||||
"If FILENAME ends with .png it will be saved as a png.\n"
|
||||
"If FILENAME is not given, the results will be printed to stdout.\n",
|
||||
pname, DEFAULT_DISPLAY_ID
|
||||
);
|
||||
pname, displayId);
|
||||
}
|
||||
|
||||
static SkColorType flinger2skia(PixelFormat f)
|
||||
@@ -127,9 +126,14 @@ static status_t notifyMediaScanner(const char* fileName) {
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::optional<PhysicalDisplayId> displayId = SurfaceComposerClient::getInternalDisplayId();
|
||||
if (!displayId) {
|
||||
fprintf(stderr, "Failed to get token for internal display\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* pname = argv[0];
|
||||
bool png = false;
|
||||
int32_t displayId = DEFAULT_DISPLAY_ID;
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, "phd:")) != -1) {
|
||||
switch (c) {
|
||||
@@ -137,11 +141,11 @@ int main(int argc, char** argv)
|
||||
png = true;
|
||||
break;
|
||||
case 'd':
|
||||
displayId = atoi(optarg);
|
||||
displayId = atoll(optarg);
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
usage(pname);
|
||||
usage(pname, *displayId);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -166,7 +170,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
usage(pname);
|
||||
usage(pname, *displayId);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -192,9 +196,10 @@ int main(int argc, char** argv)
|
||||
ProcessState::self()->setThreadPoolMaxThreadCount(0);
|
||||
ProcessState::self()->startThreadPool();
|
||||
|
||||
sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
|
||||
if (display == NULL) {
|
||||
fprintf(stderr, "Unable to get handle for display %d\n", displayId);
|
||||
const sp<IBinder> display = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
|
||||
if (display == nullptr) {
|
||||
fprintf(stderr, "Failed to get token for invalid display %"
|
||||
ANDROID_PHYSICAL_DISPLAY_ID_FORMAT "\n", *displayId);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -33456,7 +33456,6 @@ HSPLandroid/view/SurfaceControl;->destroy()V
|
||||
HSPLandroid/view/SurfaceControl;->finalize()V
|
||||
HSPLandroid/view/SurfaceControl;->getActiveColorMode(Landroid/os/IBinder;)I
|
||||
HSPLandroid/view/SurfaceControl;->getActiveConfig(Landroid/os/IBinder;)I
|
||||
HSPLandroid/view/SurfaceControl;->getBuiltInDisplay(I)Landroid/os/IBinder;
|
||||
HSPLandroid/view/SurfaceControl;->getDisplayColorModes(Landroid/os/IBinder;)[I
|
||||
HSPLandroid/view/SurfaceControl;->getDisplayConfigs(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;
|
||||
HSPLandroid/view/SurfaceControl;->getHandle()Landroid/os/IBinder;
|
||||
|
||||
@@ -22,7 +22,6 @@ import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER;
|
||||
import android.annotation.TestApi;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.graphics.FrameInfo;
|
||||
import android.graphics.Insets;
|
||||
import android.hardware.display.DisplayManagerGlobal;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
@@ -914,25 +913,11 @@ public final class Choreographer {
|
||||
super(looper, vsyncSource);
|
||||
}
|
||||
|
||||
// TODO(b/116025192): physicalDisplayId is ignored because SF only emits VSYNC events for
|
||||
// the internal display and DisplayEventReceiver#scheduleVsync only allows requesting VSYNC
|
||||
// for the internal display implicitly.
|
||||
@Override
|
||||
public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
|
||||
// Ignore vsync from secondary display.
|
||||
// This can be problematic because the call to scheduleVsync() is a one-shot.
|
||||
// We need to ensure that we will still receive the vsync from the primary
|
||||
// display which is the one we really care about. Ideally we should schedule
|
||||
// vsync for a particular display.
|
||||
// At this time Surface Flinger won't send us vsyncs for secondary displays
|
||||
// but that could change in the future so let's log a message to help us remember
|
||||
// that we need to fix this.
|
||||
if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
|
||||
Log.d(TAG, "Received vsync from secondary display, but we don't support "
|
||||
+ "this case yet. Choreographer needs a way to explicitly request "
|
||||
+ "vsync for a specific display to ensure it doesn't lose track "
|
||||
+ "of its scheduled vsync.");
|
||||
scheduleVsync();
|
||||
return;
|
||||
}
|
||||
|
||||
public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
|
||||
// Post the vsync event to the Handler.
|
||||
// The idea is to prevent incoming vsync events from completely starving
|
||||
// the message queue. If there are no messages in the queue with timestamps
|
||||
|
||||
@@ -136,12 +136,11 @@ public abstract class DisplayEventReceiver {
|
||||
*
|
||||
* @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}
|
||||
* timebase.
|
||||
* @param builtInDisplayId The surface flinger built-in display id such as
|
||||
* {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}.
|
||||
* @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
|
||||
* @param frame The frame number. Increases by one for each vertical sync interval.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
|
||||
public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,12 +148,11 @@ public abstract class DisplayEventReceiver {
|
||||
*
|
||||
* @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()}
|
||||
* timebase.
|
||||
* @param builtInDisplayId The surface flinger built-in display id such as
|
||||
* {@link SurfaceControl#BUILT_IN_DISPLAY_ID_HDMI}.
|
||||
* @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
|
||||
* @param connected True if the display is connected, false if it disconnected.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
|
||||
public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,14 +172,14 @@ public abstract class DisplayEventReceiver {
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
@UnsupportedAppUsage
|
||||
private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
|
||||
onVsync(timestampNanos, builtInDisplayId, frame);
|
||||
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
|
||||
onVsync(timestampNanos, physicalDisplayId, frame);
|
||||
}
|
||||
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
@UnsupportedAppUsage
|
||||
private void dispatchHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
|
||||
onHotplug(timestampNanos, builtInDisplayId, connected);
|
||||
private void dispatchHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
|
||||
onHotplug(timestampNanos, physicalDisplayId, connected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,8 @@ public final class SurfaceControl implements Parcelable {
|
||||
private static native boolean nativeClearAnimationFrameStats();
|
||||
private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
|
||||
|
||||
private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
|
||||
private static native long[] nativeGetPhysicalDisplayIds();
|
||||
private static native IBinder nativeGetPhysicalDisplayToken(long physicalDisplayId);
|
||||
private static native IBinder nativeCreateDisplay(String name, boolean secure);
|
||||
private static native void nativeDestroyDisplay(IBinder displayToken);
|
||||
private static native void nativeSetDisplaySurface(long transactionObj,
|
||||
@@ -330,24 +331,6 @@ public final class SurfaceControl implements Parcelable {
|
||||
*/
|
||||
private static final int SURFACE_OPAQUE = 0x02;
|
||||
|
||||
|
||||
/* built-in physical display ids (keep in sync with ISurfaceComposer.h)
|
||||
* these are different from the logical display ids used elsewhere in the framework */
|
||||
|
||||
/**
|
||||
* Built-in physical display id: Main display.
|
||||
* Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
|
||||
* @hide
|
||||
*/
|
||||
public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
|
||||
|
||||
/**
|
||||
* Built-in physical display id: Attached HDMI display.
|
||||
* Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
|
||||
* @hide
|
||||
*/
|
||||
public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
|
||||
|
||||
// Display power modes.
|
||||
/**
|
||||
* Display power mode off: used while blanking the screen.
|
||||
@@ -1730,9 +1713,28 @@ public final class SurfaceControl implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static IBinder getBuiltInDisplay(int builtInDisplayId) {
|
||||
return nativeGetBuiltInDisplay(builtInDisplayId);
|
||||
public static long[] getPhysicalDisplayIds() {
|
||||
return nativeGetPhysicalDisplayIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static IBinder getPhysicalDisplayToken(long physicalDisplayId) {
|
||||
return nativeGetPhysicalDisplayToken(physicalDisplayId);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO(116025192): Remove this stopgap once framework is display-agnostic.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static IBinder getInternalDisplayToken() {
|
||||
final long[] physicalDisplayIds = getPhysicalDisplayIds();
|
||||
if (physicalDisplayIds.length == 0) {
|
||||
return null;
|
||||
}
|
||||
return getPhysicalDisplayToken(physicalDisplayIds[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1791,8 +1793,12 @@ public final class SurfaceControl implements Parcelable {
|
||||
public static Bitmap screenshot(Rect sourceCrop, int width, int height,
|
||||
boolean useIdentityTransform, int rotation) {
|
||||
// TODO: should take the display as a parameter
|
||||
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
|
||||
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
|
||||
final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
|
||||
if (displayToken == null) {
|
||||
Log.w(TAG, "Failed to take screenshot because internal display is disconnected");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (rotation == ROTATION_90 || rotation == ROTATION_270) {
|
||||
rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90;
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ private:
|
||||
sp<MessageQueue> mMessageQueue;
|
||||
DisplayEventReceiver mReceiver;
|
||||
|
||||
virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
|
||||
virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
|
||||
void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
|
||||
void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -84,28 +84,30 @@ void NativeDisplayEventReceiver::dispose() {
|
||||
DisplayEventDispatcher::dispose();
|
||||
}
|
||||
|
||||
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) {
|
||||
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
|
||||
uint32_t count) {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
|
||||
if (receiverObj.get()) {
|
||||
ALOGV("receiver %p ~ Invoking vsync handler.", this);
|
||||
env->CallVoidMethod(receiverObj.get(),
|
||||
gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count);
|
||||
gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, displayId, count);
|
||||
ALOGV("receiver %p ~ Returned from vsync handler.", this);
|
||||
}
|
||||
|
||||
mMessageQueue->raiseAndClearException(env, "dispatchVsync");
|
||||
}
|
||||
|
||||
void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) {
|
||||
void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId,
|
||||
bool connected) {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
|
||||
if (receiverObj.get()) {
|
||||
ALOGV("receiver %p ~ Invoking hotplug handler.", this);
|
||||
env->CallVoidMethod(receiverObj.get(),
|
||||
gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, id, connected);
|
||||
gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, displayId, connected);
|
||||
ALOGV("receiver %p ~ Returned from hotplug handler.", this);
|
||||
}
|
||||
|
||||
@@ -175,9 +177,9 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
|
||||
gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
|
||||
|
||||
gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env,
|
||||
gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JII)V");
|
||||
gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V");
|
||||
gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
|
||||
gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JIZ)V");
|
||||
gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -483,8 +483,29 @@ static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
|
||||
transaction->setLayerStack(ctrl, layerStack);
|
||||
}
|
||||
|
||||
static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
|
||||
sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
|
||||
static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) {
|
||||
const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
|
||||
jlongArray array = env->NewLongArray(displayIds.size());
|
||||
if (array == nullptr) {
|
||||
jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (displayIds.empty()) {
|
||||
return array;
|
||||
}
|
||||
|
||||
jlong* values = env->GetLongArrayElements(array, 0);
|
||||
for (size_t i = 0; i < displayIds.size(); ++i) {
|
||||
values[i] = static_cast<jlong>(displayIds[i]);
|
||||
}
|
||||
|
||||
env->ReleaseLongArrayElements(array, values, 0);
|
||||
return array;
|
||||
}
|
||||
|
||||
static jobject nativeGetPhysicalDisplayToken(JNIEnv* env, jclass clazz, jlong physicalDisplayId) {
|
||||
sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(physicalDisplayId);
|
||||
return javaObjectForIBinder(env, token);
|
||||
}
|
||||
|
||||
@@ -1145,8 +1166,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
|
||||
(void*)nativeSetCornerRadius },
|
||||
{"nativeSetLayerStack", "(JJI)V",
|
||||
(void*)nativeSetLayerStack },
|
||||
{"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
|
||||
(void*)nativeGetBuiltInDisplay },
|
||||
{"nativeGetPhysicalDisplayIds", "()[J",
|
||||
(void*)nativeGetPhysicalDisplayIds },
|
||||
{"nativeGetPhysicalDisplayToken", "(J)Landroid/os/IBinder;",
|
||||
(void*)nativeGetPhysicalDisplayToken },
|
||||
{"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
|
||||
(void*)nativeCreateDisplay },
|
||||
{"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
|
||||
@@ -1314,4 +1337,4 @@ int register_android_view_SurfaceControl(JNIEnv* env)
|
||||
return err;
|
||||
}
|
||||
|
||||
};
|
||||
} // namespace android
|
||||
|
||||
@@ -68,7 +68,7 @@ status_t DisplayEventDispatcher::scheduleVsync() {
|
||||
|
||||
// Drain all pending events.
|
||||
nsecs_t vsyncTimestamp;
|
||||
int32_t vsyncDisplayId;
|
||||
PhysicalDisplayId vsyncDisplayId;
|
||||
uint32_t vsyncCount;
|
||||
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
|
||||
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "",
|
||||
@@ -101,10 +101,11 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) {
|
||||
|
||||
// Drain all pending events, keep the last vsync.
|
||||
nsecs_t vsyncTimestamp;
|
||||
int32_t vsyncDisplayId;
|
||||
PhysicalDisplayId vsyncDisplayId;
|
||||
uint32_t vsyncCount;
|
||||
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
|
||||
ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d",
|
||||
ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%"
|
||||
ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%d",
|
||||
this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);
|
||||
mWaitingForVsync = false;
|
||||
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
|
||||
@@ -114,7 +115,7 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) {
|
||||
}
|
||||
|
||||
bool DisplayEventDispatcher::processPendingEvents(
|
||||
nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) {
|
||||
nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount) {
|
||||
bool gotVsync = false;
|
||||
DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
|
||||
ssize_t n;
|
||||
@@ -128,11 +129,11 @@ bool DisplayEventDispatcher::processPendingEvents(
|
||||
// ones. That's fine, we only care about the most recent.
|
||||
gotVsync = true;
|
||||
*outTimestamp = ev.header.timestamp;
|
||||
*outId = ev.header.id;
|
||||
*outDisplayId = ev.header.displayId;
|
||||
*outCount = ev.vsync.count;
|
||||
break;
|
||||
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
|
||||
dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected);
|
||||
dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected);
|
||||
break;
|
||||
default:
|
||||
ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
|
||||
|
||||
@@ -37,10 +37,12 @@ private:
|
||||
DisplayEventReceiver mReceiver;
|
||||
bool mWaitingForVsync;
|
||||
|
||||
virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) = 0;
|
||||
virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) = 0;
|
||||
virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) = 0;
|
||||
virtual void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId,
|
||||
bool connected) = 0;
|
||||
|
||||
virtual int handleEvent(int receiveFd, int events, void* data);
|
||||
bool processPendingEvents(nsecs_t* outTimestamp, int32_t* id, uint32_t* outCount);
|
||||
bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
|
||||
uint32_t* outCount);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,9 +55,12 @@ DisplayInfo QueryDisplayInfo() {
|
||||
return sDummyDisplay;
|
||||
}
|
||||
|
||||
const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
|
||||
LOG_ALWAYS_FATAL_IF(token == nullptr,
|
||||
"Failed to get display info because internal display is disconnected");
|
||||
|
||||
DisplayInfo displayInfo;
|
||||
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
|
||||
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &displayInfo);
|
||||
status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo);
|
||||
LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
|
||||
return displayInfo;
|
||||
}
|
||||
|
||||
@@ -37,11 +37,13 @@ static android::DisplayInfo DUMMY_DISPLAY{
|
||||
0, // presentationDeadline
|
||||
};
|
||||
|
||||
DisplayInfo getBuiltInDisplay() {
|
||||
DisplayInfo getInternalDisplay() {
|
||||
#if !HWUI_NULL_GPU
|
||||
DisplayInfo display;
|
||||
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
|
||||
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &display);
|
||||
const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
|
||||
LOG_ALWAYS_FATAL_IF(token == nullptr,
|
||||
"Failed to get display info because internal display is disconnected\n");
|
||||
status_t status = SurfaceComposerClient::getDisplayInfo(token, &display);
|
||||
LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n");
|
||||
return display;
|
||||
#else
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace test {
|
||||
extern DisplayInfo gDisplay;
|
||||
#define dp(x) ((x)*android::uirenderer::test::gDisplay.density)
|
||||
|
||||
DisplayInfo getBuiltInDisplay();
|
||||
DisplayInfo getInternalDisplay();
|
||||
|
||||
class TestContext {
|
||||
public:
|
||||
|
||||
@@ -109,7 +109,7 @@ void outputBenchmarkReport(const TestScene::Info& info, const TestScene::Options
|
||||
void run(const TestScene::Info& info, const TestScene::Options& opts,
|
||||
benchmark::BenchmarkReporter* reporter) {
|
||||
// Switch to the real display
|
||||
gDisplay = getBuiltInDisplay();
|
||||
gDisplay = getInternalDisplay();
|
||||
|
||||
Properties::forceDrawFrame = true;
|
||||
TestContext testContext;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <android/choreographer.h>
|
||||
#include <androidfw/DisplayEventDispatcher.h>
|
||||
#include <gui/ISurfaceComposer.h>
|
||||
#include <gui/SurfaceComposerClient.h>
|
||||
#include <utils/Looper.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/Timers.h>
|
||||
@@ -67,8 +68,8 @@ private:
|
||||
explicit Choreographer(const sp<Looper>& looper);
|
||||
Choreographer(const Choreographer&) = delete;
|
||||
|
||||
virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
|
||||
virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
|
||||
void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
|
||||
void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
|
||||
|
||||
void scheduleCallbacks();
|
||||
|
||||
@@ -139,13 +140,10 @@ void Choreographer::scheduleCallbacks() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Choreographer::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t) {
|
||||
if (id != ISurfaceComposer::eDisplayIdMain) {
|
||||
ALOGV("choreographer %p ~ ignoring vsync signal for non-main display (id=%d)", this, id);
|
||||
scheduleVsync();
|
||||
return;
|
||||
}
|
||||
// TODO(b/74619554): The PhysicalDisplayId is ignored because SF only emits VSYNC events for the
|
||||
// internal display and DisplayEventReceiver::requestNextVsync only allows requesting VSYNC for
|
||||
// the internal display implicitly.
|
||||
void Choreographer::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId, uint32_t) {
|
||||
std::vector<FrameCallback> callbacks{};
|
||||
{
|
||||
AutoMutex _l{mLock};
|
||||
@@ -160,9 +158,10 @@ void Choreographer::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t) {
|
||||
}
|
||||
}
|
||||
|
||||
void Choreographer::dispatchHotplug(nsecs_t, int32_t id, bool connected) {
|
||||
ALOGV("choreographer %p ~ received hotplug event (id=%" PRId32 ", connected=%s), ignoring.",
|
||||
this, id, toString(connected));
|
||||
void Choreographer::dispatchHotplug(nsecs_t, PhysicalDisplayId displayId, bool connected) {
|
||||
ALOGV("choreographer %p ~ received hotplug event (displayId=%"
|
||||
ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", connected=%s), ignoring.",
|
||||
this, displayId, toString(connected));
|
||||
}
|
||||
|
||||
void Choreographer::handleMessage(const Message& message) {
|
||||
|
||||
@@ -46,7 +46,13 @@ using Transaction = SurfaceComposerClient::Transaction;
|
||||
|
||||
static bool getWideColorSupport(const sp<SurfaceControl>& surfaceControl) {
|
||||
sp<SurfaceComposerClient> client = surfaceControl->getClient();
|
||||
sp<IBinder> display(client->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
|
||||
|
||||
const sp<IBinder> display = client->getInternalDisplayToken();
|
||||
if (display == nullptr) {
|
||||
ALOGE("unable to get wide color support for disconnected internal display");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isWideColorDisplay = false;
|
||||
status_t err = client->isWideColorDisplay(display, &isWideColorDisplay);
|
||||
if (err) {
|
||||
@@ -58,7 +64,12 @@ static bool getWideColorSupport(const sp<SurfaceControl>& surfaceControl) {
|
||||
|
||||
static bool getHdrSupport(const sp<SurfaceControl>& surfaceControl) {
|
||||
sp<SurfaceComposerClient> client = surfaceControl->getClient();
|
||||
sp<IBinder> display(client->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
|
||||
|
||||
const sp<IBinder> display = client->getInternalDisplayToken();
|
||||
if (display == nullptr) {
|
||||
ALOGE("unable to get hdr capabilities for disconnected internal display");
|
||||
return false;
|
||||
}
|
||||
|
||||
HdrCapabilities hdrCapabilities;
|
||||
status_t err = client->getHdrCapabilities(display, &hdrCapabilities);
|
||||
|
||||
@@ -323,8 +323,7 @@ public final class ColorDisplayService extends SystemService {
|
||||
}
|
||||
|
||||
private ColorSpace.Rgb getDisplayColorSpaceFromSurfaceControl() {
|
||||
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
|
||||
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
|
||||
final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
|
||||
if (displayToken == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.opengl.EGLDisplay;
|
||||
import android.opengl.EGLSurface;
|
||||
import android.opengl.GLES11Ext;
|
||||
import android.opengl.GLES20;
|
||||
import android.os.IBinder;
|
||||
import android.util.Slog;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Surface;
|
||||
@@ -474,8 +475,14 @@ final class ColorFade {
|
||||
final SurfaceTexture st = new SurfaceTexture(mTexNames[0]);
|
||||
final Surface s = new Surface(st);
|
||||
try {
|
||||
SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
|
||||
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), s);
|
||||
final IBinder token = SurfaceControl.getInternalDisplayToken();
|
||||
if (token == null) {
|
||||
Slog.e(TAG,
|
||||
"Failed to take screenshot because internal display is disconnected");
|
||||
return false;
|
||||
}
|
||||
|
||||
SurfaceControl.screenshot(token, s);
|
||||
st.updateTexImage();
|
||||
st.getTransformMatrix(mTexMatrix);
|
||||
} finally {
|
||||
|
||||
@@ -17,12 +17,8 @@
|
||||
package com.android.server.display;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.content.res.Resources;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.lights.Light;
|
||||
import com.android.server.lights.LightsManager;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.sidekick.SidekickInternal;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
@@ -31,6 +27,7 @@ import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.Trace;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Display;
|
||||
@@ -38,6 +35,11 @@ import android.view.DisplayCutout;
|
||||
import android.view.DisplayEventReceiver;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.lights.Light;
|
||||
import com.android.server.lights.LightsManager;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -58,13 +60,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
|
||||
private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
|
||||
|
||||
private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {
|
||||
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,
|
||||
SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,
|
||||
};
|
||||
private final LongSparseArray<LocalDisplayDevice> mDevices =
|
||||
new LongSparseArray<LocalDisplayDevice>();
|
||||
|
||||
private final SparseArray<LocalDisplayDevice> mDevices =
|
||||
new SparseArray<LocalDisplayDevice>();
|
||||
@SuppressWarnings("unused") // Becomes active at instantiation time.
|
||||
private HotplugDisplayEventReceiver mHotplugReceiver;
|
||||
|
||||
@@ -80,28 +78,26 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
|
||||
mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());
|
||||
|
||||
for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
|
||||
tryConnectDisplayLocked(builtInDisplayId);
|
||||
for (long physicalDisplayId : SurfaceControl.getPhysicalDisplayIds()) {
|
||||
tryConnectDisplayLocked(physicalDisplayId);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryConnectDisplayLocked(int builtInDisplayId) {
|
||||
IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);
|
||||
private void tryConnectDisplayLocked(long physicalDisplayId) {
|
||||
final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
|
||||
if (displayToken != null) {
|
||||
SurfaceControl.PhysicalDisplayInfo[] configs =
|
||||
SurfaceControl.getDisplayConfigs(displayToken);
|
||||
if (configs == null) {
|
||||
// There are no valid configs for this device, so we can't use it
|
||||
Slog.w(TAG, "No valid configs found for display device " +
|
||||
builtInDisplayId);
|
||||
Slog.w(TAG, "No valid configs found for display device " + physicalDisplayId);
|
||||
return;
|
||||
}
|
||||
int activeConfig = SurfaceControl.getActiveConfig(displayToken);
|
||||
if (activeConfig < 0) {
|
||||
// There is no active config, and for now we don't have the
|
||||
// policy to set one.
|
||||
Slog.w(TAG, "No active config found for display device " +
|
||||
builtInDisplayId);
|
||||
Slog.w(TAG, "No active config found for display device " + physicalDisplayId);
|
||||
return;
|
||||
}
|
||||
int activeColorMode = SurfaceControl.getActiveColorMode(displayToken);
|
||||
@@ -110,16 +106,17 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
// configuration pass we'll go ahead and set it to whatever it was set to last (or
|
||||
// COLOR_MODE_NATIVE if this is the first configuration).
|
||||
Slog.w(TAG, "Unable to get active color mode for display device " +
|
||||
builtInDisplayId);
|
||||
physicalDisplayId);
|
||||
activeColorMode = Display.COLOR_MODE_INVALID;
|
||||
}
|
||||
int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
|
||||
LocalDisplayDevice device = mDevices.get(builtInDisplayId);
|
||||
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
|
||||
if (device == null) {
|
||||
// Display was added.
|
||||
device = new LocalDisplayDevice(displayToken, builtInDisplayId,
|
||||
configs, activeConfig, colorModes, activeColorMode);
|
||||
mDevices.put(builtInDisplayId, device);
|
||||
final boolean isInternal = mDevices.size() == 0;
|
||||
device = new LocalDisplayDevice(displayToken, physicalDisplayId,
|
||||
configs, activeConfig, colorModes, activeColorMode, isInternal);
|
||||
mDevices.put(physicalDisplayId, device);
|
||||
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
|
||||
} else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig,
|
||||
colorModes, activeColorMode)) {
|
||||
@@ -133,11 +130,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private void tryDisconnectDisplayLocked(int builtInDisplayId) {
|
||||
LocalDisplayDevice device = mDevices.get(builtInDisplayId);
|
||||
private void tryDisconnectDisplayLocked(long physicalDisplayId) {
|
||||
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
|
||||
if (device != null) {
|
||||
// Display was removed.
|
||||
mDevices.remove(builtInDisplayId);
|
||||
mDevices.remove(physicalDisplayId);
|
||||
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED);
|
||||
}
|
||||
}
|
||||
@@ -158,10 +155,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
private final class LocalDisplayDevice extends DisplayDevice {
|
||||
private final int mBuiltInDisplayId;
|
||||
private final long mPhysicalDisplayId;
|
||||
private final Light mBacklight;
|
||||
private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
|
||||
private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>();
|
||||
private final boolean mIsInternal;
|
||||
|
||||
private DisplayDeviceInfo mInfo;
|
||||
private boolean mHavePendingChanges;
|
||||
@@ -179,16 +177,17 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
|
||||
private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
|
||||
|
||||
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
|
||||
LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
|
||||
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
|
||||
int[] colorModes, int activeColorMode) {
|
||||
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
|
||||
mBuiltInDisplayId = builtInDisplayId;
|
||||
int[] colorModes, int activeColorMode, boolean isInternal) {
|
||||
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId);
|
||||
mPhysicalDisplayId = physicalDisplayId;
|
||||
mIsInternal = isInternal;
|
||||
updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo,
|
||||
colorModes, activeColorMode);
|
||||
updateColorModesLocked(colorModes, activeColorMode);
|
||||
mSidekickInternal = LocalServices.getService(SidekickInternal.class);
|
||||
if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
|
||||
if (mIsInternal) {
|
||||
LightsManager lights = LocalServices.getService(LightsManager.class);
|
||||
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
|
||||
} else {
|
||||
@@ -392,7 +391,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
final Resources res = getOverlayContext().getResources();
|
||||
if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
|
||||
if (mIsInternal) {
|
||||
mInfo.name = res.getString(
|
||||
com.android.internal.R.string.display_manager_built_in_display_name);
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
|
||||
@@ -455,7 +454,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
final boolean stateChanged = (mState != state);
|
||||
final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;
|
||||
if (stateChanged || brightnessChanged) {
|
||||
final int displayId = mBuiltInDisplayId;
|
||||
final long physicalDisplayId = mPhysicalDisplayId;
|
||||
final IBinder token = getDisplayTokenLocked();
|
||||
final int oldState = mState;
|
||||
|
||||
@@ -519,7 +518,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private void setVrMode(boolean isVrEnabled) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setVrMode("
|
||||
+ "id=" + displayId
|
||||
+ "id=" + physicalDisplayId
|
||||
+ ", state=" + Display.stateToString(state) + ")");
|
||||
}
|
||||
mBacklight.setVrMode(isVrEnabled);
|
||||
@@ -528,7 +527,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private void setDisplayState(int state) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setDisplayState("
|
||||
+ "id=" + displayId
|
||||
+ "id=" + physicalDisplayId
|
||||
+ ", state=" + Display.stateToString(state) + ")");
|
||||
}
|
||||
|
||||
@@ -546,7 +545,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
final int mode = getPowerModeForState(state);
|
||||
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
|
||||
+ "id=" + displayId
|
||||
+ "id=" + physicalDisplayId
|
||||
+ ", state=" + Display.stateToString(state) + ")");
|
||||
try {
|
||||
SurfaceControl.setDisplayPowerMode(token, mode);
|
||||
@@ -571,11 +570,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private void setDisplayBrightness(int brightness) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setDisplayBrightness("
|
||||
+ "id=" + displayId + ", brightness=" + brightness + ")");
|
||||
+ "id=" + physicalDisplayId
|
||||
+ ", brightness=" + brightness + ")");
|
||||
}
|
||||
|
||||
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
|
||||
+ "id=" + displayId + ", brightness=" + brightness + ")");
|
||||
+ "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
|
||||
try {
|
||||
mBacklight.setBrightness(brightness);
|
||||
Trace.traceCounter(Trace.TRACE_TAG_POWER,
|
||||
@@ -646,7 +646,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
@Override
|
||||
public void dumpLocked(PrintWriter pw) {
|
||||
super.dumpLocked(pw);
|
||||
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
|
||||
pw.println("mPhysicalDisplayId=" + mPhysicalDisplayId);
|
||||
pw.println("mActivePhysIndex=" + mActivePhysIndex);
|
||||
pw.println("mActiveModeId=" + mActiveModeId);
|
||||
pw.println("mActiveColorMode=" + mActiveColorMode);
|
||||
@@ -731,12 +731,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
|
||||
public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
|
||||
synchronized (getSyncRoot()) {
|
||||
if (connected) {
|
||||
tryConnectDisplayLocked(builtInDisplayId);
|
||||
tryConnectDisplayLocked(physicalDisplayId);
|
||||
} else {
|
||||
tryDisconnectDisplayLocked(builtInDisplayId);
|
||||
tryDisconnectDisplayLocked(physicalDisplayId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user