1 /*
2  * Copyright (C) 2019 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 package android.view;
18 
19 import android.graphics.Rect;
20 import android.os.IBinder;
21 
22 import com.android.internal.util.Preconditions;
23 
24 import java.util.concurrent.Executor;
25 
26 /**
27  * Listener for sampling the result of the screen composition.
28  * {@hide}
29  */
30 public abstract class CompositionSamplingListener {
31 
32     private long mNativeListener;
33     private final Executor mExecutor;
34 
CompositionSamplingListener(Executor executor)35     public CompositionSamplingListener(Executor executor) {
36         mExecutor = executor;
37         mNativeListener = nativeCreate(this);
38     }
39 
destroy()40     public void destroy() {
41         if (mNativeListener == 0) {
42             return;
43         }
44         unregister(this);
45         nativeDestroy(mNativeListener);
46         mNativeListener = 0;
47     }
48 
49     @Override
finalize()50     protected void finalize() throws Throwable {
51         try {
52             destroy();
53         } finally {
54             super.finalize();
55         }
56     }
57 
58     /**
59      * Reports a luma sample from the registered region.
60      */
onSampleCollected(float medianLuma)61     public abstract void onSampleCollected(float medianLuma);
62 
63     /**
64      * Registers a sampling listener.
65      */
register(CompositionSamplingListener listener, int displayId, IBinder stopLayer, Rect samplingArea)66     public static void register(CompositionSamplingListener listener,
67             int displayId, IBinder stopLayer, Rect samplingArea) {
68         if (listener.mNativeListener == 0) {
69             return;
70         }
71         Preconditions.checkArgument(displayId == Display.DEFAULT_DISPLAY,
72                 "default display only for now");
73         nativeRegister(listener.mNativeListener, stopLayer, samplingArea.left, samplingArea.top,
74                 samplingArea.right, samplingArea.bottom);
75     }
76 
77     /**
78      * Unregisters a sampling listener.
79      */
unregister(CompositionSamplingListener listener)80     public static void unregister(CompositionSamplingListener listener) {
81         if (listener.mNativeListener == 0) {
82             return;
83         }
84         nativeUnregister(listener.mNativeListener);
85     }
86 
87     /**
88      * Dispatch the collected sample.
89      *
90      * Called from native code on a binder thread.
91      */
dispatchOnSampleCollected(CompositionSamplingListener listener, float medianLuma)92     private static void dispatchOnSampleCollected(CompositionSamplingListener listener,
93             float medianLuma) {
94         listener.mExecutor.execute(() -> listener.onSampleCollected(medianLuma));
95     }
96 
nativeCreate(CompositionSamplingListener thiz)97     private static native long nativeCreate(CompositionSamplingListener thiz);
nativeDestroy(long ptr)98     private static native void nativeDestroy(long ptr);
nativeRegister(long ptr, IBinder stopLayer, int samplingAreaLeft, int top, int right, int bottom)99     private static native void nativeRegister(long ptr, IBinder stopLayer,
100             int samplingAreaLeft, int top, int right, int bottom);
nativeUnregister(long ptr)101     private static native void nativeUnregister(long ptr);
102 }
103