summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-01-16 18:56:56 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-01-16 18:56:56 +0000
commitff4b9b3b8f9bff0e7a973c6067c147db655efad0 (patch)
tree78d3cb4857d07fe80c11bde11467fbee2a1f90da
parent3c7499911f6f004b9060592849409408eacd46c1 (diff)
parentfccc1d1d378b45f715868cd8fab31a3c932f4394 (diff)
downloadbase-ff4b9b3b8f9bff0e7a973c6067c147db655efad0.tar.gz
Merge cherrypicks of [6072696, 6072074, 6072757, 6072120, 6072121, 6072122, 6072123, 6072575, 6072576, 6072577, 6072578, 6072579, 6072193, 6072131, 6072194, 6072076, 6072210, 6072759, 6072760, 6072698, 6072699, 6072700, 6072701, 6072702, 6072703, 6072704, 6072905, 6072906, 6072907, 6072761] into oc-m8-releaseandroid-8.1.0_r63android-8.1.0_r62
Change-Id: Ia83e95b299ccfe815cca1abec869db1456fca295
-rw-r--r--core/java/android/text/util/Linkify.java36
-rw-r--r--core/java/android/view/textclassifier/TextClassification.java2
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java13
-rw-r--r--core/tests/coretests/src/android/widget/TextViewActivityTest.java13
-rw-r--r--location/java/com/android/internal/location/GpsNetInitiatedHandler.java70
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java11
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java22
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java2
8 files changed, 128 insertions, 41 deletions
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 768aee91e5b3..bc462aa2b30b 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -28,6 +28,7 @@ import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.text.style.URLSpan;
+import android.util.Log;
import android.util.Patterns;
import android.webkit.WebView;
import android.widget.TextView;
@@ -66,6 +67,9 @@ import java.util.regex.Pattern;
*/
public class Linkify {
+
+ private static final String LOG_TAG = "Linkify";
+
/**
* Bit field indicating that web URLs should be matched in methods that
* take an options mask
@@ -228,6 +232,11 @@ public class Linkify {
private static boolean addLinks(@NonNull Spannable text, @LinkifyMask int mask,
@Nullable Context context) {
+ if (text != null && containsUnsupportedCharacters(text.toString())) {
+ android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, "");
+ return false;
+ }
+
if (mask == 0) {
return false;
}
@@ -274,6 +283,29 @@ public class Linkify {
}
/**
+ * Returns true if the specified text contains at least one unsupported character for applying
+ * links. Also logs the error.
+ *
+ * @param text the text to apply links to
+ * @hide
+ */
+ public static boolean containsUnsupportedCharacters(String text) {
+ if (text.contains("\u202C")) {
+ Log.e(LOG_TAG, "Unsupported character for applying links: u202C");
+ return true;
+ }
+ if (text.contains("\u202D")) {
+ Log.e(LOG_TAG, "Unsupported character for applying links: u202D");
+ return true;
+ }
+ if (text.contains("\u202E")) {
+ Log.e(LOG_TAG, "Unsupported character for applying links: u202E");
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Scans the text of the provided TextView and turns all occurrences of
* the link types indicated in the mask into clickable links. If matches
* are found the movement method for the TextView is set to
@@ -420,6 +452,10 @@ public class Linkify {
public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern,
@Nullable String scheme, @Nullable MatchFilter matchFilter,
@Nullable TransformFilter transformFilter) {
+ if (spannable != null && containsUnsupportedCharacters(spannable.toString())) {
+ android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, "");
+ return false;
+ }
return addLinks(spannable, pattern, scheme, null, matchFilter,
transformFilter);
}
diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java
index 1849368f6ae9..c87923392915 100644
--- a/core/java/android/view/textclassifier/TextClassification.java
+++ b/core/java/android/view/textclassifier/TextClassification.java
@@ -38,7 +38,7 @@ public final class TextClassification {
/**
* @hide
*/
- static final TextClassification EMPTY = new TextClassification.Builder().build();
+ public static final TextClassification EMPTY = new TextClassification.Builder().build();
@NonNull private final String mText;
@Nullable private final Drawable mIcon;
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 384e254e205f..f5db93e29515 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -25,6 +25,7 @@ import android.os.LocaleList;
import android.text.Selection;
import android.text.Spannable;
import android.text.TextUtils;
+import android.text.util.Linkify;
import android.util.Log;
import android.view.ActionMode;
import android.view.textclassifier.TextClassification;
@@ -692,11 +693,19 @@ final class SelectionActionModeHelper {
mLastClassificationLocales = mLocales;
trimText();
+ final TextClassification classification;
+ if (Linkify.containsUnsupportedCharacters(mText)) {
+ // Do not show smart actions for text containing unsupported characters.
+ android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, "");
+ classification = TextClassification.EMPTY;
+ } else {
+ classification = mTextClassifier.classifyText(
+ mTrimmedText, mRelativeStart, mRelativeEnd, mLocales);
+ }
mLastClassificationResult = new SelectionResult(
mSelectionStart,
mSelectionEnd,
- mTextClassifier.classifyText(
- mTrimmedText, mRelativeStart, mRelativeEnd, mLocales),
+ classification,
selection);
}
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 56c72d214347..ec8dee658360 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -839,6 +839,19 @@ public class TextViewActivityTest {
}
@Test
+ public void testNoAssistItemForTextFieldWithUnsupportedCharacters() throws Throwable {
+ useSystemDefaultTextClassifier();
+ final String text = "\u202Emoc.diordna.com";
+ final TextView textView = mActivity.findViewById(R.id.textview);
+ mActivityRule.runOnUiThread(() -> textView.setText(text));
+ mInstrumentation.waitForIdleSync();
+
+ onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('.')));
+ sleepForFloatingToolbarPopup();
+ assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist);
+ }
+
+ @Test
public void testPastePlainText_menuAction() {
initializeClipboardWithText(TextStyle.STYLED);
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 9bd59940e37b..3bfe32cb4631 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -17,6 +17,7 @@
package com.android.internal.location;
import java.io.UnsupportedEncodingException;
+import java.util.concurrent.TimeUnit;
import android.app.Notification;
import android.app.NotificationManager;
@@ -27,6 +28,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.location.INetInitiatedListener;
+import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneStateListener;
@@ -50,8 +52,7 @@ public class GpsNetInitiatedHandler {
private static final String TAG = "GpsNetInitiatedHandler";
- private static final boolean DEBUG = true;
- private static final boolean VERBOSE = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
// NI verify activity for bringing up UI (not used yet)
public static final String ACTION_NI_VERIFY = "android.intent.action.NETWORK_INITIATED_VERIFY";
@@ -94,6 +95,9 @@ public class GpsNetInitiatedHandler {
public static final int GPS_ENC_SUPL_UCS2 = 3;
public static final int GPS_ENC_UNKNOWN = -1;
+ // Limit on SUPL NI emergency mode time extension after emergency sessions ends
+ private static final int MAX_EMERGENCY_MODE_EXTENSION_SECONDS = 300; // 5 minute maximum
+
private final Context mContext;
private final TelephonyManager mTelephonyManager;
private final PhoneStateListener mPhoneStateListener;
@@ -109,7 +113,7 @@ public class GpsNetInitiatedHandler {
private volatile boolean mIsSuplEsEnabled;
// Set to true if the phone is having emergency call.
- private volatile boolean mIsInEmergency;
+ private volatile boolean mIsInEmergencyCall;
// If Location function is enabled.
private volatile boolean mIsLocationEnabled = false;
@@ -119,6 +123,10 @@ public class GpsNetInitiatedHandler {
// Set to true if string from HAL is encoded as Hex, e.g., "3F0039"
static private boolean mIsHexInput = true;
+ // End time of emergency call, and extension, if set
+ private long mCallEndElapsedRealtimeMillis = 0;
+ private long mEmergencyExtensionMillis = 0;
+
public static class GpsNiNotification
{
public int notificationId;
@@ -146,16 +154,12 @@ public class GpsNetInitiatedHandler {
if (action.equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
/*
- Emergency Mode is when during emergency call or in emergency call back mode.
- For checking if it is during emergency call:
- mIsInEmergency records if the phone is in emergency call or not. It will
+ Tracks the emergency call:
+ mIsInEmergencyCall records if the phone is in emergency call or not. It will
be set to true when the phone is having emergency call, and then will
be set to false by mPhoneStateListener when the emergency call ends.
- For checking if it is in emergency call back mode:
- Emergency call back mode will be checked by reading system properties
- when necessary: SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)
*/
- setInEmergency(PhoneNumberUtils.isEmergencyNumber(phoneNumber));
+ mIsInEmergencyCall = PhoneNumberUtils.isEmergencyNumber(phoneNumber);
if (DEBUG) Log.v(TAG, "ACTION_NEW_OUTGOING_CALL - " + getInEmergency());
} else if (action.equals(LocationManager.MODE_CHANGED_ACTION)) {
updateLocationMode();
@@ -195,7 +199,10 @@ public class GpsNetInitiatedHandler {
if (DEBUG) Log.d(TAG, "onCallStateChanged(): state is "+ state);
// listening for emergency call ends
if (state == TelephonyManager.CALL_STATE_IDLE) {
- setInEmergency(false);
+ if (mIsInEmergencyCall) {
+ mCallEndElapsedRealtimeMillis = SystemClock.elapsedRealtime();
+ mIsInEmergencyCall = false;
+ }
}
}
};
@@ -229,22 +236,35 @@ public class GpsNetInitiatedHandler {
return mIsLocationEnabled;
}
- // Note: Currently, there are two mechanisms involved to determine if a
- // phone is in emergency mode:
- // 1. If the user is making an emergency call, this is provided by activly
- // monitoring the outgoing phone number;
- // 2. If the device is in a emergency callback state, this is provided by
- // system properties.
- // If either one of above exists, the phone is considered in an emergency
- // mode. Because of this complexity, we need to be careful about how to set
- // and clear the emergency state.
- public void setInEmergency(boolean isInEmergency) {
- mIsInEmergency = isInEmergency;
- }
-
+ /**
+ * Determines whether device is in user-initiated emergency session based on the following
+ * 1. If the user is making an emergency call, this is provided by actively
+ * monitoring the outgoing phone number;
+ * 2. If the user has recently ended an emergency call, and the device is in a configured time
+ * window after the end of that call.
+ * 3. If the device is in a emergency callback state, this is provided by querying
+ * TelephonyManager.
+ * @return true if is considered in user initiated emergency mode for NI purposes
+ */
public boolean getInEmergency() {
+ boolean isInEmergencyExtension =
+ (SystemClock.elapsedRealtime() - mCallEndElapsedRealtimeMillis) <
+ mEmergencyExtensionMillis;
boolean isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode();
- return mIsInEmergency || isInEmergencyCallback;
+ return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension;
+ }
+
+ public void setEmergencyExtensionSeconds(int emergencyExtensionSeconds) {
+ if (emergencyExtensionSeconds > MAX_EMERGENCY_MODE_EXTENSION_SECONDS) {
+ Log.w(TAG, "emergencyExtensionSeconds " + emergencyExtensionSeconds
+ + " too high, reset to " + MAX_EMERGENCY_MODE_EXTENSION_SECONDS);
+ emergencyExtensionSeconds = MAX_EMERGENCY_MODE_EXTENSION_SECONDS;
+ } else if (emergencyExtensionSeconds < 0) {
+ Log.w(TAG, "emergencyExtensionSeconds " + emergencyExtensionSeconds
+ + " is negative, reset to zero.");
+ emergencyExtensionSeconds = 0;
+ }
+ mEmergencyExtensionMillis = TimeUnit.SECONDS.toMillis(emergencyExtensionSeconds);
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 74ddfc5edc37..98f4abb4763b 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -651,6 +651,17 @@ public class GnssLocationProvider implements LocationProviderInterface {
Log.e(TAG, "unable to parse SUPL_ES: " + suplESProperty);
}
}
+
+ String emergencyExtensionSecondsString
+ = properties.getProperty("ES_EXTENSION_SEC", "0");
+ try {
+ int emergencyExtensionSeconds =
+ Integer.parseInt(emergencyExtensionSecondsString);
+ mNIHandler.setEmergencyExtensionSeconds(emergencyExtensionSeconds);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "unable to parse ES_EXTENSION_SEC: "
+ + emergencyExtensionSecondsString);
+ }
}
private void loadPropertiesFromResource(Context context,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 38d7d25dc343..aac341c1e6e4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4352,18 +4352,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
}
final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
- if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
- final int realQuality = metrics.quality;
- if (realQuality < quality
- && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
- Slog.w(LOG_TAG, "resetPassword: password quality 0x"
- + Integer.toHexString(realQuality)
- + " does not meet required quality 0x"
- + Integer.toHexString(quality));
- return false;
- }
- quality = Math.max(realQuality, quality);
+ final int realQuality = metrics.quality;
+ if (realQuality < quality
+ && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
+ Slog.w(LOG_TAG, "resetPassword: password quality 0x"
+ + Integer.toHexString(realQuality)
+ + " does not meet required quality 0x"
+ + Integer.toHexString(quality));
+ return false;
}
+ quality = Math.max(realQuality, quality);
int length = getPasswordMinimumLength(null, userHandle, /* parent */ false);
if (password.length() < length) {
Slog.w(LOG_TAG, "resetPassword: password length " + password.length()
@@ -4449,7 +4447,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
result = mLockPatternUtils.setLockCredentialWithToken(password,
TextUtils.isEmpty(password) ? LockPatternUtils.CREDENTIAL_TYPE_NONE
: LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
- quality, tokenHandle, token, userHandle);
+ quality, tokenHandle, token, userHandle);
}
boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
if (requireEntry) {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 96d9605d3a3d..3eb659ad2a13 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -3654,7 +3654,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
// test reset password with token
when(getServices().lockPatternUtils.setLockCredentialWithToken(eq(password),
eq(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD),
- eq(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED), eq(handle), eq(token),
+ eq(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC), eq(handle), eq(token),
eq(UserHandle.USER_SYSTEM)))
.thenReturn(true);
assertTrue(dpm.resetPasswordWithToken(admin1, password, token, 0));