• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.view;
18 
19 import dalvik.system.CloseGuard;
20 
21 import android.os.Looper;
22 import android.os.MessageQueue;
23 import android.util.Log;
24 
25 /**
26  * Provides a low-level mechanism for an application to receive display events
27  * such as vertical sync.
28  *
29  * The display event receive is NOT thread safe.  Moreover, its methods must only
30  * be called on the Looper thread to which it is attached.
31  *
32  * @hide
33  */
34 public abstract class DisplayEventReceiver {
35     private static final String TAG = "DisplayEventReceiver";
36 
37     private final CloseGuard mCloseGuard = CloseGuard.get();
38 
39     private long mReceiverPtr;
40 
41     // We keep a reference message queue object here so that it is not
42     // GC'd while the native peer of the receiver is using them.
43     private MessageQueue mMessageQueue;
44 
nativeInit(DisplayEventReceiver receiver, MessageQueue messageQueue)45     private static native long nativeInit(DisplayEventReceiver receiver,
46             MessageQueue messageQueue);
nativeDispose(long receiverPtr)47     private static native void nativeDispose(long receiverPtr);
nativeScheduleVsync(long receiverPtr)48     private static native void nativeScheduleVsync(long receiverPtr);
49 
50     /**
51      * Creates a display event receiver.
52      *
53      * @param looper The looper to use when invoking callbacks.
54      */
DisplayEventReceiver(Looper looper)55     public DisplayEventReceiver(Looper looper) {
56         if (looper == null) {
57             throw new IllegalArgumentException("looper must not be null");
58         }
59 
60         mMessageQueue = looper.getQueue();
61         mReceiverPtr = nativeInit(this, mMessageQueue);
62 
63         mCloseGuard.open("dispose");
64     }
65 
66     @Override
finalize()67     protected void finalize() throws Throwable {
68         try {
69             dispose(true);
70         } finally {
71             super.finalize();
72         }
73     }
74 
75     /**
76      * Disposes the receiver.
77      */
dispose()78     public void dispose() {
79         dispose(false);
80     }
81 
dispose(boolean finalized)82     private void dispose(boolean finalized) {
83         if (mCloseGuard != null) {
84             if (finalized) {
85                 mCloseGuard.warnIfOpen();
86             }
87             mCloseGuard.close();
88         }
89 
90         if (mReceiverPtr != 0) {
91             nativeDispose(mReceiverPtr);
92             mReceiverPtr = 0;
93         }
94         mMessageQueue = null;
95     }
96 
97     /**
98      * Called when a vertical sync pulse is received.
99      * The recipient should render a frame and then call {@link #scheduleVsync}
100      * to schedule the next vertical sync pulse.
101      *
102      * @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}
103      * timebase.
104      * @param builtInDisplayId The surface flinger built-in display id such as
105      * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}.
106      * @param frame The frame number.  Increases by one for each vertical sync interval.
107      */
onVsync(long timestampNanos, int builtInDisplayId, int frame)108     public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
109     }
110 
111     /**
112      * Called when a display hotplug event is received.
113      *
114      * @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()}
115      * timebase.
116      * @param builtInDisplayId The surface flinger built-in display id such as
117      * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_HDMI}.
118      * @param connected True if the display is connected, false if it disconnected.
119      */
onHotplug(long timestampNanos, int builtInDisplayId, boolean connected)120     public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
121     }
122 
123     /**
124      * Schedules a single vertical sync pulse to be delivered when the next
125      * display frame begins.
126      */
scheduleVsync()127     public void scheduleVsync() {
128         if (mReceiverPtr == 0) {
129             Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
130                     + "receiver has already been disposed.");
131         } else {
132             nativeScheduleVsync(mReceiverPtr);
133         }
134     }
135 
136     // Called from native code.
137     @SuppressWarnings("unused")
dispatchVsync(long timestampNanos, int builtInDisplayId, int frame)138     private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
139         onVsync(timestampNanos, builtInDisplayId, frame);
140     }
141 
142     // Called from native code.
143     @SuppressWarnings("unused")
dispatchHotplug(long timestampNanos, int builtInDisplayId, boolean connected)144     private void dispatchHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
145         onHotplug(timestampNanos, builtInDisplayId, connected);
146     }
147 }
148