WifiDisplayAdapter.java revision a7f9c966bc90e52baaf0cf0c165463e5f44354c5
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 com.android.server.display; 18cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 19a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport com.android.internal.R; 20cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport com.android.internal.util.DumpUtils; 21cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport com.android.internal.util.IndentingPrintWriter; 22cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 23a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.app.Notification; 24a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.app.NotificationManager; 25a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.app.PendingIntent; 26a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.content.BroadcastReceiver; 27cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport android.content.Context; 28e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brownimport android.content.Intent; 29a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.content.IntentFilter; 30a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.content.res.Resources; 31e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brownimport android.hardware.display.DisplayManager; 32e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brownimport android.hardware.display.WifiDisplay; 33e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brownimport android.hardware.display.WifiDisplayStatus; 34cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport android.media.RemoteDisplay; 35cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport android.os.Handler; 36cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport android.os.IBinder; 37a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.os.Looper; 38a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.os.Message; 39a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.os.UserHandle; 40a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brownimport android.provider.Settings; 41bc335457462a12434a9df6955de1dd693cdccac7Jeff Brownimport android.util.Slog; 42cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport android.view.Surface; 43cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 44cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport java.io.PrintWriter; 45e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brownimport java.util.Arrays; 46cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 47cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown/** 48cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * Connects to Wifi displays that implement the Miracast protocol. 49cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * <p> 50cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * The Wifi display protocol relies on Wifi direct for discovering and pairing 51cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * with the display. Once connected, the Media Server opens an RTSP socket and accepts 52cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * a connection from the display. After session negotiation, the Media Server 53cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * streams encoded buffers to the display. 54cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * </p><p> 55cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * This class is responsible for connecting to Wifi displays and mediating 56cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * the interactions between Media Server, Surface Flinger and the Display Manager Service. 57cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * </p><p> 58cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock. 59cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * </p> 60cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown */ 61cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownfinal class WifiDisplayAdapter extends DisplayAdapter { 62cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private static final String TAG = "WifiDisplayAdapter"; 63cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 642444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown private static final boolean DEBUG = false; 652444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown 66a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private static final int MSG_SEND_STATUS_CHANGE_BROADCAST = 1; 67a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private static final int MSG_UPDATE_NOTIFICATION = 2; 68a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 69a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private static final String ACTION_DISCONNECT = "android.server.display.wfd.DISCONNECT"; 70a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 71a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private final WifiDisplayHandler mHandler; 7277aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown private final PersistentDataStore mPersistentDataStore; 7377aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown private final boolean mSupportsProtectedBuffers; 74a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private final NotificationManager mNotificationManager; 75a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 76a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private final PendingIntent mSettingsPendingIntent; 77a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private final PendingIntent mDisconnectPendingIntent; 7889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 79cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private WifiDisplayController mDisplayController; 80f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown private WifiDisplayDevice mDisplayDevice; 81cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 82e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown private WifiDisplayStatus mCurrentStatus; 8389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown private int mFeatureState; 84180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown private int mScanState; 85180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown private int mActiveDisplayState; 86180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown private WifiDisplay mActiveDisplay; 8789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown private WifiDisplay[] mAvailableDisplays = WifiDisplay.EMPTY_ARRAY; 8889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown private WifiDisplay[] mRememberedDisplays = WifiDisplay.EMPTY_ARRAY; 89e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 90e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown private boolean mPendingStatusChangeBroadcast; 91a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private boolean mPendingNotificationUpdate; 92e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 93cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, 9489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown Context context, Handler handler, Listener listener, 9589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown PersistentDataStore persistentDataStore) { 96cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown super(syncRoot, context, handler, listener, TAG); 97a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mHandler = new WifiDisplayHandler(handler.getLooper()); 9889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mPersistentDataStore = persistentDataStore; 9977aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown mSupportsProtectedBuffers = context.getResources().getBoolean( 10077aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown com.android.internal.R.bool.config_wifiDisplaySupportsProtectedBuffers); 101a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mNotificationManager = (NotificationManager)context.getSystemService( 102a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown Context.NOTIFICATION_SERVICE); 103a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 104a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown Intent settingsIntent = new Intent(Settings.ACTION_WIFI_DISPLAY_SETTINGS); 105a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 106a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 107a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown | Intent.FLAG_ACTIVITY_CLEAR_TOP); 108a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mSettingsPendingIntent = PendingIntent.getActivityAsUser( 109a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown context, 0, settingsIntent, 0, null, UserHandle.CURRENT); 110a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 111a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown Intent disconnectIntent = new Intent(ACTION_DISCONNECT); 112a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mDisconnectPendingIntent = PendingIntent.getBroadcastAsUser( 113a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown context, 0, disconnectIntent, 0, UserHandle.CURRENT); 114a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 115a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, 116a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown new IntentFilter(ACTION_DISCONNECT), null, mHandler); 117cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 118cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 119cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown @Override 120cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void dumpLocked(PrintWriter pw) { 121cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown super.dumpLocked(pw); 122cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 123e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown pw.println("mCurrentStatus=" + getWifiDisplayStatusLocked()); 12489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown pw.println("mFeatureState=" + mFeatureState); 125180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown pw.println("mScanState=" + mScanState); 126180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown pw.println("mActiveDisplayState=" + mActiveDisplayState); 127180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown pw.println("mActiveDisplay=" + mActiveDisplay); 12889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown pw.println("mAvailableDisplays=" + Arrays.toString(mAvailableDisplays)); 12989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown pw.println("mRememberedDisplays=" + Arrays.toString(mRememberedDisplays)); 130e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast); 131a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown pw.println("mPendingNotificationUpdate=" + mPendingNotificationUpdate); 13277aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown pw.println("mSupportsProtectedBuffers=" + mSupportsProtectedBuffers); 133e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 134cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown // Try to dump the controller state. 135cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown if (mDisplayController == null) { 136cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mDisplayController=null"); 137cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } else { 138cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mDisplayController:"); 139cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 140cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown ipw.increaseIndent(); 141cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown DumpUtils.dumpAsync(getHandler(), mDisplayController, ipw, 200); 142cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 143cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 144cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 145cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown @Override 146cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void registerLocked() { 147cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown super.registerLocked(); 148cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 14989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown updateRememberedDisplaysLocked(); 15089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 151cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown getHandler().post(new Runnable() { 152cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown @Override 153cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void run() { 154cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mDisplayController = new WifiDisplayController( 155cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown getContext(), getHandler(), mWifiDisplayListener); 156cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 157cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown }); 158cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 159cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 160e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void requestScanLocked() { 1612444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown if (DEBUG) { 1622444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown Slog.d(TAG, "requestScanLocked"); 1632444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown } 1642444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown 165e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown getHandler().post(new Runnable() { 166e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown @Override 167e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void run() { 168e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown if (mDisplayController != null) { 169e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown mDisplayController.requestScan(); 170e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 171e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 172e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown }); 173e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 174e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 175bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown public void requestConnectLocked(final String address, final boolean trusted) { 1762444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown if (DEBUG) { 1772444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown Slog.d(TAG, "requestConnectLocked: address=" + address + ", trusted=" + trusted); 1782444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown } 1792444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown 180bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown if (!trusted) { 181bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown synchronized (getSyncRoot()) { 182bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown if (!isRememberedDisplayLocked(address)) { 183bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown Slog.w(TAG, "Ignoring request by an untrusted client to connect to " 184bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown + "an unknown wifi display: " + address); 185bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown return; 186bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown } 187bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown } 188bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown } 189bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown 190e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown getHandler().post(new Runnable() { 191e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown @Override 192e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void run() { 193e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown if (mDisplayController != null) { 194e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown mDisplayController.requestConnect(address); 195e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 196e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 197e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown }); 198e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 199e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 200bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown private boolean isRememberedDisplayLocked(String address) { 201bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown for (WifiDisplay display : mRememberedDisplays) { 202bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown if (display.getDeviceAddress().equals(address)) { 203bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown return true; 204bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown } 205bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown } 206bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown return false; 207bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown } 208bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown 209e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void requestDisconnectLocked() { 2102444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown if (DEBUG) { 2112444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown Slog.d(TAG, "requestDisconnectedLocked"); 2122444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown } 2132444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown 214e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown getHandler().post(new Runnable() { 215e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown @Override 216e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void run() { 217e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown if (mDisplayController != null) { 218e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown mDisplayController.requestDisconnect(); 219e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 220e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 221e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown }); 222e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 223e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 22489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown public void requestRenameLocked(String address, String alias) { 2252444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown if (DEBUG) { 2262444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown Slog.d(TAG, "requestRenameLocked: address=" + address + ", alias=" + alias); 2272444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown } 2282444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown 22989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown if (alias != null) { 23089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown alias = alias.trim(); 2312444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown if (alias.isEmpty() || alias.equals(address)) { 23289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown alias = null; 23389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 23489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 23589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 23689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown if (mPersistentDataStore.renameWifiDisplay(address, alias)) { 23789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mPersistentDataStore.saveIfNeeded(); 23889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown updateRememberedDisplaysLocked(); 23989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown scheduleStatusChangedBroadcastLocked(); 24089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 241ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown 242ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address) 243ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown && mDisplayDevice != null) { 244ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown mDisplayDevice.setNameLocked(mActiveDisplay.getFriendlyDisplayName()); 245ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED); 246ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown } 24789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 24889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 24989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown public void requestForgetLocked(String address) { 2502444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown if (DEBUG) { 2512444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown Slog.d(TAG, "requestForgetLocked: address=" + address); 2522444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown } 2532444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown 25489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown if (mPersistentDataStore.forgetWifiDisplay(address)) { 25589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mPersistentDataStore.saveIfNeeded(); 25689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown updateRememberedDisplaysLocked(); 25789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown scheduleStatusChangedBroadcastLocked(); 25889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 25989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 26089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address)) { 26189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown requestDisconnectLocked(); 26289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 26389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 26489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 265e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public WifiDisplayStatus getWifiDisplayStatusLocked() { 266e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown if (mCurrentStatus == null) { 26789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mCurrentStatus = new WifiDisplayStatus( 26889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mFeatureState, mScanState, mActiveDisplayState, 26989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mActiveDisplay, mAvailableDisplays, mRememberedDisplays); 270e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 2712444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown 2722444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown if (DEBUG) { 2732444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown Slog.d(TAG, "getWifiDisplayStatusLocked: result=" + mCurrentStatus); 2742444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown } 275e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown return mCurrentStatus; 276e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 277cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 27889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown private void updateRememberedDisplaysLocked() { 27989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mRememberedDisplays = mPersistentDataStore.getRememberedWifiDisplays(); 28089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mActiveDisplay = mPersistentDataStore.applyWifiDisplayAlias(mActiveDisplay); 28189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mAvailableDisplays = mPersistentDataStore.applyWifiDisplayAliases(mAvailableDisplays); 28289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 28389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 284f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown private void handleConnectLocked(WifiDisplay display, 285f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown Surface surface, int width, int height, int flags) { 286e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown handleDisconnectLocked(); 287e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 28889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown if (mPersistentDataStore.rememberWifiDisplay(display)) { 28989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mPersistentDataStore.saveIfNeeded(); 29089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown updateRememberedDisplaysLocked(); 29189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown scheduleStatusChangedBroadcastLocked(); 29289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 29389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 294f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown int deviceFlags = 0; 295f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown if ((flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0) { 29677aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown deviceFlags |= DisplayDeviceInfo.FLAG_SECURE; 29777aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown } 29877aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown if (mSupportsProtectedBuffers) { 29977aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown deviceFlags |= DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; 300f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown } 301f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown 302f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown float refreshRate = 60.0f; // TODO: get this for real 303f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown 30489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown String name = display.getFriendlyDisplayName(); 305f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown IBinder displayToken = Surface.createDisplay(name); 306f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height, 307f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown refreshRate, deviceFlags, surface); 308f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED); 309a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 310a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown scheduleUpdateNotificationLocked(); 311cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 312cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 313e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown private void handleDisconnectLocked() { 314f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown if (mDisplayDevice != null) { 315f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown mDisplayDevice.clearSurfaceLocked(); 316f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED); 317f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown mDisplayDevice = null; 318a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 319a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown scheduleUpdateNotificationLocked(); 320cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 321cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 322cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 323e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown private void scheduleStatusChangedBroadcastLocked() { 32489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mCurrentStatus = null; 325e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown if (!mPendingStatusChangeBroadcast) { 326e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown mPendingStatusChangeBroadcast = true; 327a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mHandler.sendEmptyMessage(MSG_SEND_STATUS_CHANGE_BROADCAST); 328e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 329e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 330e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 331a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private void scheduleUpdateNotificationLocked() { 332a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown if (!mPendingNotificationUpdate) { 333a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mPendingNotificationUpdate = true; 334a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mHandler.sendEmptyMessage(MSG_UPDATE_NOTIFICATION); 335a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 336a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 337a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 338a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown // Runs on the handler. 339a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private void handleSendStatusChangeBroadcast() { 340a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown final Intent intent; 341a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown synchronized (getSyncRoot()) { 342a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown if (!mPendingStatusChangeBroadcast) { 343a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown return; 344a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 345a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 346a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mPendingStatusChangeBroadcast = false; 347a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown intent = new Intent(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); 348a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 349a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown intent.putExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS, 350a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown getWifiDisplayStatusLocked()); 351a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 352e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 353a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown // Send protected broadcast about wifi display status to registered receivers. 354a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown getContext().sendBroadcastAsUser(intent, UserHandle.ALL); 355a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 356a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 357a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown // Runs on the handler. 358a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private void handleUpdateNotification() { 359a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown final boolean isConnected; 360a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown synchronized (getSyncRoot()) { 361a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown if (!mPendingNotificationUpdate) { 362a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown return; 363e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 364e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 365a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mPendingNotificationUpdate = false; 366a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown isConnected = (mDisplayDevice != null); 367a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 368a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 369a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mNotificationManager.cancelAsUser(null, 370a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown R.string.wifi_display_notification_title, UserHandle.ALL); 371a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 372a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown if (isConnected) { 373a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown Context context = getContext(); 374a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 375a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown Resources r = context.getResources(); 376a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown Notification notification = new Notification.Builder(context) 377a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown .setContentTitle(r.getString( 378a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown R.string.wifi_display_notification_title)) 379a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown .setContentText(r.getString( 380a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown R.string.wifi_display_notification_message)) 381a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown .setContentIntent(mSettingsPendingIntent) 382a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown .setSmallIcon(R.drawable.ic_notify_wifidisplay) 383a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown .setOngoing(true) 384a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown .addAction(android.R.drawable.ic_menu_close_clear_cancel, 385a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown r.getString(R.string.wifi_display_notification_disconnect), 386a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mDisconnectPendingIntent) 387a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown .build(); 388a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown mNotificationManager.notifyAsUser(null, 389a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown R.string.wifi_display_notification_title, 390a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown notification, UserHandle.ALL); 391a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 392a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 393a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 394a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 395a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown @Override 396a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown public void onReceive(Context context, Intent intent) { 397a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown if (intent.getAction().equals(ACTION_DISCONNECT)) { 398a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown synchronized (getSyncRoot()) { 399a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown requestDisconnectLocked(); 400a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 401a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 402e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 403e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown }; 404e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 405cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private final WifiDisplayController.Listener mWifiDisplayListener = 406cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown new WifiDisplayController.Listener() { 407cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown @Override 40889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown public void onFeatureStateChanged(int featureState) { 409e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown synchronized (getSyncRoot()) { 41089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown if (mFeatureState != featureState) { 41189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mFeatureState = featureState; 412e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown scheduleStatusChangedBroadcastLocked(); 413e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 414e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 415e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 416e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 417e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown @Override 418e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void onScanStarted() { 419e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown synchronized (getSyncRoot()) { 420180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown if (mScanState != WifiDisplayStatus.SCAN_STATE_SCANNING) { 421180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mScanState = WifiDisplayStatus.SCAN_STATE_SCANNING; 422e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown scheduleStatusChangedBroadcastLocked(); 423e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 424e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 425e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 426e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 4272444ae7e2b8658a4a90f996e678423558744b4a2Jeff Brown @Override 42889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown public void onScanFinished(WifiDisplay[] availableDisplays) { 429e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown synchronized (getSyncRoot()) { 43089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown availableDisplays = mPersistentDataStore.applyWifiDisplayAliases( 43189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown availableDisplays); 43289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 433180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown if (mScanState != WifiDisplayStatus.SCAN_STATE_NOT_SCANNING 43489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown || !Arrays.equals(mAvailableDisplays, availableDisplays)) { 435180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mScanState = WifiDisplayStatus.SCAN_STATE_NOT_SCANNING; 43689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mAvailableDisplays = availableDisplays; 437e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown scheduleStatusChangedBroadcastLocked(); 438e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 439e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 440e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 441e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 442e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown @Override 443e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void onDisplayConnecting(WifiDisplay display) { 444e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown synchronized (getSyncRoot()) { 44589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown display = mPersistentDataStore.applyWifiDisplayAlias(display); 44689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 447180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTING 448180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown || mActiveDisplay == null 449180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown || !mActiveDisplay.equals(display)) { 450180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_CONNECTING; 451180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mActiveDisplay = display; 452e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown scheduleStatusChangedBroadcastLocked(); 453e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 454e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 455e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 456e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 457e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown @Override 458e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void onDisplayConnectionFailed() { 459e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown synchronized (getSyncRoot()) { 460180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED 461180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown || mActiveDisplay != null) { 462180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED; 463180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mActiveDisplay = null; 464e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown scheduleStatusChangedBroadcastLocked(); 465e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 466e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 467e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 468e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 469e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown @Override 470f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown public void onDisplayConnected(WifiDisplay display, Surface surface, 471f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown int width, int height, int flags) { 472cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown synchronized (getSyncRoot()) { 47389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown display = mPersistentDataStore.applyWifiDisplayAlias(display); 474f8f0eddd07d22ab815d97dd32ae6ed52dc31a80cJeff Brown handleConnectLocked(display, surface, width, height, flags); 475e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 476180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED 477180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown || mActiveDisplay == null 478180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown || !mActiveDisplay.equals(display)) { 479180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_CONNECTED; 480180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mActiveDisplay = display; 481e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown scheduleStatusChangedBroadcastLocked(); 482e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 483cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 484cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 485cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 486cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown @Override 487cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onDisplayDisconnected() { 488cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown // Stop listening. 489cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown synchronized (getSyncRoot()) { 490e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown handleDisconnectLocked(); 491e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 492180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED 493180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown || mActiveDisplay != null) { 494180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED; 495180bbc71810496e280e9993177bfeddb3ad1f558Jeff Brown mActiveDisplay = null; 496e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown scheduleStatusChangedBroadcastLocked(); 497e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 498cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 499cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 500cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown }; 501cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 502cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private final class WifiDisplayDevice extends DisplayDevice { 503ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown private String mName; 504cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private final int mWidth; 505cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private final int mHeight; 506cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private final float mRefreshRate; 507cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private final int mFlags; 508cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 509cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private Surface mSurface; 510cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown private DisplayDeviceInfo mInfo; 511cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 512cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public WifiDisplayDevice(IBinder displayToken, String name, 513cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown int width, int height, float refreshRate, int flags, 514cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown Surface surface) { 515cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown super(WifiDisplayAdapter.this, displayToken); 516cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mName = name; 517cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mWidth = width; 518cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mHeight = height; 519cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mRefreshRate = refreshRate; 520cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mFlags = flags; 521cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mSurface = surface; 522cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 523cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 524cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void clearSurfaceLocked() { 525cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mSurface = null; 526cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown sendTraversalRequestLocked(); 527cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 528cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 529ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown public void setNameLocked(String name) { 530ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown mName = name; 531ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown mInfo = null; 532ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown } 533ee4f029ff4905abbdbc1ce47db2cf2c3510949e9Jeff Brown 534cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown @Override 535cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void performTraversalInTransactionLocked() { 536cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown setSurfaceInTransactionLocked(mSurface); 537cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 538cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 539cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown @Override 540cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public DisplayDeviceInfo getDisplayDeviceInfoLocked() { 541cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown if (mInfo == null) { 542cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mInfo = new DisplayDeviceInfo(); 543cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mInfo.name = mName; 544cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mInfo.width = mWidth; 545cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mInfo.height = mHeight; 546cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mInfo.refreshRate = mRefreshRate; 547cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mInfo.flags = mFlags; 548d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL; 549cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown mInfo.setAssumedDensityForExternalDisplay(mWidth, mHeight); 550cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 551cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown return mInfo; 552cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 553cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 554a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 555a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown private final class WifiDisplayHandler extends Handler { 556a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown public WifiDisplayHandler(Looper looper) { 557a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown super(looper, null, true /*async*/); 558a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 559a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 560a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown @Override 561a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown public void handleMessage(Message msg) { 562a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown switch (msg.what) { 563a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown case MSG_SEND_STATUS_CHANGE_BROADCAST: 564a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown handleSendStatusChangeBroadcast(); 565a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown break; 566a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown 567a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown case MSG_UPDATE_NOTIFICATION: 568a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown handleUpdateNotification(); 569a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown break; 570a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 571a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 572a7f9c966bc90e52baaf0cf0c165463e5f44354c5Jeff Brown } 573cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown} 574