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

Commit 928b9904 authored by Ling Ma's avatar Ling Ma Committed by Android (Google) Code Review
Browse files

Merge "Add dialog for enable auto data switch"

parents 1b1a394b d6b117fc
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -2398,6 +2398,13 @@
    <!-- Message for the dialog asking to user to change the preferred SIM  [CHAR LIMIT=NONE] -->
    <string name="sim_preferred_message"><xliff:g id="new_sim">%1$s</xliff:g> is the only SIM in your device. Do you want to use this SIM for mobile data, calls, and SMS messages?</string>
    <!-- Title for the dialog asking to user to enable auto data switch upon enabling multi-SIM  [CHAR LIMIT=30] -->
    <string name="enable_auto_data_switch_dialog_title">Switch SIMs automatically?</string>
    <!-- Message for the dialog asking to user to change the preferred SIM  [CHAR LIMIT=NONE] -->
    <string name="enable_auto_data_switch_dialog_message">Allow your phone to automatically switch to <xliff:g id="backup_carrier" example="T-mobile">%1$s</xliff:g> for mobile data when it has better availability.</string>
    <!-- Message for the dialog asking to user to change the preferred SIM  [CHAR LIMIT=NONE] -->
    <string name="auto_data_switch_dialog_managed_profile_warning">\n\nCalls, messages, and network traffic may be visible to your organization.</string>
    <!-- Instructions telling the user that they entered the wrong SIM PIN for the last time.
         Displayed in a dialog box.  [CHAR LIMIT=100] -->
    <string name="wrong_pin_code_pukked">Incorrect SIM PIN code you must now contact your carrier to unlock your device.</string>
+209 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.sim;

import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
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.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;

import com.android.settings.R;
import com.android.settings.network.SubscriptionUtil;

import java.util.List;

/**
 * Show a dialog prompting the user to enable auto data switch following the dialog where user chose
 * default data SIM.
 */
public class EnableAutoDataSwitchDialogFragment extends SimDialogFragment implements
        DialogInterface.OnClickListener {
    private static final String TAG = "EnableAutoDataSwitchDialogFragment";
    /** Sub Id of the non-default data SIM */
    private int mBackupDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;

    /** @return a new instance of this fragment */
    public static EnableAutoDataSwitchDialogFragment newInstance() {
        final EnableAutoDataSwitchDialogFragment fragment =
                new EnableAutoDataSwitchDialogFragment();
        final Bundle args = initArguments(SimDialogActivity.ENABLE_AUTO_DATA_SWITCH,
                R.string.enable_auto_data_switch_dialog_title);
        fragment.setArguments(args);
        return fragment;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        final AlertDialog dialog = new AlertDialog.Builder(getContext())
                .setPositiveButton(R.string.yes, this)
                .setNegativeButton(R.string.sim_action_no_thanks, null)
                .create();
        updateDialog(dialog);
        return dialog;
    }

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

    /** update dialog */
    public void updateDialog(AlertDialog dialog) {
        Log.d(TAG, "Dialog updated, dismiss status: " + mWasDismissed);

        if (mWasDismissed) {
            return;
        }

        if (dialog == null) {
            Log.d(TAG, "Dialog is null.");
            dismiss();
            return;
        }

        // Set message
        View content = LayoutInflater.from(getContext()).inflate(
                R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null);
        TextView dialogMessage = content != null ? content.findViewById(R.id.msg) : null;
        final String message = getMessage();
        if (TextUtils.isEmpty(message) || dialogMessage == null) {
            onDismiss(dialog);
            return;
        }
        dialogMessage.setText(message);
        dialogMessage.setVisibility(View.VISIBLE);
        dialog.setView(content);

        // Set title
        View titleView = LayoutInflater.from(getContext()).inflate(
                R.layout.sim_confirm_dialog_title_multiple_enabled_profiles_supported, null);
        TextView titleTextView = titleView.findViewById(R.id.title);
        titleTextView.setText(getContext().getString(getTitleResId()));
        dialog.setCustomTitle(titleTextView);
    }

    /**
     * @return The message of the dialog. {@code null} if the dialog shouldn't be displayed.
     */
    @VisibleForTesting
    protected String getMessage() {
        int ddsSubId = getDefaultDataSubId();
        if (ddsSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) return null;
        Log.d(TAG, "DDS SubId: " + ddsSubId);

        SubscriptionManager subscriptionManager = getSubscriptionManager();
        List<SubscriptionInfo> activeSubscriptions  = subscriptionManager
                .getActiveSubscriptionInfoList();
        if (activeSubscriptions == null) return null;

        // Find if a backup data sub exists.
        SubscriptionInfo backupSubInfo = activeSubscriptions.stream()
                .filter(subInfo -> subInfo.getSubscriptionId() != ddsSubId)
                .findFirst()
                .orElse(null);
        if (backupSubInfo == null) return null;
        mBackupDataSubId = backupSubInfo.getSubscriptionId();

        // Check if auto data switch is already enabled
        final TelephonyManager telephonyManager = getTelephonyManagerForSub(mBackupDataSubId);
        if (telephonyManager == null) {
            Log.d(TAG, "telephonyManager for " + mBackupDataSubId + " is null");
            return null;
        }
        if (telephonyManager.isMobileDataPolicyEnabled(
                TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)) {
            Log.d(TAG, "AUTO_DATA_SWITCH already enabled");
            return null;
        }

        Log.d(TAG, "Backup data sub Id: " + mBackupDataSubId);
        // The description of the feature
        String message =
                getContext().getString(
                        R.string.enable_auto_data_switch_dialog_message,
                        SubscriptionUtil.getUniqueSubscriptionDisplayName(
                                backupSubInfo, getContext()));
        UserManager userManager = getUserManager();
        if (userManager == null) return message;

        // If one of the sub is dedicated to work profile(enterprise-managed), which means we might
        // switching between personal & work profile, append a warning to the message.
        UserHandle ddsUserHandle = subscriptionManager.getSubscriptionUserHandle(ddsSubId);
        UserHandle nDdsUserHandle = subscriptionManager.getSubscriptionUserHandle(mBackupDataSubId);
        boolean isDdsManaged = ddsUserHandle != null && userManager.isManagedProfile(
                ddsUserHandle.getIdentifier());
        boolean isNDdsManaged = nDdsUserHandle != null && userManager.isManagedProfile(
                nDdsUserHandle.getIdentifier());
        Log.d(TAG, "isDdsManaged= " + isDdsManaged + " isNDdsManaged=" + isNDdsManaged);
        if (isDdsManaged ^ isNDdsManaged) {
            message += getContext().getString(
                    R.string.auto_data_switch_dialog_managed_profile_warning);
        }

        return message;
    }

    @Override
    public void updateDialog() {
        updateDialog((AlertDialog) getDialog());
    }

    @Override
    public void onClick(DialogInterface dialog, int buttonClicked) {
        if (buttonClicked != DialogInterface.BUTTON_POSITIVE) {
            return;
        }
        final SimDialogActivity activity = (SimDialogActivity) getActivity();
        if (mBackupDataSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            activity.onSubscriptionSelected(getDialogType(), mBackupDataSubId);
        }
    }

    private TelephonyManager getTelephonyManagerForSub(int subId) {
        return getContext().getSystemService(TelephonyManager.class)
                .createForSubscriptionId(subId);
    }

    private SubscriptionManager getSubscriptionManager() {
        return getContext().getSystemService(SubscriptionManager.class);
    }

    @VisibleForTesting
    protected int getDefaultDataSubId() {
        return SubscriptionManager.getDefaultDataSubscriptionId();
    }

    private UserManager getUserManager() {
        return getContext().getSystemService(UserManager.class);
    }
}
+23 −6
Original line number Diff line number Diff line
@@ -72,16 +72,33 @@ public class SelectSpecificDataSimDialogFragment extends SimDialogFragment imple
    }

    @Override
    public void onClick(DialogInterface dialog, int buttonClicked) {
        if (buttonClicked != DialogInterface.BUTTON_POSITIVE) {
            return;
    public void onDismiss(@NonNull DialogInterface dialog) {
        Log.d(TAG, "Dialog onDismiss, dismiss status: " + mWasDismissed);
        if (!mWasDismissed) {
            // This dialog might be called onDismiss twice due to first time called by onDismiss()
            // as a consequence of user action. We need this fragment alive so the activity
            // doesn't end, which allows the following dialog to attach. Upon the second dialog
            // dismiss, this fragment is removed from SimDialogActivity.onFragmentDismissed to
            // end the activity.
            mWasDismissed = true;
            final SimDialogActivity activity = (SimDialogActivity) getActivity();
            activity.showEnableAutoDataSwitchDialog();
            // Not using super.onDismiss because it will result in an immediate end of the activity,
            // before the second auto data switch dialog can attach.
            if (getDialog() != null) getDialog().dismiss();
        }
    }

    @Override
    public void onClick(DialogInterface dialog, int buttonClicked) {
        final SimDialogActivity activity = (SimDialogActivity) getActivity();
        if (buttonClicked == DialogInterface.BUTTON_POSITIVE) {
            final SubscriptionInfo info = getTargetSubscriptionInfo();
            if (info != null) {
                activity.onSubscriptionSelected(getDialogType(), info.getSubscriptionId());
            }
        }
    }

    private SubscriptionInfo getNonDefaultDataSubscriptionInfo(SubscriptionInfo dds) {
        List<SubscriptionInfo> subInfos = getSubscriptionManager().getActiveSubscriptionInfoList();
+34 −6
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.settings.sim;

import static android.content.Context.MODE_PRIVATE;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -61,6 +59,8 @@ public class SimDialogActivity extends FragmentActivity {
    public static final int SMS_PICK_FOR_MESSAGE = 4;
    // Dismiss the current dialog and finish the activity.
    public static final int PICK_DISMISS = 5;
    // Show auto data switch dialog(when user enables multi-SIM)
    public static final int ENABLE_AUTO_DATA_SWITCH = 6;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
@@ -122,7 +122,7 @@ public class SimDialogActivity extends FragmentActivity {
    private SimDialogFragment createFragment(int dialogType) {
        switch (dialogType) {
            case DATA_PICK:
                return getDataPickDialogFramgent();
                return getDataPickDialogFragment();
            case CALLS_PICK:
                return CallsSimListDialogFragment.newInstance(dialogType,
                        R.string.select_sim_for_calls,
@@ -141,12 +141,14 @@ public class SimDialogActivity extends FragmentActivity {
                return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms,
                        false /* includeAskEveryTime */,
                        false /* isCancelItemShowed */);
            case ENABLE_AUTO_DATA_SWITCH:
                return EnableAutoDataSwitchDialogFragment.newInstance();
            default:
                throw new IllegalArgumentException("Invalid dialog type " + dialogType + " sent.");
        }
    }

    private SimDialogFragment getDataPickDialogFramgent() {
    private SimDialogFragment getDataPickDialogFragment() {
        if (SubscriptionManager.getDefaultDataSubscriptionId()
                == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            return SimListDialogFragment.newInstance(DATA_PICK, R.string.select_sim_for_data,
@@ -181,15 +183,40 @@ public class SimDialogActivity extends FragmentActivity {
                intent.putExtra(RESULT_SUB_ID, subId);
                setResult(Activity.RESULT_OK, intent);
                break;
            case ENABLE_AUTO_DATA_SWITCH:
                onEnableAutoDataSwitch(subId);
                break;
            default:
                throw new IllegalArgumentException(
                        "Invalid dialog type " + dialogType + " sent.");
        }
    }

    /**
     * Show dialog prompting the user to enable auto data switch
     */
    public void showEnableAutoDataSwitchDialog() {
        final FragmentManager fragmentManager = getSupportFragmentManager();
        SimDialogFragment fragment = createFragment(ENABLE_AUTO_DATA_SWITCH);
        fragment.show(fragmentManager, Integer.toString(ENABLE_AUTO_DATA_SWITCH));
    }

    /**
     * @param subId The sub Id to enable auto data switch
     */
    public void onEnableAutoDataSwitch(int subId) {
        Log.d(TAG, "onEnableAutoDataSwitch subId:" + subId);
        final TelephonyManager telephonyManager = getSystemService(
                TelephonyManager.class).createForSubscriptionId(subId);
        telephonyManager.setMobileDataPolicyEnabled(
                TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, true);
    }

    public void onFragmentDismissed(SimDialogFragment simDialogFragment) {
        final List<Fragment> fragments = getSupportFragmentManager().getFragments();
        if (fragments.size() == 1 && fragments.get(0) == simDialogFragment) {
        if (fragments.size() == 1 && fragments.get(0) == simDialogFragment
                || simDialogFragment.getDialogType() == ENABLE_AUTO_DATA_SWITCH) {
            Log.d(TAG, "onFragmentDismissed dialogType:" + simDialogFragment.getDialogType());
            finishAndRemoveTask();
        }
    }
@@ -200,7 +227,8 @@ public class SimDialogActivity extends FragmentActivity {
                TelephonyManager.class).createForSubscriptionId(subId);
        subscriptionManager.setDefaultDataSubId(subId);
        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            telephonyManager.setDataEnabled(true);
            telephonyManager.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER,
                    true);
            Toast.makeText(this, R.string.data_switch_started, Toast.LENGTH_LONG).show();
        }
    }
+4 −2
Original line number Diff line number Diff line
@@ -109,16 +109,18 @@ public class SimListDialogFragment extends SimDialogFragment {
     * @param selectionIndex the index of item in the list.
     */
    public void onClick(int selectionIndex) {
        final SimDialogActivity activity = (SimDialogActivity) getActivity();
        if (selectionIndex >= 0 && selectionIndex < mSubscriptions.size()) {
            int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
            final SubscriptionInfo subscription = mSubscriptions.get(selectionIndex);
            if (subscription != null) {
                subId = subscription.getSubscriptionId();
            }
            final SimDialogActivity activity = (SimDialogActivity) getActivity();
            activity.onSubscriptionSelected(getDialogType(), subId);
        }
        dismiss();
        Log.d(TAG, "Start showing auto data switch dialog");
        activity.showEnableAutoDataSwitchDialog();
        if (getDialog() != null) getDialog().dismiss();
    }

    protected List<SubscriptionInfo> getCurrentSubscriptions() {
Loading