diff options
3 files changed, 173 insertions, 13 deletions
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 6019b0e9ed9e..91e46cbf34fe 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -3025,6 +3025,8 @@ <string name="wifi_empty_list_wifi_on">Searching for networks\u2026</string> <!-- Provider Model: Failure notification for connect --> <string name="wifi_failed_connect_message">Failed to connect to network</string> + <!-- Provider Model: Toast message for when the user selects cellular as the internet provider and Wi-Fi auto-connect is temporarily disabled [CHAR LIMIT=60]--> + <string name="wifi_wont_autoconnect_for_now">Wi\u2011Fi won\u2019t auto-connect for now</string> <!-- Provider Model: Title to see all the networks [CHAR LIMIT=50] --> <string name="see_all_networks">See all</string> <!-- Summary for warning to disconnect ethernet first then switch to other networks. [CHAR LIMIT=60] --> diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java index 66d9c5558c2f..25de6f0fc4fa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java @@ -19,11 +19,16 @@ package com.android.systemui.qs.tiles.dialog; import static com.android.settingslib.mobile.MobileMappings.getIconKey; import static com.android.settingslib.mobile.MobileMappings.mapIconSets; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Color; +import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; @@ -32,6 +37,7 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.wifi.WifiManager; import android.os.Handler; +import android.os.UserHandle; import android.provider.Settings; import android.telephony.AccessNetworkConstants; import android.telephony.NetworkRegistrationInfo; @@ -45,7 +51,8 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.view.Gravity; -import android.widget.Toast; +import android.view.View; +import android.view.WindowManager; import androidx.annotation.MainThread; import androidx.annotation.NonNull; @@ -71,6 +78,8 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.AccessPointController; +import com.android.systemui.toast.SystemUIToast; +import com.android.systemui.toast.ToastFactory; import com.android.systemui.util.settings.GlobalSettings; import com.android.wifitrackerlib.MergedCarrierEntry; import com.android.wifitrackerlib.WifiEntry; @@ -133,8 +142,16 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, private GlobalSettings mGlobalSettings; private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private ConnectivityManager.NetworkCallback mConnectivityManagerNetworkCallback; + private WindowManager mWindowManager; + private ToastFactory mToastFactory; @VisibleForTesting + static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f; + @VisibleForTesting + static final float TOAST_PARAMS_VERTICAL_WEIGHT = 1.0f; + @VisibleForTesting + static final long SHORT_DURATION_TIMEOUT = 4000; + @VisibleForTesting protected ActivityStarter mActivityStarter; @VisibleForTesting protected SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangedListener; @@ -173,7 +190,8 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, @Nullable WifiManager wifiManager, ConnectivityManager connectivityManager, @Main Handler handler, @Main Executor mainExecutor, BroadcastDispatcher broadcastDispatcher, KeyguardUpdateMonitor keyguardUpdateMonitor, - GlobalSettings globalSettings, KeyguardStateController keyguardStateController) { + GlobalSettings globalSettings, KeyguardStateController keyguardStateController, + WindowManager windowManager, ToastFactory toastFactory) { if (DEBUG) { Log.d(TAG, "Init InternetDialogController"); } @@ -196,6 +214,8 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, mConfig = MobileMappings.Config.readConfig(mContext); mWifiIconInjector = new WifiUtils.InternetIconInjector(mContext); mConnectivityManagerNetworkCallback = new DataConnectivityListener(); + mWindowManager = windowManager; + mToastFactory = toastFactory; } void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) { @@ -580,7 +600,8 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, final MergedCarrierEntry mergedCarrierEntry = mAccessPointController.getMergedCarrierEntry(); if (mergedCarrierEntry != null && mergedCarrierEntry.canConnect()) { - mergedCarrierEntry.connect(null /* ConnectCallback */); + mergedCarrierEntry.connect(null /* ConnectCallback */, false); + makeOverlayToast(R.string.wifi_wont_autoconnect_for_now); } } @@ -729,20 +750,20 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, Log.d(TAG, "connect to unsaved network " + ap.getTitle()); } } - ap.connect(new WifiEntryConnectCallback(mActivityStarter, mContext, ap)); + ap.connect(new WifiEntryConnectCallback(mActivityStarter, ap, this)); return false; } static class WifiEntryConnectCallback implements WifiEntry.ConnectCallback { final ActivityStarter mActivityStarter; - final Context mContext; final WifiEntry mWifiEntry; + final InternetDialogController mInternetDialogController; - WifiEntryConnectCallback(ActivityStarter activityStarter, Context context, - WifiEntry connectWifiEntry) { + WifiEntryConnectCallback(ActivityStarter activityStarter, WifiEntry connectWifiEntry, + InternetDialogController internetDialogController) { mActivityStarter = activityStarter; - mContext = context; mWifiEntry = connectWifiEntry; + mInternetDialogController = internetDialogController; } @Override @@ -757,8 +778,7 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mActivityStarter.startActivity(intent, false /* dismissShade */); } else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) { - Toast.makeText(mContext, R.string.wifi_failed_connect_message, - Toast.LENGTH_SHORT).show(); + mInternetDialogController.makeOverlayToast(R.string.wifi_failed_connect_message); } else { if (DEBUG) { Log.d(TAG, "connect failure reason=" + status); @@ -967,4 +987,57 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries, @Nullable WifiEntry connectedEntry); } + + void makeOverlayToast(int stringId) { + final Resources res = mContext.getResources(); + + final SystemUIToast systemUIToast = mToastFactory.createToast(mContext, + res.getString(stringId), mContext.getPackageName(), UserHandle.myUserId(), + res.getConfiguration().orientation); + if (systemUIToast == null) { + return; + } + + View toastView = systemUIToast.getView(); + + final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); + params.height = WindowManager.LayoutParams.WRAP_CONTENT; + params.width = WindowManager.LayoutParams.WRAP_CONTENT; + params.format = PixelFormat.TRANSLUCENT; + params.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; + params.y = systemUIToast.getYOffset(); + + int absGravity = Gravity.getAbsoluteGravity(systemUIToast.getGravity(), + res.getConfiguration().getLayoutDirection()); + params.gravity = absGravity; + if ((absGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { + params.horizontalWeight = TOAST_PARAMS_HORIZONTAL_WEIGHT; + } + if ((absGravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { + params.verticalWeight = TOAST_PARAMS_VERTICAL_WEIGHT; + } + + mWindowManager.addView(toastView, params); + + Animator inAnimator = systemUIToast.getInAnimation(); + if (inAnimator != null) { + inAnimator.start(); + } + + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + Animator outAnimator = systemUIToast.getOutAnimation(); + if (outAnimator != null) { + outAnimator.start(); + outAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animator) { + mWindowManager.removeViewImmediate(toastView); + } + }); + } + } + }, SHORT_DURATION_TIMEOUT); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java index 18f48a36100c..b270a7f90d94 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java @@ -1,21 +1,28 @@ package com.android.systemui.qs.tiles.dialog; +import static com.android.systemui.qs.tiles.dialog.InternetDialogController.TOAST_PARAMS_HORIZONTAL_WEIGHT; +import static com.android.systemui.qs.tiles.dialog.InternetDialogController.TOAST_PARAMS_VERTICAL_WEIGHT; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.animation.Animator; import android.content.Context; import android.content.Intent; +import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; @@ -25,7 +32,15 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.testing.TestableResources; import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.TextView; +import android.view.Gravity; +import android.view.View; +import android.view.WindowManager; import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; @@ -41,14 +56,19 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.AccessPointController; +import com.android.systemui.toast.SystemUIToast; +import com.android.systemui.toast.ToastFactory; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.settings.GlobalSettings; import com.android.systemui.util.time.FakeSystemClock; +import com.android.wifitrackerlib.MergedCarrierEntry; import com.android.wifitrackerlib.WifiEntry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -65,6 +85,11 @@ public class InternetDialogControllerTest extends SysuiTestCase { private static final String CONNECTED_TITLE = "Connected Wi-Fi Title"; private static final String CONNECTED_SUMMARY = "Connected Wi-Fi Summary"; + //SystemUIToast + private static final int GRAVITY_FLAGS = Gravity.FILL_HORIZONTAL | Gravity.FILL_VERTICAL; + private static final int TOAST_MESSAGE_STRING_ID = 1; + private static final String TOAST_MESSAGE_STRING = "toast message"; + @Mock private WifiManager mWifiManager; @Mock @@ -92,6 +117,8 @@ public class InternetDialogControllerTest extends SysuiTestCase { @Mock private WifiEntry mWifiEntry4; @Mock + private MergedCarrierEntry mMergedCarrierEntry; + @Mock private ServiceState mServiceState; @Mock private BroadcastDispatcher mBroadcastDispatcher; @@ -99,7 +126,18 @@ public class InternetDialogControllerTest extends SysuiTestCase { private WifiUtils.InternetIconInjector mWifiIconInjector; @Mock InternetDialogController.InternetDialogCallback mInternetDialogCallback; + @Mock + private WindowManager mWindowManager; + @Mock + private ToastFactory mToastFactory; + @Mock + private SystemUIToast mSystemUIToast; + @Mock + private View mToastView; + @Mock + private Animator mAnimator; + private TestableResources mTestableResources; private MockInternetDialogController mInternetDialogController; private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); private List<WifiEntry> mAccessPoints = new ArrayList<>(); @@ -108,6 +146,7 @@ public class InternetDialogControllerTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); + mTestableResources = mContext.getOrCreateTestableResources(); doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt()); when(mKeyguardStateController.isUnlocked()).thenReturn(true); when(mConnectedEntry.isDefaultNetwork()).thenReturn(true); @@ -119,12 +158,19 @@ public class InternetDialogControllerTest extends SysuiTestCase { mAccessPoints.add(mConnectedEntry); mAccessPoints.add(mWifiEntry1); when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{SUB_ID}); + when(mAccessPointController.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry); + when(mToastFactory.createToast(any(), anyString(), anyString(), anyInt(), anyInt())) + .thenReturn(mSystemUIToast); + when(mSystemUIToast.getView()).thenReturn(mToastView); + when(mSystemUIToast.getGravity()).thenReturn(GRAVITY_FLAGS); + when(mSystemUIToast.getInAnimation()).thenReturn(mAnimator); mInternetDialogController = new MockInternetDialogController(mContext, mock(UiEventLogger.class), mock(ActivityStarter.class), mAccessPointController, mSubscriptionManager, mTelephonyManager, mWifiManager, mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher, - mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController); + mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController, + mWindowManager, mToastFactory); mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor, mInternetDialogController.mOnSubscriptionsChangedListener); mInternetDialogController.onStart(mInternetDialogCallback, true); @@ -134,6 +180,44 @@ public class InternetDialogControllerTest extends SysuiTestCase { } @Test + public void connectCarrierNetwork_mergedCarrierEntryCanConnect_connectAndCreateSysUiToast() { + when(mMergedCarrierEntry.canConnect()).thenReturn(true); + mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now, + TOAST_MESSAGE_STRING); + + mInternetDialogController.connectCarrierNetwork(); + + verify(mMergedCarrierEntry).connect(null /* callback */, false /* showToast */); + verify(mToastFactory).createToast(any(), eq(TOAST_MESSAGE_STRING), anyString(), anyInt(), + anyInt()); + } + + @Test + public void makeOverlayToast_withGravityFlags_addViewWithLayoutParams() { + mTestableResources.addOverride(TOAST_MESSAGE_STRING_ID, TOAST_MESSAGE_STRING); + + mInternetDialogController.makeOverlayToast(TOAST_MESSAGE_STRING_ID); + + ArgumentCaptor<WindowManager.LayoutParams> paramsCaptor = ArgumentCaptor.forClass( + WindowManager.LayoutParams.class); + verify(mWindowManager).addView(eq(mToastView), paramsCaptor.capture()); + WindowManager.LayoutParams params = paramsCaptor.getValue(); + assertThat(params.format).isEqualTo(PixelFormat.TRANSLUCENT); + assertThat(params.type).isEqualTo(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL); + assertThat(params.horizontalWeight).isEqualTo(TOAST_PARAMS_HORIZONTAL_WEIGHT); + assertThat(params.verticalWeight).isEqualTo(TOAST_PARAMS_VERTICAL_WEIGHT); + } + + @Test + public void makeOverlayToast_withAnimation_verifyAnimatorStart() { + mTestableResources.addOverride(TOAST_MESSAGE_STRING_ID, TOAST_MESSAGE_STRING); + + mInternetDialogController.makeOverlayToast(TOAST_MESSAGE_STRING_ID); + + verify(mAnimator).start(); + } + + @Test public void getDialogTitleText_withAirplaneModeOn_returnAirplaneMode() { mInternetDialogController.setAirplaneModeEnabled(true); @@ -506,11 +590,12 @@ public class InternetDialogControllerTest extends SysuiTestCase { @Main Handler handler, @Main Executor mainExecutor, BroadcastDispatcher broadcastDispatcher, KeyguardUpdateMonitor keyguardUpdateMonitor, GlobalSettings globalSettings, - KeyguardStateController keyguardStateController) { + KeyguardStateController keyguardStateController, WindowManager windowManager, + ToastFactory toastFactory) { super(context, uiEventLogger, starter, accessPointController, subscriptionManager, telephonyManager, wifiManager, connectivityManager, handler, mainExecutor, broadcastDispatcher, keyguardUpdateMonitor, globalSettings, - keyguardStateController); + keyguardStateController, windowManager, toastFactory); mGlobalSettings = globalSettings; } |