Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df4ed63c authored by changbetty's avatar changbetty
Browse files

Customize the Toast for Internet Dialog

Bug: 192923855
Test: Manual Test
Test: atest -c InternetDialogControllerTest
`

Change-Id: I9747eb39265d7d32be2f213c0e96a954658824a8
parent 509c8c26
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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] -->
+83 −10
Original line number Diff line number Diff line
@@ -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,7 +142,15 @@ 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
@@ -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);
    }
}
+88 −3
Original line number Diff line number Diff line
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);
@@ -133,6 +179,44 @@ public class InternetDialogControllerTest extends SysuiTestCase {
        mInternetDialogController.mWifiIconInjector = mWifiIconInjector;
    }

    @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;
        }