RemoteDisplay.java revision fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30
1cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown/*
2cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * Copyright (C) 2012 The Android Open Source Project
3cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown *
4cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * you may not use this file except in compliance with the License.
6cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * You may obtain a copy of the License at
7cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown *
8cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown *
10cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * Unless required by applicable law or agreed to in writing, software
11cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * See the License for the specific language governing permissions and
14cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * limitations under the License.
15cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown */
16cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
17cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownpackage android.media;
18cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
19cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport dalvik.system.CloseGuard;
20cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
21cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport android.os.Handler;
22cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport android.view.Surface;
23cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
24cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown/**
25cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * Listens for Wifi remote display connections managed by the media server.
26cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown *
27cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * @hide
28cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown */
29cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownpublic final class RemoteDisplay {
30cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    /* these constants must be kept in sync with IRemoteDisplayClient.h */
31cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
32cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    public static final int DISPLAY_FLAG_SECURE = 1 << 0;
33cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
34cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    public static final int DISPLAY_ERROR_UNKOWN = 1;
35cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    public static final int DISPLAY_ERROR_CONNECTION_DROPPED = 2;
36cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
37cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    private final CloseGuard mGuard = CloseGuard.get();
38cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    private final Listener mListener;
39cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    private final Handler mHandler;
40fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    private final String mOpPackageName;
41cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
42075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    private long mPtr;
43cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
44fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    private native long nativeListen(String iface, String opPackageName);
45075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    private native void nativeDispose(long ptr);
46075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    private native void nativePause(long ptr);
47075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    private native void nativeResume(long ptr);
48cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
49fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    private RemoteDisplay(Listener listener, Handler handler, String opPackageName) {
50cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        mListener = listener;
51cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        mHandler = handler;
52fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov        mOpPackageName = opPackageName;
53cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
54cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
55cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    @Override
56cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    protected void finalize() throws Throwable {
57cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        try {
58cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            dispose(true);
59cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        } finally {
60cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            super.finalize();
61cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        }
62cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
63cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
64cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    /**
65cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     * Starts listening for displays to be connected on the specified interface.
66cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     *
67cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     * @param iface The interface address and port in the form "x.x.x.x:y".
68cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     * @param listener The listener to invoke when displays are connected or disconnected.
69cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     * @param handler The handler on which to invoke the listener.
70cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     */
71fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov    public static RemoteDisplay listen(String iface, Listener listener, Handler handler,
72fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov            String opPackageName) {
73cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        if (iface == null) {
74cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            throw new IllegalArgumentException("iface must not be null");
75cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        }
76cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        if (listener == null) {
77cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            throw new IllegalArgumentException("listener must not be null");
78cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        }
79cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        if (handler == null) {
80cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            throw new IllegalArgumentException("handler must not be null");
81cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        }
82cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
83fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov        RemoteDisplay display = new RemoteDisplay(listener, handler, opPackageName);
84cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        display.startListening(iface);
85cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        return display;
86cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
87cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
88cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    /**
89cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     * Disconnects the remote display and stops listening for new connections.
90cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     */
91cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    public void dispose() {
92cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        dispose(false);
93cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
94cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
951f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    public void pause() {
961f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        nativePause(mPtr);
971f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    }
981f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang
991f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    public void resume() {
1001f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        nativeResume(mPtr);
1011f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    }
1021f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang
103cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    private void dispose(boolean finalized) {
104cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        if (mPtr != 0) {
105cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            if (mGuard != null) {
106cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                if (finalized) {
107cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                    mGuard.warnIfOpen();
108cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                } else {
109cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                    mGuard.close();
110cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                }
111cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            }
112cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
113cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            nativeDispose(mPtr);
114cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            mPtr = 0;
115cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        }
116cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
117cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
118cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    private void startListening(String iface) {
119fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov        mPtr = nativeListen(iface, mOpPackageName);
120cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        if (mPtr == 0) {
121cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            throw new IllegalStateException("Could not start listening for "
122cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                    + "remote display connection on \"" + iface + "\"");
123cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        }
124cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        mGuard.open("dispose");
125cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
126cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
127cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    // Called from native.
128cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    private void notifyDisplayConnected(final Surface surface,
1291f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang            final int width, final int height, final int flags, final int session) {
130cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        mHandler.post(new Runnable() {
131cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            @Override
132cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            public void run() {
1331f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang                mListener.onDisplayConnected(surface, width, height, flags, session);
134cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            }
135cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        });
136cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
137cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
138cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    // Called from native.
139cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    private void notifyDisplayDisconnected() {
140cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        mHandler.post(new Runnable() {
141cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            @Override
142cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            public void run() {
143cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                mListener.onDisplayDisconnected();
144cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            }
145cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        });
146cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
147cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
148cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    // Called from native.
149cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    private void notifyDisplayError(final int error) {
150cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        mHandler.post(new Runnable() {
151cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            @Override
152cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            public void run() {
153cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                mListener.onDisplayError(error);
154cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            }
155cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        });
156cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
157cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
158cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    /**
159cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     * Listener invoked when the remote display connection changes state.
160cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown     */
161cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    public interface Listener {
1621f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        void onDisplayConnected(Surface surface,
1631f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang                int width, int height, int flags, int session);
164cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        void onDisplayDisconnected();
165cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        void onDisplayError(int error);
166cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
167cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown}
168