blob: 283ba0d057c5700b36682e62c0bc161ac83df14e [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>
31#include <ui/Rect.h>
32
33namespace android {
34
35namespace {
36
37struct {
38 jclass mClass;
39 jmethodID mDispatchOnSampleCollected;
40} gListenerClassInfo;
41
42struct CompositionSamplingListener : public BnRegionSamplingListener {
43 CompositionSamplingListener(JNIEnv* env, jobject listener)
44 : mListener(env->NewGlobalRef(listener)) {}
45
46 void onSampleCollected(float medianLuma) override {
47 JNIEnv* env = AndroidRuntime::getJNIEnv();
48 LOG_ALWAYS_FATAL_IF(env == nullptr, "Unable to retrieve JNIEnv in onSampleCollected.");
49
50 env->CallStaticVoidMethod(gListenerClassInfo.mClass,
51 gListenerClassInfo.mDispatchOnSampleCollected, mListener,
52 static_cast<jfloat>(medianLuma));
53 if (env->ExceptionCheck()) {
54 ALOGE("CompositionSamplingListener.onSampleCollected() failed.");
55 LOGE_EX(env);
56 env->ExceptionClear();
57 }
58 }
59
60protected:
61 virtual ~CompositionSamplingListener() {
62 JNIEnv* env = AndroidRuntime::getJNIEnv();
63 env->DeleteGlobalRef(mListener);
64 }
65
66private:
67 jobject mListener;
68};
69
70jlong nativeCreate(JNIEnv* env, jclass clazz, jobject obj) {
71 CompositionSamplingListener* listener = new CompositionSamplingListener(env, obj);
72 listener->incStrong((void*)nativeCreate);
73 return reinterpret_cast<jlong>(listener);
74}
75
76void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) {
77 CompositionSamplingListener* listener = reinterpret_cast<CompositionSamplingListener*>(ptr);
78 listener->decStrong((void*)nativeCreate);
79}
80
81void nativeRegister(JNIEnv* env, jclass clazz, jlong ptr, jobject stopLayerTokenObj,
82 jint left, jint top, jint right, jint bottom) {
83 sp<CompositionSamplingListener> listener = reinterpret_cast<CompositionSamplingListener*>(ptr);
84 sp<IBinder> stopLayerHandle = ibinderForJavaObject(env, stopLayerTokenObj);
85
86 // TODO: Use SurfaceComposerClient once it has addRegionSamplingListener.
87 sp<ISurfaceComposer> composer;
88 if (getService(String16("SurfaceFlinger"), &composer) != NO_ERROR) {
89 jniThrowRuntimeException(env, "Couldn't retrieve SurfaceFlinger");
90 return;
91 }
92
93 composer->addRegionSamplingListener(
94 Rect(left, top, right, bottom), stopLayerHandle, listener);
95}
96
97void nativeUnregister(JNIEnv* env, jclass clazz, jlong ptr) {
98 sp<CompositionSamplingListener> listener = reinterpret_cast<CompositionSamplingListener*>(ptr);
99
100 // TODO: Use SurfaceComposerClient once it has addRegionSamplingListener.
101 sp<ISurfaceComposer> composer;
102 if (getService(String16("SurfaceFlinger"), &composer) != NO_ERROR) {
103 jniThrowRuntimeException(env, "Couldn't retrieve SurfaceFlinger");
104 return;
105 }
106
107 composer->removeRegionSamplingListener(listener);
108}
109
110const JNINativeMethod gMethods[] = {
111 /* name, signature, funcPtr */
112 { "nativeCreate", "(Landroid/view/CompositionSamplingListener;)J",
113 (void*)nativeCreate },
114 { "nativeDestroy", "(J)V",
115 (void*)nativeDestroy },
116 { "nativeRegister", "(JLandroid/os/IBinder;IIII)V",
117 (void*)nativeRegister },
118 { "nativeUnregister", "(J)V",
119 (void*)nativeUnregister }
120};
121
122} // namespace
123
124int register_android_view_CompositionSamplingListener(JNIEnv* env) {
125 int res = jniRegisterNativeMethods(env, "android/view/CompositionSamplingListener",
126 gMethods, NELEM(gMethods));
127 LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
128
129 jclass clazz = env->FindClass("android/view/CompositionSamplingListener");
130 gListenerClassInfo.mDispatchOnSampleCollected = env->GetStaticMethodID(
131 clazz, "dispatchOnSampleCollected", "(Landroid/view/CompositionSamplingListener;F)V");
132 return 0;
133}
134
135} // namespace android