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 
21 import com.android.internal.util.Preconditions;
22 
23 import java.util.concurrent.Executor;
24 
25 /**
26  * Listener for sampling the result of the screen composition.
27  * {@hide}
28  */
29 public abstract class CompositionSamplingListener {
30 
31     private long mNativeListener;
32     private final Executor mExecutor;
33 
CompositionSamplingListener(Executor executor)34     public CompositionSamplingListener(Executor executor) {
35         mExecutor = executor;
36         mNativeListener = nativeCreate(this);
37     }
38 
destroy()39     public void destroy() {
40         if (mNativeListener == 0) {
41             return;
42         }
43         unregister(this);
44         nativeDestroy(mNativeListener);
45         mNativeListener = 0;
46     }
47 
48     @Override
finalize()49     protected void finalize() throws Throwable {
50         try {
51             destroy();
52         } finally {
53             super.finalize();
54         }
55     }
56 
57     /**
58      * Reports a luma sample from the registered region.
59      */
onSampleCollected(float medianLuma)60     public abstract void onSampleCollected(float medianLuma);
61 
62     /**
63      * Registers a sampling listener.
64      */
register(CompositionSamplingListener listener, int displayId, SurfaceControl stopLayer, Rect samplingArea)65     public static void register(CompositionSamplingListener listener,
66             int displayId, SurfaceControl stopLayer, Rect samplingArea) {
67         if (listener.mNativeListener == 0) {
68             return;
69         }
70         Preconditions.checkArgument(displayId == Display.DEFAULT_DISPLAY,
71                 "default display only for now");
72         long nativeStopLayerObject = stopLayer != null ? stopLayer.mNativeObject : 0;
73         nativeRegister(listener.mNativeListener, nativeStopLayerObject, samplingArea.left,
74                 samplingArea.top, 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, long stopLayerObject, int samplingAreaLeft, int top, int right, int bottom)99     private static native void nativeRegister(long ptr, long stopLayerObject,
100             int samplingAreaLeft, int top, int right, int bottom);
nativeUnregister(long ptr)101     private static native void nativeUnregister(long ptr);
102 }
103