blob: 7141e6e141763829fd43b4b1e37cf80d7779e9c1 [file] [log] [blame]
Adrian Roos9b963d32019-02-13 18:39:36 +00001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "CompositionSamplingListener"
18
19#include "android_util_Binder.h"
20
21#include <nativehelper/JNIHelp.h>
22
23#include <android_runtime/AndroidRuntime.h>
24#include <android_runtime/Log.h>
25#include <utils/Log.h>
26#include <utils/RefBase.h>
27#include <binder/IServiceManager.h>
28
29#include <gui/IRegionSamplingListener.h>
30#include <gui/ISurfaceComposer.h>
Kevin DuBois66ed4f82019-02-18 16:27:11 -080031#include <gui/SurfaceComposerClient.h>
Adrian Roos9b963d32019-02-13 18:39:36 +000032#include <ui/Rect.h>
33
34namespace android {
35
36namespace {
37
38struct {
39 jclass mClass;
40 jmethodID mDispatchOnSampleCollected;
41} gListenerClassInfo;
42
43struct CompositionSamplingListener : public BnRegionSamplingListener {
44 CompositionSamplingListener(JNIEnv* env, jobject listener)
45 : mListener(env->NewGlobalRef(listener)) {}
46
47 void onSampleCollected(float medianLuma) override {
48 JNIEnv* env = AndroidRuntime::getJNIEnv();
49 LOG_ALWAYS_FATAL_IF(env == nullptr, "Unable to retrieve JNIEnv in onSampleCollected.");
50
51 env->CallStaticVoidMethod(gListenerClassInfo.mClass,
52 gListenerClassInfo.mDispatchOnSampleCollected, mListener,
53 static_cast<jfloat>(medianLuma));
54 if (env->ExceptionCheck()) {
55 ALOGE("CompositionSamplingListener.onSampleCollected() failed.");
56 LOGE_EX(env);
57 env->ExceptionClear();
58 }
59 }
60
61protected:
62 virtual ~CompositionSamplingListener() {
63 JNIEnv* env = AndroidRuntime::getJNIEnv();
64 env->DeleteGlobalRef(mListener);
65 }
66
67private:
68 jobject mListener;
69};
70
71jlong nativeCreate(JNIEnv* env, jclass clazz, jobject obj) {
72 CompositionSamplingListener* listener = new CompositionSamplingListener(env, obj);
73 listener->incStrong((void*)nativeCreate);
74 return reinterpret_cast<jlong>(listener);
75}
76
77void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) {
78 CompositionSamplingListener* listener = reinterpret_cast<CompositionSamplingListener*>(ptr);
79 listener->decStrong((void*)nativeCreate);
80}
81
82void nativeRegister(JNIEnv* env, jclass clazz, jlong ptr, jobject stopLayerTokenObj,
83 jint left, jint top, jint right, jint bottom) {
84 sp<CompositionSamplingListener> listener = reinterpret_cast<CompositionSamplingListener*>(ptr);
85 sp<IBinder> stopLayerHandle = ibinderForJavaObject(env, stopLayerTokenObj);
86
Kevin DuBois66ed4f82019-02-18 16:27:11 -080087 if (SurfaceComposerClient::addRegionSamplingListener(
88 Rect(left, top, right, bottom), stopLayerHandle, listener) != OK) {
89 constexpr auto error_msg = "Couldn't addRegionSamplingListener";
90 ALOGE(error_msg);
91 jniThrowRuntimeException(env, error_msg);
Adrian Roos9b963d32019-02-13 18:39:36 +000092 }
Adrian Roos9b963d32019-02-13 18:39:36 +000093}
94
95void nativeUnregister(JNIEnv* env, jclass clazz, jlong ptr) {
96 sp<CompositionSamplingListener> listener = reinterpret_cast<CompositionSamplingListener*>(ptr);
97
Kevin DuBois66ed4f82019-02-18 16:27:11 -080098 if (SurfaceComposerClient::removeRegionSamplingListener(listener) != OK) {
99 constexpr auto error_msg = "Couldn't removeRegionSamplingListener";
100 ALOGE(error_msg);
101 jniThrowRuntimeException(env, error_msg);
Adrian Roos9b963d32019-02-13 18:39:36 +0000102 }
Adrian Roos9b963d32019-02-13 18:39:36 +0000103}
104
105const JNINativeMethod gMethods[] = {
106 /* name, signature, funcPtr */
107 { "nativeCreate", "(Landroid/view/CompositionSamplingListener;)J",
108 (void*)nativeCreate },
109 { "nativeDestroy", "(J)V",
110 (void*)nativeDestroy },
111 { "nativeRegister", "(JLandroid/os/IBinder;IIII)V",
112 (void*)nativeRegister },
113 { "nativeUnregister", "(J)V",
114 (void*)nativeUnregister }
115};
116
117} // namespace
118
119int register_android_view_CompositionSamplingListener(JNIEnv* env) {
120 int res = jniRegisterNativeMethods(env, "android/view/CompositionSamplingListener",
121 gMethods, NELEM(gMethods));
122 LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
123
124 jclass clazz = env->FindClass("android/view/CompositionSamplingListener");
125 gListenerClassInfo.mDispatchOnSampleCollected = env->GetStaticMethodID(
126 clazz, "dispatchOnSampleCollected", "(Landroid/view/CompositionSamplingListener;F)V");
127 return 0;
128}
129
130} // namespace android