Compare commits

..

No commits in common. "aosp16" and "aosp15" have entirely different histories.

7 changed files with 0 additions and 272 deletions

View file

@ -1,19 +0,0 @@
//
// SPDX-FileCopyrightText: 2019 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
lineage_sdk_lib_src = "src/java/org/lineageos/lib/"
java_library {
name: "org.lineageos.lib.phone",
sdk_version: "current",
static_libs: [
"libphonenumber",
],
srcs: [
lineage_sdk_lib_src + "/phone/*.java",
":spn-info",
],
}

View file

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 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.
-->
<xs:schema version="2.0"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="sensitivePNS">
<xs:complexType>
<xs:sequence>
<xs:element name="sensitivePN" maxOccurs="unbounded" type="sensitivePN" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="sensitivePN">
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded" type="item" />
</xs:sequence>
<xs:attribute name="network" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="item">
<xs:sequence>
<xs:element name="number" type="xs:string" />
<xs:element name="name" minOccurs="0" type="xs:string" />
<xs:element name="categories" minOccurs="0" type="xs:string" />
<xs:element name="languages" minOccurs="0" type="xs:string" />
<xs:element name="organization" minOccurs="0" type="xs:string" />
<xs:element name="website" minOccurs="0" type="xs:anyURI" />
</xs:sequence>
</xs:complexType>
</xs:schema>

View file

@ -1,40 +0,0 @@
// Signature format: 2.0
package org.lineageos.lib.phone.spn {
public class Item {
ctor public Item();
method public String getCategories();
method public String getLanguages();
method public String getName();
method public String getNumber();
method public String getOrganization();
method public String getWebsite();
method public void setCategories(String);
method public void setLanguages(String);
method public void setName(String);
method public void setNumber(String);
method public void setOrganization(String);
method public void setWebsite(String);
}
public class SensitivePN {
ctor public SensitivePN();
method public java.util.List<org.lineageos.lib.phone.spn.Item> getItem();
method public String getNetwork();
method public void setNetwork(String);
}
public class SensitivePNS {
ctor public SensitivePNS();
method public java.util.List<org.lineageos.lib.phone.spn.SensitivePN> getSensitivePN();
}
public class XmlParser {
ctor public XmlParser();
method public static org.lineageos.lib.phone.spn.SensitivePNS read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
}
}

View file

@ -1 +0,0 @@
// Signature format: 2.0

View file

@ -1,165 +0,0 @@
/*
* SPDX-FileCopyrightText: 2017 The Android Open Source Project
* SPDX-FileCopyrightText: 2017-2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.lib.phone;
import android.content.Context;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
import com.google.i18n.phonenumbers.Phonenumber;
import org.lineageos.lib.phone.spn.Item;
import org.lineageos.lib.phone.spn.SensitivePN;
import org.lineageos.lib.phone.spn.XmlParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.xml.datatype.DatatypeConfigurationException;
public class SensitivePhoneNumbers {
private final String LOG_TAG = this.getClass().getSimpleName();
public static final String SENSIBLE_PHONENUMBERS_FILE_PATH = "/product/etc/sensitive_pn.xml";
private static final String ns = null;
private static SensitivePhoneNumbers sInstance = null;
private static boolean sNumbersLoaded;
private HashMap<String, ArrayList<Item>> mSensitiveNumbersMap = new HashMap<>();
private SensitivePhoneNumbers() { }
public static SensitivePhoneNumbers getInstance() {
if (sInstance == null) {
sInstance = new SensitivePhoneNumbers();
}
return sInstance;
}
private void loadSensiblePhoneNumbers() {
if (sNumbersLoaded) {
return;
}
File sensiblePNFile = new File(SENSIBLE_PHONENUMBERS_FILE_PATH);
FileInputStream sensiblePNInputStream;
try {
sensiblePNInputStream = new FileInputStream(sensiblePNFile);
} catch (FileNotFoundException e) {
Log.w(LOG_TAG, "Can not open " + sensiblePNFile.getAbsolutePath());
return;
}
try {
for (SensitivePN sensitivePN : new XmlParser().read(sensiblePNInputStream).getSensitivePN()) {
String[] mccs = sensitivePN.getNetwork().split(",");
for (String mcc : mccs) {
mSensitiveNumbersMap.put(mcc, new ArrayList(sensitivePN.getItem()));
}
}
} catch (DatatypeConfigurationException | IOException | XmlPullParserException e) {
Log.w(LOG_TAG, "Exception in spn-conf parser", e);
}
sNumbersLoaded = true;
}
public ArrayList<Item> getSensitivePnInfosForMcc(String mcc) {
loadSensiblePhoneNumbers();
return mSensitiveNumbersMap.getOrDefault(mcc, new ArrayList<Item>());
}
public boolean isSensitiveNumber(Context context, String numberToCheck, int subId) {
String nationalNumber = formatNumberToNational(context, numberToCheck);
if (TextUtils.isEmpty(nationalNumber)) {
return false;
}
loadSensiblePhoneNumbers();
SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
List<SubscriptionInfo> list = subManager.getActiveSubscriptionInfoList();
if (list != null) {
// Test all subscriptions so an accidential use of a wrong sim also hides the number
for (SubscriptionInfo subInfo : list) {
String mcc = String.valueOf(subInfo.getMcc());
if (isSensitiveNumber(nationalNumber, mcc)) {
return true;
}
}
}
// Fall back to check with the passed subId
TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
subId = SubscriptionManager.getDefaultSubscriptionId();
}
telephonyManager = telephonyManager.createForSubscriptionId(subId);
String networkUsed = telephonyManager.getNetworkOperator();
if (!TextUtils.isEmpty(networkUsed)) {
String networkMCC = networkUsed.substring(0, 3);
if (isSensitiveNumber(nationalNumber, networkMCC)) {
return true;
}
}
// Also try the sim's operator
if (telephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY) {
String simOperator = telephonyManager.getSimOperator();
if (!TextUtils.isEmpty(simOperator)) {
String networkMCC = simOperator.substring(0, 3);
if (isSensitiveNumber(nationalNumber, networkMCC)) {
return true;
}
}
}
return false;
}
private boolean isSensitiveNumber(String numberToCheck, String mcc) {
if (mSensitiveNumbersMap.containsKey(mcc)) {
for (Item item : mSensitiveNumbersMap.get(mcc)) {
if (PhoneNumberUtils.compare(numberToCheck, item.getNumber())) {
return true;
}
}
}
return false;
}
private String formatNumberToNational(Context context, String number) {
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
String countryIso = context.getResources().getConfiguration().locale.getCountry();
Phonenumber.PhoneNumber pn = null;
try {
pn = util.parse(number, countryIso);
} catch (NumberParseException e) {
}
if (pn != null) {
return util.format(pn, PhoneNumberFormat.NATIONAL);
} else {
return number;
}
}
}