summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlaia Segovia <olaia.segovia@bq.com>2017-03-16 08:40:30 +0100
committerKra1o5 <kra1o5x@gmail.com>2017-05-14 21:30:21 +0200
commitea38cbf38f8fa3c8308e901a790d8950639443b9 (patch)
treedfdc17aac3a3a71987056f8a53158b231160dec6
parent99aef234bb5f1f81016121a0ef78193718bcf1ba (diff)
downloadandroid_packages_services_Telecomm-ea38cbf38f8fa3c8308e901a790d8950639443b9.tar.gz
android_packages_services_Telecomm-ea38cbf38f8fa3c8308e901a790d8950639443b9.tar.bz2
android_packages_services_Telecomm-ea38cbf38f8fa3c8308e901a790d8950639443b9.zip
(1/2) Make sensitive phone numbers not to be shown in call log history.
Considering sensitive phone numbers to be, hotlines dealing with violence against women. In the EU, these numbers do not show up in the phone bill. In order to avoid these phone numbers to be listed in the Call Log, we have implemented a new XML file which is parsed with phone numbers from different countries to be filtered. This file needs to be copied to device via desired Android.mk file in order to be able to process it. The comparison is made checking the network MCC the SIM is connected to in order to consider roaming and multisim scenarios. Test: CallLogManagerTest.testDontLogCallsToSensitivePhoneNumber PASS Change-Id: I4a59ff0577942ce56924f1a434ae0a3a38eacc62 Signed-off-by: Olaia Segovia <olaia.segovia@bq.com>
-rw-r--r--src/com/android/server/telecom/CallLogManager.java9
-rw-r--r--src/com/android/server/telecom/SensitivePhoneNumber.java90
-rw-r--r--src/com/android/server/telecom/SensitivePhoneNumbers.java116
-rw-r--r--tests/src/com/android/server/telecom/tests/CallLogManagerTest.java49
4 files changed, 262 insertions, 2 deletions
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index 1fd66af1..6b61108e 100644
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -125,6 +125,7 @@ public final class CallLogManager extends CallsManagerListenerBase {
private Object mLock;
private String mCurrentCountryIso;
+ private SensitivePhoneNumbers mSensitivePhoneNumbers;
public CallLogManager(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
MissedCallNotifier missedCallNotifier) {
@@ -132,6 +133,7 @@ public final class CallLogManager extends CallsManagerListenerBase {
mPhoneAccountRegistrar = phoneAccountRegistrar;
mMissedCallNotifier = missedCallNotifier;
mLock = new Object();
+ mSensitivePhoneNumbers = new SensitivePhoneNumbers();
}
@Override
@@ -268,8 +270,11 @@ public final class CallLogManager extends CallsManagerListenerBase {
CarrierConfigManager.KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL);
}
- // Don't log emergency numbers if the device doesn't allow it.
- final boolean isOkToLogThisCall = !isEmergency || okToLogEmergencyNumber;
+ // Don't log emergency nor sensitive numbers if the device doesn't allow it.
+ boolean isSensitiveNumber = mSensitivePhoneNumbers.isSensitiveNumber(mContext, number,
+ accountHandle.getId());
+ Log.d(TAG, "isSensitiveNumber: "+ isSensitiveNumber);
+ final boolean isOkToLogThisCall = (!isEmergency || okToLogEmergencyNumber) && !isSensitiveNumber;
sendAddCallBroadcast(callType, duration);
diff --git a/src/com/android/server/telecom/SensitivePhoneNumber.java b/src/com/android/server/telecom/SensitivePhoneNumber.java
new file mode 100644
index 00000000..d0eb936d
--- /dev/null
+++ b/src/com/android/server/telecom/SensitivePhoneNumber.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2017 The LineageOS 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.server.telecom;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class SensitivePhoneNumber {
+ private static final String LOG_TAG = "SensitivePhoneNumber";
+ private static final String ns = null;
+
+ private String networkNumeric;
+ private ArrayList<String> phoneNumbers;
+
+ public SensitivePhoneNumber(String networkNumeric, ArrayList<String> phoneNumbers) {
+ this.networkNumeric = networkNumeric;
+ this.phoneNumbers = phoneNumbers;
+ }
+
+ public String getNetworkNumeric() {
+ return networkNumeric;
+ }
+
+ public ArrayList<String> getPhoneNumbers() {
+ return phoneNumbers;
+ }
+
+ public void setNetworkNumeric(String networkNumeric) {
+ this.networkNumeric = networkNumeric;
+ }
+
+ public void setPhoneNumbers(ArrayList<String> phoneNumbers) {
+ this.phoneNumbers = phoneNumbers;
+ }
+
+ public void addPhoneNumber(String phoneNumber) {
+ this.phoneNumbers.add(phoneNumber);
+ }
+
+ public static SensitivePhoneNumber readSensitivePhoneNumbers (XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ parser.require(XmlPullParser.START_TAG, ns, "sensitivePN");
+
+ String numeric = parser.getAttributeValue(null, "network");
+
+ ArrayList<String> numbers = null;
+ numbers = readPhoneNumber(parser);
+
+ return new SensitivePhoneNumber(numeric, numbers);
+ }
+
+ private static ArrayList<String> readPhoneNumber (XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ ArrayList<String> numbers = new ArrayList<>();
+ while (parser.next() != XmlPullParser.END_TAG) {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ continue;
+ }
+ parser.require(XmlPullParser.START_TAG, ns, "item");
+
+ String item = "";
+ if (parser.next() == XmlPullParser.TEXT) {
+ item = parser.getText();
+ parser.nextTag();
+ }
+ parser.require(XmlPullParser.END_TAG, ns, "item");
+
+ numbers.add(item);
+ }
+ return numbers;
+ }
+}
diff --git a/src/com/android/server/telecom/SensitivePhoneNumbers.java b/src/com/android/server/telecom/SensitivePhoneNumbers.java
new file mode 100644
index 00000000..e652bc04
--- /dev/null
+++ b/src/com/android/server/telecom/SensitivePhoneNumbers.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2017 The LineageOS 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.server.telecom;
+
+import android.content.Context;
+import android.os.Environment;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class SensitivePhoneNumbers {
+ private final String LOG_TAG = this.getClass().getSimpleName();
+
+ public static final String SENSIBLE_PHONENUMBERS_FILE_PATH = "etc/sensitive_pn.xml";
+ private static final String ns = null;
+
+ private HashMap<String, ArrayList<String>> mSensitiveNumbersMap = new HashMap<>();
+
+ public SensitivePhoneNumbers() {
+ loadSensiblePhoneNumbers();
+ }
+
+ private void loadSensiblePhoneNumbers() {
+ FileReader sensiblePNReader;
+
+ File sensiblePNFile = new File(Environment.getRootDirectory(),
+ SENSIBLE_PHONENUMBERS_FILE_PATH);
+
+ try {
+ sensiblePNReader = new FileReader(sensiblePNFile);
+ } catch (FileNotFoundException e) {
+ Log.w(LOG_TAG, "Can not open " + sensiblePNFile.getAbsolutePath());
+ return;
+ }
+
+ try {
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(sensiblePNReader);
+ parser.nextTag();
+
+ readSensitivePNS(parser);
+
+ sensiblePNReader.close();
+ } catch (XmlPullParserException e) {
+ Log.w(LOG_TAG, "Exception in spn-conf parser " + e);
+ } catch (IOException e) {
+ Log.w(LOG_TAG, "Exception in spn-conf parser " + e);
+ }
+ }
+
+ private void readSensitivePNS(XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ parser.require(XmlPullParser.START_TAG, ns, "sensitivePNS");
+ while (parser.next() != XmlPullParser.END_TAG) {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ continue;
+ }
+ String name = parser.getName();
+ if ("sensitivePN".equals(name)) {
+ SensitivePhoneNumber sensitivePN = SensitivePhoneNumber
+ .readSensitivePhoneNumbers(parser);
+ mSensitiveNumbersMap.put(sensitivePN.getNetworkNumeric(),
+ sensitivePN.getPhoneNumbers());
+ } else {
+ break;
+ }
+ }
+ }
+
+ public boolean isSensitiveNumber(Context context, String numberToCheck, String subId) {
+ TelephonyManager telephonyManager =
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+
+ int subIdInt = SubscriptionManager.getDefaultSubscriptionId();
+ try{
+ subIdInt = Integer.valueOf(subId);
+ }catch (NumberFormatException e) {
+ Log.w(LOG_TAG, "Error parsing subId");
+ }
+
+ String networkUsed = telephonyManager.getNetworkOperator(subIdInt);
+ if (!TextUtils.isEmpty(networkUsed)) {
+ String networkMCC = networkUsed.substring(0, 3);
+ return mSensitiveNumbersMap.containsKey(networkMCC) &&
+ mSensitiveNumbersMap.get(networkMCC).contains(numberToCheck);
+ }
+ return false;
+ }
+}
diff --git a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
index e9db5437..5281999f 100644
--- a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
@@ -27,6 +27,7 @@ import android.location.Country;
import android.location.CountryDetector;
import android.location.CountryListener;
import android.net.Uri;
+import android.os.Environment;
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.UserHandle;
@@ -40,15 +41,18 @@ import android.telecom.PhoneAccountHandle;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallLogManager;
import com.android.server.telecom.CallState;
+import com.android.server.telecom.CallsManager;
import com.android.server.telecom.MissedCallNotifier;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.R;
+import com.android.server.telecom.SensitivePhoneNumbers;
import com.android.server.telecom.TelephonyUtil;
import static org.mockito.Matchers.any;
@@ -57,15 +61,18 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import java.io.File;
import java.util.Arrays;
import java.util.Locale;
@@ -78,6 +85,7 @@ public class CallLogManagerTest extends TelecomTestCase {
private PhoneAccountHandle mManagedProfileAccountHandle;
private static final Uri TEL_PHONEHANDLE = Uri.parse("tel:5555551234");
+ private static final Uri TEL_SENSITIVE_PHONEHANDLE = Uri.parse("tel:016");
private static final PhoneAccountHandle EMERGENCY_ACCT_HANDLE = TelephonyUtil
.getDefaultEmergencyPhoneAccount()
@@ -224,6 +232,32 @@ public class CallLogManagerTest extends TelecomTestCase {
}
@MediumTest
+ public void testDontLogCallsToSensitivePhoneNumber() {
+ when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(any(PhoneAccountHandle.class)))
+ .thenReturn(makeFakePhoneAccount(mDefaultAccountHandle, CURRENT_USER_ID));
+
+ TelephonyManager mockTelephonyManager =
+ (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ when(mockTelephonyManager.getNetworkOperator(Mockito.anyInt())).thenReturn("21407");
+
+ Call fakeCall = makeFakeCall(
+ DisconnectCause.OTHER, // disconnectCauseCode
+ false, // isConference
+ false, // isIncoming
+ 1L, // creationTimeMillis
+ 1000L, // ageMillis
+ TEL_SENSITIVE_PHONEHANDLE, // callHandle
+ mDefaultAccountHandle, // phoneAccountHandle
+ NO_VIDEO_STATE, // callVideoState
+ POST_DIAL_STRING, // postDialDigits
+ VIA_NUMBER_STRING, // viaNumber
+ UserHandle.of(CURRENT_USER_ID)
+ );
+ mCallLogManager.onCallStateChanged(fakeCall, CallState.ACTIVE, CallState.DISCONNECTED);
+ verifyNoInsertionIfFileExists();
+ }
+
+ @MediumTest
public void testLogCallDirectionOutgoing() {
when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(any(PhoneAccountHandle.class)))
.thenReturn(makeFakePhoneAccount(mDefaultAccountHandle, CURRENT_USER_ID));
@@ -679,6 +713,21 @@ public class CallLogManagerTest extends TelecomTestCase {
}
}
+ private void verifyNoInsertionIfFileExists() {
+ File sensiblePNFile = new File(Environment.getRootDirectory(),
+ SensitivePhoneNumbers.SENSIBLE_PHONENUMBERS_FILE_PATH);
+ try {
+ Thread.sleep(TEST_TIMEOUT_MILLIS);
+ verify(mContentProvider,
+ sensiblePNFile.exists() ? never() : atLeastOnce()).insert(any(String.class),
+ any(Uri.class), any(ContentValues.class));
+ } catch (android.os.RemoteException e) {
+ fail("Remote exception occurred during test execution");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
private void verifyNoInsertionInUser(int userId) {
try {