Merge "Marked some WM flaky tests as such" into qt-dev
diff --git a/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
index c149195..bd3b673 100644
--- a/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
+++ b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
@@ -52,7 +52,7 @@
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
textClassificationManager.getTextClassifier();
- textClassificationManager.invalidate();
+ textClassificationManager.invalidateForTesting();
}
}
@@ -68,7 +68,7 @@
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
textClassificationManager.getTextClassifier();
- textClassificationManager.invalidate();
+ textClassificationManager.invalidateForTesting();
}
}
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 82a34ce..1ad0cfd 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2764,6 +2764,9 @@
if (itemInfo.packageName != null) {
dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
}
+ if (dr == null && itemInfo != appInfo) {
+ dr = loadUnbadgedItemIcon(appInfo, appInfo);
+ }
if (dr == null) {
dr = itemInfo.loadDefaultIcon(this);
}
diff --git a/core/java/android/app/SharedElementCallback.java b/core/java/android/app/SharedElementCallback.java
index 9fabfde..0287564 100644
--- a/core/java/android/app/SharedElementCallback.java
+++ b/core/java/android/app/SharedElementCallback.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.RectF;
@@ -49,6 +50,7 @@
private static final String BUNDLE_SNAPSHOT_BITMAP = "sharedElement:snapshot:bitmap";
private static final String BUNDLE_SNAPSHOT_GRAPHIC_BUFFER =
"sharedElement:snapshot:graphicBuffer";
+ private static final String BUNDLE_SNAPSHOT_COLOR_SPACE = "sharedElement:snapshot:colorSpace";
private static final String BUNDLE_SNAPSHOT_IMAGE_SCALETYPE = "sharedElement:snapshot:imageScaleType";
private static final String BUNDLE_SNAPSHOT_IMAGE_MATRIX = "sharedElement:snapshot:imageMatrix";
@@ -186,6 +188,10 @@
} else {
GraphicBuffer graphicBuffer = bitmap.createGraphicBufferHandle();
bundle.putParcelable(BUNDLE_SNAPSHOT_GRAPHIC_BUFFER, graphicBuffer);
+ ColorSpace cs = bitmap.getColorSpace();
+ if (cs != null) {
+ bundle.putInt(BUNDLE_SNAPSHOT_COLOR_SPACE, cs.getId());
+ }
}
bundle.putString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE,
imageView.getScaleType().toString());
@@ -235,8 +241,13 @@
return null;
}
if (bitmap == null) {
+ ColorSpace colorSpace = null;
+ int colorSpaceId = bundle.getInt(BUNDLE_SNAPSHOT_COLOR_SPACE, 0);
+ if (colorSpaceId >= 0 && colorSpaceId < ColorSpace.Named.values().length) {
+ colorSpace = ColorSpace.get(ColorSpace.Named.values()[colorSpaceId]);
+ }
bitmap = Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(buffer),
- null);
+ colorSpace);
}
ImageView imageView = new ImageView(context);
view = imageView;
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index d2f0fb3..338eb2d 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1509,11 +1509,6 @@
* state of the permission can be determined only at install time and cannot be
* changed on updated or at a later point via the package manager APIs.
*
- * <p>The whitelisted non-immutably restricted permissions would be added to
- * the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER installer whitelist}
- * while the immutably restricted permissions would be added to the {@link
- * PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM system whitelist}
- *
* @see PackageManager#addWhitelistedRestrictedPermission(String, String, int)
* @see PackageManager#removeWhitelistedRestrictedPermission(String, String, int)
*/
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 6478de2..8536158 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -881,6 +881,7 @@
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
+ maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);
}
}
@@ -896,6 +897,7 @@
maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
+ maybeSetHiddenApiAccessStatslogSampleRate(secondaryZygoteState);
}
}
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 774d4ae..9a11104 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -263,6 +263,7 @@
* Namespace for TextClassifier related features.
*
* @hide
+ * @see android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
*/
@SystemApi
public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8231a92..75b40fd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -12039,26 +12039,27 @@
* entity_list_default use ":" as delimiter for values. Ex:
*
* <pre>
- * smart_linkify_enabled (boolean)
- * system_textclassifier_enabled (boolean)
+ * classify_text_max_range_length (int)
+ * detect_language_from_text_enabled (boolean)
+ * entity_list_default (String[])
+ * entity_list_editable (String[])
+ * entity_list_not_editable (String[])
+ * generate_links_log_sample_rate (int)
+ * generate_links_max_text_length (int)
+ * in_app_conversation_action_types_default (String[])
+ * lang_id_context_settings (float[])
+ * lang_id_threshold_override (float)
+ * local_textclassifier_enabled (boolean)
* model_dark_launch_enabled (boolean)
- * smart_selection_enabled (boolean)
- * smart_text_share_enabled (boolean)
+ * notification_conversation_action_types_default (String[])
* smart_linkify_enabled (boolean)
* smart_select_animation_enabled (boolean)
+ * smart_selection_enabled (boolean)
+ * smart_text_share_enabled (boolean)
* suggest_selection_max_range_length (int)
- * classify_text_max_range_length (int)
- * generate_links_max_text_length (int)
- * generate_links_log_sample_rate (int)
- * entity_list_default (String[])
- * entity_list_not_editable (String[])
- * entity_list_editable (String[])
- * in_app_conversation_action_types_default (String[])
- * notification_conversation_action_types_default (String[])
- * lang_id_threshold_override (float)
+ * system_textclassifier_enabled (boolean)
* template_intent_factory_enabled (boolean)
* translate_in_classification_enabled (boolean)
- * detect_language_from_text_enabled (boolean)
* </pre>
*
* <p>
diff --git a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
index 55e6141..516d336 100644
--- a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
+++ b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
@@ -30,6 +30,7 @@
import android.app.contentsuggestions.SelectionsRequest;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.os.Bundle;
import android.os.Handler;
@@ -62,11 +63,15 @@
private final IContentSuggestionsService mInterface = new IContentSuggestionsService.Stub() {
@Override
public void provideContextImage(int taskId, GraphicBuffer contextImage,
- Bundle imageContextRequestExtras) {
+ int colorSpaceId, Bundle imageContextRequestExtras) {
Bitmap wrappedBuffer = null;
if (contextImage != null) {
- wrappedBuffer = Bitmap.wrapHardwareBuffer(contextImage, null);
+ ColorSpace colorSpace = null;
+ if (colorSpaceId >= 0 && colorSpaceId < ColorSpace.Named.values().length) {
+ colorSpace = ColorSpace.get(ColorSpace.Named.values()[colorSpaceId]);
+ }
+ wrappedBuffer = Bitmap.wrapHardwareBuffer(contextImage, colorSpace);
}
mHandler.sendMessage(
diff --git a/core/java/android/service/contentsuggestions/IContentSuggestionsService.aidl b/core/java/android/service/contentsuggestions/IContentSuggestionsService.aidl
index 1926478..6240e00 100644
--- a/core/java/android/service/contentsuggestions/IContentSuggestionsService.aidl
+++ b/core/java/android/service/contentsuggestions/IContentSuggestionsService.aidl
@@ -32,6 +32,7 @@
void provideContextImage(
int taskId,
in GraphicBuffer contextImage,
+ int colorSpaceId,
in Bundle imageContextRequestExtras);
void suggestContentSelections(
in SelectionsRequest request,
diff --git a/core/java/android/view/textclassifier/ConfigParser.java b/core/java/android/view/textclassifier/ConfigParser.java
index b475412..63de059 100644
--- a/core/java/android/view/textclassifier/ConfigParser.java
+++ b/core/java/android/view/textclassifier/ConfigParser.java
@@ -17,9 +17,19 @@
import android.annotation.Nullable;
import android.provider.DeviceConfig;
+import android.util.ArrayMap;
import android.util.KeyValueListParser;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.internal.util.Preconditions;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
/**
* Retrieves settings from {@link DeviceConfig} and {@link android.provider.Settings}.
@@ -27,80 +37,228 @@
*
* @hide
*/
-@VisibleForTesting
+@VisibleForTesting(visibility = Visibility.PACKAGE)
public final class ConfigParser {
private static final String TAG = "ConfigParser";
- private final KeyValueListParser mParser;
+ static final boolean ENABLE_DEVICE_CONFIG = true;
- // TODO: Re-enable DeviceConfig when it has reasonable performance or just delete the
- // option of using DeviceConfig entirely.
- static final boolean ENABLE_DEVICE_CONFIG = false;
+ private static final String STRING_LIST_DELIMITER = ":";
- public ConfigParser(@Nullable String textClassifierConstants) {
- final KeyValueListParser parser = new KeyValueListParser(',');
- try {
- parser.setString(textClassifierConstants);
- } catch (IllegalArgumentException e) {
- // Failed to parse the settings string, log this and move on with defaults.
- Log.w(TAG, "Bad text_classifier_constants: " + textClassifierConstants);
+ private final Supplier<String> mLegacySettingsSupplier;
+ private final Object mLock = new Object();
+ @GuardedBy("mLock")
+ private final Map<String, Object> mCache = new ArrayMap<>();
+ @GuardedBy("mLock")
+ private @Nullable KeyValueListParser mSettingsParser; // Call getLegacySettings() instead.
+
+ public ConfigParser(Supplier<String> legacySettingsSupplier) {
+ mLegacySettingsSupplier = Preconditions.checkNotNull(legacySettingsSupplier);
+ }
+
+ private KeyValueListParser getLegacySettings() {
+ synchronized (mLock) {
+ if (mSettingsParser == null) {
+ final String legacySettings = mLegacySettingsSupplier.get();
+ try {
+ mSettingsParser = new KeyValueListParser(',');
+ mSettingsParser.setString(legacySettings);
+ } catch (IllegalArgumentException e) {
+ // Failed to parse the settings string, log this and move on with defaults.
+ Log.w(TAG, "Bad text_classifier_constants: " + legacySettings);
+ }
+ }
+ return mSettingsParser;
}
- mParser = parser;
}
/**
- * Reads a boolean flag.
+ * Reads a boolean setting through the cache.
*/
public boolean getBoolean(String key, boolean defaultValue) {
- if (ENABLE_DEVICE_CONFIG) {
- return DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
- key,
- mParser.getBoolean(key, defaultValue));
- } else {
- return mParser.getBoolean(key, defaultValue);
+ synchronized (mLock) {
+ final Object cached = mCache.get(key);
+ if (cached instanceof Boolean) {
+ return (boolean) cached;
+ }
+ final boolean value;
+ if (ENABLE_DEVICE_CONFIG) {
+ value = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ getLegacySettings().getBoolean(key, defaultValue));
+ } else {
+ value = getLegacySettings().getBoolean(key, defaultValue);
+ }
+ mCache.put(key, value);
+ return value;
}
}
/**
- * Reads an integer flag.
+ * Reads an integer setting through the cache.
*/
public int getInt(String key, int defaultValue) {
- if (ENABLE_DEVICE_CONFIG) {
- return DeviceConfig.getInt(
- DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
- key,
- mParser.getInt(key, defaultValue));
- } else {
- return mParser.getInt(key, defaultValue);
+ synchronized (mLock) {
+ final Object cached = mCache.get(key);
+ if (cached instanceof Integer) {
+ return (int) cached;
+ }
+ final int value;
+ if (ENABLE_DEVICE_CONFIG) {
+ value = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ getLegacySettings().getInt(key, defaultValue));
+ } else {
+ value = getLegacySettings().getInt(key, defaultValue);
+ }
+ mCache.put(key, value);
+ return value;
}
}
/**
- * Reads a float flag.
+ * Reads a float setting through the cache.
*/
public float getFloat(String key, float defaultValue) {
- if (ENABLE_DEVICE_CONFIG) {
- return DeviceConfig.getFloat(
- DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
- key,
- mParser.getFloat(key, defaultValue));
- } else {
- return mParser.getFloat(key, defaultValue);
+ synchronized (mLock) {
+ final Object cached = mCache.get(key);
+ if (cached instanceof Float) {
+ return (float) cached;
+ }
+ final float value;
+ if (ENABLE_DEVICE_CONFIG) {
+ value = DeviceConfig.getFloat(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ getLegacySettings().getFloat(key, defaultValue));
+ } else {
+ value = getLegacySettings().getFloat(key, defaultValue);
+ }
+ mCache.put(key, value);
+ return value;
}
}
/**
- * Reads a string flag.
+ * Reads a string setting through the cache.
*/
public String getString(String key, String defaultValue) {
- if (ENABLE_DEVICE_CONFIG) {
- return DeviceConfig.getString(
- DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
- key,
- mParser.getString(key, defaultValue));
+ synchronized (mLock) {
+ final Object cached = mCache.get(key);
+ if (cached instanceof String) {
+ return (String) cached;
+ }
+ final String value;
+ if (ENABLE_DEVICE_CONFIG) {
+ value = DeviceConfig.getString(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ getLegacySettings().getString(key, defaultValue));
+ } else {
+ value = getLegacySettings().getString(key, defaultValue);
+ }
+ mCache.put(key, value);
+ return value;
+ }
+ }
+
+ /**
+ * Reads a string list setting through the cache.
+ */
+ public List<String> getStringList(String key, List<String> defaultValue) {
+ synchronized (mLock) {
+ final Object cached = mCache.get(key);
+ if (cached instanceof List) {
+ final List asList = (List) cached;
+ if (asList.isEmpty()) {
+ return Collections.emptyList();
+ } else if (asList.get(0) instanceof String) {
+ return (List<String>) cached;
+ }
+ }
+ final List<String> value;
+ if (ENABLE_DEVICE_CONFIG) {
+ value = getDeviceConfigStringList(
+ key,
+ getSettingsStringList(key, defaultValue));
+ } else {
+ value = getSettingsStringList(key, defaultValue);
+ }
+ mCache.put(key, value);
+ return value;
+ }
+ }
+
+ /**
+ * Reads a float array through the cache. The returned array should be expected to be of the
+ * same length as that of the defaultValue.
+ */
+ public float[] getFloatArray(String key, float[] defaultValue) {
+ synchronized (mLock) {
+ final Object cached = mCache.get(key);
+ if (cached instanceof float[]) {
+ return (float[]) cached;
+ }
+ final float[] value;
+ if (ENABLE_DEVICE_CONFIG) {
+ value = getDeviceConfigFloatArray(
+ key,
+ getSettingsFloatArray(key, defaultValue));
+ } else {
+ value = getSettingsFloatArray(key, defaultValue);
+ }
+ mCache.put(key, value);
+ return value;
+ }
+ }
+
+ private List<String> getSettingsStringList(String key, List<String> defaultValue) {
+ return parse(mSettingsParser.getString(key, null), defaultValue);
+ }
+
+ private static List<String> getDeviceConfigStringList(String key, List<String> defaultValue) {
+ return parse(
+ DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null),
+ defaultValue);
+ }
+
+ private static float[] getDeviceConfigFloatArray(String key, float[] defaultValue) {
+ return parse(
+ DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null),
+ defaultValue);
+ }
+
+ private float[] getSettingsFloatArray(String key, float[] defaultValue) {
+ return parse(mSettingsParser.getString(key, null), defaultValue);
+ }
+
+ private static List<String> parse(@Nullable String listStr, List<String> defaultValue) {
+ if (listStr != null) {
+ return Collections.unmodifiableList(
+ Arrays.asList(listStr.split(STRING_LIST_DELIMITER)));
+ }
+ return defaultValue;
+ }
+
+ private static float[] parse(@Nullable String arrayStr, float[] defaultValue) {
+ if (arrayStr != null) {
+ final String[] split = arrayStr.split(STRING_LIST_DELIMITER);
+ if (split.length != defaultValue.length) {
+ return defaultValue;
+ }
+ final float[] result = new float[split.length];
+ for (int i = 0; i < split.length; i++) {
+ try {
+ result[i] = Float.parseFloat(split[i]);
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
+ return result;
} else {
- return mParser.getString(key, defaultValue);
+ return defaultValue;
}
}
}
diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
index 876e5cc..2964f51 100644
--- a/core/java/android/view/textclassifier/TextClassificationConstants.java
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -16,58 +16,39 @@
package android.view.textclassifier;
-import android.annotation.Nullable;
-
import com.android.internal.util.IndentingPrintWriter;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
-import java.util.StringJoiner;
+import java.util.function.Supplier;
/**
* TextClassifier specific settings.
- * This is encoded as a key=value list, separated by commas. Ex:
- *
- * <pre>
- * smart_linkify_enabled (boolean)
- * system_textclassifier_enabled (boolean)
- * model_dark_launch_enabled (boolean)
- * smart_selection_enabled (boolean)
- * smart_text_share_enabled (boolean)
- * smart_linkify_enabled (boolean)
- * smart_select_animation_enabled (boolean)
- * suggest_selection_max_range_length (int)
- * classify_text_max_range_length (int)
- * generate_links_max_text_length (int)
- * generate_links_log_sample_rate (int)
- * entity_list_default (String[])
- * entity_list_not_editable (String[])
- * entity_list_editable (String[])
- * in_app_conversation_action_types_default (String[])
- * notification_conversation_action_types_default (String[])
- * lang_id_threshold_override (float)
- * template_intent_factory_enabled (boolean)
- * translate_in_classification_enabled (boolean)
- * detect_languages_from_text_enabled (boolean)
- * lang_id_context_settings (float[])
- * </pre>
- *
+ * This is encoded as a key=value list, separated by commas.
* <p>
- * Type: string
- * see also android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
- *
* Example of setting the values for testing.
+ * <p>
+ * <pre>
* adb shell settings put global text_classifier_constants \
* model_dark_launch_enabled=true,smart_selection_enabled=true, \
* entity_list_default=phone:address, \
* lang_id_context_settings=20:1.0:0.4
+ * </pre>
+ * <p>
+ * Settings are also available in device config. These take precedence over those in settings
+ * global.
+ * <p>
+ * <pre>
+ * adb shell cmd device_config put textclassifier system_textclassifier_enabled true
+ * </pre>
+ *
+ * @see android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
+ * @see android.provider.DeviceConfig.NAMESPACE_TEXTCLASSIFIER
* @hide
*/
+// TODO: Rename to TextClassifierSettings.
public final class TextClassificationConstants {
- private static final String LOG_TAG = TextClassifier.DEFAULT_LOG_TAG;
-
/**
* Whether the smart linkify feature is enabled.
*/
@@ -188,29 +169,26 @@
private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000;
private static final int GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT = 100;
- private static final String STRING_LIST_DELIMITER = ":";
- private static final String ENTITY_LIST_DEFAULT_VALUE = new StringJoiner(STRING_LIST_DELIMITER)
- .add(TextClassifier.TYPE_ADDRESS)
- .add(TextClassifier.TYPE_EMAIL)
- .add(TextClassifier.TYPE_PHONE)
- .add(TextClassifier.TYPE_URL)
- .add(TextClassifier.TYPE_DATE)
- .add(TextClassifier.TYPE_DATE_TIME)
- .add(TextClassifier.TYPE_FLIGHT_NUMBER).toString();
- private static final String CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES =
- new StringJoiner(STRING_LIST_DELIMITER)
- .add(ConversationAction.TYPE_TEXT_REPLY)
- .add(ConversationAction.TYPE_CREATE_REMINDER)
- .add(ConversationAction.TYPE_CALL_PHONE)
- .add(ConversationAction.TYPE_OPEN_URL)
- .add(ConversationAction.TYPE_SEND_EMAIL)
- .add(ConversationAction.TYPE_SEND_SMS)
- .add(ConversationAction.TYPE_TRACK_FLIGHT)
- .add(ConversationAction.TYPE_VIEW_CALENDAR)
- .add(ConversationAction.TYPE_VIEW_MAP)
- .add(ConversationAction.TYPE_ADD_CONTACT)
- .add(ConversationAction.TYPE_COPY)
- .toString();
+ private static final List<String> ENTITY_LIST_DEFAULT_VALUE = Arrays.asList(
+ TextClassifier.TYPE_ADDRESS,
+ TextClassifier.TYPE_EMAIL,
+ TextClassifier.TYPE_PHONE,
+ TextClassifier.TYPE_URL,
+ TextClassifier.TYPE_DATE,
+ TextClassifier.TYPE_DATE_TIME,
+ TextClassifier.TYPE_FLIGHT_NUMBER);
+ private static final List<String> CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES = Arrays.asList(
+ ConversationAction.TYPE_TEXT_REPLY,
+ ConversationAction.TYPE_CREATE_REMINDER,
+ ConversationAction.TYPE_CALL_PHONE,
+ ConversationAction.TYPE_OPEN_URL,
+ ConversationAction.TYPE_SEND_EMAIL,
+ ConversationAction.TYPE_SEND_SMS,
+ ConversationAction.TYPE_TRACK_FLIGHT,
+ ConversationAction.TYPE_VIEW_CALENDAR,
+ ConversationAction.TYPE_VIEW_MAP,
+ ConversationAction.TYPE_ADD_CONTACT,
+ ConversationAction.TYPE_COPY);
/**
* < 0 : Not set. Use value from LangId model.
* 0 - 1: Override value in LangId model.
@@ -221,259 +199,185 @@
private static final boolean TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT = true;
private static final boolean TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT = true;
private static final boolean DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT = true;
- private static final String LANG_ID_CONTEXT_SETTINGS_DEFAULT =
- new StringJoiner(STRING_LIST_DELIMITER).add("20").add("1.0").add("0.4").toString();
+ private static final float[] LANG_ID_CONTEXT_SETTINGS_DEFAULT = new float[] {20f, 1.0f, 0.4f};
- private final boolean mSystemTextClassifierEnabled;
- private final boolean mLocalTextClassifierEnabled;
- private final boolean mModelDarkLaunchEnabled;
- private final boolean mSmartSelectionEnabled;
- private final boolean mSmartTextShareEnabled;
- private final boolean mSmartLinkifyEnabled;
- private final boolean mSmartSelectionAnimationEnabled;
- private final int mSuggestSelectionMaxRangeLength;
- private final int mClassifyTextMaxRangeLength;
- private final int mGenerateLinksMaxTextLength;
- private final int mGenerateLinksLogSampleRate;
- private final List<String> mEntityListDefault;
- private final List<String> mEntityListNotEditable;
- private final List<String> mEntityListEditable;
- private final List<String> mInAppConversationActionTypesDefault;
- private final List<String> mNotificationConversationActionTypesDefault;
- private final float mLangIdThresholdOverride;
- private final boolean mTemplateIntentFactoryEnabled;
- private final boolean mTranslateInClassificationEnabled;
- private final boolean mDetectLanguagesFromTextEnabled;
- private final float[] mLangIdContextSettings;
+ private final ConfigParser mConfigParser;
- private TextClassificationConstants(@Nullable String settings) {
- ConfigParser configParser = new ConfigParser(settings);
- mSystemTextClassifierEnabled =
- configParser.getBoolean(
- SYSTEM_TEXT_CLASSIFIER_ENABLED,
- SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT);
- mLocalTextClassifierEnabled =
- configParser.getBoolean(
- LOCAL_TEXT_CLASSIFIER_ENABLED,
- LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT);
- mModelDarkLaunchEnabled =
- configParser.getBoolean(
- MODEL_DARK_LAUNCH_ENABLED,
- MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
- mSmartSelectionEnabled =
- configParser.getBoolean(
- SMART_SELECTION_ENABLED,
- SMART_SELECTION_ENABLED_DEFAULT);
- mSmartTextShareEnabled =
- configParser.getBoolean(
- SMART_TEXT_SHARE_ENABLED,
- SMART_TEXT_SHARE_ENABLED_DEFAULT);
- mSmartLinkifyEnabled =
- configParser.getBoolean(
- SMART_LINKIFY_ENABLED,
- SMART_LINKIFY_ENABLED_DEFAULT);
- mSmartSelectionAnimationEnabled =
- configParser.getBoolean(
- SMART_SELECT_ANIMATION_ENABLED,
- SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
- mSuggestSelectionMaxRangeLength =
- configParser.getInt(
- SUGGEST_SELECTION_MAX_RANGE_LENGTH,
- SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
- mClassifyTextMaxRangeLength =
- configParser.getInt(
- CLASSIFY_TEXT_MAX_RANGE_LENGTH,
- CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
- mGenerateLinksMaxTextLength =
- configParser.getInt(
- GENERATE_LINKS_MAX_TEXT_LENGTH,
- GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
- mGenerateLinksLogSampleRate =
- configParser.getInt(
- GENERATE_LINKS_LOG_SAMPLE_RATE,
- GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
- mEntityListDefault = parseStringList(
- configParser.getString(
- ENTITY_LIST_DEFAULT,
- ENTITY_LIST_DEFAULT_VALUE));
- mEntityListNotEditable = parseStringList(
- configParser.getString(
- ENTITY_LIST_NOT_EDITABLE,
- ENTITY_LIST_DEFAULT_VALUE));
- mEntityListEditable = parseStringList(
- configParser.getString(
- ENTITY_LIST_EDITABLE,
- ENTITY_LIST_DEFAULT_VALUE));
- mInAppConversationActionTypesDefault = parseStringList(
- configParser.getString(
- IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT,
- CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
- mNotificationConversationActionTypesDefault = parseStringList(
- configParser.getString(
- NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT,
- CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
- mLangIdThresholdOverride =
- configParser.getFloat(
- LANG_ID_THRESHOLD_OVERRIDE,
- LANG_ID_THRESHOLD_OVERRIDE_DEFAULT);
- mTemplateIntentFactoryEnabled =
- configParser.getBoolean(
- TEMPLATE_INTENT_FACTORY_ENABLED,
- TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
- mTranslateInClassificationEnabled =
- configParser.getBoolean(
- TRANSLATE_IN_CLASSIFICATION_ENABLED,
- TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT);
- mDetectLanguagesFromTextEnabled =
- configParser.getBoolean(
- DETECT_LANGUAGES_FROM_TEXT_ENABLED,
- DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT);
- mLangIdContextSettings = parseFloatArray(
- configParser,
- LANG_ID_CONTEXT_SETTINGS,
- LANG_ID_CONTEXT_SETTINGS_DEFAULT);
- }
-
- /** Load from a settings string. */
- public static TextClassificationConstants loadFromString(String settings) {
- return new TextClassificationConstants(settings);
+ public TextClassificationConstants(Supplier<String> legacySettingsSupplier) {
+ mConfigParser = new ConfigParser(legacySettingsSupplier);
}
public boolean isLocalTextClassifierEnabled() {
- return mLocalTextClassifierEnabled;
+ return mConfigParser.getBoolean(
+ LOCAL_TEXT_CLASSIFIER_ENABLED,
+ LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT);
}
public boolean isSystemTextClassifierEnabled() {
- return mSystemTextClassifierEnabled;
+ return mConfigParser.getBoolean(
+ SYSTEM_TEXT_CLASSIFIER_ENABLED,
+ SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT);
}
public boolean isModelDarkLaunchEnabled() {
- return mModelDarkLaunchEnabled;
+ return mConfigParser.getBoolean(
+ MODEL_DARK_LAUNCH_ENABLED,
+ MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
}
public boolean isSmartSelectionEnabled() {
- return mSmartSelectionEnabled;
+ return mConfigParser.getBoolean(
+ SMART_SELECTION_ENABLED,
+ SMART_SELECTION_ENABLED_DEFAULT);
}
public boolean isSmartTextShareEnabled() {
- return mSmartTextShareEnabled;
+ return mConfigParser.getBoolean(
+ SMART_TEXT_SHARE_ENABLED,
+ SMART_TEXT_SHARE_ENABLED_DEFAULT);
}
public boolean isSmartLinkifyEnabled() {
- return mSmartLinkifyEnabled;
+ return mConfigParser.getBoolean(
+ SMART_LINKIFY_ENABLED,
+ SMART_LINKIFY_ENABLED_DEFAULT);
}
public boolean isSmartSelectionAnimationEnabled() {
- return mSmartSelectionAnimationEnabled;
+ return mConfigParser.getBoolean(
+ SMART_SELECT_ANIMATION_ENABLED,
+ SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
}
public int getSuggestSelectionMaxRangeLength() {
- return mSuggestSelectionMaxRangeLength;
+ return mConfigParser.getInt(
+ SUGGEST_SELECTION_MAX_RANGE_LENGTH,
+ SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
}
public int getClassifyTextMaxRangeLength() {
- return mClassifyTextMaxRangeLength;
+ return mConfigParser.getInt(
+ CLASSIFY_TEXT_MAX_RANGE_LENGTH,
+ CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
}
public int getGenerateLinksMaxTextLength() {
- return mGenerateLinksMaxTextLength;
+ return mConfigParser.getInt(
+ GENERATE_LINKS_MAX_TEXT_LENGTH,
+ GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
}
public int getGenerateLinksLogSampleRate() {
- return mGenerateLinksLogSampleRate;
+ return mConfigParser.getInt(
+ GENERATE_LINKS_LOG_SAMPLE_RATE,
+ GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
}
public List<String> getEntityListDefault() {
- return mEntityListDefault;
+ return mConfigParser.getStringList(
+ ENTITY_LIST_DEFAULT,
+ ENTITY_LIST_DEFAULT_VALUE);
}
public List<String> getEntityListNotEditable() {
- return mEntityListNotEditable;
+ return mConfigParser.getStringList(
+ ENTITY_LIST_NOT_EDITABLE,
+ ENTITY_LIST_DEFAULT_VALUE);
}
public List<String> getEntityListEditable() {
- return mEntityListEditable;
+ return mConfigParser.getStringList(
+ ENTITY_LIST_EDITABLE,
+ ENTITY_LIST_DEFAULT_VALUE);
}
public List<String> getInAppConversationActionTypes() {
- return mInAppConversationActionTypesDefault;
+ return mConfigParser.getStringList(
+ IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT,
+ CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES);
}
public List<String> getNotificationConversationActionTypes() {
- return mNotificationConversationActionTypesDefault;
+ return mConfigParser.getStringList(
+ NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT,
+ CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES);
}
public float getLangIdThresholdOverride() {
- return mLangIdThresholdOverride;
+ return mConfigParser.getFloat(
+ LANG_ID_THRESHOLD_OVERRIDE,
+ LANG_ID_THRESHOLD_OVERRIDE_DEFAULT);
}
public boolean isTemplateIntentFactoryEnabled() {
- return mTemplateIntentFactoryEnabled;
+ return mConfigParser.getBoolean(
+ TEMPLATE_INTENT_FACTORY_ENABLED,
+ TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
}
public boolean isTranslateInClassificationEnabled() {
- return mTranslateInClassificationEnabled;
+ return mConfigParser.getBoolean(
+ TRANSLATE_IN_CLASSIFICATION_ENABLED,
+ TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT);
}
public boolean isDetectLanguagesFromTextEnabled() {
- return mDetectLanguagesFromTextEnabled;
+ return mConfigParser.getBoolean(
+ DETECT_LANGUAGES_FROM_TEXT_ENABLED,
+ DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT);
}
public float[] getLangIdContextSettings() {
- return mLangIdContextSettings;
- }
-
- private static List<String> parseStringList(String listStr) {
- return Collections.unmodifiableList(Arrays.asList(listStr.split(STRING_LIST_DELIMITER)));
- }
-
- private static float[] parseFloatArray(
- ConfigParser configParser, String key, String defaultStr) {
- final String str = configParser.getString(key, defaultStr);
- final String[] defaultSplit = defaultStr.split(STRING_LIST_DELIMITER);
- String[] split = str.split(STRING_LIST_DELIMITER);
- if (split.length != defaultSplit.length) {
- Log.v(LOG_TAG, "Error parsing " + key + " flag. Using defaults.");
- split = defaultSplit;
- }
- final float[] result = new float[split.length];
- for (int i = 0; i < split.length; i++) {
- try {
- result[i] = Float.parseFloat(split[i]);
- } catch (NumberFormatException e) {
- Log.v(LOG_TAG, "Error parsing part of " + key + " flag. Using defaults.");
- result[i] = Float.parseFloat(defaultSplit[i]);
- }
- }
- return result;
+ return mConfigParser.getFloatArray(
+ LANG_ID_CONTEXT_SETTINGS,
+ LANG_ID_CONTEXT_SETTINGS_DEFAULT);
}
void dump(IndentingPrintWriter pw) {
pw.println("TextClassificationConstants:");
pw.increaseIndent();
- pw.printPair("isLocalTextClassifierEnabled", mLocalTextClassifierEnabled);
- pw.printPair("isSystemTextClassifierEnabled", mSystemTextClassifierEnabled);
- pw.printPair("isModelDarkLaunchEnabled", mModelDarkLaunchEnabled);
- pw.printPair("isSmartSelectionEnabled", mSmartSelectionEnabled);
- pw.printPair("isSmartTextShareEnabled", mSmartTextShareEnabled);
- pw.printPair("isSmartLinkifyEnabled", mSmartLinkifyEnabled);
- pw.printPair("isSmartSelectionAnimationEnabled", mSmartSelectionAnimationEnabled);
- pw.printPair("getSuggestSelectionMaxRangeLength", mSuggestSelectionMaxRangeLength);
- pw.printPair("getClassifyTextMaxRangeLength", mClassifyTextMaxRangeLength);
- pw.printPair("getGenerateLinksMaxTextLength", mGenerateLinksMaxTextLength);
- pw.printPair("getGenerateLinksLogSampleRate", mGenerateLinksLogSampleRate);
- pw.printPair("getEntityListDefault", mEntityListDefault);
- pw.printPair("getEntityListNotEditable", mEntityListNotEditable);
- pw.printPair("getEntityListEditable", mEntityListEditable);
- pw.printPair("getInAppConversationActionTypes", mInAppConversationActionTypesDefault);
- pw.printPair("getNotificationConversationActionTypes",
- mNotificationConversationActionTypesDefault);
- pw.printPair("getLangIdThresholdOverride", mLangIdThresholdOverride);
- pw.printPair("isTemplateIntentFactoryEnabled", mTemplateIntentFactoryEnabled);
- pw.printPair("isTranslateInClassificationEnabled", mTranslateInClassificationEnabled);
- pw.printPair("isDetectLanguageFromTextEnabled", mDetectLanguagesFromTextEnabled);
- pw.printPair("getLangIdContextSettings", Arrays.toString(mLangIdContextSettings));
+ pw.printPair("classify_text_max_range_length", getClassifyTextMaxRangeLength())
+ .println();
+ pw.printPair("detect_language_from_text_enabled", isDetectLanguagesFromTextEnabled())
+ .println();
+ pw.printPair("entity_list_default", getEntityListDefault())
+ .println();
+ pw.printPair("entity_list_editable", getEntityListEditable())
+ .println();
+ pw.printPair("entity_list_not_editable", getEntityListNotEditable())
+ .println();
+ pw.printPair("generate_links_log_sample_rate", getGenerateLinksLogSampleRate())
+ .println();
+ pw.printPair("generate_links_max_text_length", getGenerateLinksMaxTextLength())
+ .println();
+ pw.printPair("in_app_conversation_action_types_default", getInAppConversationActionTypes())
+ .println();
+ pw.printPair("lang_id_context_settings", Arrays.toString(getLangIdContextSettings()))
+ .println();
+ pw.printPair("lang_id_threshold_override", getLangIdThresholdOverride())
+ .println();
+ pw.printPair("local_textclassifier_enabled", isLocalTextClassifierEnabled())
+ .println();
+ pw.printPair("model_dark_launch_enabled", isModelDarkLaunchEnabled())
+ .println();
+ pw.printPair("notification_conversation_action_types_default",
+ getNotificationConversationActionTypes()).println();
+ pw.printPair("smart_linkify_enabled", isSmartLinkifyEnabled())
+ .println();
+ pw.printPair("smart_select_animation_enabled", isSmartSelectionAnimationEnabled())
+ .println();
+ pw.printPair("smart_selection_enabled", isSmartSelectionEnabled())
+ .println();
+ pw.printPair("smart_text_share_enabled", isSmartTextShareEnabled())
+ .println();
+ pw.printPair("suggest_selection_max_range_length", getSuggestSelectionMaxRangeLength())
+ .println();
+ pw.printPair("system_textclassifier_enabled", isSystemTextClassifierEnabled())
+ .println();
+ pw.printPair("template_intent_factory_enabled", isTemplateIntentFactoryEnabled())
+ .println();
+ pw.printPair("translate_in_classification_enabled", isTranslateInClassificationEnabled())
+ .println();
pw.decreaseIndent();
- pw.println();
}
-}
+}
\ No newline at end of file
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 042b943..95ca9de 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -45,6 +45,9 @@
private static final String LOG_TAG = "TextClassificationManager";
+ private static final TextClassificationConstants sDefaultSettings =
+ new TextClassificationConstants(() -> null);
+
private final Object mLock = new Object();
private final TextClassificationSessionFactory mDefaultSessionFactory =
classificationContext -> new TextClassificationSession(
@@ -129,9 +132,10 @@
private TextClassificationConstants getSettings() {
synchronized (mLock) {
if (mSettings == null) {
- mSettings = TextClassificationConstants.loadFromString(Settings.Global.getString(
- getApplicationContext().getContentResolver(),
- Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+ mSettings = new TextClassificationConstants(
+ () -> Settings.Global.getString(
+ getApplicationContext().getContentResolver(),
+ Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
}
return mSettings;
}
@@ -251,7 +255,11 @@
/** @hide */
@VisibleForTesting
- public void invalidate() {
+ public void invalidateForTesting() {
+ invalidate();
+ }
+
+ private void invalidate() {
synchronized (mLock) {
mSettings = null;
mLocalTextClassifier = null;
@@ -280,9 +288,8 @@
if (tcm != null) {
return tcm.getSettings();
} else {
- return TextClassificationConstants.loadFromString(Settings.Global.getString(
- context.getApplicationContext().getContentResolver(),
- Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+ // Use default settings if there is no tcm.
+ return sDefaultSettings;
}
}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 3297523..3e95f1b 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -301,7 +301,7 @@
final ZonedDateTime refTime = ZonedDateTime.now();
final Collection<String> entitiesToIdentify = request.getEntityConfig() != null
? request.getEntityConfig().resolveEntityListModifications(
- getEntitiesForHints(request.getEntityConfig().getHints()))
+ getEntitiesForHints(request.getEntityConfig().getHints()))
: mSettings.getEntityListDefault();
final String localesString = concatenateLocales(request.getDefaultLocales());
final String detectLanguageTags = detectLanguageTagsFromText(request.getText());
@@ -779,8 +779,8 @@
final float moreTextScoreRatio = 1f - subjectTextScoreRatio;
Log.v(LOG_TAG,
String.format(Locale.US, "LangIdContextSettings: "
- + "minimumTextSize=%d, penalizeRatio=%.2f, "
- + "subjectTextScoreRatio=%.2f, moreTextScoreRatio=%.2f",
+ + "minimumTextSize=%d, penalizeRatio=%.2f, "
+ + "subjectTextScoreRatio=%.2f, moreTextScoreRatio=%.2f",
minimumTextSize, penalizeRatio, subjectTextScoreRatio, moreTextScoreRatio));
if (end - start < minimumTextSize && penalizeRatio <= 0) {
@@ -903,4 +903,3 @@
}
}
}
-
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 96331c2..659272c 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2881,10 +2881,10 @@
if (startType != lastStartType
|| rowPosition == getContentPreviewRowCount() + getProfileRowCount()) {
- row.setBackground(
+ row.setForeground(
getResources().getDrawable(R.drawable.chooser_row_layer_list, null));
} else {
- row.setBackground(null);
+ row.setForeground(null);
}
int columnCount = holder.getColumnCount();
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index dd6fb72..2987b4e 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -406,8 +406,13 @@
private int mHiddenApiAccessStatslogSampleRate = 0;
public static void setHiddenApiAccessLogSampleRates(int sampleRate, int newSampleRate) {
- sInstance.mHiddenApiAccessLogSampleRate = sampleRate;
- sInstance.mHiddenApiAccessStatslogSampleRate = newSampleRate;
+ if (sampleRate != -1) {
+ sInstance.mHiddenApiAccessLogSampleRate = sampleRate;
+ }
+
+ if (newSampleRate != -1) {
+ sInstance.mHiddenApiAccessStatslogSampleRate = newSampleRate;
+ }
}
public static HiddenApiUsageLogger getInstance() {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index ecc9d64..986771d 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -136,8 +136,8 @@
// ColorSpace.Named.SRGB.ordinal() = 0;
static constexpr jint SRGB = 0;
- // ColorSpace.Named.DISPLAY_P3.ordinal() = 6;
- static constexpr jint DISPLAY_P3 = 6;
+ // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
+ static constexpr jint DISPLAY_P3 = 7;
};
constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index e889e85..96a642c 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -60,7 +60,7 @@
android:minWidth="48dp"
android:minHeight="48dp"
android:clickable="true"
- android:background="?android:attr/selectableItemBackgroundBorderless">
+ style="?attr/borderlessButtonStyle">
<ImageView
android:layout_width="24dp"
diff --git a/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
index f1cfe24..d54ce51 100644
--- a/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
@@ -26,16 +26,17 @@
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
+import java.util.function.Supplier;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ConfigParserTest {
- private static final String SETTINGS = "int=42,float=12.3,boolean=true,string=abc";
+ private static final Supplier<String> SETTINGS =
+ () -> "int=42,float=12.3,boolean=true,string=abc";
private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
"device_config delete " + DeviceConfig.NAMESPACE_TEXTCLASSIFIER;
private static final String[] DEVICE_CONFIG_KEYS = new String[]{
@@ -59,7 +60,6 @@
}
@Test
- @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized
public void getBoolean_deviceConfig() {
DeviceConfig.setProperty(
DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
@@ -79,7 +79,6 @@
}
@Test
- @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized
public void getInt_deviceConfig() {
DeviceConfig.setProperty(
DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
@@ -97,7 +96,6 @@
}
@Test
- @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized
public void getFloat_deviceConfig() {
DeviceConfig.setProperty(
DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
@@ -115,7 +113,6 @@
}
@Test
- @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized
public void getString_deviceConfig() {
DeviceConfig.setProperty(
DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java
index f6bb1bf..789b829 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java
@@ -50,9 +50,11 @@
+ "in_app_conversation_action_types_default=text_reply,"
+ "notification_conversation_action_types_default=send_email:call_phone,"
+ "lang_id_threshold_override=0.3,"
- + "lang_id_context_settings=10:1:0.5";
- final TextClassificationConstants constants =
- TextClassificationConstants.loadFromString(s);
+ + "lang_id_context_settings=10:1:0.5,"
+ + "detect_language_from_text_enabled=true,"
+ + "template_intent_factory_enabled=true,"
+ + "translate_in_classification_enabled=true";
+ final TextClassificationConstants constants = new TextClassificationConstants(() -> s);
assertWithMessage("local_textclassifier_enabled")
.that(constants.isLocalTextClassifierEnabled()).isTrue();
@@ -95,6 +97,12 @@
.that(constants.getLangIdThresholdOverride()).isWithin(EPSILON).of(0.3f);
Assert.assertArrayEquals("lang_id_context_settings",
constants.getLangIdContextSettings(), new float[]{10, 1, 0.5f}, EPSILON);
+ assertWithMessage("detect_language_from_text_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isTrue();
+ assertWithMessage("template_intent_factory_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isTrue();
+ assertWithMessage("translate_in_classification_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isTrue();
}
@Test
@@ -116,9 +124,11 @@
+ "in_app_conversation_action_types_default=view_map:track_flight,"
+ "notification_conversation_action_types_default=share_location,"
+ "lang_id_threshold_override=2,"
- + "lang_id_context_settings=30:0.5:0.3";
- final TextClassificationConstants constants =
- TextClassificationConstants.loadFromString(s);
+ + "lang_id_context_settings=30:0.5:0.3,"
+ + "detect_language_from_text_enabled=false,"
+ + "template_intent_factory_enabled=false,"
+ + "translate_in_classification_enabled=false";
+ final TextClassificationConstants constants = new TextClassificationConstants(() -> s);
assertWithMessage("local_textclassifier_enabled")
.that(constants.isLocalTextClassifierEnabled()).isFalse();
@@ -161,12 +171,17 @@
.that(constants.getLangIdThresholdOverride()).isWithin(EPSILON).of(2f);
Assert.assertArrayEquals("lang_id_context_settings",
constants.getLangIdContextSettings(), new float[]{30, 0.5f, 0.3f}, EPSILON);
+ assertWithMessage("detect_language_from_text_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isFalse();
+ assertWithMessage("template_intent_factory_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isFalse();
+ assertWithMessage("translate_in_classification_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isFalse();
}
@Test
public void testLoadFromString_defaultValues() {
- final TextClassificationConstants constants =
- TextClassificationConstants.loadFromString("");
+ final TextClassificationConstants constants = new TextClassificationConstants(() -> "");
assertWithMessage("local_textclassifier_enabled")
.that(constants.isLocalTextClassifierEnabled()).isTrue();
@@ -213,5 +228,11 @@
.that(constants.getLangIdThresholdOverride()).isWithin(EPSILON).of(-1f);
Assert.assertArrayEquals("lang_id_context_settings",
constants.getLangIdContextSettings(), new float[]{20, 1, 0.4f}, EPSILON);
+ assertWithMessage("detect_language_from_text_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isTrue();
+ assertWithMessage("template_intent_factory_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isTrue();
+ assertWithMessage("translate_in_classification_enabled")
+ .that(constants.isLocalTextClassifierEnabled()).isTrue();
}
}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index 4fcd51c..9148185 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -77,7 +77,7 @@
TextClassifier fallback = TextClassifier.NO_OP;
TextClassifier classifier = new TextClassifierImpl(
- fakeContext, TextClassificationConstants.loadFromString(null), fallback);
+ fakeContext, new TextClassificationConstants(() -> null), fallback);
String text = "Contact me at +12122537077";
String classifiedText = "+12122537077";
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
index aeb8949..e3eb2a3 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
@@ -59,7 +59,7 @@
// TODO: Implement TextClassifierService testing.
private static final TextClassificationConstants TC_CONSTANTS =
- TextClassificationConstants.loadFromString("");
+ new TextClassificationConstants(() -> "");
private static final LocaleList LOCALES = LocaleList.forLanguageTags("en-US");
private static final String NO_TYPE = null;
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 98ef00e..27e859c 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -83,6 +83,7 @@
<permission name="android.permission.SET_TIME_ZONE"/>
<permission name="android.permission.SHUTDOWN"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
</privapp-permissions>
<privapp-permissions package="com.android.mms.service">
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 07f81c1..4471017 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -2197,8 +2197,12 @@
}
/**
- *
* @return {@link GraphicBuffer} which is internally used by hardware bitmap
+ *
+ * Note: the GraphicBuffer does *not* have an associated {@link ColorSpace}.
+ * To render this object the same as its rendered with this Bitmap, you
+ * should also call {@link getColorSpace}.
+ *
* @hide
*/
@UnsupportedAppUsage
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
index 9b70272..7709311 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
@@ -28,6 +28,7 @@
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.os.Bundle;
import android.os.RemoteException;
@@ -99,11 +100,17 @@
ActivityManager.TaskSnapshot snapshot =
mActivityTaskManagerInternal.getTaskSnapshot(taskId, false);
GraphicBuffer snapshotBuffer = null;
+ int colorSpaceId = 0;
if (snapshot != null) {
snapshotBuffer = snapshot.getSnapshot();
+ ColorSpace colorSpace = snapshot.getColorSpace();
+ if (colorSpace != null) {
+ colorSpaceId = colorSpace.getId();
+ }
}
- service.provideContextImage(taskId, snapshotBuffer, imageContextRequestExtras);
+ service.provideContextImage(taskId, snapshotBuffer, colorSpaceId,
+ imageContextRequestExtras);
}
}
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
index 4b36352..a8b7b81 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
@@ -68,9 +68,9 @@
}
void provideContextImage(int taskId, @Nullable GraphicBuffer contextImage,
- @NonNull Bundle imageContextRequestExtras) {
+ int colorSpaceId, @NonNull Bundle imageContextRequestExtras) {
scheduleAsyncRequest((s) -> s.provideContextImage(taskId, contextImage,
- imageContextRequestExtras));
+ colorSpaceId, imageContextRequestExtras));
}
void suggestContentSelections(
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 11ddceb..4d0d3d2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2185,24 +2185,38 @@
"hidden_api_access_statslog_sampling_rate";
public void onPropertiesChanged(DeviceConfig.Properties properties) {
- int logSampleRate = properties.getInt(HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, 0x0);
- if (logSampleRate < 0 || logSampleRate > 0x10000) {
- logSampleRate = -1;
- }
- if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
+ int logSampleRate = properties.getInt(HIDDEN_API_ACCESS_LOG_SAMPLING_RATE,
+ mLogSampleRate);
+ int statslogSampleRate = properties.getInt(HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE,
+ mStatslogSampleRate);
+ setSampleRates(logSampleRate, statslogSampleRate);
+ }
+
+ private void setSampleRates(int logSampleRate, int statslogSampleRate) {
+ if (logSampleRate >= 0 && logSampleRate <= 0x10000
+ && logSampleRate != mLogSampleRate) {
mLogSampleRate = logSampleRate;
ZYGOTE_PROCESS.setHiddenApiAccessLogSampleRate(mLogSampleRate);
}
- int statslogSampleRate =
- properties.getInt(HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE, 0);
- if (statslogSampleRate < 0 || statslogSampleRate > 0x10000) {
- statslogSampleRate = -1;
- }
- if (statslogSampleRate != -1 && statslogSampleRate != mStatslogSampleRate) {
+ if (statslogSampleRate >= 0 && statslogSampleRate <= 0x10000
+ && statslogSampleRate != mStatslogSampleRate) {
mStatslogSampleRate = statslogSampleRate;
ZYGOTE_PROCESS.setHiddenApiAccessStatslogSampleRate(mStatslogSampleRate);
}
+
+ }
+
+ /**
+ * Set initial sampling rates from DeviceConfig. This is required after each restart,
+ * if they never get updated.
+ */
+ private void initializeSampleRates() {
+ int logSampleRate = DeviceConfig.getInt(DeviceConfig.NAMESPACE_APP_COMPAT,
+ HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, 0);
+ int statslogSampleRate = DeviceConfig.getInt(DeviceConfig.NAMESPACE_APP_COMPAT,
+ HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE, 0);
+ setSampleRates(logSampleRate, statslogSampleRate);
}
public HiddenApiSettings(Handler handler, Context context) {
@@ -2219,6 +2233,7 @@
Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY),
false,
this);
+ initializeSampleRates();
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APP_COMPAT,
mContext.getMainExecutor(), this);
update();
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index c56d8ea..d04aa89 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3292,7 +3292,7 @@
pw.println(" Starts a given operation for a particular application.");
pw.println(" stop [--user <USER_ID>] <PACKAGE | UID> <OP> ");
pw.println(" Stops a given operation for a particular application.");
- pw.println(" set [--user <USER_ID>] <--uid PACKAGE | PACKAGE | UID> <OP> <MODE>");
+ pw.println(" set [--user <USER_ID>] <[--uid] PACKAGE | UID> <OP> <MODE>");
pw.println(" Set the mode for a particular application and operation.");
pw.println(" get [--user <USER_ID>] <PACKAGE | UID> [<OP>]");
pw.println(" Return the mode for a particular application and optional operation.");
@@ -3305,12 +3305,11 @@
pw.println(" read-settings");
pw.println(" Read the last written settings, replacing current state in RAM.");
pw.println(" options:");
- pw.println(" <PACKAGE> an Android package name.");
+ pw.println(" <PACKAGE> an Android package name or its UID if prefixed by --uid");
pw.println(" <OP> an AppOps operation.");
pw.println(" <MODE> one of allow, ignore, deny, or default");
pw.println(" <USER_ID> the user id under which the package is installed. If --user is not");
pw.println(" specified, the current user is assumed.");
- pw.println(" --uid PACKAGE refer to the UID of the package");
}
static int onShellCommand(Shell shell, String cmd) {
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index ba4dcdb..998ee1e 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -1104,11 +1104,13 @@
@Override
public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
+ final int callingUid = Binder.getCallingUid();
long identityToken = clearCallingIdentity();
try {
SyncManager syncManager = getSyncManager();
if (syncManager != null && callback != null) {
- syncManager.getSyncStorageEngine().addStatusChangeListener(mask, callback);
+ syncManager.getSyncStorageEngine().addStatusChangeListener(
+ mask, UserHandle.getUserId(callingUid), callback);
}
} finally {
restoreCallingIdentity(identityToken);
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 9f80a83..7e79a12 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -3375,7 +3375,8 @@
}
scheduleSyncOperationH(op);
- mSyncStorageEngine.reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+ mSyncStorageEngine.reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
+ target.userId);
}
/**
@@ -3877,7 +3878,8 @@
EventLog.writeEvent(2720,
syncOperation.toEventLog(SyncStorageEngine.EVENT_STOP));
mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime,
- resultMessage, downstreamActivity, upstreamActivity);
+ resultMessage, downstreamActivity, upstreamActivity,
+ syncOperation.target.userId);
}
}
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 6b441a0..c7a3f4b 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -43,6 +43,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.EventLog;
import android.util.Log;
@@ -54,6 +55,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.IntPair;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -588,9 +590,10 @@
return mSyncRandomOffset;
}
- public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
+ public void addStatusChangeListener(int mask, int userId, ISyncStatusObserver callback) {
synchronized (mAuthorities) {
- mChangeListeners.register(callback, mask);
+ final long cookie = IntPair.of(userId, mask);
+ mChangeListeners.register(callback, cookie);
}
}
@@ -622,14 +625,16 @@
}
}
- void reportChange(int which) {
+ void reportChange(int which, int callingUserId) {
ArrayList<ISyncStatusObserver> reports = null;
synchronized (mAuthorities) {
int i = mChangeListeners.beginBroadcast();
while (i > 0) {
i--;
- Integer mask = (Integer)mChangeListeners.getBroadcastCookie(i);
- if ((which & mask.intValue()) == 0) {
+ final long cookie = (long) mChangeListeners.getBroadcastCookie(i);
+ final int userId = IntPair.first(cookie);
+ final int mask = IntPair.second(cookie);
+ if ((which & mask) == 0 || callingUserId != userId) {
continue;
}
if (reports == null) {
@@ -719,7 +724,7 @@
new Bundle(),
syncExemptionFlag, callingUid, callingPid);
}
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, userId);
queueBackup();
}
@@ -787,7 +792,7 @@
requestSync(aInfo, SyncOperation.REASON_IS_SYNCABLE, new Bundle(),
ContentResolver.SYNC_EXEMPTION_NONE, callingUid, callingPid);
}
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, target.userId);
}
public Pair<Long, Long> getBackoff(EndPoint info) {
@@ -833,7 +838,7 @@
}
}
if (changed) {
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, info.userId);
}
}
@@ -871,7 +876,7 @@
}
public void clearAllBackoffsLocked() {
- boolean changed = false;
+ final ArraySet<Integer> changedUserIds = new ArraySet<>();
synchronized (mAuthorities) {
// Clear backoff for all sync adapters.
for (AccountInfo accountInfo : mAccounts.values()) {
@@ -888,14 +893,14 @@
}
authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
- changed = true;
+ changedUserIds.add(accountInfo.accountAndUser.userId);
}
}
}
}
- if (changed) {
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+ for (int i = changedUserIds.size() - 1; i > 0; i--) {
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, changedUserIds.valueAt(i));
}
}
@@ -921,7 +926,7 @@
}
authority.delayUntil = delayUntil;
}
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, info.userId);
}
/**
@@ -964,7 +969,7 @@
new Bundle(),
syncExemptionFlag, callingUid, callingPid);
}
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, userId);
mContext.sendBroadcast(ContentResolver.ACTION_SYNC_CONN_STATUS_CHANGED);
queueBackup();
}
@@ -1015,7 +1020,7 @@
SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
status.pending = pendingValue;
}
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING);
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING, info.userId);
}
/**
@@ -1103,7 +1108,7 @@
activeSyncContext.mStartTime);
getCurrentSyncs(authorityInfo.target.userId).add(syncInfo);
}
- reportActiveChange();
+ reportActiveChange(activeSyncContext.mSyncOperation.target.userId);
return syncInfo;
}
@@ -1120,14 +1125,14 @@
getCurrentSyncs(userId).remove(syncInfo);
}
- reportActiveChange();
+ reportActiveChange(userId);
}
/**
* To allow others to send active change reports, to poke clients.
*/
- public void reportActiveChange() {
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE);
+ public void reportActiveChange(int userId) {
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, userId);
}
/**
@@ -1162,12 +1167,12 @@
if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "returning historyId " + id);
}
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS);
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS, op.target.userId);
return id;
}
public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
- long downstreamActivity, long upstreamActivity) {
+ long downstreamActivity, long upstreamActivity, int userId) {
synchronized (mAuthorities) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Slog.v(TAG, "stopSyncEvent: historyId=" + historyId);
@@ -1307,7 +1312,7 @@
}
}
- reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS);
+ reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS, userId);
}
/**
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 803ab2d..bb9f674 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -44,13 +44,11 @@
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.storage.IStorageManager;
import android.util.Slog;
import android.util.SparseArray;
import android.util.apk.ApkSignatureVerifier;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.content.PackageHelper;
import com.android.internal.os.BackgroundThread;
import java.io.File;
@@ -255,21 +253,6 @@
}
}
- // Make sure we start a filesystem checkpoint on the next boot.
- try {
- IStorageManager storageManager = PackageHelper.getStorageManager();
- if (storageManager.supportsCheckpoint()) {
- storageManager.startCheckpoint(1 /* numRetries */);
- }
- } catch (Exception e) { // TODO(b/130190815) make a RemoteException again
- // While StorageManager lives in the same process, the native implementation
- // it calls through lives in 'vold'; so, this call can fail if 'vold' isn't
- // reachable.
- // Since we can live without filesystem checkpointing, just warn in this case
- // and continue.
- Slog.w(TAG, "Could not start filesystem checkpoint:", e);
- }
-
session.setStagedSessionReady();
if (sessionContainsApex(session)
&& !mApexManager.markStagedSessionReady(session.sessionId)) {
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index db2c742..1682858 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -649,8 +649,7 @@
// hasn't actually been updated.
onPackageReplaced(apexPackageName);
}
-
- mPackageHealthObserver.onBootCompleted();
+ mPackageHealthObserver.onBootCompletedAsync();
});
}
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 748a661..bcef66c 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -32,6 +32,7 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.PowerManager;
+import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Slog;
import android.util.StatsLog;
@@ -49,9 +50,12 @@
import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.TimeUnit;
/**
- * {@code PackageHealthObserver} for {@code RollbackManagerService}.
+ * {@link PackageHealthObserver} for {@link RollbackManagerService}.
+ * This class monitors crashes and triggers RollbackManager rollback accordingly.
+ * It also monitors native crashes for some short while after boot.
*
* @hide
*/
@@ -59,12 +63,21 @@
private static final String TAG = "RollbackPackageHealthObserver";
private static final String NAME = "rollback-observer";
private static final int INVALID_ROLLBACK_ID = -1;
+ // TODO: make the following values configurable via DeviceConfig
+ private static final long NATIVE_CRASH_POLLING_INTERVAL_MILLIS =
+ TimeUnit.SECONDS.toMillis(30);
+ private static final long NUMBER_OF_NATIVE_CRASH_POLLS = 10;
+
private final Context mContext;
private final Handler mHandler;
private final File mLastStagedRollbackIdFile;
+ // this field is initialized in the c'tor and then only accessed from mHandler thread, so
+ // no need to guard with a lock
+ private long mNumberOfNativeCrashPollsRemaining;
RollbackPackageHealthObserver(Context context) {
mContext = context;
+ mNumberOfNativeCrashPollsRemaining = NUMBER_OF_NATIVE_CRASH_POLLS;
HandlerThread handlerThread = new HandlerThread("RollbackPackageHealthObserver");
handlerThread.start();
mHandler = handlerThread.getThreadHandler();
@@ -76,8 +89,6 @@
@Override
public int onHealthCheckFailed(VersionedPackage failedPackage) {
- VersionedPackage moduleMetadataPackage = getModuleMetadataPackage();
-
if (getAvailableRollback(mContext.getSystemService(RollbackManager.class), failedPackage)
== null) {
// Don't handle the notification, no rollbacks available for the package
@@ -145,16 +156,29 @@
PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs);
}
- /** Verifies the rollback state after a reboot. */
- public void onBootCompleted() {
+ /** Verifies the rollback state after a reboot and schedules polling for sometime after reboot
+ * to check for native crashes and mitigate them if needed.
+ */
+ public void onBootCompletedAsync() {
+ mHandler.post(()->onBootCompleted());
+ }
+
+ private void onBootCompleted() {
+ RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
+ PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
+ String moduleMetadataPackageName = getModuleMetadataPackageName();
+ VersionedPackage newModuleMetadataPackage = getModuleMetadataPackage();
+
+ if (getAvailableRollback(rollbackManager, newModuleMetadataPackage) != null) {
+ scheduleCheckAndMitigateNativeCrashes();
+ }
+
int rollbackId = popLastStagedRollbackId();
if (rollbackId == INVALID_ROLLBACK_ID) {
// No staged rollback before reboot
return;
}
- RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
- PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
RollbackInfo rollback = null;
for (RollbackInfo info : rollbackManager.getRecentlyCommittedRollbacks()) {
if (rollbackId == info.getRollbackId()) {
@@ -168,14 +192,12 @@
return;
}
- String moduleMetadataPackageName = getModuleMetadataPackageName();
-
// Use the version of the metadata package that was installed before
// we rolled back for logging purposes.
- VersionedPackage moduleMetadataPackage = null;
+ VersionedPackage oldModuleMetadataPackage = null;
for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
if (packageRollback.getPackageName().equals(moduleMetadataPackageName)) {
- moduleMetadataPackage = packageRollback.getVersionRolledBackFrom();
+ oldModuleMetadataPackage = packageRollback.getVersionRolledBackFrom();
break;
}
}
@@ -187,12 +209,12 @@
return;
}
if (sessionInfo.isStagedSessionApplied()) {
- logEvent(moduleMetadataPackage,
+ logEvent(oldModuleMetadataPackage,
StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS);
} else if (sessionInfo.isStagedSessionReady()) {
// TODO: What do for staged session ready but not applied
} else {
- logEvent(moduleMetadataPackage,
+ logEvent(oldModuleMetadataPackage,
StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
}
}
@@ -320,4 +342,34 @@
moduleMetadataPackage.getPackageName(), moduleMetadataPackage.getVersionCode());
}
}
+
+ /**
+ * This method should be only called on mHandler thread, since it modifies
+ * {@link #mNumberOfNativeCrashPollsRemaining} and we want to keep this class lock free.
+ */
+ private void checkAndMitigateNativeCrashes() {
+ mNumberOfNativeCrashPollsRemaining--;
+ // Check if native watchdog reported a crash
+ if ("1".equals(SystemProperties.get("ro.init.updatable_crashing"))) {
+ execute(getModuleMetadataPackage());
+ // we stop polling after an attempt to execute rollback, regardless of whether the
+ // attempt succeeds or not
+ } else {
+ if (mNumberOfNativeCrashPollsRemaining > 0) {
+ mHandler.postDelayed(() -> checkAndMitigateNativeCrashes(),
+ NATIVE_CRASH_POLLING_INTERVAL_MILLIS);
+ }
+ }
+ }
+
+ /**
+ * Since this method can eventually trigger a RollbackManager rollback, it should be called
+ * only once boot has completed {@code onBootCompleted} and not earlier, because the install
+ * session must be entirely completed before we try to rollback.
+ */
+ private void scheduleCheckAndMitigateNativeCrashes() {
+ Slog.i(TAG, "Scheduling " + mNumberOfNativeCrashPollsRemaining + " polls to check "
+ + "and mitigate native crashes");
+ mHandler.post(()->checkAndMitigateNativeCrashes());
+ }
}
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
index 6318486..4d972dc 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -129,7 +129,7 @@
mSurfaceAnimator.startAnimation(t, new LocalAnimationAdapter(
new WindowAnimationSpec(anim, position,
mAppToken.getDisplayContent().mAppTransition.canSkipFirstFrame(),
- mAppToken.getWindowCornerRadiusForAnimation()),
+ mAppToken.getDisplayContent().getWindowCornerRadius()),
mAppToken.mWmService.mSurfaceAnimationRunner), false /* hidden */);
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 8785b01..81d6898 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2558,7 +2558,7 @@
getDisplayContent().mAppTransition.canSkipFirstFrame(),
appStackClipMode,
true /* isAppAnimation */,
- getWindowCornerRadiusForAnimation()),
+ getDisplayContent().getWindowCornerRadius()),
mWmService.mSurfaceAnimationRunner);
if (a.getZAdjustment() == Animation.ZORDER_TOP) {
mNeedsZBoost = true;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index b4b60ea..6a5c84a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -554,6 +554,9 @@
// Last systemUiVisibility we dispatched to windows.
private int mLastDispatchedSystemUiVisibility = 0;
+ /** Corner radius that windows should have in order to match the display. */
+ private final float mWindowCornerRadius;
+
private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
WindowStateAnimator winAnimator = w.mWinAnimator;
final AppWindowToken atoken = w.mAppToken;
@@ -914,6 +917,7 @@
if (mWmService.mSystemReady) {
mDisplayPolicy.systemReady();
}
+ mWindowCornerRadius = mDisplayPolicy.getWindowCornerRadius();
mDividerControllerLocked = new DockedStackDividerController(service, this);
mPinnedStackControllerLocked = new PinnedStackController(service, this);
@@ -958,6 +962,10 @@
return mDisplayId;
}
+ float getWindowCornerRadius() {
+ return mWindowCornerRadius;
+ }
+
WindowToken getWindowToken(IBinder binder) {
return mTokenMap.get(binder);
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 32d0b32..26430fb 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -25,6 +25,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
+import static android.view.Display.TYPE_BUILT_IN;
import static android.view.InsetsState.TYPE_TOP_BAR;
import static android.view.InsetsState.TYPE_TOP_GESTURES;
import static android.view.InsetsState.TYPE_TOP_TAPPABLE_ELEMENT;
@@ -157,6 +158,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.util.ScreenshotHelper;
import com.android.internal.util.function.TriConsumer;
@@ -2870,6 +2872,16 @@
- statusBarHeight;
}
+ /**
+ * Return corner radius in pixels that should be used on windows in order to cover the display.
+ * The radius is only valid for built-in displays since the one who configures window corner
+ * radius cannot know the corner radius of non-built-in display.
+ */
+ float getWindowCornerRadius() {
+ return mDisplayContent.getDisplay().getType() == TYPE_BUILT_IN
+ ? ScreenDecorationsUtils.getWindowCornerRadius(mContext.getResources()) : 0f;
+ }
+
boolean isShowingDreamLw() {
return mShowingDream;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7c1ea20..7ac887e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -240,7 +240,6 @@
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
-import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.LatencyTracker;
@@ -793,9 +792,6 @@
final DisplayManager mDisplayManager;
final ActivityTaskManagerService mAtmService;
- /** Corner radius that windows should have in order to match the display. */
- final float mWindowCornerRadius;
-
/** Indicates whether this device supports wide color gamut / HDR rendering */
private boolean mHasWideColorGamutSupport;
private boolean mHasHdrSupport;
@@ -1020,7 +1016,6 @@
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplayWindowSettings = new DisplayWindowSettings(this);
- mWindowCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context.getResources());
mTransactionFactory = transactionFactory;
mTransaction = mTransactionFactory.make();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 2a621be..8cbad2d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -4599,7 +4599,7 @@
anim.scaleCurrentDuration(mWmService.getWindowAnimationScaleLocked());
final AnimationAdapter adapter = new LocalAnimationAdapter(
new WindowAnimationSpec(anim, mSurfacePosition, false /* canSkipFirstFrame */,
- mToken.getWindowCornerRadiusForAnimation()),
+ getDisplayContent().getWindowCornerRadius()),
mWmService.mSurfaceAnimationRunner);
startAnimation(mPendingTransaction, adapter);
commitPendingTransaction();
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index f65f0ab..f0b9c62 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -345,8 +345,4 @@
mOwnerCanManageAppTokens);
return mOwnerCanManageAppTokens && (layer > navLayer);
}
-
- float getWindowCornerRadiusForAnimation() {
- return mDisplayContent.isDefaultDisplay ? mWmService.mWindowCornerRadius : 0;
- }
}