• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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.media;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.os.Build;
21 import android.os.Handler;
22 import android.view.Surface;
23 
24 import dalvik.system.CloseGuard;
25 
26 /**
27  * Listens for Wifi remote display connections managed by the media server.
28  *
29  * @hide
30  */
31 public final class RemoteDisplay {
32     /* these constants must be kept in sync with IRemoteDisplayClient.h */
33 
34     public static final int DISPLAY_FLAG_SECURE = 1 << 0;
35 
36     public static final int DISPLAY_ERROR_UNKOWN = 1;
37     public static final int DISPLAY_ERROR_CONNECTION_DROPPED = 2;
38 
39     private final CloseGuard mGuard = CloseGuard.get();
40     private final Listener mListener;
41     private final Handler mHandler;
42     private final String mOpPackageName;
43 
44     private long mPtr;
45 
nativeListen(String iface, String opPackageName)46     private native long nativeListen(String iface, String opPackageName);
nativeDispose(long ptr)47     private native void nativeDispose(long ptr);
nativePause(long ptr)48     private native void nativePause(long ptr);
nativeResume(long ptr)49     private native void nativeResume(long ptr);
50 
RemoteDisplay(Listener listener, Handler handler, String opPackageName)51     private RemoteDisplay(Listener listener, Handler handler, String opPackageName) {
52         mListener = listener;
53         mHandler = handler;
54         mOpPackageName = opPackageName;
55     }
56 
57     @Override
finalize()58     protected void finalize() throws Throwable {
59         try {
60             dispose(true);
61         } finally {
62             super.finalize();
63         }
64     }
65 
66     /**
67      * Starts listening for displays to be connected on the specified interface.
68      *
69      * @param iface The interface address and port in the form "x.x.x.x:y".
70      * @param listener The listener to invoke when displays are connected or disconnected.
71      * @param handler The handler on which to invoke the listener.
72      */
listen(String iface, Listener listener, Handler handler, String opPackageName)73     public static RemoteDisplay listen(String iface, Listener listener, Handler handler,
74             String opPackageName) {
75         if (iface == null) {
76             throw new IllegalArgumentException("iface must not be null");
77         }
78         if (listener == null) {
79             throw new IllegalArgumentException("listener must not be null");
80         }
81         if (handler == null) {
82             throw new IllegalArgumentException("handler must not be null");
83         }
84 
85         RemoteDisplay display = new RemoteDisplay(listener, handler, opPackageName);
86         display.startListening(iface);
87         return display;
88     }
89 
90     /**
91      * Disconnects the remote display and stops listening for new connections.
92      */
93     @UnsupportedAppUsage
dispose()94     public void dispose() {
95         dispose(false);
96     }
97 
pause()98     public void pause() {
99         nativePause(mPtr);
100     }
101 
resume()102     public void resume() {
103         nativeResume(mPtr);
104     }
105 
dispose(boolean finalized)106     private void dispose(boolean finalized) {
107         if (mPtr != 0) {
108             if (mGuard != null) {
109                 if (finalized) {
110                     mGuard.warnIfOpen();
111                 } else {
112                     mGuard.close();
113                 }
114             }
115 
116             nativeDispose(mPtr);
117             mPtr = 0;
118         }
119     }
120 
startListening(String iface)121     private void startListening(String iface) {
122         mPtr = nativeListen(iface, mOpPackageName);
123         if (mPtr == 0) {
124             throw new IllegalStateException("Could not start listening for "
125                     + "remote display connection on \"" + iface + "\"");
126         }
127         mGuard.open("dispose");
128     }
129 
130     // Called from native.
131     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
notifyDisplayConnected(final Surface surface, final int width, final int height, final int flags, final int session)132     private void notifyDisplayConnected(final Surface surface,
133             final int width, final int height, final int flags, final int session) {
134         mHandler.post(new Runnable() {
135             @Override
136             public void run() {
137                 mListener.onDisplayConnected(surface, width, height, flags, session);
138             }
139         });
140     }
141 
142     // Called from native.
143     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
notifyDisplayDisconnected()144     private void notifyDisplayDisconnected() {
145         mHandler.post(new Runnable() {
146             @Override
147             public void run() {
148                 mListener.onDisplayDisconnected();
149             }
150         });
151     }
152 
153     // Called from native.
154     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
notifyDisplayError(final int error)155     private void notifyDisplayError(final int error) {
156         mHandler.post(new Runnable() {
157             @Override
158             public void run() {
159                 mListener.onDisplayError(error);
160             }
161         });
162     }
163 
164     /**
165      * Listener invoked when the remote display connection changes state.
166      */
167     public interface Listener {
onDisplayConnected(Surface surface, int width, int height, int flags, int session)168         void onDisplayConnected(Surface surface,
169                 int width, int height, int flags, int session);
onDisplayDisconnected()170         void onDisplayDisconnected();
onDisplayError(int error)171         void onDisplayError(int error);
172     }
173 }
174