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

Commit f4ee4ef3 authored by Antony Sargent's avatar Antony Sargent
Browse files

Add page listing multiple mobile networks

When a device supports simultaneous connection to multiple mobile
networks, we want the "Mobile network" entry on the Network & internet
page to list the number of active SIMs and when clicked, go to a page
that lists them all.

Bug: 116349402
Test: make RunSettingsRoboTests
Change-Id: Ie642d7801cda07dcbbe74d42c234db6605566be4
parent de324b9b
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -10320,6 +10320,34 @@
    <!-- Mobile network settings screen, title of Mobile data switch preference [CHAR LIMIT=NONE] -->
    <string name="mobile_data_settings_summary">Access data using mobile network</string>
    <!-- Summary of the 'Mobile network' item on the Network & internet page when there is no mobile
         service setup yet (eg no SIM card inserted and no eSIM configured). Tapping it leads to a
         UI where the user can setup service. [CHAR LIMIT=50] -->
    <string name="mobile_network_summary_add_a_network">Add a network</string>
    <!-- Summary of the 'Mobile network' item on the Network & internet page when there is more than
         one mobile service configured (aka "dual SIM") - it shows a count of SIM/eSIM and tapping
         it leads to a page showing a list of the mobile service subscriptions. [CHAR LIMIT=40] -->
    <plurals name="mobile_network_summary_count">
        <item quantity="one"><xliff:g id="count" example="1">%1$d</xliff:g> SIM</item>
        <item quantity="other"><xliff:g id="count" example="2">%1$d</xliff:g> SIMs</item>
    </plurals>
    <!-- Title of item shown at the bottom of the page listing multiple mobile service
         subscriptions; tapping it leads to a UI to add more [CHAR LIMIT=40] -->
    <string name="mobile_network_list_add_more">Add more</string>
    <!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
         that service is active and is tied to a physical SIM card [CHAR LIMIT=40] -->
    <string name="mobile_network_active_sim">Active SIM</string>
    <!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
         that service is inactive and is tied to a physical SIM card [CHAR LIMIT=40] -->
    <string name="mobile_network_inactive_sim">Inactive SIM</string>
    <!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
         that service is active and is tied to an eSIM profile [CHAR LIMIT=40] -->
    <string name="mobile_network_active_esim">Active eSIM</string>
    <!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
         that service is inactive and is tied to an eSIM profile [CHAR LIMIT=40] -->
    <string name="mobile_network_inactive_esim">Inactive eSIM</string>
    <!-- Title for preferred network type [CHAR LIMIT=NONE] -->
    <string name="preferred_network_mode_title">Preferred network type</string>
    <!-- Summary for preferred network type [CHAR LIMIT=NONE] -->
+28 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="mobile_network_list_screen"
    android:title="@string/network_settings_title">

    <Preference
        android:key="add_more"
        android:title="@string/mobile_network_list_add_more"
        android:icon="@drawable/ic_menu_add"
        android:order="100" />

</PreferenceScreen>
+2 −3
Original line number Diff line number Diff line
@@ -40,15 +40,14 @@
    </com.android.settings.widget.MasterSwitchPreference>

    <com.android.settingslib.RestrictedPreference
        android:key="mobile_network_settings"
        android:key="mobile_network_list"
        android:title="@string/network_settings_title"
        android:summary="@string/summary_placeholder"
        android:icon="@drawable/ic_network_cell"
        android:order="-15"
        settings:keywords="@string/keywords_more_mobile_networks"
        settings:userRestriction="no_config_mobile_networks"
        settings:useAdminDisabledSummary="true">
    </com.android.settingslib.RestrictedPreference>
        settings:useAdminDisabledSummary="true" />

    <com.android.settingslib.RestrictedSwitchPreference
        android:key="toggle_airplane"
+149 −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.network;

import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;

import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.util.ArrayMap;

import com.android.settings.R;
import com.android.settings.network.telephony.MobileNetworkActivity;
import com.android.settingslib.core.AbstractPreferenceController;

import java.util.List;
import java.util.Map;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

/**
 * This populates the entries on a page which lists all available mobile subscriptions. Each entry
 * has the name of the subscription with some subtext giving additional detail, and clicking on the
 * entry brings you to a details page for that network.
 */
public class MobileNetworkListController extends AbstractPreferenceController implements
        LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
    private static final String TAG = "MobileNetworkListCtlr";

    private SubscriptionManager mSubscriptionManager;
    private SubscriptionsChangeListener mChangeListener;
    private PreferenceScreen mPreferenceScreen;
    private Map<Integer, Preference> mPreferences;

    public MobileNetworkListController(Context context, Lifecycle lifecycle) {
        super(context);
        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
        mChangeListener = new SubscriptionsChangeListener(context, this);
        mPreferences = new ArrayMap<>();
        lifecycle.addObserver(this);
    }

    @OnLifecycleEvent(ON_RESUME)
    public void onResume() {
        mChangeListener.start();
        update();
    }

    @OnLifecycleEvent(ON_PAUSE)
    public void onPause() {
        mChangeListener.stop();
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreferenceScreen = screen;
        update();
    }

    private void update() {
        if (mPreferenceScreen == null) {
            return;
        }

        // Since we may already have created some preferences previously, we first grab the list of
        // those, then go through the current available subscriptions making sure they are all
        // present in the screen, and finally remove any now-outdated ones.
        final Map<Integer, Preference> existingPreferences = mPreferences;
        mPreferences = new ArrayMap<>();

        final List<SubscriptionInfo> subscriptions = SubscriptionUtil.getAvailableSubscriptions(
                mSubscriptionManager);
        for (SubscriptionInfo info : subscriptions) {
            int subId = info.getSubscriptionId();
            Preference pref = existingPreferences.remove(subId);
            if (pref == null) {
                pref = new Preference(mPreferenceScreen.getContext());
                mPreferenceScreen.addPreference(pref);
            }
            pref.setTitle(info.getDisplayName());

            if (info.isEmbedded()) {
                if (mSubscriptionManager.isActiveSubscriptionId(subId)) {
                    pref.setSummary(R.string.mobile_network_active_esim);
                } else {
                    pref.setSummary(R.string.mobile_network_inactive_esim);
                }
            } else {
                if (mSubscriptionManager.isActiveSubscriptionId(subId)) {
                    pref.setSummary(R.string.mobile_network_active_sim);
                } else {
                    pref.setSummary(R.string.mobile_network_inactive_sim);
                }
            }

            pref.setOnPreferenceClickListener(clickedPref -> {
                final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
                intent.putExtra(Settings.EXTRA_SUB_ID, info.getSubscriptionId());
                mContext.startActivity(intent);
                return true;
            });
            mPreferences.put(subId, pref);
        }
        for (Preference pref : existingPreferences.values()) {
            mPreferenceScreen.removePreference(pref);
        }
    }

    @Override
    public boolean isAvailable() {
        return true;
    }

    @Override
    public String getPreferenceKey() {
        return null;
    }

    @Override
    public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
    }

    @Override
    public void onSubscriptionsChanged() {
        update();
    }
}
+71 −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.network;

import android.content.Context;
import android.provider.SearchIndexableResource;

import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable;

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

@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class MobileNetworkListFragment extends DashboardFragment {
    private static final String LOG_TAG = "NetworkListFragment";

    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.mobile_network_list;
    }

    @Override
    protected String getLogTag() {
        return LOG_TAG;
    }

    @Override
    public int getMetricsCategory() {
        // TODO(asargent) - return SettingsEnums.MOBILE_NETWORK_LIST once the CL defining it has
        // landed.
        return 0;
    }

    @Override
    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
        final List<AbstractPreferenceController> controllers = new ArrayList<>();
        controllers.add(new MobileNetworkListController(getContext(), getLifecycle()));
        return controllers;
    }

    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider() {
                @Override
                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
                        boolean enabled) {
                    final ArrayList<SearchIndexableResource> result = new ArrayList<>();
                    final SearchIndexableResource sir = new SearchIndexableResource(context);
                    sir.xmlResId = R.xml.mobile_network_list;
                    result.add(sir);
                    return result;
                }
            };
}
Loading