android_view_SurfaceControl.cpp revision a9408d4a4809dd229fb7fb8f9594cb6db4b1da64
1e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/*
2e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Copyright (C) 2013 The Android Open Source Project
3e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
4e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * you may not use this file except in compliance with the License.
6e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * You may obtain a copy of the License at
7e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
8e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
10e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Unless required by applicable law or agreed to in writing, software
11e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * See the License for the specific language governing permissions and
14e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * limitations under the License.
15e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
16e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
1785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#define LOG_TAG "SurfaceControl"
18e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
19e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include "android_os_Parcel.h"
20e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include "android_util_Binder.h"
21e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include "android/graphics/Bitmap.h"
22e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include "android/graphics/GraphicsJNI.h"
23bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy#include "android/graphics/Region.h"
24694b519ac647fe998fd396fe0784cc8e179aadc4Romain Guy#include "core_jni_helpers.h"
255cbbce535744b89df5ecea95de21ee3733298260Romain Guy
265cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include <JNIHelp.h>
27e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy#include <ScopedUtfChars.h>
2885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <android_runtime/android_view_Surface.h>
2985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <android_runtime/android_view_SurfaceSession.h>
30e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <gui/Surface.h>
31e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <gui/SurfaceComposerClient.h>
329d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <jni.h>
339d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <memory>
349d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <stdio.h>
359d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <ui/DisplayInfo.h>
369d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <ui/HdrCapabilities.h>
379d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <ui/FrameStats.h>
3806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include <ui/Rect.h>
3906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include <ui/Region.h>
40dda570201ac851dd85af3861f7e575721d3345daRomain Guy#include <utils/Log.h>
41bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
429d5316e3f56d138504565ff311145ac01621dff4Romain Guy// ----------------------------------------------------------------------------
43759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy
44759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guynamespace android {
45759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy
469d5316e3f56d138504565ff311145ac01621dff4Romain Guystatic const char* const OutOfResourcesException =
479d5316e3f56d138504565ff311145ac01621dff4Romain Guy    "android/view/Surface$OutOfResourcesException";
489d5316e3f56d138504565ff311145ac01621dff4Romain Guy
499d5316e3f56d138504565ff311145ac01621dff4Romain Guystatic struct {
50026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    jclass clazz;
51026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    jmethodID ctor;
52ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    jfieldID width;
53c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    jfieldID height;
54c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    jfieldID refreshRate;
55c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    jfieldID density;
56c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    jfieldID xDpi;
57bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    jfieldID yDpi;
58ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    jfieldID secure;
59ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    jfieldID appVsyncOffsetNanos;
60026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    jfieldID presentationDeadlineNanos;
61889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    jfieldID colorTransform;
62889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy} gPhysicalDisplayInfoClassInfo;
63889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy
64889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guystatic struct {
65889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    jfieldID bottom;
66889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    jfieldID left;
67889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    jfieldID right;
68889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    jfieldID top;
69889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy} gRectClassInfo;
70026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy
71026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
72026c5e16704e817cac7d9c382914c947e34f87e0Romain Guyvoid DeleteScreenshot(void* addr, void* context) {
73026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    SkASSERT(addr == ((ScreenshotClient*) context)->getPixels());
74026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    delete ((ScreenshotClient*) context);
75026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy}
76026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy
77026c5e16704e817cac7d9c382914c947e34f87e0Romain Guystatic struct {
78026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    nsecs_t UNDEFINED_TIME_NANO;
79026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    jmethodID init;
80026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy} gWindowContentFrameStatsClassInfo;
81026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy
82026c5e16704e817cac7d9c382914c947e34f87e0Romain Guystatic struct {
83026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    nsecs_t UNDEFINED_TIME_NANO;
84026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy    jmethodID init;
85026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy} gWindowAnimationFrameStatsClassInfo;
86e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
8787a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guystatic struct {
8887a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guy    jclass clazz;
8987a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guy    jmethodID ctor;
90f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy} gHdrCapabilitiesClassInfo;
91f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
92f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy// ----------------------------------------------------------------------------
93f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
94f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guystatic jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
95f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        jstring nameStr, jint w, jint h, jint format, jint flags) {
96f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    ScopedUtfChars name(env, nameStr);
97f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
98f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    sp<SurfaceControl> surface = client->createSurface(
99f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy            String8(name.c_str()), w, h, format, flags);
100f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    if (surface == NULL) {
101f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        jniThrowException(env, OutOfResourcesException, NULL);
102f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        return 0;
103f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    }
104f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    surface->incStrong((void *)nativeCreate);
105889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    return reinterpret_cast<jlong>(surface.get());
10606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}
10706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy
10806f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) {
109d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
110d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895Romain Guy    ctrl->decStrong((void *)nativeCreate);
111f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
112f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
113f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guystatic void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
114f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
115fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    ctrl->clear();
11606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy    ctrl->decStrong((void *)nativeCreate);
117db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy}
1181e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
119026c5e16704e817cac7d9c382914c947e34f87e0Romain Guystatic void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
120ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
121ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    if (ctrl != NULL) {
122ae5575b3421c8fbe590ab046d7d5f2b36ecfd821Romain Guy        ctrl->disconnect();
123ae5575b3421c8fbe590ab046d7d5f2b36ecfd821Romain Guy    }
124ae5575b3421c8fbe590ab046d7d5f2b36ecfd821Romain Guy}
125ae5575b3421c8fbe590ab046d7d5f2b36ecfd821Romain Guy
126ae5575b3421c8fbe590ab046d7d5f2b36ecfd821Romain Guystatic jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
127889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
128889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
129b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy        int rotation) {
130b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
131e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    if (displayToken == NULL) {
132e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return NULL;
13385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy    }
13429d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy
13529d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy    int left = env->GetIntField(sourceCropObj, gRectClassInfo.left);
136e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    int top = env->GetIntField(sourceCropObj, gRectClassInfo.top);
137e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    int right = env->GetIntField(sourceCropObj, gRectClassInfo.right);
138f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom);
139f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    Rect sourceCrop(left, top, right, bottom);
140f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
141f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    std::unique_ptr<ScreenshotClient> screenshot(new ScreenshotClient());
14285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy    status_t res;
14308ae317c21ec3086b5017672bba87420cc38a407Romain Guy    if (allLayers) {
144260e102162322958cf17dbd895cd6bd30dc87e32Romain Guy        minLayer = 0;
145bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        maxLayer = -1;
146bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    }
147bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
148eb99356a0548684a501766e6a524529ab93304c8Romain Guy    res = screenshot->update(displayToken, sourceCrop, width, height,
149eb99356a0548684a501766e6a524529ab93304c8Romain Guy        minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation));
150eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (res != NO_ERROR) {
151e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return NULL;
152e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
15385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
1548aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    SkColorType colorType;
1558aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    SkAlphaType alphaType;
1568fb954263dd2f918ad339045cc6d82e346515599Romain Guy    switch (screenshot->getFormat()) {
157f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        case PIXEL_FORMAT_RGBX_8888: {
158fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy            colorType = kRGBA_8888_SkColorType;
159fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy            alphaType = kOpaque_SkAlphaType;
160d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            break;
16108ae317c21ec3086b5017672bba87420cc38a407Romain Guy        }
162bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        case PIXEL_FORMAT_RGBA_8888: {
16308ae317c21ec3086b5017672bba87420cc38a407Romain Guy            colorType = kRGBA_8888_SkColorType;
16408ae317c21ec3086b5017672bba87420cc38a407Romain Guy            alphaType = kPremul_SkAlphaType;
165bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy            break;
16608ae317c21ec3086b5017672bba87420cc38a407Romain Guy        }
167c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy        case PIXEL_FORMAT_RGB_565: {
168f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy            colorType = kRGB_565_SkColorType;
169b82da65cb1601be504241f36778395cd6cb9f87bRomain Guy            alphaType = kOpaque_SkAlphaType;
170bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy            break;
171bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        }
172b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy        default: {
173b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy            return NULL;
174b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy        }
175b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    }
176b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    SkImageInfo screenshotInfo = SkImageInfo::Make(screenshot->getWidth(),
177b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy                                                   screenshot->getHeight(),
178b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy                                                   colorType, alphaType);
179b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
180b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    const size_t rowBytes =
181da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
182da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
183da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    if (!screenshotInfo.width() || !screenshotInfo.height()) {
184da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy        return NULL;
185da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    }
186da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
187da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    Bitmap* bitmap = new Bitmap(
188da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            (void*) screenshot->getPixels(), (void*) screenshot.get(), DeleteScreenshot,
189da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            screenshotInfo, rowBytes, nullptr);
190da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    screenshot.release();
191eb99356a0548684a501766e6a524529ab93304c8Romain Guy    bitmap->peekAtPixelRef()->setImmutable();
192da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
193da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    return GraphicsJNI::createBitmap(env, bitmap,
194da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL);
195da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy}
196f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
197f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guystatic void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,
198f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        jobject surfaceObj, jobject sourceCropObj, jint width, jint height,
199f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
200da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
201da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    if (displayToken != NULL) {
202da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy        sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);
203f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        if (consumer != NULL) {
204da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            int left = env->GetIntField(sourceCropObj, gRectClassInfo.left);
205da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            int top = env->GetIntField(sourceCropObj, gRectClassInfo.top);
206da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            int right = env->GetIntField(sourceCropObj, gRectClassInfo.right);
207da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom);
208da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy            Rect sourceCrop(left, top, right, bottom);
209f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
210f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy            if (allLayers) {
211f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy                minLayer = 0;
212f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy                maxLayer = -1;
213bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy            }
2147ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            ScreenshotClient::capture(displayToken,
215bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy                    consumer->getIGraphicBufferProducer(), sourceCrop,
216bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy                    width, height, uint32_t(minLayer), uint32_t(maxLayer),
217bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy                    useIdentityTransform);
2188aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        }
219bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    }
220bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
221bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
2222542d199745cdf3ec910b8e3e4cff5851ed24e9bRomain Guystatic void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
2232542d199745cdf3ec910b8e3e4cff5851ed24e9bRomain Guy    SurfaceComposerClient::openGlobalTransaction();
2247ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy}
225bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
226bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
227bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guystatic void nativeCloseTransaction(JNIEnv* env, jclass clazz, jboolean sync) {
2288fb954263dd2f918ad339045cc6d82e346515599Romain Guy    SurfaceComposerClient::closeGlobalTransaction(sync);
229bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
2308fb954263dd2f918ad339045cc6d82e346515599Romain Guy
2312542d199745cdf3ec910b8e3e4cff5851ed24e9bRomain Guystatic void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
2327ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    SurfaceComposerClient::setAnimationTransaction();
233bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
234bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
2358aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guystatic void nativeSetLayer(JNIEnv* env, jclass clazz, jlong nativeObject, jint zorder) {
2368aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
2378fb954263dd2f918ad339045cc6d82e346515599Romain Guy    status_t err = ctrl->setLayer(zorder);
238bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    if (err < 0 && err != NO_INIT) {
239bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        doThrowIAE(env);
240bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    }
2417ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy}
242bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
243eb99356a0548684a501766e6a524529ab93304c8Romain Guystatic void nativeSetPosition(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat x, jfloat y) {
244bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
245bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    status_t err = ctrl->setPosition(x, y);
2467ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    if (err < 0 && err != NO_INIT) {
247bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        doThrowIAE(env);
248eb99356a0548684a501766e6a524529ab93304c8Romain Guy    }
249eb99356a0548684a501766e6a524529ab93304c8Romain Guy}
250eb99356a0548684a501766e6a524529ab93304c8Romain Guy
251eb99356a0548684a501766e6a524529ab93304c8Romain Guystatic void nativeSetPositionAppliesWithResize(JNIEnv* env, jclass clazz,
252eb99356a0548684a501766e6a524529ab93304c8Romain Guy        jlong nativeObject) {
253eb99356a0548684a501766e6a524529ab93304c8Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
2548b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    status_t err = ctrl->setPositionAppliesWithResize();
2558b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    if (err < 0 && err != NO_INIT) {
2568b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy        doThrowIAE(env);
257bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    }
258d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy}
259d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy
260bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guystatic void nativeSetSize(JNIEnv* env, jclass clazz, jlong nativeObject, jint w, jint h) {
2612542d199745cdf3ec910b8e3e4cff5851ed24e9bRomain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
2622542d199745cdf3ec910b8e3e4cff5851ed24e9bRomain Guy    status_t err = ctrl->setSize(w, h);
2638fb954263dd2f918ad339045cc6d82e346515599Romain Guy    if (err < 0 && err != NO_INIT) {
2642542d199745cdf3ec910b8e3e4cff5851ed24e9bRomain Guy        doThrowIAE(env);
2652542d199745cdf3ec910b8e3e4cff5851ed24e9bRomain Guy    }
266d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy}
2675cbbce535744b89df5ecea95de21ee3733298260Romain Guy
268f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guystatic void nativeSetFlags(JNIEnv* env, jclass clazz, jlong nativeObject, jint flags, jint mask) {
269bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
270bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    status_t err = ctrl->setFlags(flags, mask);
271bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    if (err < 0 && err != NO_INIT) {
272bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        doThrowIAE(env);
273bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    }
274eb99356a0548684a501766e6a524529ab93304c8Romain Guy}
275eb99356a0548684a501766e6a524529ab93304c8Romain Guy
276d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guystatic void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong nativeObject, jobject regionObj) {
277d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
278d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy    SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
279d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy    if (!region) {
280d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy        doThrowIAE(env);
281d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy        return;
282a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy    }
283a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy
284a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy    const SkIRect& b(region->getBounds());
285a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy    Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom));
286a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy    if (region->isComplex()) {
287a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy        SkRegion::Iterator it(*region);
288a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy        while (!it.done()) {
289a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy            const SkIRect& r(it.rect());
290d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy            reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom);
291d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy            it.next();
292d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy        }
293d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy    }
294d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy
295eb99356a0548684a501766e6a524529ab93304c8Romain Guy    status_t err = ctrl->setTransparentRegionHint(reg);
296d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy    if (err < 0 && err != NO_INIT) {
297d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy        doThrowIAE(env);
298bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    }
299bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy}
300bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
301bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guystatic void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat alpha) {
3028aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
3038aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    status_t err = ctrl->setAlpha(alpha);
3048b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    if (err < 0 && err != NO_INIT) {
3058aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        doThrowIAE(env);
3068aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    }
3078aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy}
3088b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy
309d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guystatic void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong nativeObject,
310bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) {
3111c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
3121c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    status_t err = ctrl->setMatrix(dsdx, dtdx, dsdy, dtdy);
3131c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    if (err < 0 && err != NO_INIT) {
3141c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy        doThrowIAE(env);
3151c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    }
3161c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy}
3171c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy
3181c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guystatic void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong nativeObject,
3191c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy        jint l, jint t, jint r, jint b) {
3201c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
3211c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    Rect crop(l, t, r, b);
3221c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    status_t err = ctrl->setCrop(crop);
3231c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    if (err < 0 && err != NO_INIT) {
3241c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy        doThrowIAE(env);
3251c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    }
3261c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy}
3271c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy
3281c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guystatic void nativeSetFinalCrop(JNIEnv* env, jclass clazz, jlong nativeObject,
3291c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy        jint l, jint t, jint r, jint b) {
3301c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
3311c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    Rect crop(l, t, r, b);
3321c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    status_t err = ctrl->setFinalCrop(crop);
33387a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guy    if (err < 0 && err != NO_INIT) {
3341c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy        doThrowIAE(env);
3351c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    }
3361c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy}
3371c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy
3381c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guystatic void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong nativeObject, jint layerStack) {
3391c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
3401c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    status_t err = ctrl->setLayerStack(layerStack);
3411c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    if (err < 0 && err != NO_INIT) {
3421c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy        doThrowIAE(env);
3431c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    }
3441c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy}
3451c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy
3461c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guystatic jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
3471c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
3481c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    return javaObjectForIBinder(env, token);
3491c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy}
3501c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy
3511c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guystatic jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
3521c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy        jboolean secure) {
35387a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guy    ScopedUtfChars name(env, nameObj);
35487a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guy    sp<IBinder> token(SurfaceComposerClient::createDisplay(
35587a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guy            String8(name.c_str()), bool(secure)));
35687a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guy    return javaObjectForIBinder(env, token);
35787a76578f76f4a6bceb187da6b7a01899ca0d85aRomain Guy}
3581c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy
359d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guystatic void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
360eb99356a0548684a501766e6a524529ab93304c8Romain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
361eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (token == NULL) return;
362eb99356a0548684a501766e6a524529ab93304c8Romain Guy    SurfaceComposerClient::destroyDisplay(token);
363fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy}
364dda570201ac851dd85af3861f7e575721d3345daRomain Guy
365eb99356a0548684a501766e6a524529ab93304c8Romain Guystatic void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
366eb99356a0548684a501766e6a524529ab93304c8Romain Guy        jobject tokenObj, jlong nativeSurfaceObject) {
367f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
3688aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    if (token == NULL) return;
369eb99356a0548684a501766e6a524529ab93304c8Romain Guy    sp<IGraphicBufferProducer> bufferProducer;
370eb99356a0548684a501766e6a524529ab93304c8Romain Guy    sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject));
371eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (sur != NULL) {
372eb99356a0548684a501766e6a524529ab93304c8Romain Guy        bufferProducer = sur->getIGraphicBufferProducer();
373eb99356a0548684a501766e6a524529ab93304c8Romain Guy    }
374eb99356a0548684a501766e6a524529ab93304c8Romain Guy    SurfaceComposerClient::setDisplaySurface(token, bufferProducer);
375bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy}
376b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
377b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guystatic void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
378b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy        jobject tokenObj, jint layerStack) {
379b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
380dda570201ac851dd85af3861f7e575721d3345daRomain Guy    if (token == NULL) return;
3810bb5667b4ef91fefd0500fae0186789d15d54e0eRomain Guy
3820bb5667b4ef91fefd0500fae0186789d15d54e0eRomain Guy    SurfaceComposerClient::setDisplayLayerStack(token, layerStack);
3838411f336c786379c5a03106e9ed3bc8622b579a5Romain Guy}
384f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
385f18fd99b5c182329cd8936a9611f0103d8ece44aRomain Guystatic void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
386f18fd99b5c182329cd8936a9611f0103d8ece44aRomain Guy        jobject tokenObj, jint orientation,
387bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom,
388bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) {
389dda570201ac851dd85af3861f7e575721d3345daRomain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
390f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    if (token == NULL) return;
3918aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom);
392dda570201ac851dd85af3861f7e575721d3345daRomain Guy    Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom);
3938fb954263dd2f918ad339045cc6d82e346515599Romain Guy    SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect);
3948fb954263dd2f918ad339045cc6d82e346515599Romain Guy}
395dda570201ac851dd85af3861f7e575721d3345daRomain Guy
3961d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guystatic void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
397eb99356a0548684a501766e6a524529ab93304c8Romain Guy        jobject tokenObj, jint width, jint height) {
398eb99356a0548684a501766e6a524529ab93304c8Romain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
39938c85b907a478af96d71b9a5df5a2066b8475311Romain Guy    if (token == NULL) return;
400eb99356a0548684a501766e6a524529ab93304c8Romain Guy    SurfaceComposerClient::setDisplaySize(token, width, height);
401eb99356a0548684a501766e6a524529ab93304c8Romain Guy}
402eb99356a0548684a501766e6a524529ab93304c8Romain Guy
403eb99356a0548684a501766e6a524529ab93304c8Romain Guystatic jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
404eb99356a0548684a501766e6a524529ab93304c8Romain Guy        jobject tokenObj) {
405eb99356a0548684a501766e6a524529ab93304c8Romain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
406eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (token == NULL) return NULL;
407eb99356a0548684a501766e6a524529ab93304c8Romain Guy
4080bb5667b4ef91fefd0500fae0186789d15d54e0eRomain Guy    Vector<DisplayInfo> configs;
4090bb5667b4ef91fefd0500fae0186789d15d54e0eRomain Guy    if (SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR ||
410f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy            configs.size() == 0) {
411eb99356a0548684a501766e6a524529ab93304c8Romain Guy        return NULL;
412eb99356a0548684a501766e6a524529ab93304c8Romain Guy    }
413eb99356a0548684a501766e6a524529ab93304c8Romain Guy
414eb99356a0548684a501766e6a524529ab93304c8Romain Guy    jobjectArray configArray = env->NewObjectArray(configs.size(),
415eb99356a0548684a501766e6a524529ab93304c8Romain Guy            gPhysicalDisplayInfoClassInfo.clazz, NULL);
416eb99356a0548684a501766e6a524529ab93304c8Romain Guy
417eb99356a0548684a501766e6a524529ab93304c8Romain Guy    for (size_t c = 0; c < configs.size(); ++c) {
418eb99356a0548684a501766e6a524529ab93304c8Romain Guy        const DisplayInfo& info = configs[c];
419eb99356a0548684a501766e6a524529ab93304c8Romain Guy        jobject infoObj = env->NewObject(gPhysicalDisplayInfoClassInfo.clazz,
420eb99356a0548684a501766e6a524529ab93304c8Romain Guy                gPhysicalDisplayInfoClassInfo.ctor);
421eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w);
422eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h);
423eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps);
424eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density);
425eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi);
426eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi);
427eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure);
428eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos,
429eb99356a0548684a501766e6a524529ab93304c8Romain Guy                info.appVsyncOffset);
430eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos,
431eb99356a0548684a501766e6a524529ab93304c8Romain Guy                info.presentationDeadline);
432eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.colorTransform,
433eb99356a0548684a501766e6a524529ab93304c8Romain Guy                info.colorTransform);
434eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj);
435eb99356a0548684a501766e6a524529ab93304c8Romain Guy        env->DeleteLocalRef(infoObj);
436eb99356a0548684a501766e6a524529ab93304c8Romain Guy    }
437eb99356a0548684a501766e6a524529ab93304c8Romain Guy
438eb99356a0548684a501766e6a524529ab93304c8Romain Guy    return configArray;
439eb99356a0548684a501766e6a524529ab93304c8Romain Guy}
440eb99356a0548684a501766e6a524529ab93304c8Romain Guy
441eb99356a0548684a501766e6a524529ab93304c8Romain Guystatic jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) {
442eb99356a0548684a501766e6a524529ab93304c8Romain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
443eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (token == NULL) return -1;
444eb99356a0548684a501766e6a524529ab93304c8Romain Guy    return static_cast<jint>(SurfaceComposerClient::getActiveConfig(token));
445eb99356a0548684a501766e6a524529ab93304c8Romain Guy}
446eb99356a0548684a501766e6a524529ab93304c8Romain Guy
447eb99356a0548684a501766e6a524529ab93304c8Romain Guystatic jboolean nativeSetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj, jint id) {
448eb99356a0548684a501766e6a524529ab93304c8Romain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
449eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (token == NULL) return JNI_FALSE;
450eb99356a0548684a501766e6a524529ab93304c8Romain Guy    status_t err = SurfaceComposerClient::setActiveConfig(token, static_cast<int>(id));
451eb99356a0548684a501766e6a524529ab93304c8Romain Guy    return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
452eb99356a0548684a501766e6a524529ab93304c8Romain Guy}
453eb99356a0548684a501766e6a524529ab93304c8Romain Guy
454eb99356a0548684a501766e6a524529ab93304c8Romain Guystatic void nativeSetDisplayPowerMode(JNIEnv* env, jclass clazz, jobject tokenObj, jint mode) {
455eb99356a0548684a501766e6a524529ab93304c8Romain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
456eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (token == NULL) return;
457eb99356a0548684a501766e6a524529ab93304c8Romain Guy
458eb99356a0548684a501766e6a524529ab93304c8Romain Guy    ALOGD_IF_SLOW(100, "Excessive delay in setPowerMode()");
459eb99356a0548684a501766e6a524529ab93304c8Romain Guy    SurfaceComposerClient::setDisplayPowerMode(token, mode);
460eb99356a0548684a501766e6a524529ab93304c8Romain Guy}
461eb99356a0548684a501766e6a524529ab93304c8Romain Guy
462eb99356a0548684a501766e6a524529ab93304c8Romain Guystatic jboolean nativeClearContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject) {
463eb99356a0548684a501766e6a524529ab93304c8Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
464eb99356a0548684a501766e6a524529ab93304c8Romain Guy    status_t err = ctrl->clearLayerFrameStats();
465eb99356a0548684a501766e6a524529ab93304c8Romain Guy
466eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (err < 0 && err != NO_INIT) {
467eb99356a0548684a501766e6a524529ab93304c8Romain Guy        doThrowIAE(env);
468f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    }
469d55a86120dd1e8ebcc6906c9ffd463f7460348daRomain Guy
470bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    // The other end is not ready, just report we failed.
471bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    if (err == NO_INIT) {
4721c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy        return JNI_FALSE;
4731c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    }
4741c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy
4751d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    return JNI_TRUE;
4761d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy}
4771d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy
4781d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guystatic jboolean nativeGetContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject,
4791d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    jobject outStats) {
4801d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    FrameStats stats;
481eb99356a0548684a501766e6a524529ab93304c8Romain Guy
482eb99356a0548684a501766e6a524529ab93304c8Romain Guy    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
483eb99356a0548684a501766e6a524529ab93304c8Romain Guy    status_t err = ctrl->getLayerFrameStats(&stats);
484eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (err < 0 && err != NO_INIT) {
485eb99356a0548684a501766e6a524529ab93304c8Romain Guy        doThrowIAE(env);
486eb99356a0548684a501766e6a524529ab93304c8Romain Guy    }
487eb99356a0548684a501766e6a524529ab93304c8Romain Guy
4881d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    // The other end is not ready, fine just return empty stats.
4898aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    if (err == NO_INIT) {
490eb99356a0548684a501766e6a524529ab93304c8Romain Guy        return JNI_FALSE;
4911d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    }
4921d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy
4931d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
4941d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    size_t frameCount = stats.desiredPresentTimesNano.size();
495eb99356a0548684a501766e6a524529ab93304c8Romain Guy
496f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    jlongArray postedTimesNanoDst = env->NewLongArray(frameCount);
4971c740bce8a762f02b5283045a0e2de7c8fb41277Romain Guy    if (postedTimesNanoDst == NULL) {
498f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy        return JNI_FALSE;
499f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy    }
500f607bdc167f66b3e7003acaa4736ae46d78c1492Romain Guy
5018b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
5028b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    if (presentedTimesNanoDst == NULL) {
503eb99356a0548684a501766e6a524529ab93304c8Romain Guy        return JNI_FALSE;
504eb99356a0548684a501766e6a524529ab93304c8Romain Guy    }
505eb99356a0548684a501766e6a524529ab93304c8Romain Guy
506eb99356a0548684a501766e6a524529ab93304c8Romain Guy    jlongArray readyTimesNanoDst = env->NewLongArray(frameCount);
507eb99356a0548684a501766e6a524529ab93304c8Romain Guy    if (readyTimesNanoDst == NULL) {
508eb99356a0548684a501766e6a524529ab93304c8Romain Guy        return JNI_FALSE;
509eb99356a0548684a501766e6a524529ab93304c8Romain Guy    }
510eb99356a0548684a501766e6a524529ab93304c8Romain Guy
5111d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy    nsecs_t postedTimesNanoSrc[frameCount];
5128b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    nsecs_t presentedTimesNanoSrc[frameCount];
5138b55f377655d13a445b08a0a8ed09b6e95c752b0Romain Guy    nsecs_t readyTimesNanoSrc[frameCount];
514eb99356a0548684a501766e6a524529ab93304c8Romain Guy
515eb99356a0548684a501766e6a524529ab93304c8Romain Guy    for (size_t i = 0; i < frameCount; i++) {
516eb99356a0548684a501766e6a524529ab93304c8Romain Guy        nsecs_t postedTimeNano = stats.desiredPresentTimesNano[i];
517eb99356a0548684a501766e6a524529ab93304c8Romain Guy        if (postedTimeNano == INT64_MAX) {
518eb99356a0548684a501766e6a524529ab93304c8Romain Guy            postedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
519eb99356a0548684a501766e6a524529ab93304c8Romain Guy        }
520eb99356a0548684a501766e6a524529ab93304c8Romain Guy        postedTimesNanoSrc[i] = postedTimeNano;
521eb99356a0548684a501766e6a524529ab93304c8Romain Guy
522eb99356a0548684a501766e6a524529ab93304c8Romain Guy        nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
523eb99356a0548684a501766e6a524529ab93304c8Romain Guy        if (presentedTimeNano == INT64_MAX) {
5241d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy            presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
525eb99356a0548684a501766e6a524529ab93304c8Romain Guy        }
526fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        presentedTimesNanoSrc[i] = presentedTimeNano;
5271d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy
5281d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy        nsecs_t readyTimeNano = stats.frameReadyTimesNano[i];
5291d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy        if (readyTimeNano == INT64_MAX) {
5301d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy            readyTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
5311d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy        }
5321d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy        readyTimesNanoSrc[i] = readyTimeNano;
5338694230ff25fa0a60e480d424843e56b718f0516Romain Guy    }
5348694230ff25fa0a60e480d424843e56b718f0516Romain Guy
5358694230ff25fa0a60e480d424843e56b718f0516Romain Guy    env->SetLongArrayRegion(postedTimesNanoDst, 0, frameCount, postedTimesNanoSrc);
5368694230ff25fa0a60e480d424843e56b718f0516Romain Guy    env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
5378694230ff25fa0a60e480d424843e56b718f0516Romain Guy    env->SetLongArrayRegion(readyTimesNanoDst, 0, frameCount, readyTimesNanoSrc);
5388694230ff25fa0a60e480d424843e56b718f0516Romain Guy
5398694230ff25fa0a60e480d424843e56b718f0516Romain Guy    env->CallVoidMethod(outStats, gWindowContentFrameStatsClassInfo.init, refreshPeriodNano,
5408694230ff25fa0a60e480d424843e56b718f0516Romain Guy            postedTimesNanoDst, presentedTimesNanoDst, readyTimesNanoDst);
5418694230ff25fa0a60e480d424843e56b718f0516Romain Guy
5428694230ff25fa0a60e480d424843e56b718f0516Romain Guy    if (env->ExceptionCheck()) {
5438694230ff25fa0a60e480d424843e56b718f0516Romain Guy        return JNI_FALSE;
5448694230ff25fa0a60e480d424843e56b718f0516Romain Guy    }
5458694230ff25fa0a60e480d424843e56b718f0516Romain Guy
5468694230ff25fa0a60e480d424843e56b718f0516Romain Guy    return JNI_TRUE;
5478694230ff25fa0a60e480d424843e56b718f0516Romain Guy}
5488694230ff25fa0a60e480d424843e56b718f0516Romain Guy
5498694230ff25fa0a60e480d424843e56b718f0516Romain Guystatic jboolean nativeClearAnimationFrameStats(JNIEnv* env, jclass clazz) {
5508694230ff25fa0a60e480d424843e56b718f0516Romain Guy    status_t err = SurfaceComposerClient::clearAnimationFrameStats();
5518694230ff25fa0a60e480d424843e56b718f0516Romain Guy
5528694230ff25fa0a60e480d424843e56b718f0516Romain Guy    if (err < 0 && err != NO_INIT) {
553bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        doThrowIAE(env);
554f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    }
555f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
556f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    // The other end is not ready, just report we failed.
557f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    if (err == NO_INIT) {
5588aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        return JNI_FALSE;
559f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    }
560f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
561f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    return JNI_TRUE;
5628aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy}
563f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
564f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guystatic jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject outStats) {
565f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    FrameStats stats;
5668aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
567f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    status_t err = SurfaceComposerClient::getAnimationFrameStats(&stats);
568f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    if (err < 0 && err != NO_INIT) {
569f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        doThrowIAE(env);
5708aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    }
571f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
572f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    // The other end is not ready, fine just return empty stats.
573f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    if (err == NO_INIT) {
5748aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy        return JNI_FALSE;
575f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    }
576f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
577f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
5787ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    size_t frameCount = stats.desiredPresentTimesNano.size();
5798aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
580f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
581f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    if (presentedTimesNanoDst == NULL) {
582f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        return JNI_FALSE;
583f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    }
584f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
585f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    nsecs_t presentedTimesNanoSrc[frameCount];
586bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
5878aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    for (size_t i = 0; i < frameCount; i++) {
588eb99356a0548684a501766e6a524529ab93304c8Romain Guy        nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
5899d5316e3f56d138504565ff311145ac01621dff4Romain Guy        if (presentedTimeNano == INT64_MAX) {
5909d5316e3f56d138504565ff311145ac01621dff4Romain Guy            presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
5919d5316e3f56d138504565ff311145ac01621dff4Romain Guy        }
592079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        presentedTimesNanoSrc[i] = presentedTimeNano;
593bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    }
594bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
595c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy    env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
5961d83e1981c8b89da93dff37a4f8b2b1ad8480b44Romain Guy
5978aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    env->CallVoidMethod(outStats, gWindowAnimationFrameStatsClassInfo.init, refreshPeriodNano,
5988aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy            presentedTimesNanoDst);
599c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
600c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy    if (env->ExceptionCheck()) {
601079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return JNI_FALSE;
602079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    }
6037ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
6047ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    return JNI_TRUE;
6057ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy}
6068aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
607e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
608e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guystatic void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong nativeObject,
609f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy        jobject handleObject, jlong frameNumber) {
610f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
611f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    sp<IBinder> handle = ibinderForJavaObject(env, handleObject);
612f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
613c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    ctrl->deferTransactionUntil(handle, frameNumber);
6146926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy}
6156926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
6166926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guystatic void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong nativeObject,
6176926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy        jint scalingMode) {
6186926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
6196926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
6206926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    ctrl->setOverrideScalingMode(scalingMode);
62161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy}
622fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy
6239cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guystatic jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
62422158e139a3d6c6a9787ca0de224e9368f643284Romain Guy    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
62522158e139a3d6c6a9787ca0de224e9368f643284Romain Guy
6266926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    return javaObjectForIBinder(env, ctrl->getHandle());
6278ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy}
6288ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy
629f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guystatic jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
630f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
631f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    if (token == NULL) return NULL;
632f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy
633f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy    HdrCapabilities capabilities;
6346926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    SurfaceComposerClient::getHdrCapabilities(token, &capabilities);
6356926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
6366926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    const auto& types = capabilities.getSupportedHdrTypes();
6376926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    auto typesArray = env->NewIntArray(types.size());
63861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    env->SetIntArrayRegion(typesArray, 0, types.size(), types.data());
639fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy
6409cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy    return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gHdrCapabilitiesClassInfo.ctor,
64122158e139a3d6c6a9787ca0de224e9368f643284Romain Guy            typesArray, capabilities.getDesiredMaxLuminance(),
64222158e139a3d6c6a9787ca0de224e9368f643284Romain Guy            capabilities.getDesiredMaxAverageLuminance(), capabilities.getDesiredMinLuminance());
64382ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy}
644f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy
645f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy// ----------------------------------------------------------------------------
6468ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy
6478ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guystatic const JNINativeMethod sSurfaceControlMethods[] = {
6488ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy    {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)J",
649f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy            (void*)nativeCreate },
6506926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    {"nativeRelease", "(J)V",
6516926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy            (void*)nativeRelease },
6526926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    {"nativeDestroy", "(J)V",
6536926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy            (void*)nativeDestroy },
65461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    {"nativeDisconnect", "(J)V",
655fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy            (void*)nativeDisconnect },
6569cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;",
65722158e139a3d6c6a9787ca0de224e9368f643284Romain Guy            (void*)nativeScreenshotBitmap },
6588ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
6598ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy            (void*)nativeScreenshot },
6608ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy    {"nativeOpenTransaction", "()V",
661c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy            (void*)nativeOpenTransaction },
6628ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy    {"nativeCloseTransaction", "(Z)V",
6638ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy            (void*)nativeCloseTransaction },
6648ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy    {"nativeSetAnimationTransaction", "()V",
6658ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy            (void*)nativeSetAnimationTransaction },
666c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    {"nativeSetLayer", "(JI)V",
6678ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy            (void*)nativeSetLayer },
6688ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy    {"nativeSetPosition", "(JFF)V",
66982ba814ca0dea659be2cc6523bc0137679d961ceRomain Guy            (void*)nativeSetPosition },
6708ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy    {"nativeSetPositionAppliesWithResize", "(J)V",
6718ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy            (void*)nativeSetPositionAppliesWithResize },
672ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    {"nativeSetSize", "(JII)V",
673ce0537b80087a6225273040a987414b1dd081aa0Romain Guy            (void*)nativeSetSize },
6744aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    {"nativeSetTransparentRegionHint", "(JLandroid/graphics/Region;)V",
6754aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy            (void*)nativeSetTransparentRegionHint },
6764aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    {"nativeSetAlpha", "(JF)V",
6776926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy            (void*)nativeSetAlpha },
6786926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    {"nativeSetMatrix", "(JFFFF)V",
6796926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy            (void*)nativeSetMatrix },
6806926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    {"nativeSetFlags", "(JII)V",
68161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            (void*)nativeSetFlags },
682fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    {"nativeSetWindowCrop", "(JIIII)V",
6839cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy            (void*)nativeSetWindowCrop },
68422158e139a3d6c6a9787ca0de224e9368f643284Romain Guy    {"nativeSetFinalCrop", "(JIIII)V",
685f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy            (void*)nativeSetFinalCrop },
686f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy    {"nativeSetLayerStack", "(JI)V",
687f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy            (void*)nativeSetLayerStack },
688f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy    {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
689f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy            (void*)nativeGetBuiltInDisplay },
6904aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
691759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            (void*)nativeCreateDisplay },
6924aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
693f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy            (void*)nativeDestroyDisplay },
694f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy    {"nativeSetDisplaySurface", "(Landroid/os/IBinder;J)V",
695f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy            (void*)nativeSetDisplaySurface },
696a979474f15b454c8e2963f239a3770e200bb227cRomain Guy    {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V",
697a979474f15b454c8e2963f239a3770e200bb227cRomain Guy            (void*)nativeSetDisplayLayerStack },
6986820ac8b14b4558f5d8b833dde80895306a3e137Romain Guy    {"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V",
699f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy            (void*)nativeSetDisplayProjection },
700f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy    {"nativeSetDisplaySize", "(Landroid/os/IBinder;II)V",
701759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            (void*)nativeSetDisplaySize },
702759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    {"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;",
703759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            (void*)nativeGetDisplayConfigs },
704759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    {"nativeGetActiveConfig", "(Landroid/os/IBinder;)I",
705759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            (void*)nativeGetActiveConfig },
706759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    {"nativeSetActiveConfig", "(Landroid/os/IBinder;I)Z",
707759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            (void*)nativeSetActiveConfig },
708759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    {"nativeGetHdrCapabilities", "(Landroid/os/IBinder;)Landroid/view/Display$HdrCapabilities;",
709759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            (void*)nativeGetHdrCapabilities },
710759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    {"nativeClearContentFrameStats", "(J)Z",
711759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            (void*)nativeClearContentFrameStats },
712c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy    {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
713c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy            (void*)nativeGetContentFrameStats },
714c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy    {"nativeClearAnimationFrameStats", "()Z",
71529d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy            (void*)nativeClearAnimationFrameStats },
71629d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy    {"nativeGetAnimationFrameStats", "(Landroid/view/WindowAnimationFrameStats;)Z",
717c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy            (void*)nativeGetAnimationFrameStats },
718c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy    {"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V",
719c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy            (void*)nativeSetDisplayPowerMode },
720c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy    {"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
721c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy            (void*)nativeDeferTransactionUntil },
72229d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy    {"nativeSetOverrideScalingMode", "(JI)V",
723c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy            (void*)nativeSetOverrideScalingMode },
724759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    {"nativeGetHandle", "(J)Landroid/os/IBinder;",
725759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            (void*)nativeGetHandle }
726759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy};
727759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy
728759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guyint register_android_view_SurfaceControl(JNIEnv* env)
729c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy{
73029d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy    int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl",
731c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy            sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
732c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy
733b5ab4173e0927e4668a45298c9900cd8007584e1Romain Guy    jclass clazz = FindClassOrDie(env, "android/view/SurfaceControl$PhysicalDisplayInfo");
734c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy    gPhysicalDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
735759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env,
736759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            gPhysicalDisplayInfoClassInfo.clazz, "<init>", "()V");
737759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.width =       GetFieldIDOrDie(env, clazz, "width", "I");
738759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.height =      GetFieldIDOrDie(env, clazz, "height", "I");
739759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.refreshRate = GetFieldIDOrDie(env, clazz, "refreshRate", "F");
740759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.density =     GetFieldIDOrDie(env, clazz, "density", "F");
741759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.xDpi =        GetFieldIDOrDie(env, clazz, "xDpi", "F");
742759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.yDpi =        GetFieldIDOrDie(env, clazz, "yDpi", "F");
743759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.secure =      GetFieldIDOrDie(env, clazz, "secure", "Z");
744759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos = GetFieldIDOrDie(env,
745759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            clazz, "appVsyncOffsetNanos", "J");
746c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy    gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = GetFieldIDOrDie(env,
74729d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy            clazz, "presentationDeadlineNanos", "J");
74829d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy    gPhysicalDisplayInfoClassInfo.colorTransform = GetFieldIDOrDie(env, clazz,
749c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy            "colorTransform", "I");
750c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy
751759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
752759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
753759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gRectClassInfo.left =   GetFieldIDOrDie(env, rectClazz, "left", "I");
754759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gRectClassInfo.right =  GetFieldIDOrDie(env, rectClazz, "right", "I");
755759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gRectClassInfo.top =    GetFieldIDOrDie(env, rectClazz, "top", "I");
756759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy
757c95c8d6bf8fda5c4e8ebd0033b789be7868e6e07Romain Guy    jclass frameStatsClazz = FindClassOrDie(env, "android/view/FrameStats");
758759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    jfieldID undefined_time_nano_field = GetStaticFieldIDOrDie(env,
759759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            frameStatsClazz, "UNDEFINED_TIME_NANO", "J");
76029d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy    nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field);
76129d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy
76229d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy    jclass contFrameStatsClazz = FindClassOrDie(env, "android/view/WindowContentFrameStats");
763759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    gWindowContentFrameStatsClassInfo.init = GetMethodIDOrDie(env,
764759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy            contFrameStatsClazz, "init", "(J[J[J[J)V");
76585bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy    gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
7668aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy
7673d58c03de0d8877b36cdb78b0ca8b5cac7f600e2Romain Guy    jclass animFrameStatsClazz = FindClassOrDie(env, "android/view/WindowAnimationFrameStats");
768c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy    gWindowAnimationFrameStatsClassInfo.init =  GetMethodIDOrDie(env,
7699d5316e3f56d138504565ff311145ac01621dff4Romain Guy            animFrameStatsClazz, "init", "(J[J)V");
770bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    gWindowAnimationFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
7716926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
7726926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    jclass hdrCapabilitiesClazz = FindClassOrDie(env, "android/view/Display$HdrCapabilities");
7736926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    gHdrCapabilitiesClassInfo.clazz = MakeGlobalRefOrDie(env, hdrCapabilitiesClazz);
7746926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy    gHdrCapabilitiesClassInfo.ctor = GetMethodIDOrDie(env, hdrCapabilitiesClazz, "<init>",
775026c5e16704e817cac7d9c382914c947e34f87e0Romain Guy            "([IFFF)V");
776a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy
777a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy    return err;
778a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy}
779a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy
780a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy};
781a5aed0d58962a24c44728ffc46dc9e1ba2f9fda5Romain Guy