diff options
5 files changed, 106 insertions, 100 deletions
diff --git a/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java b/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java index c0960d405..38c0ad058 100644 --- a/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java +++ b/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java @@ -35,10 +35,6 @@ public class ConnectToNetworkNotificationBuilder { public static final String ACTION_USER_DISMISSED_NOTIFICATION = "com.android.server.wifi.ConnectToNetworkNotification.USER_DISMISSED_NOTIFICATION"; - /** Intent when user tapped the "Connect to Network" notification. */ - public static final String ACTION_USER_TAPPED_CONTENT = - "com.android.server.wifi.ConnectToNetworkNotification.USER_TAPPED_CONTENT"; - /** Intent when user tapped action button to connect to recommended network. */ public static final String ACTION_CONNECT_TO_NETWORK = "com.android.server.wifi.ConnectToNetworkNotification.CONNECT_TO_NETWORK"; @@ -67,17 +63,24 @@ public class ConnectToNetworkNotificationBuilder { * Creates the connect to network notification that alerts users of a recommended connectable * network. * - * @param numNetworks Number of available open networks nearby + * There are two actions - "Options" link to the Wi-Fi picker activity, and "Connect" prompts + * the connection to the recommended network. + * + * @param network The network to be recommended */ - public Notification createConnectToNetworkNotification(int numNetworks) { - - CharSequence title = mResources.getQuantityText( - com.android.internal.R.plurals.wifi_available, numNetworks); - CharSequence content = mResources.getQuantityText( - com.android.internal.R.plurals.wifi_available_detailed, numNetworks); - - return createNotificationBuilder(title, content) - .setContentIntent(getPrivateBroadcast(ACTION_USER_TAPPED_CONTENT)) + public Notification createConnectToNetworkNotification(ScanResult network) { + Notification.Action connectAction = new Notification.Action.Builder( + null /* icon */, + mResources.getText(R.string.wifi_available_action_connect), + getPrivateBroadcast(ACTION_CONNECT_TO_NETWORK)).build(); + Notification.Action allNetworksAction = new Notification.Action.Builder( + null /* icon */, + mResources.getText(R.string.wifi_available_action_all_networks), + getPrivateBroadcast(ACTION_PICK_WIFI_NETWORK)).build(); + return createNotificationBuilder( + mContext.getText(R.string.wifi_available_title), network.SSID) + .addAction(connectAction) + .addAction(allNetworksAction) .build(); } @@ -116,6 +119,7 @@ public class ConnectToNetworkNotificationBuilder { mContext.getText(R.string.wifi_available_content_failed_to_connect)) .setContentIntent( getPrivateBroadcast(ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE)) + .setAutoCancel(true) .build(); } @@ -124,7 +128,6 @@ public class ConnectToNetworkNotificationBuilder { return mFrameworkFacade.makeNotificationBuilder(mContext, SystemNotificationChannels.NETWORK_AVAILABLE) .setSmallIcon(R.drawable.stat_notify_wifi_in_range) - .setAutoCancel(true) .setTicker(title) .setContentTitle(title) .setContentText(content) diff --git a/service/java/com/android/server/wifi/OpenNetworkNotifier.java b/service/java/com/android/server/wifi/OpenNetworkNotifier.java index d2d45c37c..31ff44b72 100644 --- a/service/java/com/android/server/wifi/OpenNetworkNotifier.java +++ b/service/java/com/android/server/wifi/OpenNetworkNotifier.java @@ -20,7 +20,6 @@ import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION_PICK_WIFI_NETWORK; import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE; import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION_USER_DISMISSED_NOTIFICATION; -import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION_USER_TAPPED_CONTENT; import android.annotation.IntDef; import android.annotation.NonNull; @@ -169,7 +168,6 @@ public class OpenNetworkNotifier { IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_USER_DISMISSED_NOTIFICATION); - filter.addAction(ACTION_USER_TAPPED_CONTENT); filter.addAction(ACTION_CONNECT_TO_NETWORK); filter.addAction(ACTION_PICK_WIFI_NETWORK); filter.addAction(ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE); @@ -182,9 +180,6 @@ public class OpenNetworkNotifier { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { - case ACTION_USER_TAPPED_CONTENT: - handleUserClickedContentAction(); - break; case ACTION_USER_DISMISSED_NOTIFICATION: handleUserDismissedAction(); break; @@ -257,18 +252,29 @@ public class OpenNetworkNotifier { return; } - // Do not show or update the notification if screen is off. We want to avoid a race that - // could occur between a user picking a network in settings and a network candidate picked - // through network selection, which will happen because screen on triggers a new - // connectivity scan. - if (mState != STATE_NO_NOTIFICATION || !mScreenOn) { + // Not enough time has passed to show a recommendation notification again + if (mState == STATE_NO_NOTIFICATION + && mClock.getWallClockMillis() < mNotificationRepeatTime) { return; } - mRecommendedNetwork = mOpenNetworkRecommender.recommendNetwork( - availableNetworks, new ArraySet<>(mBlacklistedSsids)); + // Do nothing when the screen is off and no notification is showing. + if (mState == STATE_NO_NOTIFICATION && !mScreenOn) { + return; + } - postInitialNotification(availableNetworks.size()); + // Only show a new or update an existing recommendation notification. + if (mState == STATE_NO_NOTIFICATION + || mState == STATE_SHOWING_RECOMMENDATION_NOTIFICATION) { + ScanResult recommendation = mOpenNetworkRecommender.recommendNetwork( + availableNetworks, new ArraySet<>(mBlacklistedSsids)); + + if (recommendation != null) { + postInitialNotification(recommendation); + } else { + clearPendingNotification(false /* resetRepeatTime */); + } + } } /** Handles screen state changes. */ @@ -321,19 +327,11 @@ public class OpenNetworkNotifier { return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); } - private void postInitialNotification(int numNetworks) { - if (mState != STATE_NO_NOTIFICATION - && mState != STATE_SHOWING_RECOMMENDATION_NOTIFICATION) { - return; - } - // Not enough time has passed to show the notification again - if (mClock.getWallClockMillis() < mNotificationRepeatTime) { - return; - } - + private void postInitialNotification(ScanResult recommendedNetwork) { postNotification(mNotificationBuilder.createConnectToNetworkNotification( - numNetworks)); + recommendedNetwork)); mState = STATE_SHOWING_RECOMMENDATION_NOTIFICATION; + mRecommendedNetwork = recommendedNetwork; mNotificationRepeatTime = mClock.getWallClockMillis() + mNotificationRepeatDelay; } @@ -372,6 +370,8 @@ public class OpenNetworkNotifier { } private void startWifiSettings() { + // Close notification drawer before opening the picker. + mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); mContext.startActivity( new Intent(Settings.ACTION_WIFI_SETTINGS) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); @@ -382,11 +382,6 @@ public class OpenNetworkNotifier { startWifiSettings(); } - private void handleUserClickedContentAction() { - startWifiSettings(); - resetStateAndDelayNotification(); - } - private void handleUserDismissedAction() { if (mState == STATE_SHOWING_RECOMMENDATION_NOTIFICATION) { // blacklist dismissed network diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 1c5ac2821..7e730c838 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -1073,7 +1073,7 @@ public class WifiConnectivityManager { mWifiState = state; if (mWifiState == WIFI_STATE_CONNECTED) { - mOpenNetworkNotifier.clearPendingNotification(false /* resetRepeatDelay */); + mOpenNetworkNotifier.handleWifiConnected(); } // Reset BSSID of last connection attempt and kick off diff --git a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java index 3af19e163..46ec1597e 100644 --- a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java +++ b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java @@ -120,7 +120,7 @@ public class OpenNetworkNotifierTest { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); } @@ -144,42 +144,48 @@ public class OpenNetworkNotifierTest { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mNotificationController.handleScanResults(new ArrayList<>()); verify(mNotificationManager).cancel(anyInt()); } + /** - * When a notification is showing, screen is off, and scan results with no open networks are - * handled, the notification is cleared. + * When a notification is showing and no recommendation is made for the new scan results, the + * notification is cleared. */ @Test - public void handleScanResults_notificationShown_screenOff_emptyList_notificationCleared() { + public void handleScanResults_notificationShown_noRecommendation_notificationCleared() { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); - mNotificationController.handleScreenStateChanged(false); - mNotificationController.handleScanResults(new ArrayList<>()); + when(mOpenNetworkRecommender.recommendNetwork(any(), any())).thenReturn(null); + mNotificationController.handleScanResults(mOpenNetworks); verify(mNotificationManager).cancel(anyInt()); } /** - * If notification is showing, do not post another notification. + * When a notification is showing, screen is off, and scan results with no open networks are + * handled, the notification is cleared. */ @Test - public void handleScanResults_notificationShowing_doesNotRepostNotification() { - mNotificationController.handleScanResults(mOpenNetworks); + public void handleScanResults_notificationShown_screenOff_emptyList_notificationCleared() { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); + + mNotificationController.handleScreenStateChanged(false); + mNotificationController.handleScanResults(new ArrayList<>()); + + verify(mNotificationManager).cancel(anyInt()); } /** @@ -191,7 +197,7 @@ public class OpenNetworkNotifierTest { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mNotificationController.clearPendingNotification(true); @@ -215,7 +221,7 @@ public class OpenNetworkNotifierTest { * new scan results with open networks. */ @Test - public void screenOff_handleScanResults_notificationNotDisplayed() { + public void screenOff_notificationNotShowing_handleScanResults_notificationNotDisplayed() { mNotificationController.handleScreenStateChanged(false); mNotificationController.handleScanResults(mOpenNetworks); @@ -224,69 +230,69 @@ public class OpenNetworkNotifierTest { } /** - * When a notification is posted and cleared without resetting delay, the next scan with open - * networks should not post another notification. + * When screen is off and notification is displayed, the notification can be updated with a new + * recommendation. */ @Test - public void postNotification_clearNotificationWithoutDelayReset_shouldNotPostNotification() { + public void screenOff_notificationShowing_handleScanResults_recommendationCanBeUpdated() { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); - mNotificationController.clearPendingNotification(false); - + mNotificationController.handleScreenStateChanged(false); mNotificationController.handleScanResults(mOpenNetworks); - // Recommendation made twice but no new notification posted. + // Recommendation made twice verify(mOpenNetworkRecommender, times(2)).recommendNetwork( mOpenNetworks, mBlacklistedSsids); - verify(mNotificationManager).notify(anyInt(), any()); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); - verify(mNotificationManager).cancel(anyInt()); + verify(mNotificationBuilder, times(2)).createConnectToNetworkNotification(mDummyNetwork); + verify(mNotificationManager, times(2)).notify(anyInt(), any()); } /** * When a notification is posted and cleared without resetting delay, the next scan with open - * networks should post a notification. + * networks should not post another notification. */ @Test - public void postNotification_clearNotificationWithDelayReset_shouldPostNotification() { + public void postNotification_clearNotificationWithoutDelayReset_shouldNotPostNotification() { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); - mNotificationController.clearPendingNotification(true); + mNotificationController.clearPendingNotification(false); + + verify(mNotificationManager).cancel(anyInt()); mNotificationController.handleScanResults(mOpenNetworks); - verify(mOpenNetworkRecommender, times(2)).recommendNetwork( - mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder, times(2)).createConnectToNetworkNotification(1); - verify(mNotificationManager, times(2)).notify(anyInt(), any()); + // no new notification posted + verify(mNotificationManager).notify(anyInt(), any()); } /** - * When a notification is tapped, open Wi-Fi settings. + * When a notification is posted and cleared without resetting delay, the next scan with open + * networks should post a notification. */ @Test - public void notificationTap_opensWifiSettings() { + public void postNotification_clearNotificationWithDelayReset_shouldPostNotification() { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); - mBroadcastReceiver.onReceive( - mContext, - new Intent(ConnectToNetworkNotificationBuilder.ACTION_USER_TAPPED_CONTENT)); + mNotificationController.clearPendingNotification(true); - ArgumentCaptor<Intent> pickerIntentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mContext).startActivity(pickerIntentCaptor.capture()); - assertEquals(pickerIntentCaptor.getValue().getAction(), Settings.ACTION_WIFI_SETTINGS); + mNotificationController.handleScanResults(mOpenNetworks); + + verify(mOpenNetworkRecommender, times(2)).recommendNetwork( + mOpenNetworks, mBlacklistedSsids); + verify(mNotificationBuilder, times(2)).createConnectToNetworkNotification(mDummyNetwork); + verify(mNotificationManager, times(2)).notify(anyInt(), any()); } /** @@ -298,7 +304,7 @@ public class OpenNetworkNotifierTest { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mBroadcastReceiver.onReceive( @@ -307,7 +313,9 @@ public class OpenNetworkNotifierTest { verify(mWifiConfigManager).saveToStore(false /* forceWrite */); - mNotificationController.handleScanResults(mOpenNetworks); + mNotificationController.clearPendingNotification(true); + List<ScanDetail> scanResults = mOpenNetworks; + mNotificationController.handleScanResults(scanResults); Set<String> expectedBlacklist = new ArraySet<>(); expectedBlacklist.add(mDummyNetwork.SSID); @@ -323,7 +331,7 @@ public class OpenNetworkNotifierTest { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mNotificationController.clearPendingNotification(false); @@ -335,6 +343,7 @@ public class OpenNetworkNotifierTest { verify(mOpenNetworkRecommender, times(2)).recommendNetwork( mOpenNetworks, mBlacklistedSsids); + verify(mNotificationBuilder, times(2)).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager, times(2)).notify(anyInt(), any()); } @@ -356,7 +365,7 @@ public class OpenNetworkNotifierTest { mNotificationController.handleScanResults(mOpenNetworks); verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT)) @@ -389,7 +398,7 @@ public class OpenNetworkNotifierTest { verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); // Initial Notification - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mBroadcastReceiver.onReceive(mContext, @@ -421,7 +430,7 @@ public class OpenNetworkNotifierTest { verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); // Initial Notification - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mNotificationController.handleWifiConnected(); @@ -439,7 +448,7 @@ public class OpenNetworkNotifierTest { verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); // Initial Notification - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mBroadcastReceiver.onReceive(mContext, @@ -477,7 +486,7 @@ public class OpenNetworkNotifierTest { verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); // Initial Notification - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mBroadcastReceiver.onReceive(mContext, @@ -505,7 +514,7 @@ public class OpenNetworkNotifierTest { verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids); // Initial Notification - verify(mNotificationBuilder).createConnectToNetworkNotification(1); + verify(mNotificationBuilder).createConnectToNetworkNotification(mDummyNetwork); verify(mNotificationManager).notify(anyInt(), any()); mBroadcastReceiver.onReceive(mContext, diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java index cb1160cc1..6420fac88 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java @@ -637,18 +637,17 @@ public class WifiConnectivityManagerTest { } /** - * When wifi is connected, {@link OpenNetworkNotifier} tries to clear the pending - * notification and does not reset notification repeat delay. + * When wifi is connected, {@link OpenNetworkNotifier} handles the Wi-Fi connected behavior. * - * Expected behavior: ONA clears pending notification and does not reset repeat delay. + * Expected behavior: ONA handles connected behavior */ @Test - public void wifiConnected_openNetworkNotifierClearsPendingNotification() { + public void wifiConnected_openNetworkNotifierHandlesConnection() { // Set WiFi to connected state mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_CONNECTED); - verify(mOpenNetworkNotifier).clearPendingNotification(false /* resetRepeatDelay*/); + verify(mOpenNetworkNotifier).handleWifiConnected(); } /** |