diff options
author | Jeff Brown <jeffbrown@google.com> | 2013-11-21 16:42:03 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2013-11-21 19:32:59 -0800 |
commit | ce468a35b388ca46578934706b38dbae94941643 (patch) | |
tree | 0e403cf705d7b938c0f0f77d09052486b7e14fb3 /services/java/com/android/server/display/DisplayManagerService.java | |
parent | 90e9b1d3dc15e97bb7ecb88289c3707fe03fb1a6 (diff) |
Stop wifi display discovery when no longer needed.
Keep track of how many clients are requesting scans and scan
continuously until all of them are gone then explicitly terminate the
scan instead of letting it time out as before.
Suspend wifi display scans while connecting or connected to a remote
display. This is handled by both the display manager and media router
since neither has complete information about what is happening.
Much of this code will no longer be needed once wifi display support
is integrated directly into the media router service.
Ensure that we don't attempt to scan or connect to wifi displays
while the wifi display feature is off.
Infer when a connection attempt fails and unselect the wifi display
route automatically so it doesn't appear to be connecting forever.
Fix issues around correctly canceling and retrying connection attempts.
Often we would cancel but not retry.
Improved connection reliability somewhat. It seems that discovery must
already be in progress in order for a connection attempt to succeed.
Ensure QuickSettings uses exactly the same logic as the MediaRouteButton
to determine when the remote display tile should be made visible.
Bug: 11717053
Change-Id: I18afc977b0e8c26204b8c96adaa79f05225f7b6e
Diffstat (limited to 'services/java/com/android/server/display/DisplayManagerService.java')
-rw-r--r-- | services/java/com/android/server/display/DisplayManagerService.java | 82 |
1 files changed, 75 insertions, 7 deletions
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index 02f26b375a2a..bcb677fa455f 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -35,6 +35,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; import android.text.TextUtils; +import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.view.Display; @@ -173,6 +174,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub { // The Wifi display adapter, or null if not registered. private WifiDisplayAdapter mWifiDisplayAdapter; + // The number of active wifi display scan requests. + private int mWifiDisplayScanRequestCount; + // The virtual display adapter, or null if not registered. private VirtualDisplayAdapter mVirtualDisplayAdapter; @@ -458,29 +462,81 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } - private void onCallbackDied(int pid) { + private void onCallbackDied(CallbackRecord record) { synchronized (mSyncRoot) { - mCallbacks.remove(pid); + mCallbacks.remove(record.mPid); + stopWifiDisplayScanLocked(record); } } @Override // Binder call - public void scanWifiDisplays() { + public void startWifiDisplayScan() { mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, - "Permission required to scan wifi displays"); + "Permission required to start wifi display scans"); + final int callingPid = Binder.getCallingPid(); final long token = Binder.clearCallingIdentity(); try { synchronized (mSyncRoot) { + CallbackRecord record = mCallbacks.get(callingPid); + if (record == null) { + throw new IllegalStateException("The calling process has not " + + "registered an IDisplayManagerCallback."); + } + startWifiDisplayScanLocked(record); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private void startWifiDisplayScanLocked(CallbackRecord record) { + if (!record.mWifiDisplayScanRequested) { + record.mWifiDisplayScanRequested = true; + if (mWifiDisplayScanRequestCount++ == 0) { if (mWifiDisplayAdapter != null) { - mWifiDisplayAdapter.requestScanLocked(); + mWifiDisplayAdapter.requestStartScanLocked(); } } + } + } + + @Override // Binder call + public void stopWifiDisplayScan() { + mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, + "Permission required to stop wifi display scans"); + + final int callingPid = Binder.getCallingPid(); + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mSyncRoot) { + CallbackRecord record = mCallbacks.get(callingPid); + if (record == null) { + throw new IllegalStateException("The calling process has not " + + "registered an IDisplayManagerCallback."); + } + stopWifiDisplayScanLocked(record); + } } finally { Binder.restoreCallingIdentity(token); } } + private void stopWifiDisplayScanLocked(CallbackRecord record) { + if (record.mWifiDisplayScanRequested) { + record.mWifiDisplayScanRequested = false; + if (--mWifiDisplayScanRequestCount == 0) { + if (mWifiDisplayAdapter != null) { + mWifiDisplayAdapter.requestStopScanLocked(); + } + } else if (mWifiDisplayScanRequestCount < 0) { + Log.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " + + mWifiDisplayScanRequestCount); + mWifiDisplayScanRequestCount = 0; + } + } + } + @Override // Binder call public void connectWifiDisplay(String address) { if (address == null) { @@ -1107,6 +1163,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { pw.println(" mDefaultViewport=" + mDefaultViewport); pw.println(" mExternalTouchViewport=" + mExternalTouchViewport); pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); + pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.increaseIndent(); @@ -1134,6 +1191,15 @@ public final class DisplayManagerService extends IDisplayManager.Stub { pw.println(" Display " + displayId + ":"); display.dumpLocked(ipw); } + + final int callbackCount = mCallbacks.size(); + pw.println(); + pw.println("Callbacks: size=" + callbackCount); + for (int i = 0; i < callbackCount; i++) { + CallbackRecord callback = mCallbacks.valueAt(i); + pw.println(" " + i + ": mPid=" + callback.mPid + + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); + } } } @@ -1234,9 +1300,11 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } private final class CallbackRecord implements DeathRecipient { - private final int mPid; + public final int mPid; private final IDisplayManagerCallback mCallback; + public boolean mWifiDisplayScanRequested; + public CallbackRecord(int pid, IDisplayManagerCallback callback) { mPid = pid; mCallback = callback; @@ -1247,7 +1315,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { if (DEBUG) { Slog.d(TAG, "Display listener for pid " + mPid + " died."); } - onCallbackDied(mPid); + onCallbackDied(this); } public void notifyDisplayEventAsync(int displayId, int event) { |