aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/car
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/car')
-rw-r--r--src/com/android/car/calendar/CarCalendarActivity.java25
-rw-r--r--src/com/android/car/calendar/CarCalendarViewModel.java13
-rw-r--r--src/com/android/car/calendar/EventCalendarItem.java2
-rw-r--r--src/com/android/car/calendar/common/EventDescriptions.java68
4 files changed, 62 insertions, 46 deletions
diff --git a/src/com/android/car/calendar/CarCalendarActivity.java b/src/com/android/car/calendar/CarCalendarActivity.java
index 97e2031..945482a 100644
--- a/src/com/android/car/calendar/CarCalendarActivity.java
+++ b/src/com/android/car/calendar/CarCalendarActivity.java
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.StrictMode;
+import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -58,7 +59,10 @@ public class CarCalendarActivity extends FragmentActivity {
// Tests can set fake dependencies before onCreate.
if (mDependencies == null) {
mDependencies = new Dependencies(
- Locale.getDefault(), Clock.systemDefaultZone(), getContentResolver());
+ Locale.getDefault(),
+ Clock.systemDefaultZone(),
+ getContentResolver(),
+ getSystemService(TelephonyManager.class));
}
CarCalendarViewModel carCalendarViewModel =
@@ -67,6 +71,7 @@ public class CarCalendarActivity extends FragmentActivity {
new CarCalendarViewModelFactory(
mDependencies.mResolver,
mDependencies.mLocale,
+ mDependencies.mTelephonyManager,
mDependencies.mClock))
.get(CarCalendarViewModel.class);
@@ -142,12 +147,18 @@ public class CarCalendarActivity extends FragmentActivity {
private static class CarCalendarViewModelFactory implements ViewModelProvider.Factory {
private final ContentResolver mResolver;
+ private final TelephonyManager mTelephonyManager;
private final Locale mLocale;
private final Clock mClock;
- CarCalendarViewModelFactory(ContentResolver resolver, Locale locale, Clock clock) {
+ CarCalendarViewModelFactory(
+ ContentResolver resolver,
+ Locale locale,
+ TelephonyManager telephonyManager,
+ Clock clock) {
mResolver = resolver;
mLocale = locale;
+ mTelephonyManager = telephonyManager;
mClock = clock;
}
@@ -155,7 +166,7 @@ public class CarCalendarActivity extends FragmentActivity {
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> aClass) {
- return (T) new CarCalendarViewModel(mResolver, mLocale, mClock);
+ return (T) new CarCalendarViewModel(mResolver, mLocale, mTelephonyManager, mClock);
}
}
@@ -163,11 +174,17 @@ public class CarCalendarActivity extends FragmentActivity {
private final Locale mLocale;
private final Clock mClock;
private final ContentResolver mResolver;
+ private final TelephonyManager mTelephonyManager;
- Dependencies(Locale locale, Clock clock, ContentResolver resolver) {
+ Dependencies(
+ Locale locale,
+ Clock clock,
+ ContentResolver resolver,
+ TelephonyManager telephonyManager) {
mLocale = locale;
mClock = clock;
mResolver = resolver;
+ mTelephonyManager = telephonyManager;
}
}
}
diff --git a/src/com/android/car/calendar/CarCalendarViewModel.java b/src/com/android/car/calendar/CarCalendarViewModel.java
index c8e80ee..337f794 100644
--- a/src/com/android/car/calendar/CarCalendarViewModel.java
+++ b/src/com/android/car/calendar/CarCalendarViewModel.java
@@ -17,7 +17,9 @@
package com.android.car.calendar;
import android.content.ContentResolver;
+import android.os.Handler;
import android.os.HandlerThread;
+import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.annotation.Nullable;
@@ -38,14 +40,17 @@ class CarCalendarViewModel extends ViewModel {
private final Clock mClock;
private final ContentResolver mResolver;
private final Locale mLocale;
+ private final TelephonyManager mTelephonyManager;
@Nullable private EventsLiveData mEventsLiveData;
- CarCalendarViewModel(ContentResolver resolver, Locale locale, Clock clock) {
+ CarCalendarViewModel(ContentResolver resolver, Locale locale,
+ TelephonyManager telephonyManager, Clock clock) {
+ mLocale = locale;
if (DEBUG) Log.d(TAG, "Creating view model");
mResolver = resolver;
+ mTelephonyManager = telephonyManager;
mHandlerThread.start();
- mLocale = locale;
mClock = clock;
}
@@ -55,9 +60,9 @@ class CarCalendarViewModel extends ViewModel {
mEventsLiveData =
new EventsLiveData(
mClock,
- mHandlerThread.getThreadHandler(),
+ new Handler(mHandlerThread.getLooper()),
mResolver,
- new EventDescriptions(mLocale),
+ new EventDescriptions(mLocale, mTelephonyManager),
new EventLocations());
}
return mEventsLiveData;
diff --git a/src/com/android/car/calendar/EventCalendarItem.java b/src/com/android/car/calendar/EventCalendarItem.java
index a7c023d..e83c21c 100644
--- a/src/com/android/car/calendar/EventCalendarItem.java
+++ b/src/com/android/car/calendar/EventCalendarItem.java
@@ -17,7 +17,6 @@
package com.android.car.calendar;
import android.Manifest;
-import android.annotation.ColorInt;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.InsetDrawable;
@@ -34,6 +33,7 @@ import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
+import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
diff --git a/src/com/android/car/calendar/common/EventDescriptions.java b/src/com/android/car/calendar/common/EventDescriptions.java
index e6aad5b..8d2030f 100644
--- a/src/com/android/car/calendar/common/EventDescriptions.java
+++ b/src/com/android/car/calendar/common/EventDescriptions.java
@@ -16,20 +16,15 @@
package com.android.car.calendar.common;
-import static com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL;
-import static com.android.i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE;
-import static com.android.i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE_LOCAL_ONLY;
-import static com.android.i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_LONG;
-
import static com.google.common.base.Verify.verifyNotNull;
import android.net.Uri;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
import com.android.car.calendar.common.Dialer.NumberAndAccess;
-import com.android.i18n.phonenumbers.NumberParseException;
-import com.android.i18n.phonenumbers.PhoneNumberUtil;
-import com.android.i18n.phonenumbers.Phonenumber;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import java.util.LinkedHashMap;
@@ -45,37 +40,45 @@ import javax.annotation.Nullable;
public class EventDescriptions {
// Requires a phone number to include only numbers, spaces and dash, optionally a leading "+".
- // The number must be at least 6 characters.
+ // The number must be at least 6 characters and can contain " " or "-" but end with a digit.
// The access code must be at least 3 characters.
// The number and the access to include "pin" or "code" between the numbers.
private static final Pattern PHONE_PIN_PATTERN =
Pattern.compile(
- "(\\+?[\\d -]{6,})(?:.*\\b(?:PIN|code)\\b.*?([\\d,;#*]{3,}))?",
+ "(\\+?[\\d -]{6,}\\d)(?:.*\\b(?:PIN|code)\\b.*?([\\d,;#*]{3,}))?",
Pattern.CASE_INSENSITIVE);
// Matches numbers in the encoded format "<tel: ... >".
private static final Pattern TEL_PIN_PATTERN =
Pattern.compile("<tel:(\\+?[\\d -]{6,})([\\d,;#*]{3,})?>");
- private static final PhoneNumberUtil PHONE_NUMBER_UTIL = PhoneNumberUtil.getInstance();
-
// Ensure numbers are over 5 digits to reduce false positives.
- private static final int MIN_NATIONAL_NUMBER = 10_000;
+ private static final int MIN_DIGITS = 5;
- private final Locale mLocale;
+ private final String mCountryIso;
- public EventDescriptions(Locale locale) {
- mLocale = locale;
+ public EventDescriptions(Locale locale, TelephonyManager telephonyManager) {
+ String networkCountryIso = telephonyManager.getNetworkCountryIso().toUpperCase();
+ if (!Strings.isNullOrEmpty(networkCountryIso)) {
+ mCountryIso = networkCountryIso;
+ } else {
+ mCountryIso = locale.getCountry();
+ }
}
/** Find conference call data embedded in the description. */
public List<NumberAndAccess> extractNumberAndPins(String descriptionText) {
String decoded = Uri.decode(descriptionText);
+ // Use a map keyed by number to act like a set and only add a single number.
Map<String, NumberAndAccess> results = new LinkedHashMap<>();
addMatchedNumbers(decoded, results, PHONE_PIN_PATTERN);
+
+ // Add the most restrictive precise format last to replace others with the same number.
addMatchedNumbers(decoded, results, TEL_PIN_PATTERN);
- return ImmutableList.copyOf(results.values());
+
+ // Reverse order so the most precise format is first.
+ return ImmutableList.copyOf(results.values()).reverse();
}
private void addMatchedNumbers(
@@ -93,27 +96,18 @@ public class EventDescriptions {
private NumberAndAccess validNumberAndAccess(Matcher phoneFormatMatcher) {
String number = verifyNotNull(phoneFormatMatcher.group(1));
String access = phoneFormatMatcher.group(2);
- try {
- Phonenumber.PhoneNumber phoneNumber =
- PHONE_NUMBER_UTIL.parse(number, mLocale.getCountry());
- PhoneNumberUtil.ValidationResult result =
- PHONE_NUMBER_UTIL.isPossibleNumberWithReason(phoneNumber);
- if (isAcceptableResult(result)) {
- if (phoneNumber.getNationalNumber() < MIN_NATIONAL_NUMBER) {
- return null;
- }
- String formatted = PHONE_NUMBER_UTIL.format(phoneNumber, INTERNATIONAL);
- return new NumberAndAccess(formatted, access);
- }
- } catch (NumberParseException e) {
- // Ignore invalid numbers.
+
+ // Ensure that there are a minimum number of digits to reduce false positives.
+ String onlyDigits = number.replaceAll("\\D", "");
+ if (onlyDigits.length() < MIN_DIGITS) {
+ return null;
}
- return null;
- }
- private boolean isAcceptableResult(PhoneNumberUtil.ValidationResult result) {
- // The result can be too long and still valid because the US locale is used by default
- // which does not accept valid long numbers from other regions.
- return result == IS_POSSIBLE || result == IS_POSSIBLE_LOCAL_ONLY || result == TOO_LONG;
+ // Keep local numbers in local format which the dialer can make more sense of.
+ String formatted = PhoneNumberUtils.formatNumber(number, mCountryIso);
+ if (formatted == null) {
+ return null;
+ }
+ return new NumberAndAccess(formatted, access);
}
}