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

Commit 3c26c93b authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add new dialogue when user is going to delete multiple sims where...

Merge "Add new dialogue when user is going to delete multiple sims where aleast on of them use RAC." into main
parents e9ee2c66 9ac44b3a
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import androidx.preference.Preference;

import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.system.ResetDashboardFragment;

@@ -51,7 +50,12 @@ public class EraseEuiccDataController extends BasePreferenceController {
        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
            return false;
        }
        if (SubscriptionUtil.hasSubscriptionWithRacCarrier(mContext)
                && !SubscriptionUtil.isConnectedToWifi(mContext)) {
            EuiccRacConnectivityDialogFragment.show(mHostFragment);
        } else {
            EraseEuiccDataDialogFragment.show(mHostFragment);
        }
        return true;
    }

+115 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.network;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.system.ResetDashboardFragment;

public class EuiccRacConnectivityDialogFragment extends InstrumentedDialogFragment
        implements DialogInterface.OnClickListener {
    public static final String TAG = "EuiccRacConnectivityDlg";

    static void show(ResetDashboardFragment host) {
        final EuiccRacConnectivityDialogFragment dialog = new EuiccRacConnectivityDialogFragment();
        dialog.setTargetFragment(host, /* requestCode= */ 0);
        final FragmentManager manager = host.getActivity().getSupportFragmentManager();
        dialog.show(manager, TAG);
    }

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.RESET_EUICC;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        String title = getString(R.string.wifi_warning_dialog_title);
        String message = getString(R.string.wifi_warning_dialog_text);

        AlertDialog.Builder builder =
                new AlertDialog.Builder(getContext())
                        .setOnDismissListener(this)
                        // Return is on the right side
                        .setPositiveButton(R.string.wifi_warning_return_button, null)
                        // Continue is on the left side
                        .setNegativeButton(R.string.wifi_warning_continue_button, this);

        View content =
                LayoutInflater.from(getContext())
                        .inflate(R.layout.sim_warning_dialog_wifi_connectivity, null);

        // Found the layout resource
        if (content != null) {
            TextView dialogTitle = content.findViewById(R.id.title);
            if (!TextUtils.isEmpty(title) && dialogTitle != null) {
                dialogTitle.setText(title);
                dialogTitle.setVisibility(View.VISIBLE);
            }
            TextView dialogMessage = content.findViewById(R.id.msg);
            if (!TextUtils.isEmpty(message) && dialogMessage != null) {
                dialogMessage.setText(message);
                dialogMessage.setVisibility(View.VISIBLE);
            }

            builder.setView(content);
        } else { // Not found the layout resource, use standard layout
            if (!TextUtils.isEmpty(title)) {
                builder.setTitle(title);
            }
            if (!TextUtils.isEmpty(message)) {
                builder.setMessage(message);
            }
        }

        AlertDialog dialog = builder.create();
        dialog.setCanceledOnTouchOutside(false);
        return dialog;
    }

    @Override
    public void onClick(@NonNull DialogInterface dialog, int which) {
        final Fragment fragment = getTargetFragment();
        if (!(fragment instanceof ResetDashboardFragment)) {
            Log.e(TAG, "getTargetFragment return unexpected type");
            return;
        }

        // Positions of the buttons have been switch:
        // negative button = left button = the button to continue
        if (which == DialogInterface.BUTTON_NEGATIVE) {
            EraseEuiccDataDialogFragment.show(((ResetDashboardFragment) fragment));
        }
    }
}
+70 −21
Original line number Diff line number Diff line
@@ -523,20 +523,21 @@ public class SubscriptionUtil {

    /**
     * Starts a dialog activity to handle eSIM deletion.
     *
     * @param context {@code Context}
     * @param subId The id of subscription need to be deleted.
     * @param carrierId The carrier id of the subscription.
     */
    public static void startDeleteEuiccSubscriptionDialogActivity(Context context, int subId,
            int carrierId) {
    public static void startDeleteEuiccSubscriptionDialogActivity(
            @NonNull Context context, int subId, int carrierId) {
        if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
            Log.i(TAG, "Unable to delete subscription due to invalid subscription ID.");
            return;
        }
        final int[] carriersThatUseRAC = context.getResources().getIntArray(
                R.array.config_carrier_use_rac);
        boolean isCarrierRac = Arrays.stream(carriersThatUseRAC).anyMatch(cid -> cid == carrierId);

        if (isCarrierRac && !isConnectedToWifiOrDifferentSubId(context, subId)) {
        if (isCarrierRac(context, carrierId)
                && (!isConnectedToWifi(context)
                        || isConnectedToMobileDataWithDifferentSubId(context, subId))) {
            context.startActivity(EuiccRacConnectivityDialogActivity.getIntent(context, subId));
        } else {
            context.startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(context, subId));
@@ -814,27 +815,75 @@ public class SubscriptionUtil {
    }

    /**
     * Returns {@code true} if device is connected to Wi-Fi or mobile data provided by a different
     * subId.
     * Checks if the device is connected to Wi-Fi.
     *
     * @param context context
     * @return {@code true} if connected to Wi-Fi
     */
    static boolean isConnectedToWifi(@NonNull Context context) {
        NetworkCapabilities capabilities = getNetworkCapabilities(context);

        return capabilities != null
                && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
    }

    /**
     * Checks if the device is connected to mobile data provided by a different subId.
     *
     * @param context context
     * @param targetSubId subscription that is going to be deleted
     * @return {@code true} if connected to mobile data provided by a different subId
     */
    @VisibleForTesting
    static boolean isConnectedToWifiOrDifferentSubId(@NonNull Context context, int targetSubId) {
        ConnectivityManager connectivityManager =
                context.getSystemService(ConnectivityManager.class);
        NetworkCapabilities capabilities =
                connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
    static boolean isConnectedToMobileDataWithDifferentSubId(
            @NonNull Context context, int targetSubId) {
        NetworkCapabilities capabilities = getNetworkCapabilities(context);

        if (capabilities != null) {
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                // Connected to WiFi
                return true;
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                return targetSubId != SubscriptionManager.getActiveDataSubscriptionId();
        return capabilities != null
                && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                && targetSubId != SubscriptionManager.getActiveDataSubscriptionId();
    }

    /**
     * Checks if any subscription carrier use reusable activation codes.
     *
     * @param context The context used to retrieve carriers that uses reusable activation codes.
     * @return {@code true} if any subscription has a matching carrier that uses reusable activation
     *     codes
     */
    static boolean hasSubscriptionWithRacCarrier(@NonNull Context context) {
        List<SubscriptionInfo> subs = getAvailableSubscriptions(context);
        final int[] carriersThatUseRac =
                context.getResources().getIntArray(R.array.config_carrier_use_rac);

        return Arrays.stream(carriersThatUseRac)
                .anyMatch(cid -> subs.stream().anyMatch(sub -> sub.getCarrierId() == cid));
    }
        return false;

    /**
     * Checks if a carrier use reusable activation codes.
     *
     * @param context The context used to retrieve carriers that uses reusable activation codes.
     * @param carrierId The carrier id to check if it use reusable activation codes.
     * @return {@code true} if carrier id use reusable activation codes.
     */
    @VisibleForTesting
    static boolean isCarrierRac(@NonNull Context context, int carrierId) {
        final int[] carriersThatUseRAC =
                context.getResources().getIntArray(R.array.config_carrier_use_rac);

        return Arrays.stream(carriersThatUseRAC).anyMatch(cid -> cid == carrierId);
    }

    /**
     * Retrieves NetworkCapabilities for the active network.
     *
     * @param context context
     * @return NetworkCapabilities or null if not available
     */
    private static NetworkCapabilities getNetworkCapabilities(@NonNull Context context) {
        ConnectivityManager connectivityManager =
                context.getSystemService(ConnectivityManager.class);
        return connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
    }
}
+7 −7
Original line number Diff line number Diff line
@@ -16,11 +16,11 @@

package com.android.settings.network;

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;

import android.content.Context;
@@ -59,19 +59,19 @@ public class SubscriptionUtilRoboTest {
    }

    @Test
    public void isConnectedToWifiOrDifferentSubId_hasDataOnSubId2_returnTrue() {
    public void isConnectedToMobileDataWithDifferentSubId_hasDataOnSubId2_returnTrue() {
        addNetworkTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        mShadowSubscriptionManager.setActiveDataSubscriptionId(SUBID_2);

        assertTrue(SubscriptionUtil.isConnectedToWifiOrDifferentSubId(mContext, SUBID_1));
        assertTrue(SubscriptionUtil.isConnectedToMobileDataWithDifferentSubId(mContext, SUBID_1));
    }

    @Test
    public void isConnectedToWifiOrDifferentSubId_hasDataOnSubId1_returnFalse() {
    public void isConnectedToMobileDataWithDifferentSubId_hasDataOnSubId1_returnFalse() {
        addNetworkTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        mShadowSubscriptionManager.setActiveDataSubscriptionId(SUBID_1);

        assertFalse(SubscriptionUtil.isConnectedToWifiOrDifferentSubId(mContext, SUBID_1));
        assertFalse(SubscriptionUtil.isConnectedToMobileDataWithDifferentSubId(mContext, SUBID_1));
    }

    private void addNetworkTransportType(int networkType) {
+43 −6
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -65,6 +66,9 @@ public class SubscriptionUtilTest {
    private static final CharSequence CARRIER_1 = "carrier1";
    private static final CharSequence CARRIER_1_SPACE = " carrier1       ";
    private static final CharSequence CARRIER_2 = "carrier2";
    private static final int RAC_CARRIER_ID = 1;
    private static final int NO_RAC_CARRIER_ID = 2;
    private static final int[] CARRIERS_THAT_USE_RAC = {RAC_CARRIER_ID};

    private Context mContext;
    private NetworkCapabilities mNetworkCapabilities;
@@ -81,6 +85,7 @@ public class SubscriptionUtilTest {
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = spy(ApplicationProvider.getApplicationContext());
        when(mContext.getResources()).thenReturn(mResources);
        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubMgr);
        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelMgr);
        when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
@@ -109,6 +114,40 @@ public class SubscriptionUtilTest {
        assertThat(subs).hasSize(1);
    }

    @Test
    public void hasSubscriptionWithRacCarrier_containsRac_returnTrue() {
        when(mResources.getIntArray(anyInt())).thenReturn(CARRIERS_THAT_USE_RAC);
        final SubscriptionInfo info = mock(SubscriptionInfo.class);
        when(info.getCarrierId()).thenReturn(RAC_CARRIER_ID);
        when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info));

        assertTrue(SubscriptionUtil.hasSubscriptionWithRacCarrier(mContext));
    }

    @Test
    public void hasSubscriptionWithRacCarrier_doesNotContainsRac_returnFalse() {
        when(mResources.getIntArray(anyInt())).thenReturn(CARRIERS_THAT_USE_RAC);
        final SubscriptionInfo info = mock(SubscriptionInfo.class);
        when(info.getCarrierId()).thenReturn(NO_RAC_CARRIER_ID);
        when(mSubMgr.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info));

        assertFalse(SubscriptionUtil.hasSubscriptionWithRacCarrier(mContext));
    }

    @Test
    public void isCarrierRac_returnTrue() {
        when(mResources.getIntArray(anyInt())).thenReturn(CARRIERS_THAT_USE_RAC);

        assertTrue(SubscriptionUtil.isCarrierRac(mContext, RAC_CARRIER_ID));
    }

    @Test
    public void isCarrierRac_returnFalse() {
        when(mResources.getIntArray(anyInt())).thenReturn(CARRIERS_THAT_USE_RAC);

        assertFalse(SubscriptionUtil.isCarrierRac(mContext, NO_RAC_CARRIER_ID));
    }

    @Ignore
    @Test
    public void getAvailableSubscriptions_twoSubscriptions_twoResults() {
@@ -526,7 +565,6 @@ public class SubscriptionUtilTest {

    @Test
    public void isSimHardwareVisible_configAsInvisible_returnFalse() {
        when(mContext.getResources()).thenReturn(mResources);
        when(mResources.getBoolean(R.bool.config_show_sim_info))
                .thenReturn(false);

@@ -535,7 +573,6 @@ public class SubscriptionUtilTest {

    @Test
    public void isSimHardwareVisible_configAsVisible_returnTrue() {
        when(mContext.getResources()).thenReturn(mResources);
        when(mResources.getBoolean(R.bool.config_show_sim_info))
                .thenReturn(true);

@@ -599,17 +636,17 @@ public class SubscriptionUtilTest {
    }

    @Test
    public void isConnectedToWifiOrDifferentSubId_hasWiFi_returnTrue() {
    public void isConnectedToWifi_hasWiFi_returnTrue() {
        addNetworkTransportType(NetworkCapabilities.TRANSPORT_WIFI);

        assertTrue(SubscriptionUtil.isConnectedToWifiOrDifferentSubId(mContext, SUBID_1));
        assertTrue(SubscriptionUtil.isConnectedToWifi(mContext));
    }

    @Test
    public void isConnectedToWifiOrDifferentSubId_noData_and_noWiFi_returnFalse() {
    public void isConnectedToWifi_noWiFi_returnFalse() {
        addNetworkTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH);

        assertFalse(SubscriptionUtil.isConnectedToWifiOrDifferentSubId(mContext, SUBID_1));
        assertFalse(SubscriptionUtil.isConnectedToWifi(mContext));
    }

    private void addNetworkTransportType(int networkType) {