Skip to content

Commit c10914c

Browse files
Craig MautnerAndroid (Google) Code Review
authored andcommitted
Merge "Support Wifi display devices that rename themselves." into jb-mr1.1-dev
2 parents ed41bc2 + 74da109 commit c10914c

File tree

5 files changed

+149
-39
lines changed

5 files changed

+149
-39
lines changed

core/java/android/hardware/display/WifiDisplay.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ public boolean equals(WifiDisplay other) {
107107
&& Objects.equal(mDeviceAlias, other.mDeviceAlias);
108108
}
109109

110+
/**
111+
* Returns true if the other display is not null and has the same address as this one.
112+
* Can be used to perform identity comparisons on displays ignoring properties
113+
* that might change during a connection such as the name or alias.
114+
*/
115+
public boolean hasSameAddress(WifiDisplay other) {
116+
return other != null && mDeviceAddress.equals(other.mDeviceAddress);
117+
}
118+
110119
@Override
111120
public int hashCode() {
112121
// The address on its own should be sufficiently unique for hashing purposes.

media/java/android/media/MediaRouter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ private static void updateWifiDisplayRoute(RouteInfo route, WifiDisplay display,
862862
private static WifiDisplay findMatchingDisplay(WifiDisplay d, WifiDisplay[] displays) {
863863
for (int i = 0; i < displays.length; i++) {
864864
final WifiDisplay other = displays[i];
865-
if (d.getDeviceAddress().equals(other.getDeviceAddress())) {
865+
if (d.hasSameAddress(other)) {
866866
return other;
867867
}
868868
}

services/java/com/android/server/display/PersistentDataStore.java

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ public void saveIfNeeded() {
8181
}
8282
}
8383

84+
public WifiDisplay getRememberedWifiDisplay(String deviceAddress) {
85+
loadIfNeeded();
86+
int index = findRememberedWifiDisplay(deviceAddress);
87+
if (index >= 0) {
88+
return mRememberedWifiDisplays.get(index);
89+
}
90+
return null;
91+
}
92+
8493
public WifiDisplay[] getRememberedWifiDisplays() {
8594
loadIfNeeded();
8695
return mRememberedWifiDisplays.toArray(new WifiDisplay[mRememberedWifiDisplays.size()]);
@@ -137,22 +146,6 @@ public boolean rememberWifiDisplay(WifiDisplay display) {
137146
return true;
138147
}
139148

140-
public boolean renameWifiDisplay(String deviceAddress, String alias) {
141-
int index = findRememberedWifiDisplay(deviceAddress);
142-
if (index >= 0) {
143-
WifiDisplay display = mRememberedWifiDisplays.get(index);
144-
if (Objects.equal(display.getDeviceAlias(), alias)) {
145-
return false; // already has this alias
146-
}
147-
WifiDisplay renamedDisplay = new WifiDisplay(deviceAddress,
148-
display.getDeviceName(), alias);
149-
mRememberedWifiDisplays.set(index, renamedDisplay);
150-
setDirty();
151-
return true;
152-
}
153-
return false;
154-
}
155-
156149
public boolean forgetWifiDisplay(String deviceAddress) {
157150
int index = findRememberedWifiDisplay(deviceAddress);
158151
if (index >= 0) {

services/java/com/android/server/display/WifiDisplayAdapter.java

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
import java.io.PrintWriter;
4646
import java.util.Arrays;
4747

48+
import libcore.util.Objects;
49+
4850
/**
4951
* Connects to Wifi displays that implement the Miracast protocol.
5052
* <p>
@@ -224,16 +226,18 @@ public void requestRenameLocked(String address, String alias) {
224226
}
225227
}
226228

227-
if (mPersistentDataStore.renameWifiDisplay(address, alias)) {
228-
mPersistentDataStore.saveIfNeeded();
229-
updateRememberedDisplaysLocked();
230-
scheduleStatusChangedBroadcastLocked();
229+
WifiDisplay display = mPersistentDataStore.getRememberedWifiDisplay(address);
230+
if (display != null && !Objects.equal(display.getDeviceAlias(), alias)) {
231+
display = new WifiDisplay(address, display.getDeviceName(), alias);
232+
if (mPersistentDataStore.rememberWifiDisplay(display)) {
233+
mPersistentDataStore.saveIfNeeded();
234+
updateRememberedDisplaysLocked();
235+
scheduleStatusChangedBroadcastLocked();
236+
}
231237
}
232238

233-
if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address)
234-
&& mDisplayDevice != null) {
235-
mDisplayDevice.setNameLocked(mActiveDisplay.getFriendlyDisplayName());
236-
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED);
239+
if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address)) {
240+
renameDisplayDeviceLocked(mActiveDisplay.getFriendlyDisplayName());
237241
}
238242
}
239243

@@ -272,9 +276,42 @@ private void updateRememberedDisplaysLocked() {
272276
mAvailableDisplays = mPersistentDataStore.applyWifiDisplayAliases(mAvailableDisplays);
273277
}
274278

275-
private void handleConnectLocked(WifiDisplay display,
279+
private void fixRememberedDisplayNamesFromAvailableDisplaysLocked() {
280+
// It may happen that a display name has changed since it was remembered.
281+
// Consult the list of available displays and update the name if needed.
282+
// We don't do anything special for the active display here. The display
283+
// controller will send a separate event when it needs to be updates.
284+
boolean changed = false;
285+
for (int i = 0; i < mRememberedDisplays.length; i++) {
286+
WifiDisplay rememberedDisplay = mRememberedDisplays[i];
287+
WifiDisplay availableDisplay = findAvailableDisplayLocked(
288+
rememberedDisplay.getDeviceAddress());
289+
if (availableDisplay != null && !rememberedDisplay.equals(availableDisplay)) {
290+
if (DEBUG) {
291+
Slog.d(TAG, "fixRememberedDisplayNamesFromAvailableDisplaysLocked: "
292+
+ "updating remembered display to " + availableDisplay);
293+
}
294+
mRememberedDisplays[i] = availableDisplay;
295+
changed |= mPersistentDataStore.rememberWifiDisplay(availableDisplay);
296+
}
297+
}
298+
if (changed) {
299+
mPersistentDataStore.saveIfNeeded();
300+
}
301+
}
302+
303+
private WifiDisplay findAvailableDisplayLocked(String address) {
304+
for (WifiDisplay display : mAvailableDisplays) {
305+
if (display.getDeviceAddress().equals(address)) {
306+
return display;
307+
}
308+
}
309+
return null;
310+
}
311+
312+
private void addDisplayDeviceLocked(WifiDisplay display,
276313
Surface surface, int width, int height, int flags) {
277-
handleDisconnectLocked();
314+
removeDisplayDeviceLocked();
278315

279316
if (mPersistentDataStore.rememberWifiDisplay(display)) {
280317
mPersistentDataStore.saveIfNeeded();
@@ -303,7 +340,7 @@ private void handleConnectLocked(WifiDisplay display,
303340
scheduleUpdateNotificationLocked();
304341
}
305342

306-
private void handleDisconnectLocked() {
343+
private void removeDisplayDeviceLocked() {
307344
if (mDisplayDevice != null) {
308345
mDisplayDevice.clearSurfaceLocked();
309346
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
@@ -313,6 +350,13 @@ private void handleDisconnectLocked() {
313350
}
314351
}
315352

353+
private void renameDisplayDeviceLocked(String name) {
354+
if (mDisplayDevice != null && !mDisplayDevice.getNameLocked().equals(name)) {
355+
mDisplayDevice.setNameLocked(name);
356+
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED);
357+
}
358+
}
359+
316360
private void scheduleStatusChangedBroadcastLocked() {
317361
mCurrentStatus = null;
318362
if (!mPendingStatusChangeBroadcast) {
@@ -446,6 +490,7 @@ public void onScanFinished(WifiDisplay[] availableDisplays) {
446490
|| !Arrays.equals(mAvailableDisplays, availableDisplays)) {
447491
mScanState = WifiDisplayStatus.SCAN_STATE_NOT_SCANNING;
448492
mAvailableDisplays = availableDisplays;
493+
fixRememberedDisplayNamesFromAvailableDisplaysLocked();
449494
scheduleStatusChangedBroadcastLocked();
450495
}
451496
}
@@ -483,7 +528,7 @@ public void onDisplayConnected(WifiDisplay display, Surface surface,
483528
int width, int height, int flags) {
484529
synchronized (getSyncRoot()) {
485530
display = mPersistentDataStore.applyWifiDisplayAlias(display);
486-
handleConnectLocked(display, surface, width, height, flags);
531+
addDisplayDeviceLocked(display, surface, width, height, flags);
487532

488533
if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED
489534
|| mActiveDisplay == null
@@ -495,11 +540,25 @@ public void onDisplayConnected(WifiDisplay display, Surface surface,
495540
}
496541
}
497542

543+
@Override
544+
public void onDisplayChanged(WifiDisplay display) {
545+
synchronized (getSyncRoot()) {
546+
display = mPersistentDataStore.applyWifiDisplayAlias(display);
547+
if (mActiveDisplay != null
548+
&& mActiveDisplay.hasSameAddress(display)
549+
&& !mActiveDisplay.equals(display)) {
550+
mActiveDisplay = display;
551+
renameDisplayDeviceLocked(display.getFriendlyDisplayName());
552+
scheduleStatusChangedBroadcastLocked();
553+
}
554+
}
555+
}
556+
498557
@Override
499558
public void onDisplayDisconnected() {
500559
// Stop listening.
501560
synchronized (getSyncRoot()) {
502-
handleDisconnectLocked();
561+
removeDisplayDeviceLocked();
503562

504563
if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED
505564
|| mActiveDisplay != null) {

services/java/com/android/server/display/WifiDisplayController.java

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ final class WifiDisplayController implements DumpUtils.Dump {
120120
// or are not trying to connect.
121121
private WifiP2pDevice mConnectingDevice;
122122

123+
// The device from which we are currently disconnecting.
124+
private WifiP2pDevice mDisconnectingDevice;
125+
126+
// The device to which we were previously trying to connect and are now canceling.
127+
private WifiP2pDevice mCancelingDevice;
128+
123129
// The device to which we are currently connected, which means we have an active P2P group.
124130
private WifiP2pDevice mConnectedDevice;
125131

@@ -186,6 +192,7 @@ private void updateSettings() {
186192
updateWfdEnableState();
187193
}
188194

195+
@Override
189196
public void dump(PrintWriter pw) {
190197
pw.println("mWifiDisplayOnSetting=" + mWifiDisplayOnSetting);
191198
pw.println("mWifiP2pEnabled=" + mWifiP2pEnabled);
@@ -196,6 +203,8 @@ public void dump(PrintWriter pw) {
196203
pw.println("mDiscoverPeersRetriesLeft=" + mDiscoverPeersRetriesLeft);
197204
pw.println("mDesiredDevice=" + describeWifiP2pDevice(mDesiredDevice));
198205
pw.println("mConnectingDisplay=" + describeWifiP2pDevice(mConnectingDevice));
206+
pw.println("mDisconnectingDisplay=" + describeWifiP2pDevice(mDisconnectingDevice));
207+
pw.println("mCancelingDisplay=" + describeWifiP2pDevice(mCancelingDevice));
199208
pw.println("mConnectedDevice=" + describeWifiP2pDevice(mConnectedDevice));
200209
pw.println("mConnectionRetriesLeft=" + mConnectionRetriesLeft);
201210
pw.println("mRemoteDisplay=" + mRemoteDisplay);
@@ -384,7 +393,9 @@ private void handleScanFinished() {
384393
final int count = mAvailableWifiDisplayPeers.size();
385394
final WifiDisplay[] displays = WifiDisplay.CREATOR.newArray(count);
386395
for (int i = 0; i < count; i++) {
387-
displays[i] = createWifiDisplay(mAvailableWifiDisplayPeers.get(i));
396+
WifiP2pDevice device = mAvailableWifiDisplayPeers.get(i);
397+
displays[i] = createWifiDisplay(device);
398+
updateDesiredDevice(device);
388399
}
389400

390401
mHandler.post(new Runnable() {
@@ -395,6 +406,23 @@ public void run() {
395406
});
396407
}
397408

409+
private void updateDesiredDevice(WifiP2pDevice device) {
410+
// Handle the case where the device to which we are connecting or connected
411+
// may have been renamed or reported different properties in the latest scan.
412+
final String address = device.deviceAddress;
413+
if (mDesiredDevice != null && mDesiredDevice.deviceAddress.equals(address)) {
414+
if (DEBUG) {
415+
Slog.d(TAG, "updateDesiredDevice: new information "
416+
+ describeWifiP2pDevice(device));
417+
}
418+
mDesiredDevice.update(device);
419+
if (mAdvertisedDisplay != null
420+
&& mAdvertisedDisplay.getDeviceAddress().equals(address)) {
421+
readvertiseDisplay(createWifiDisplay(mDesiredDevice));
422+
}
423+
}
424+
}
425+
398426
private void connect(final WifiP2pDevice device) {
399427
if (mDesiredDevice != null
400428
&& !mDesiredDevice.deviceAddress.equals(device.deviceAddress)) {
@@ -459,12 +487,17 @@ private void updateConnection() {
459487
}
460488

461489
// Step 2. Before we try to connect to a new device, disconnect from the old one.
490+
if (mDisconnectingDevice != null) {
491+
return; // wait for asynchronous callback
492+
}
462493
if (mConnectedDevice != null && mConnectedDevice != mDesiredDevice) {
463494
Slog.i(TAG, "Disconnecting from Wifi display: " + mConnectedDevice.deviceName);
495+
mDisconnectingDevice = mConnectedDevice;
496+
mConnectedDevice = null;
464497

465498
unadvertiseDisplay();
466499

467-
final WifiP2pDevice oldDevice = mConnectedDevice;
500+
final WifiP2pDevice oldDevice = mDisconnectingDevice;
468501
mWifiP2pManager.removeGroup(mWifiP2pChannel, new ActionListener() {
469502
@Override
470503
public void onSuccess() {
@@ -480,8 +513,8 @@ public void onFailure(int reason) {
480513
}
481514

482515
private void next() {
483-
if (mConnectedDevice == oldDevice) {
484-
mConnectedDevice = null;
516+
if (mDisconnectingDevice == oldDevice) {
517+
mDisconnectingDevice = null;
485518
updateConnection();
486519
}
487520
}
@@ -491,13 +524,18 @@ private void next() {
491524

492525
// Step 3. Before we try to connect to a new device, stop trying to connect
493526
// to the old one.
527+
if (mCancelingDevice != null) {
528+
return; // wait for asynchronous callback
529+
}
494530
if (mConnectingDevice != null && mConnectingDevice != mDesiredDevice) {
495531
Slog.i(TAG, "Canceling connection to Wifi display: " + mConnectingDevice.deviceName);
532+
mCancelingDevice = mConnectingDevice;
533+
mConnectingDevice = null;
496534

497535
unadvertiseDisplay();
498536
mHandler.removeCallbacks(mConnectionTimeout);
499537

500-
final WifiP2pDevice oldDevice = mConnectingDevice;
538+
final WifiP2pDevice oldDevice = mCancelingDevice;
501539
mWifiP2pManager.cancelConnect(mWifiP2pChannel, new ActionListener() {
502540
@Override
503541
public void onSuccess() {
@@ -513,8 +551,8 @@ public void onFailure(int reason) {
513551
}
514552

515553
private void next() {
516-
if (mConnectingDevice == oldDevice) {
517-
mConnectingDevice = null;
554+
if (mCancelingDevice == oldDevice) {
555+
mCancelingDevice = null;
518556
updateConnection();
519557
}
520558
}
@@ -763,13 +801,17 @@ private void advertiseDisplay(final WifiDisplay display,
763801
public void run() {
764802
if (oldSurface != null && surface != oldSurface) {
765803
mListener.onDisplayDisconnected();
766-
} else if (oldDisplay != null && !Objects.equal(display, oldDisplay)) {
804+
} else if (oldDisplay != null && !oldDisplay.hasSameAddress(display)) {
767805
mListener.onDisplayConnectionFailed();
768806
}
769807

770808
if (display != null) {
771-
if (!Objects.equal(display, oldDisplay)) {
809+
if (!display.hasSameAddress(oldDisplay)) {
772810
mListener.onDisplayConnecting(display);
811+
} else if (!display.equals(oldDisplay)) {
812+
// The address is the same but some other property such as the
813+
// name must have changed.
814+
mListener.onDisplayChanged(display);
773815
}
774816
if (surface != null && surface != oldSurface) {
775817
mListener.onDisplayConnected(display, surface, width, height, flags);
@@ -784,6 +826,12 @@ private void unadvertiseDisplay() {
784826
advertiseDisplay(null, null, 0, 0, 0);
785827
}
786828

829+
private void readvertiseDisplay(WifiDisplay display) {
830+
advertiseDisplay(display, mAdvertisedDisplaySurface,
831+
mAdvertisedDisplayWidth, mAdvertisedDisplayHeight,
832+
mAdvertisedDisplayFlags);
833+
}
834+
787835
private static Inet4Address getInterfaceAddress(WifiP2pGroup info) {
788836
NetworkInterface iface;
789837
try {
@@ -885,6 +933,7 @@ public interface Listener {
885933

886934
void onDisplayConnecting(WifiDisplay display);
887935
void onDisplayConnectionFailed();
936+
void onDisplayChanged(WifiDisplay display);
888937
void onDisplayConnected(WifiDisplay display,
889938
Surface surface, int width, int height, int flags);
890939
void onDisplayDisconnected();

0 commit comments

Comments
 (0)