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

Commit f3d3be52 authored by Betty Chang's avatar Betty Chang Committed by Android (Google) Code Review
Browse files

Merge "Customize the Toast for Internet Dialog" into sc-qpr1-dev

parents 0287b472 df4ed63c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3027,6 +3027,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;
        }