Merge "Add dispatcher activity to forward privileged euicc intents." am: 0cad33a5bc
am: 6c1f9973df
Change-Id: I1e0b704a9415ec9dca3e5c1a4f862c33c422a0ad
diff --git a/res/layout/emergency_shortcut_buttons_group.xml b/res/layout/emergency_shortcut_buttons_group.xml
index 54563c9..7911f30 100644
--- a/res/layout/emergency_shortcut_buttons_group.xml
+++ b/res/layout/emergency_shortcut_buttons_group.xml
@@ -77,4 +77,4 @@
android:divider="@drawable/emergency_shortcuts_divider"
android:showDividers="middle">
</LinearLayout>
-</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index cce7ebc..bf152c9 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -245,7 +245,7 @@
<string name="data_usage_title" msgid="8759619109516889802">"Data usage"</string>
<string name="data_usage_template" msgid="8526428824844656364">"<xliff:g id="ID_1">%1$s</xliff:g> mobile data used <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="advanced_options_title" msgid="8074895510265488035">"Advanced"</string>
- <string name="carrier_settings_euicc" msgid="6714062862127226405">"Operator"</string>
+ <string name="carrier_settings_euicc" msgid="6714062862127226405">"Carrier"</string>
<string name="keywords_carrier_settings_euicc" msgid="6861505396475991277">"operator, esim, sim, euicc, switch operators, add operator"</string>
<string name="carrier_settings_euicc_summary" msgid="5115001942761995457">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> — <xliff:g id="PHONE_NUMBER">%2$s</xliff:g>"</string>
<string name="mobile_data_settings_title" msgid="4661165467914727157">"Mobile data"</string>
diff --git a/src/com/android/phone/ecc/CountryEccInfo.java b/src/com/android/phone/ecc/CountryEccInfo.java
deleted file mode 100644
index 969901d..0000000
--- a/src/com/android/phone/ecc/CountryEccInfo.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2018 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.phone.ecc;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.Collection;
-
-/**
- * ECC info of a country.
- */
-public class CountryEccInfo {
- private final String mFallbackEcc;
- private final EccInfo[] mEccInfoList;
-
- public CountryEccInfo(String eccFallback, @NonNull Collection<EccInfo> eccInfoList) {
- mFallbackEcc = eccFallback;
- mEccInfoList = eccInfoList.toArray(new EccInfo[eccInfoList.size()]);
- }
-
- /**
- * @return fallback ECC, null if not available.
- */
- public @Nullable String getFallbackEcc() {
- return mFallbackEcc;
- }
-
- public @NonNull EccInfo[] getEccInfoList() {
- return mEccInfoList.clone();
- }
-}
diff --git a/src/com/android/phone/ecc/EccInfo.java b/src/com/android/phone/ecc/EccInfo.java
deleted file mode 100644
index fb41370..0000000
--- a/src/com/android/phone/ecc/EccInfo.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 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.phone.ecc;
-
-import androidx.annotation.NonNull;
-
-import java.util.Collection;
-
-/**
- * Emergency call code info.
- */
-public class EccInfo {
- /**
- * ECC Types.
- */
- public enum Type {
- POLICE,
- AMBULANCE,
- FIRE,
- }
-
- private final String mNumber;
- private final Type[] mTypes;
-
- public EccInfo(@NonNull String number, @NonNull Type type) {
- mNumber = number;
- mTypes = new Type[]{ type };
- }
-
- public EccInfo(@NonNull String number, @NonNull Collection<Type> types) {
- mNumber = number;
- mTypes = types.toArray(new Type[types.size()]);
- }
-
- /**
- * @return ECC number.
- */
- public @NonNull String getNumber() {
- return mNumber;
- }
-
- /**
- * Check whether the ECC number has any matches to the target type.
- *
- * @param target The target type to check.
- * @return true if the target matches.
- */
- public boolean containsType(@NonNull Type target) {
- for (Type type : mTypes) {
- if (target.equals(type)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Get the types of the ECC number.
- *
- * @return Copied types array.
- */
- public Type[] getTypes() {
- return mTypes.clone();
- }
-
- /**
- * Get how many types the ECC number is.
- *
- * @return Count of types.
- */
- public int getTypesCount() {
- return mTypes.length;
- }
-}
diff --git a/src/com/android/phone/ecc/EccInfoHelper.java b/src/com/android/phone/ecc/EccInfoHelper.java
deleted file mode 100644
index c471c4b..0000000
--- a/src/com/android/phone/ecc/EccInfoHelper.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2018 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.phone.ecc;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import android.provider.Settings;
-import android.telephony.CellIdentityGsm;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityWcdma;
-import android.telephony.CellInfo;
-import android.telephony.CellInfoGsm;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoWcdma;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.telephony.MccTable;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Helper for retrieve ECC info for current country.
- */
-public class EccInfoHelper {
- // Debug constants.
- private static final boolean DBG = false;
- private static final String LOG_TAG = "EccInfoHelper";
-
- /**
- * Check if current CountryEccInfo is available for current environment.
- */
- public static boolean isCountryEccInfoAvailable(Context context, String countryIso) {
- CountryEccInfo countryEccInfo;
- try {
- countryEccInfo = IsoToEccProtobufRepository.getInstance()
- .getCountryEccInfo(context, countryIso);
- } catch (IOException e) {
- Log.e(LOG_TAG, "Failed to retrieve ECC: ", e);
- return false;
- }
-
- if (countryEccInfo == null) {
- return false;
- }
- for (EccInfo entry : countryEccInfo.getEccInfoList()) {
- if (!PhoneNumberUtils.isEmergencyNumber(entry.getNumber())) {
- // The CountryEccInfo is unavailable if any ecc number in the local table was
- // declined.
- return false;
- }
- }
- return true;
- }
-
- // country ISO to ECC list data source
- private IsoToEccRepository mEccRepo;
-
- /**
- * Callback for {@link #getCountryEccInfoAsync}.
- */
- public interface CountryEccInfoResultCallback {
- /**
- * Called if successfully get country ECC info.
- *
- * @param iso Detected current country ISO.
- * @param countryEccInfo The EccInfo of current country.
- */
- void onSuccess(@NonNull String iso, @NonNull CountryEccInfo countryEccInfo);
-
- /**
- * Called if failed to get country ISO.
- */
- void onDetectCountryFailed();
-
- /**
- * Called if failed to get ECC info for given country ISO.
- *
- * @param iso Detected current country ISO.
- */
- void onRetrieveCountryEccInfoFailed(@NonNull String iso);
- }
-
- /**
- * Constructor of EccInfoHelper
- *
- * @param eccRepository A repository for ECC info, indexed by country ISO.
- */
- public EccInfoHelper(@NonNull IsoToEccRepository eccRepository) {
- mEccRepo = eccRepository;
- }
-
- /**
- * Get ECC info for current location, base on detected country ISO.
- * It's possible we cannot detect current country, ex. device is in airplane mode,
- * or there's no available base station near by.
- *
- * @param context The context used to access resources.
- * @param callback Callback for result.
- */
- public void getCountryEccInfoAsync(final @NonNull Context context,
- final CountryEccInfoResultCallback callback) {
- new AsyncTask<Void, Void, Pair<String, CountryEccInfo>>() {
- @Override
- protected Pair<String, CountryEccInfo> doInBackground(Void... voids) {
- String iso = getCurrentCountryIso(context);
- if (TextUtils.isEmpty(iso)) {
- return null;
- }
-
- CountryEccInfo dialableCountryEccInfo;
- try {
- // access data source in background thread to avoid possible file IO caused ANR.
- CountryEccInfo rawEccInfo = mEccRepo.getCountryEccInfo(context, iso);
- dialableCountryEccInfo = getDialableCountryEccInfo(rawEccInfo);
- } catch (IOException e) {
- Log.e(LOG_TAG, "Failed to retrieve ECC: " + e.getMessage());
- dialableCountryEccInfo = null;
- }
- return new Pair<>(iso, dialableCountryEccInfo);
- }
-
- @Override
- protected void onPostExecute(Pair<String, CountryEccInfo> result) {
- if (callback != null) {
- if (result == null) {
- callback.onDetectCountryFailed();
- } else {
- String iso = result.first;
- CountryEccInfo countryEccInfo = result.second;
- if (countryEccInfo == null) {
- callback.onRetrieveCountryEccInfoFailed(iso);
- } else {
- callback.onSuccess(iso, countryEccInfo);
- }
- }
- }
- }
- }.execute();
- }
-
- @NonNull
- private CountryEccInfo getDialableCountryEccInfo(CountryEccInfo countryEccInfo) {
- ArrayList<EccInfo> dialableECCList = new ArrayList<>();
- String dialableFallback = null;
-
- // filter out non-dialable ECC
- if (countryEccInfo != null) {
- for (EccInfo entry : countryEccInfo.getEccInfoList()) {
- if (PhoneNumberUtils.isEmergencyNumber(entry.getNumber())) {
- dialableECCList.add(entry);
- }
- }
- String defaultFallback = countryEccInfo.getFallbackEcc();
- if (PhoneNumberUtils.isEmergencyNumber(defaultFallback)) {
- dialableFallback = defaultFallback;
- }
- }
- return new CountryEccInfo(dialableFallback, dialableECCList);
- }
-
- @Nullable
- private String getCurrentCountryIso(@NonNull Context context) {
- // Do not detect country ISO if airplane mode is on
- int airplaneMode = Settings.System.getInt(context.getContentResolver(),
- Settings.Global.AIRPLANE_MODE_ON, 0);
- if (airplaneMode != 0) {
- Log.d(LOG_TAG, "Airplane mode is on, do not get country ISO.");
- return null;
- }
-
- TelephonyManager tm = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
- String iso = tm.getNetworkCountryIso();
- if (DBG) Log.d(LOG_TAG, "Current country ISO is " + Rlog.pii(LOG_TAG, iso));
-
- if (TextUtils.isEmpty(iso)) {
- // XXX: according to ServiceStateTracker's implementation, retrieve cell info in a
- // thread other than TelephonyManager's main thread.
- String mcc = getCurrentMccFromCellInfo(context);
- iso = MccTable.countryCodeForMcc(mcc);
- if (DBG) {
- Log.d(LOG_TAG, "Current mcc is " + Rlog.pii(LOG_TAG, mcc) + ", mapping to ISO: "
- + Rlog.pii(LOG_TAG, iso));
- }
- }
- return iso;
- }
-
- // XXX: According to ServiceStateTracker implementation, to actually get current cell info,
- // this method must be called in a separate thread from ServiceStateTracker, which is the
- // main thread of Telephony service.
- @Nullable
- private String getCurrentMccFromCellInfo(@NonNull Context context) {
- // retrieve mcc info from base station even no SIM present.
- TelephonyManager tm = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
- List<CellInfo> cellInfos = tm.getAllCellInfo();
- String mcc = null;
- if (cellInfos != null) {
- for (CellInfo ci : cellInfos) {
- if (ci instanceof CellInfoGsm) {
- CellInfoGsm cellInfoGsm = (CellInfoGsm) ci;
- CellIdentityGsm cellIdentityGsm = cellInfoGsm.getCellIdentity();
- mcc = cellIdentityGsm.getMccString();
- break;
- } else if (ci instanceof CellInfoWcdma) {
- CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) ci;
- CellIdentityWcdma cellIdentityWcdma = cellInfoWcdma.getCellIdentity();
- mcc = cellIdentityWcdma.getMccString();
- break;
- } else if (ci instanceof CellInfoLte) {
- CellInfoLte cellInfoLte = (CellInfoLte) ci;
- CellIdentityLte cellIdentityLte = cellInfoLte.getCellIdentity();
- mcc = cellIdentityLte.getMccString();
- break;
- }
- }
- if (DBG) Log.d(LOG_TAG, "Retrieve MCC from cell info list: " + Rlog.pii(LOG_TAG, mcc));
- } else {
- Log.w(LOG_TAG, "Cannot get cell info list.");
- }
- return mcc;
- }
-}
diff --git a/src/com/android/phone/ecc/IsoToEccProtobufRepository.java b/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
deleted file mode 100644
index 7d9b4f0..0000000
--- a/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2018 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.phone.ecc;
-
-import android.content.Context;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.zip.GZIPInputStream;
-
-/**
- * Provides a mapping table from country ISO to ECC info. The data is stored in Protocol Buffers
- * binary format, compressed with GZIP.
- */
-public class IsoToEccProtobufRepository implements IsoToEccRepository {
- private static final String LOG_TAG = "EccRepository";
-
- private static IsoToEccProtobufRepository sInstance;
-
- /**
- * Returns the singleton instance of IsoToEccProtobufRepository
- */
- public static synchronized IsoToEccProtobufRepository getInstance() {
- if (sInstance == null) {
- sInstance = new IsoToEccProtobufRepository();
- }
- return sInstance;
- }
-
- private final Map<String, CountryEccInfo> mEccTable = new HashMap<>();
-
- private IsoToEccProtobufRepository() {
- }
-
- @Override
- @Nullable
- public CountryEccInfo getCountryEccInfo(@NonNull Context context, String iso)
- throws IOException {
- if (TextUtils.isEmpty(iso)) {
- return null;
- }
-
- synchronized (mEccTable) {
- return mEccTable.get(iso.toUpperCase());
- }
- }
-
- /**
- * Loads the mapping table.
- */
- public void loadMappingTable(@NonNull Context context) {
- ProtobufEccData.AllInfo allEccData = null;
-
- long startTime = SystemClock.uptimeMillis();
- try {
- allEccData = parseEccData(new BufferedInputStream(
- context.getAssets().open("eccdata")));
- } catch (IOException e) {
- Log.e(LOG_TAG, "Failed to retrieve ECC: ", e);
- }
- long endTime = SystemClock.uptimeMillis();
-
- if (allEccData == null) {
- return;
- }
-
- if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
- Log.d(LOG_TAG, "Loading time = " + (endTime - startTime) + "ms"
- + ", Country Count = " + allEccData.getCountriesCount()
- + ", initialized = " + allEccData.isInitialized());
- }
-
- // Converts to run-time data from Protobuf data.
- synchronized (mEccTable) {
- mEccTable.clear();
- for (ProtobufEccData.CountryInfo countryData : allEccData.getCountriesList()) {
- if (countryData.hasIsoCode()) {
- CountryEccInfo countryInfo = loadCountryEccInfo(countryData);
- if (countryInfo != null) {
- mEccTable.put(countryData.getIsoCode().toUpperCase(), countryInfo);
- }
- }
- }
- }
- }
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- Map<String, CountryEccInfo> getEccTable() {
- return mEccTable;
- }
-
- private ProtobufEccData.AllInfo parseEccData(InputStream input) throws IOException {
- return ProtobufEccData.AllInfo.parseFrom(new GZIPInputStream(input));
- }
-
- private EccInfo loadEccInfo(String isoCode, ProtobufEccData.EccInfo eccData) {
- String phoneNumber = eccData.getPhoneNumber().trim();
- if (phoneNumber.isEmpty()) {
- Log.i(LOG_TAG, "Discard ecc " + phoneNumber
- + " for " + isoCode + " due to empty phone number");
- return null;
- }
-
- ArraySet<EccInfo.Type> eccTypes = new ArraySet<>(eccData.getTypesCount());
- for (ProtobufEccData.EccInfo.Type typeData : eccData.getTypesList()) {
- switch (typeData) {
- case POLICE:
- eccTypes.add(EccInfo.Type.POLICE);
- break;
- case AMBULANCE:
- eccTypes.add(EccInfo.Type.AMBULANCE);
- break;
- case FIRE:
- eccTypes.add(EccInfo.Type.FIRE);
- break;
- default:
- // Ignores unknown types.
- }
- }
-
- if (eccTypes.isEmpty()) {
- Log.i(LOG_TAG, "Discard ecc " + phoneNumber
- + " for " + isoCode + " due to no valid type");
- return null;
- }
- return new EccInfo(phoneNumber, eccTypes);
- }
-
- private CountryEccInfo loadCountryEccInfo(ProtobufEccData.CountryInfo countryData) {
- ArrayMap<String, EccInfo> eccInfoMap = new ArrayMap<>(countryData.getEccsCount());
- for (ProtobufEccData.EccInfo eccData : countryData.getEccsList()) {
- EccInfo eccInfo = loadEccInfo(countryData.getIsoCode(), eccData);
- String key = eccInfo.getNumber().trim();
- EccInfo existentEccInfo = eccInfoMap.get(key);
- if (existentEccInfo == null) {
- eccInfoMap.put(key, eccInfo);
- } else {
- // Merges types of duplicated ECC info objects.
- ArraySet<EccInfo.Type> eccTypes = new ArraySet<>(
- eccInfo.getTypesCount() + existentEccInfo.getTypesCount());
- for (EccInfo.Type type : eccInfo.getTypes()) {
- eccTypes.add(type);
- }
- for (EccInfo.Type type : existentEccInfo.getTypes()) {
- eccTypes.add(type);
- }
- eccInfoMap.put(key, new EccInfo(eccInfo.getNumber(), eccTypes));
- }
- }
-
- if (eccInfoMap.isEmpty() && !countryData.hasEccFallback()) {
- Log.i(LOG_TAG, "Discard empty data for " + countryData.getIsoCode());
- return null;
- }
- return new CountryEccInfo(countryData.getEccFallback(), eccInfoMap.values());
- }
-}
diff --git a/src/com/android/phone/ecc/IsoToEccRepository.java b/src/com/android/phone/ecc/IsoToEccRepository.java
deleted file mode 100644
index 6d95af4..0000000
--- a/src/com/android/phone/ecc/IsoToEccRepository.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2018 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.phone.ecc;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.io.IOException;
-
-/**
- * Data source for country ISO to ECC info list mapping.
- */
-public interface IsoToEccRepository {
- /**
- * Get available emergency numbers for given country ISO. Because the possible of IO wait
- * (depends on the implementation), this method should not be called in the main thread.
- *
- * @param context The context used to access resources.
- * @param iso For which ECC info list is returned.
- * @return The ECC info of given ISO. Null if no match.
- * @throws IOException if an error occurs while initialize the repository or retrieving
- * the {@link CountryEccInfo}.
- */
- @Nullable CountryEccInfo getCountryEccInfo(@NonNull Context context, @Nullable String iso)
- throws IOException;
-}