blob: 67cdfc53fb39bdaffe2e239d35cc5cc93644ed3f [file] [log] [blame]
Jeff Brown0a0a1242011-12-02 02:25:22 -08001/*
2 * Copyright (C) 2011 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
17package android.view;
18
Jeff Brown0a0a1242011-12-02 02:25:22 -080019import android.os.Looper;
20import android.os.MessageQueue;
21import android.util.Log;
22
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070023import dalvik.annotation.optimization.FastNative;
24import dalvik.system.CloseGuard;
25
Jeff Brown3b4049e2015-04-17 15:22:27 -070026import java.lang.ref.WeakReference;
27
Jeff Brown0a0a1242011-12-02 02:25:22 -080028/**
29 * Provides a low-level mechanism for an application to receive display events
30 * such as vertical sync.
Jeff Brown58aedbc2012-02-13 20:15:01 -080031 *
32 * The display event receive is NOT thread safe. Moreover, its methods must only
33 * be called on the Looper thread to which it is attached.
34 *
Jeff Brown0a0a1242011-12-02 02:25:22 -080035 * @hide
36 */
37public abstract class DisplayEventReceiver {
38 private static final String TAG = "DisplayEventReceiver";
39
40 private final CloseGuard mCloseGuard = CloseGuard.get();
41
Ashok Bhat27285822013-12-18 18:00:05 +000042 private long mReceiverPtr;
Jeff Brown0a0a1242011-12-02 02:25:22 -080043
44 // We keep a reference message queue object here so that it is not
45 // GC'd while the native peer of the receiver is using them.
46 private MessageQueue mMessageQueue;
47
Jeff Brown3b4049e2015-04-17 15:22:27 -070048 private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver,
Jeff Brown0a0a1242011-12-02 02:25:22 -080049 MessageQueue messageQueue);
Ashok Bhat27285822013-12-18 18:00:05 +000050 private static native void nativeDispose(long receiverPtr);
John Recke46af372016-10-03 16:21:30 -070051 @FastNative
Ashok Bhat27285822013-12-18 18:00:05 +000052 private static native void nativeScheduleVsync(long receiverPtr);
Jeff Brown0a0a1242011-12-02 02:25:22 -080053
54 /**
55 * Creates a display event receiver.
56 *
57 * @param looper The looper to use when invoking callbacks.
58 */
59 public DisplayEventReceiver(Looper looper) {
60 if (looper == null) {
61 throw new IllegalArgumentException("looper must not be null");
62 }
63
64 mMessageQueue = looper.getQueue();
Jeff Brown3b4049e2015-04-17 15:22:27 -070065 mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue);
Jeff Brown0a0a1242011-12-02 02:25:22 -080066
67 mCloseGuard.open("dispose");
68 }
69
70 @Override
71 protected void finalize() throws Throwable {
72 try {
Jeff Brown3e7e7f02012-08-27 14:33:53 -070073 dispose(true);
Jeff Brown0a0a1242011-12-02 02:25:22 -080074 } finally {
75 super.finalize();
76 }
77 }
78
79 /**
80 * Disposes the receiver.
81 */
82 public void dispose() {
Jeff Brown3e7e7f02012-08-27 14:33:53 -070083 dispose(false);
84 }
85
86 private void dispose(boolean finalized) {
Jeff Brown0a0a1242011-12-02 02:25:22 -080087 if (mCloseGuard != null) {
Jeff Brown3e7e7f02012-08-27 14:33:53 -070088 if (finalized) {
89 mCloseGuard.warnIfOpen();
90 }
Jeff Brown0a0a1242011-12-02 02:25:22 -080091 mCloseGuard.close();
92 }
Jeff Brown3e7e7f02012-08-27 14:33:53 -070093
Jeff Brown0a0a1242011-12-02 02:25:22 -080094 if (mReceiverPtr != 0) {
95 nativeDispose(mReceiverPtr);
96 mReceiverPtr = 0;
97 }
98 mMessageQueue = null;
99 }
100
101 /**
102 * Called when a vertical sync pulse is received.
103 * The recipient should render a frame and then call {@link #scheduleVsync}
104 * to schedule the next vertical sync pulse.
105 *
106 * @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}
107 * timebase.
Jeff Browne87bf032012-09-20 18:30:13 -0700108 * @param builtInDisplayId The surface flinger built-in display id such as
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800109 * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}.
Jeff Brown0a0a1242011-12-02 02:25:22 -0800110 * @param frame The frame number. Increases by one for each vertical sync interval.
111 */
Jeff Browne87bf032012-09-20 18:30:13 -0700112 public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
113 }
114
115 /**
116 * Called when a display hotplug event is received.
117 *
118 * @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()}
119 * timebase.
120 * @param builtInDisplayId The surface flinger built-in display id such as
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800121 * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_HDMI}.
Jeff Browne87bf032012-09-20 18:30:13 -0700122 * @param connected True if the display is connected, false if it disconnected.
123 */
124 public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
Jeff Brown0a0a1242011-12-02 02:25:22 -0800125 }
126
127 /**
128 * Schedules a single vertical sync pulse to be delivered when the next
129 * display frame begins.
130 */
131 public void scheduleVsync() {
132 if (mReceiverPtr == 0) {
133 Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
134 + "receiver has already been disposed.");
135 } else {
136 nativeScheduleVsync(mReceiverPtr);
137 }
138 }
139
140 // Called from native code.
141 @SuppressWarnings("unused")
Jeff Browne87bf032012-09-20 18:30:13 -0700142 private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
143 onVsync(timestampNanos, builtInDisplayId, frame);
144 }
145
146 // Called from native code.
147 @SuppressWarnings("unused")
148 private void dispatchHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
149 onHotplug(timestampNanos, builtInDisplayId, connected);
Jeff Brown0a0a1242011-12-02 02:25:22 -0800150 }
151}