1 /*
2 * Copyright 2021 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 "TunnelModeEnabledListener"
18
19 #include "android_util_Binder.h"
20 #include "core_jni_helpers.h"
21
22 #include <nativehelper/JNIHelp.h>
23
24 #include <android/gui/BnTunnelModeEnabledListener.h>
25 #include <android_runtime/AndroidRuntime.h>
26 #include <android_runtime/Log.h>
27 #include <utils/Log.h>
28
29 #include <gui/SurfaceComposerClient.h>
30 #include <ui/Rect.h>
31
32 namespace android {
33
34 namespace {
35
36 struct {
37 jclass mClass;
38 jmethodID mDispatchOnTunnelModeEnabledChanged;
39 } gListenerClassInfo;
40
41 struct TunnelModeEnabledListener : public gui::BnTunnelModeEnabledListener {
TunnelModeEnabledListenerandroid::__anon534e80e60110::TunnelModeEnabledListener42 TunnelModeEnabledListener(JNIEnv* env, jobject listener)
43 : mListener(env->NewWeakGlobalRef(listener)) {}
44
onTunnelModeEnabledChangedandroid::__anon534e80e60110::TunnelModeEnabledListener45 binder::Status onTunnelModeEnabledChanged(bool tunnelModeEnabled) override {
46 JNIEnv* env = AndroidRuntime::getJNIEnv();
47 LOG_ALWAYS_FATAL_IF(env == nullptr,
48 "Unable to retrieve JNIEnv in onTunnelModeEnabledChanged.");
49
50 jobject listener = env->NewGlobalRef(mListener);
51 if (listener == NULL) {
52 // Weak reference went out of scope
53 return binder::Status::ok();
54 }
55 env->CallStaticVoidMethod(gListenerClassInfo.mClass,
56 gListenerClassInfo.mDispatchOnTunnelModeEnabledChanged, listener,
57 static_cast<jboolean>(tunnelModeEnabled));
58 env->DeleteGlobalRef(listener);
59
60 if (env->ExceptionCheck()) {
61 ALOGE("TunnelModeEnabledListener.onTunnelModeEnabledChanged() failed.");
62 LOGE_EX(env);
63 env->ExceptionClear();
64 }
65 return binder::Status::ok();
66 }
67
68 protected:
~TunnelModeEnabledListenerandroid::__anon534e80e60110::TunnelModeEnabledListener69 virtual ~TunnelModeEnabledListener() {
70 JNIEnv* env = AndroidRuntime::getJNIEnv();
71 env->DeleteWeakGlobalRef(mListener);
72 }
73
74 private:
75 jweak mListener;
76 };
77
nativeCreate(JNIEnv * env,jclass clazz,jobject obj)78 jlong nativeCreate(JNIEnv* env, jclass clazz, jobject obj) {
79 TunnelModeEnabledListener* listener = new TunnelModeEnabledListener(env, obj);
80 listener->incStrong((void*)nativeCreate);
81 return reinterpret_cast<jlong>(listener);
82 }
83
nativeDestroy(JNIEnv * env,jclass clazz,jlong ptr)84 void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) {
85 TunnelModeEnabledListener* listener = reinterpret_cast<TunnelModeEnabledListener*>(ptr);
86 listener->decStrong((void*)nativeCreate);
87 }
88
nativeRegister(JNIEnv * env,jclass clazz,jlong ptr)89 void nativeRegister(JNIEnv* env, jclass clazz, jlong ptr) {
90 sp<TunnelModeEnabledListener> listener = reinterpret_cast<TunnelModeEnabledListener*>(ptr);
91 if (SurfaceComposerClient::addTunnelModeEnabledListener(listener) != OK) {
92 constexpr auto error_msg = "Couldn't addTunnelModeEnabledListener";
93 ALOGE(error_msg);
94 jniThrowRuntimeException(env, error_msg);
95 }
96 }
97
nativeUnregister(JNIEnv * env,jclass clazz,jlong ptr)98 void nativeUnregister(JNIEnv* env, jclass clazz, jlong ptr) {
99 sp<TunnelModeEnabledListener> listener = reinterpret_cast<TunnelModeEnabledListener*>(ptr);
100
101 if (SurfaceComposerClient::removeTunnelModeEnabledListener(listener) != OK) {
102 constexpr auto error_msg = "Couldn't removeTunnelModeEnabledListener";
103 ALOGE(error_msg);
104 jniThrowRuntimeException(env, error_msg);
105 }
106 }
107
108 const JNINativeMethod gMethods[] = {
109 /* name, signature, funcPtr */
110 {"nativeCreate", "(Landroid/view/TunnelModeEnabledListener;)J", (void*)nativeCreate},
111 {"nativeDestroy", "(J)V", (void*)nativeDestroy},
112 {"nativeRegister", "(J)V", (void*)nativeRegister},
113 {"nativeUnregister", "(J)V", (void*)nativeUnregister}};
114
115 } // namespace
116
register_android_view_TunnelModeEnabledListener(JNIEnv * env)117 int register_android_view_TunnelModeEnabledListener(JNIEnv* env) {
118 int res = jniRegisterNativeMethods(env, "android/view/TunnelModeEnabledListener", gMethods,
119 NELEM(gMethods));
120 LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
121
122 jclass clazz = env->FindClass("android/view/TunnelModeEnabledListener");
123 gListenerClassInfo.mClass = MakeGlobalRefOrDie(env, clazz);
124 gListenerClassInfo.mDispatchOnTunnelModeEnabledChanged =
125 env->GetStaticMethodID(clazz, "dispatchOnTunnelModeEnabledChanged",
126 "(Landroid/view/TunnelModeEnabledListener;Z)V");
127 return 0;
128 }
129
130 } // namespace android
131