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

Commit 01b63327 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix problem of multiple stacked copies of "Select SIM" dialog" into qt-dev

parents e128d27a a7dc2774
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -2692,9 +2692,11 @@
            android:excludeFromRecents="true"
            android:exported="false" />

        <activity android:name=".sim.SimDialogActivity"
        <activity
            android:name=".sim.SimDialogActivity"
            android:theme="@style/Theme.AlertDialog"
            android:label="@string/sim_settings_title"
            android:launchMode="singleTop"
            android:excludeFromRecents="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
+59 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.content.Context;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;

import java.util.ArrayList;
import java.util.List;

/**
 * Specialized version of SimListDialogFragment that fetches a list of SIMs which support calls.
 */
public class CallsSimListDialogFragment extends SimListDialogFragment {
    @Override
    protected List<SubscriptionInfo> getCurrentSubscriptions() {
        final Context context = getContext();
        final SubscriptionManager subscriptionManager = context.getSystemService(
                SubscriptionManager.class);
        final TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
        final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
        final List<PhoneAccountHandle> phoneAccounts =
                telecomManager.getCallCapablePhoneAccounts();
        final List<SubscriptionInfo> result = new ArrayList<>();

        if (phoneAccounts == null) {
            return result;
        }
        for (PhoneAccountHandle handle : phoneAccounts) {
            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
            final int subId = telephonyManager.getSubIdForPhoneAccount(phoneAccount);

            if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
                continue;
            }
            result.add(subscriptionManager.getActiveSubscriptionInfo(subId));
        }
        return result;
    }
}
+101 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;

import com.android.settings.R;

/**
 * Presents a dialog asking the user if they want to update all services to use a given "preferred"
 * SIM. Typically this would be used in a case where a device goes from having multiple SIMs down to
 * only one.
 */
public class PreferredSimDialogFragment extends SimDialogFragment implements
        DialogInterface.OnClickListener {
    private static final String TAG = "PreferredSimDialogFrag";

    public static PreferredSimDialogFragment newInstance() {
        final PreferredSimDialogFragment fragment = new PreferredSimDialogFragment();
        final Bundle args = initArguments(SimDialogActivity.PREFERRED_PICK,
                R.string.sim_preferred_title);
        fragment.setArguments(args);
        return fragment;
    }

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

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

    public SubscriptionInfo getPreferredSubscription() {
        final Activity activity = getActivity();
        final int slotId = activity.getIntent().getIntExtra(SimDialogActivity.PREFERRED_SIM,
                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        return getSubscriptionManager().getActiveSubscriptionInfoForSimSlotIndex(slotId);
    }

    private void updateDialog(AlertDialog dialog) {
        final SubscriptionInfo info = getPreferredSubscription();
        if (info == null) {
            dismiss();
            return;
        }
        final String message =
                getContext().getString(R.string.sim_preferred_message, info.getDisplayName());
        dialog.setMessage(message);
    }

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

    @VisibleForTesting
    protected SubscriptionManager getSubscriptionManager() {
        return getContext().getSystemService(SubscriptionManager.class);
    }
}
+93 −258
Original line number Diff line number Diff line
@@ -16,37 +16,30 @@

package com.android.settings.sim;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.content.Intent;
import android.os.Bundle;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.util.Log;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import com.android.settings.R;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class SimDialogActivity extends Activity {
/**
 * This activity provides singleton semantics per dialog type for showing various kinds of
 * dialogs asking the user to make choices about which SIM to use for various services
 * (calls, SMS, and data).
 */
public class SimDialogActivity extends FragmentActivity {
    private static String TAG = "SimDialogActivity";

    public static String PREFERRED_SIM = "preferred_sim";
@@ -60,276 +53,118 @@ public class SimDialogActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final int dialogType = getIntent().getIntExtra(DIALOG_TYPE_KEY, INVALID_PICK);

        switch (dialogType) {
            case DATA_PICK:
            case CALLS_PICK:
            case SMS_PICK:
                createDialog(this, dialogType).show();
                break;
            case PREFERRED_PICK:
                displayPreferredDialog(getIntent().getIntExtra(PREFERRED_SIM, 0));
                break;
            default:
                throw new IllegalArgumentException("Invalid dialog type " + dialogType + " sent.");
        }

        showOrUpdateDialog();
    }

    private void displayPreferredDialog(final int slotId) {
        final Resources res = getResources();
        final Context context = getApplicationContext();
        final SubscriptionInfo sir = SubscriptionManager.from(context)
                .getActiveSubscriptionInfoForSimSlotIndex(slotId);

        if (sir != null) {
            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
            alertDialogBuilder.setTitle(R.string.sim_preferred_title);
            alertDialogBuilder.setMessage(res.getString(
                        R.string.sim_preferred_message, sir.getDisplayName()));

            alertDialogBuilder.setPositiveButton(R.string.yes, new
                    DialogInterface.OnClickListener() {
    @Override
                public void onClick(DialogInterface dialog, int id) {
                    final int subId = sir.getSubscriptionId();
                    PhoneAccountHandle phoneAccountHandle =
                            subscriptionIdToPhoneAccountHandle(subId);
                    setDefaultDataSubId(context, subId);
                    setDefaultSmsSubId(context, subId);
                    setUserSelectedOutgoingPhoneAccount(phoneAccountHandle);
                    finish();
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        showOrUpdateDialog();
    }
            });
            alertDialogBuilder.setNegativeButton(R.string.no, new
                    DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog,int id) {
                    finish();
                }
            });

            alertDialogBuilder.create().show();
        } else {
            finish();
        }
    }
    private void showOrUpdateDialog() {
        final int dialogType = getIntent().getIntExtra(DIALOG_TYPE_KEY, INVALID_PICK);
        final String tag = Integer.toString(dialogType);
        final FragmentManager fragmentManager = getSupportFragmentManager();
        SimDialogFragment fragment = (SimDialogFragment) fragmentManager.findFragmentByTag(tag);

    private static void setDefaultDataSubId(final Context context, final int subId) {
        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
        final TelephonyManager telephonyManager = TelephonyManager.from(context)
                .createForSubscriptionId(subId);
        subscriptionManager.setDefaultDataSubId(subId);
        telephonyManager.setDataEnabled(true);
        Toast.makeText(context, R.string.data_switch_started, Toast.LENGTH_LONG).show();
        if (fragment == null) {
            fragment = createFragment(dialogType);
            fragment.show(fragmentManager, tag);
        } else {
            fragment.updateDialog();
        }

    private static void setDefaultSmsSubId(final Context context, final int subId) {
        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
        subscriptionManager.setDefaultSmsSubId(subId);
    }

    private void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle phoneAccount) {
        final TelecomManager telecomManager = TelecomManager.from(this);
        telecomManager.setUserSelectedOutgoingPhoneAccount(phoneAccount);
    private SimDialogFragment createFragment(int dialogType) {
        switch(dialogType) {
            case DATA_PICK:
                return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data,
                        false /* includeAskEveryTime */);
            case CALLS_PICK:
                return CallsSimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_calls,
                        true /* includeAskEveryTime */);
            case SMS_PICK:
                return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms,
                        false /* includeAskEveryTime */);
            case PREFERRED_PICK:
                if (!getIntent().hasExtra(PREFERRED_SIM)) {
                    throw new IllegalArgumentException("Missing required extra " + PREFERRED_SIM);
                }

    private PhoneAccountHandle subscriptionIdToPhoneAccountHandle(final int subId) {
        final TelecomManager telecomManager = TelecomManager.from(this);
        final TelephonyManager telephonyManager = TelephonyManager.from(this);
        final Iterator<PhoneAccountHandle> phoneAccounts =
                telecomManager.getCallCapablePhoneAccounts().listIterator();

        while (phoneAccounts.hasNext()) {
            final PhoneAccountHandle phoneAccountHandle = phoneAccounts.next();
            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(phoneAccountHandle);
            if (subId == telephonyManager.getSubIdForPhoneAccount(phoneAccount)) {
                return phoneAccountHandle;
                return PreferredSimDialogFragment.newInstance();
            default:
                throw new IllegalArgumentException( "Invalid dialog type " + dialogType + " sent.");
        }
    }

        return null;
    public void onSubscriptionSelected(int dialogType, int subId) {
        if (getSupportFragmentManager().findFragmentByTag(Integer.toString(dialogType)) == null) {
            Log.w(TAG, "onSubscriptionSelected ignored because stored fragment was null");
            return;
        }

    public Dialog createDialog(final Context context, final int id) {
        final ArrayList<String> list = new ArrayList<String>();
        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
        final List<SubscriptionInfo> subInfoList =
            subscriptionManager.getActiveSubscriptionInfoList(true);
        final int selectableSubInfoLength = subInfoList == null ? 0 : subInfoList.size();

        final DialogInterface.OnClickListener selectionListener =
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int value) {

                        final SubscriptionInfo sir;

                        switch (id) {
        switch (dialogType) {
            case DATA_PICK:
                                sir = subInfoList.get(value);
                                setDefaultDataSubId(context, sir.getSubscriptionId());
                setDefaultDataSubId(subId);
                break;
            case CALLS_PICK:
                                final TelecomManager telecomManager =
                                        TelecomManager.from(context);
                                final List<PhoneAccountHandle> phoneAccountsList =
                                        telecomManager.getCallCapablePhoneAccounts();
                                setUserSelectedOutgoingPhoneAccount(
                                        value < 1 ? null : phoneAccountsList.get(value - 1));
                setDefaultCallsSubId(subId);
                break;
            case SMS_PICK:
                                sir = subInfoList.get(value);
                                setDefaultSmsSubId(context, sir.getSubscriptionId());
                setDefaultSmsSubId(subId);
                break;
            case PREFERRED_PICK:
                setPreferredSim(subId);
                break;
            default:
                                throw new IllegalArgumentException("Invalid dialog type "
                                        + id + " in SIM dialog.");
                throw new IllegalArgumentException(
                        "Invalid dialog type " + dialogType + " sent.");
        }

                        finish();
    }
                };

        Dialog.OnKeyListener keyListener = new Dialog.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface arg0, int keyCode,
                    KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        finish();
                    }
                    return true;
                }
            };

        ArrayList<SubscriptionInfo> callsSubInfoList = new ArrayList<SubscriptionInfo>();
        if (id == CALLS_PICK) {
            final TelecomManager telecomManager = TelecomManager.from(context);
            final TelephonyManager telephonyManager = TelephonyManager.from(context);
            final Iterator<PhoneAccountHandle> phoneAccounts =
                    telecomManager.getCallCapablePhoneAccounts().listIterator();

            list.add(getResources().getString(R.string.sim_calls_ask_first_prefs_title));
            callsSubInfoList.add(null);
            while (phoneAccounts.hasNext()) {
                final PhoneAccount phoneAccount =
                        telecomManager.getPhoneAccount(phoneAccounts.next());
                list.add((String)phoneAccount.getLabel());
                int subId = telephonyManager.getSubIdForPhoneAccount(phoneAccount);
                if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
                    final SubscriptionInfo sir = SubscriptionManager.from(context)
                            .getActiveSubscriptionInfo(subId);
                    callsSubInfoList.add(sir);
                } else {
                    callsSubInfoList.add(null);
    public void onFragmentDismissed(SimDialogFragment simDialogFragment) {
        final List<Fragment> fragments = getSupportFragmentManager().getFragments();
        if (fragments.size() == 1 && fragments.get(0) == simDialogFragment) {
            finishAndRemoveTask();
        }
    }
        } else {
            for (int i = 0; i < selectableSubInfoLength; ++i) {
                final SubscriptionInfo sir = subInfoList.get(i);
                CharSequence displayName = sir.getDisplayName();
                if (displayName == null) {
                    displayName = "";
                }
                list.add(displayName.toString());
            }
        }

        String[] arr = list.toArray(new String[0]);

        AlertDialog.Builder builder = new AlertDialog.Builder(context);

        ListAdapter adapter = new SelectAccountListAdapter(
                id == CALLS_PICK ? callsSubInfoList : subInfoList,
                builder.getContext(),
                R.layout.select_account_list_item,
                arr, id);

        switch (id) {
            case DATA_PICK:
                builder.setTitle(R.string.select_sim_for_data);
                break;
            case CALLS_PICK:
                builder.setTitle(R.string.select_sim_for_calls);
                break;
            case SMS_PICK:
                builder.setTitle(R.string.select_sim_for_sms);
                break;
            default:
                throw new IllegalArgumentException("Invalid dialog type "
                        + id + " in SIM dialog.");
    private void setDefaultDataSubId(final int subId) {
        final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
        final TelephonyManager telephonyManager = getSystemService(
                TelephonyManager.class).createForSubscriptionId(subId);
        subscriptionManager.setDefaultDataSubId(subId);
        telephonyManager.setDataEnabled(true);
        Toast.makeText(this, R.string.data_switch_started, Toast.LENGTH_LONG).show();
    }

        Dialog dialog = builder.setAdapter(adapter, selectionListener).create();
        dialog.setOnKeyListener(keyListener);

        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialogInterface) {
                finish();
    private void setDefaultCallsSubId(final int subId) {
        final PhoneAccountHandle phoneAccount = subscriptionIdToPhoneAccountHandle(subId);
        final TelecomManager telecomManager = getSystemService(TelecomManager.class);
        telecomManager.setUserSelectedOutgoingPhoneAccount(phoneAccount);
    }
        });

        return dialog;

    private void setDefaultSmsSubId(final int subId) {
        final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
        subscriptionManager.setDefaultSmsSubId(subId);
    }

    private class SelectAccountListAdapter extends ArrayAdapter<String> {
        private Context mContext;
        private int mResId;
        private int mDialogId;
        private final float OPACITY = 0.54f;
        private List<SubscriptionInfo> mSubInfoList;

        public SelectAccountListAdapter(List<SubscriptionInfo> subInfoList,
                Context context, int resource, String[] arr, int dialogId) {
            super(context, resource, arr);
            mContext = context;
            mResId = resource;
            mDialogId = dialogId;
            mSubInfoList = subInfoList;
    private void setPreferredSim(final int subId) {
        setDefaultDataSubId(subId);
        setDefaultSmsSubId(subId);
        setDefaultCallsSubId(subId);
    }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater)
                    mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View rowView;
            final ViewHolder holder;

            if (convertView == null) {
                // Cache views for faster scrolling
                rowView = inflater.inflate(mResId, null);
                holder = new ViewHolder();
                holder.title = (TextView) rowView.findViewById(R.id.title);
                holder.summary = (TextView) rowView.findViewById(R.id.summary);
                holder.icon = (ImageView) rowView.findViewById(R.id.icon);
                rowView.setTag(holder);
            } else {
                rowView = convertView;
                holder = (ViewHolder) rowView.getTag();
            }
    private PhoneAccountHandle subscriptionIdToPhoneAccountHandle(final int subId) {
        final TelecomManager telecomManager = getSystemService(TelecomManager.class);
        final TelephonyManager telephonyManager = getSystemService(TelephonyManager.class);

            final SubscriptionInfo sir = mSubInfoList.get(position);
            if (sir == null) {
                holder.title.setText(getItem(position));
                holder.summary.setText("");
                holder.icon.setImageDrawable(getResources()
                        .getDrawable(R.drawable.ic_live_help));
                holder.icon.setAlpha(OPACITY);
            } else {
                holder.title.setText(sir.getDisplayName());
                holder.summary.setText(sir.getNumber());
                holder.icon.setImageBitmap(sir.createIconBitmap(mContext));
        for (PhoneAccountHandle handle : telecomManager.getCallCapablePhoneAccounts()) {
            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
            if (subId == telephonyManager.getSubIdForPhoneAccount(phoneAccount)) {
                return handle;
            }
            return rowView;
        }

        private class ViewHolder {
            TextView title;
            TextView summary;
            ImageView icon;
        }
        return null;
    }
}
+57 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading