diff options
482 files changed, 5896 insertions, 2112 deletions
diff --git a/api/TEST_MAPPING b/api/TEST_MAPPING new file mode 100644 index 000000000000..8a676e994081 --- /dev/null +++ b/api/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "CtsCurrentApiSignatureTestCases" + } + ] +} diff --git a/api/current.txt b/api/current.txt index abab90182b01..c0d10a6bc20a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -14191,13 +14191,16 @@ package android.graphics { field public static final int YV12 = 842094169; // 0x32315659 } - public final class Insets { + public final class Insets implements android.os.Parcelable { method @NonNull public static android.graphics.Insets add(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets); + method public int describeContents(); method @NonNull public static android.graphics.Insets max(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets); method @NonNull public static android.graphics.Insets min(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets); method @NonNull public static android.graphics.Insets of(int, int, int, int); method @NonNull public static android.graphics.Insets of(@Nullable android.graphics.Rect); method @NonNull public static android.graphics.Insets subtract(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.graphics.Insets> CREATOR; field public static final android.graphics.Insets NONE; field public final int bottom; field public final int left; @@ -16489,6 +16492,7 @@ package android.hardware.biometrics { field public static final int BIOMETRIC_ERROR_LOCKOUT = 7; // 0x7 field public static final int BIOMETRIC_ERROR_LOCKOUT_PERMANENT = 9; // 0x9 field public static final int BIOMETRIC_ERROR_NO_BIOMETRICS = 11; // 0xb + field public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; // 0xe field public static final int BIOMETRIC_ERROR_NO_SPACE = 4; // 0x4 field public static final int BIOMETRIC_ERROR_TIMEOUT = 3; // 0x3 field public static final int BIOMETRIC_ERROR_UNABLE_TO_PROCESS = 2; // 0x2 @@ -16511,8 +16515,8 @@ package android.hardware.biometrics { public static class BiometricPrompt.Builder { ctor public BiometricPrompt.Builder(android.content.Context); method public android.hardware.biometrics.BiometricPrompt build(); + method public android.hardware.biometrics.BiometricPrompt.Builder setAllowDeviceCredential(boolean); method public android.hardware.biometrics.BiometricPrompt.Builder setDescription(@NonNull CharSequence); - method public android.hardware.biometrics.BiometricPrompt.Builder setEnableFallback(boolean); method public android.hardware.biometrics.BiometricPrompt.Builder setNegativeButton(@NonNull CharSequence, @NonNull java.util.concurrent.Executor, @NonNull android.content.DialogInterface.OnClickListener); method public android.hardware.biometrics.BiometricPrompt.Builder setRequireConfirmation(boolean); method public android.hardware.biometrics.BiometricPrompt.Builder setSubtitle(@NonNull CharSequence); @@ -24535,7 +24539,9 @@ package android.media { } public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint { + ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int); method public boolean covers(@NonNull android.media.MediaFormat); + method public boolean covers(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint); field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_100; field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_120; field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_200; @@ -24570,8 +24576,8 @@ package android.media { field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_50; field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_60; field public final int frameRate; - field public final int height; - field public final int width; + field public final long macroBlockRate; + field public final int macroBlocks; } public final class MediaCodecList { @@ -38340,11 +38346,7 @@ package android.provider { method @NonNull public static String getVolumeName(@NonNull android.net.Uri); method @NonNull public static android.provider.MediaStore.PendingSession openPending(@NonNull android.content.Context, @NonNull android.net.Uri); method @NonNull public static android.net.Uri setIncludePending(@NonNull android.net.Uri); - method @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri); method @NonNull public static android.net.Uri setRequireOriginal(@NonNull android.net.Uri); - method public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri); - method public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri, long); - method public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri); field public static final String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE"; field public static final String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE"; field public static final String ACTION_REVIEW = "android.provider.action.REVIEW"; @@ -38615,14 +38617,14 @@ package android.provider { public static interface MediaStore.MediaColumns extends android.provider.BaseColumns { field @Deprecated public static final String DATA = "_data"; field public static final String DATE_ADDED = "date_added"; - field public static final String DATE_EXPIRES = "date_expires"; field public static final String DATE_MODIFIED = "date_modified"; field public static final String DISPLAY_NAME = "_display_name"; - field public static final String HASH = "_hash"; + field public static final String DOCUMENT_ID = "document_id"; field public static final String HEIGHT = "height"; + field public static final String INSTANCE_ID = "instance_id"; field public static final String IS_PENDING = "is_pending"; - field public static final String IS_TRASHED = "is_trashed"; field public static final String MIME_TYPE = "mime_type"; + field public static final String ORIGINAL_DOCUMENT_ID = "original_document_id"; field public static final String OWNER_PACKAGE_NAME = "owner_package_name"; field public static final String PRIMARY_DIRECTORY = "primary_directory"; field public static final String SECONDARY_DIRECTORY = "secondary_directory"; @@ -49550,6 +49552,7 @@ package android.view { ctor protected LayoutInflater(android.view.LayoutInflater, android.content.Context); method public abstract android.view.LayoutInflater cloneInContext(android.content.Context); method public final android.view.View createView(String, String, android.util.AttributeSet) throws java.lang.ClassNotFoundException, android.view.InflateException; + method @Nullable public final android.view.View createView(@NonNull android.content.Context, @NonNull String, @Nullable String, @Nullable android.util.AttributeSet) throws java.lang.ClassNotFoundException, android.view.InflateException; method public static android.view.LayoutInflater from(android.content.Context); method public android.content.Context getContext(); method public final android.view.LayoutInflater.Factory getFactory(); @@ -49561,6 +49564,7 @@ package android.view { method public android.view.View inflate(org.xmlpull.v1.XmlPullParser, @Nullable android.view.ViewGroup, boolean); method protected android.view.View onCreateView(String, android.util.AttributeSet) throws java.lang.ClassNotFoundException; method protected android.view.View onCreateView(android.view.View, String, android.util.AttributeSet) throws java.lang.ClassNotFoundException; + method @Nullable public android.view.View onCreateView(@NonNull android.content.Context, @Nullable android.view.View, @NonNull String, @Nullable android.util.AttributeSet) throws java.lang.ClassNotFoundException; method public void setFactory(android.view.LayoutInflater.Factory); method public void setFactory2(android.view.LayoutInflater.Factory2); method public void setFilter(android.view.LayoutInflater.Filter); @@ -51111,6 +51115,7 @@ package android.view { method public int getScaledHoverSlop(); method public int getScaledMaximumDrawingCacheSize(); method public int getScaledMaximumFlingVelocity(); + method public int getScaledMinScalingSpan(); method public int getScaledMinimumFlingVelocity(); method public int getScaledOverflingDistance(); method public int getScaledOverscrollDistance(); @@ -55245,6 +55250,7 @@ package android.widget { method public void performCompletion(); method protected void performFiltering(CharSequence, int); method public void performValidation(); + method public final void refreshAutoCompleteResults(); method protected void replaceText(CharSequence); method public <T extends android.widget.ListAdapter & android.widget.Filterable> void setAdapter(T); method public void setCompletionHint(CharSequence); @@ -56009,6 +56015,7 @@ package android.widget { method @Nullable public android.view.View getAnchorView(); method @StyleRes public int getAnimationStyle(); method @Nullable public android.graphics.drawable.Drawable getBackground(); + method @Nullable public android.graphics.Rect getEpicenterBounds(); method public int getHeight(); method public int getHorizontalOffset(); method public int getInputMethodMode(); @@ -56035,6 +56042,7 @@ package android.widget { method public void setBackgroundDrawable(@Nullable android.graphics.drawable.Drawable); method public void setContentWidth(int); method public void setDropDownGravity(int); + method public void setEpicenterBounds(@Nullable android.graphics.Rect); method public void setHeight(int); method public void setHorizontalOffset(int); method public void setInputMethodMode(int); @@ -56295,6 +56303,7 @@ package android.widget { method public android.view.View getContentView(); method public float getElevation(); method @Nullable public android.transition.Transition getEnterTransition(); + method @Nullable public android.graphics.Rect getEpicenterBounds(); method @Nullable public android.transition.Transition getExitTransition(); method public int getHeight(); method public int getInputMethodMode(); @@ -56307,30 +56316,37 @@ package android.widget { method public int getWindowLayoutType(); method public boolean isAboveAnchor(); method public boolean isAttachedInDecor(); + method public boolean isClipToScreenEnabled(); method public boolean isClippingEnabled(); method public boolean isFocusable(); + method public boolean isLayoutInScreenEnabled(); method public boolean isOutsideTouchable(); method public boolean isShowing(); method public boolean isSplitTouchEnabled(); + method public boolean isTouchModal(); method public boolean isTouchable(); method public void setAnimationStyle(int); method public void setAttachedInDecor(boolean); method public void setBackgroundDrawable(android.graphics.drawable.Drawable); + method public void setClipToScreenEnabled(boolean); method public void setClippingEnabled(boolean); method public void setContentView(android.view.View); method public void setElevation(float); method public void setEnterTransition(@Nullable android.transition.Transition); + method public void setEpicenterBounds(@Nullable android.graphics.Rect); method public void setExitTransition(@Nullable android.transition.Transition); method public void setFocusable(boolean); method public void setHeight(int); method public void setIgnoreCheekPress(); method public void setInputMethodMode(int); + method public void setLayoutInScreenEnabled(boolean); method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener); method public void setOutsideTouchable(boolean); method public void setOverlapAnchor(boolean); method public void setSoftInputMode(int); method public void setSplitTouchEnabled(boolean); method public void setTouchInterceptor(android.view.View.OnTouchListener); + method public void setTouchModal(boolean); method public void setTouchable(boolean); method public void setWidth(int); method @Deprecated public void setWindowLayoutMode(int, int); diff --git a/api/removed.txt b/api/removed.txt index 262ffec46de1..f5bd434c3cc0 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -507,6 +507,19 @@ package android.provider { field @Deprecated public static final String TIMESTAMP = "timestamp"; } + public final class MediaStore { + method @Deprecated @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri); + method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri); + method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri, long); + method @Deprecated public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri); + } + + public static interface MediaStore.MediaColumns extends android.provider.BaseColumns { + field @Deprecated public static final String DATE_EXPIRES = "date_expires"; + field @Deprecated public static final String HASH = "_hash"; + field @Deprecated public static final String IS_TRASHED = "is_trashed"; + } + public static final class Settings.Global extends android.provider.Settings.NameValueTable { field @Deprecated public static final String CONTACT_METADATA_SYNC = "contact_metadata_sync"; } diff --git a/api/system-current.txt b/api/system-current.txt index 02718cbaac07..3a5023992074 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -201,7 +201,6 @@ package android { } public static final class R.array { - field public static final int config_defaultRoleHolders = 17235974; // 0x1070006 field public static final int config_keySystemUuidMapping = 17235973; // 0x1070005 } @@ -237,6 +236,10 @@ package android { } public static final class R.string { + field public static final int config_defaultAssistant = 17039393; // 0x1040021 + field public static final int config_defaultBrowser = 17039394; // 0x1040022 + field public static final int config_defaultDialer = 17039395; // 0x1040023 + field public static final int config_defaultSms = 17039396; // 0x1040024 field public static final int config_feedbackIntentExtraKey = 17039391; // 0x104001f field public static final int config_feedbackIntentNameKey = 17039392; // 0x1040020 field public static final int config_helpIntentExtraKey = 17039389; // 0x104001d @@ -5739,10 +5742,6 @@ package android.provider { field public static final String SERVICE_ENABLED = "service_enabled"; } - public static interface DeviceConfig.ContentCapture { - field public static final String NAMESPACE = "content_capture"; - } - public static interface DeviceConfig.DexBoot { field public static final String NAMESPACE = "dex_boot"; field public static final String PRIV_APPS_OOB_ENABLED = "priv_apps_oob_enabled"; diff --git a/api/test-current.txt b/api/test-current.txt index 2c8d08c49fdb..b2ead4ab2464 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -17,8 +17,9 @@ package android { field public static final String WRITE_OBB = "android.permission.WRITE_OBB"; } - public static final class R.array { - field public static final int config_defaultRoleHolders = 17235974; // 0x1070006 + public static final class R.string { + field public static final int config_defaultAssistant = 17039393; // 0x1040021 + field public static final int config_defaultDialer = 17039395; // 0x1040023 } } @@ -1784,8 +1785,10 @@ package android.provider { } public final class DeviceConfig { + method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(String, String); method @RequiresPermission("android.permission.WRITE_DEVICE_CONFIG") public static void resetToDefaults(int, @Nullable String); method @RequiresPermission("android.permission.WRITE_DEVICE_CONFIG") public static boolean setProperty(String, String, String, boolean); + field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; } public static interface DeviceConfig.Privacy { @@ -1853,6 +1856,7 @@ package android.provider { field @Deprecated public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = "enabled_notification_policy_access_packages"; field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis"; field public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS = "location_access_check_interval_millis"; + field public static final String NOTIFICATION_BADGING = "notification_badging"; field public static final String NOTIFICATION_BUBBLES = "notification_bubbles"; field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds"; field public static final String USER_SETUP_COMPLETE = "user_setup_complete"; @@ -2152,6 +2156,10 @@ package android.telecom { ctor public CallAudioState(boolean, int, int, @Nullable android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.bluetooth.BluetoothDevice>); } + public abstract class Conference extends android.telecom.Conferenceable { + method public android.telecom.Connection getPrimaryConnection(); + } + public final class PhoneAccountSuggestion implements android.os.Parcelable { ctor public PhoneAccountSuggestion(android.telecom.PhoneAccountHandle, int, boolean); } @@ -2164,6 +2172,16 @@ package android.telecom { field public static final String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService"; } + public class TelecomManager { + method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getCurrentTtyMode(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(android.telecom.PhoneAccountHandle); + field public static final int TTY_MODE_FULL = 1; // 0x1 + field public static final int TTY_MODE_HCO = 2; // 0x2 + field public static final int TTY_MODE_OFF = 0; // 0x0 + field public static final int TTY_MODE_VCO = 3; // 0x3 + } + } package android.telephony { @@ -2717,6 +2735,7 @@ package android.view.contentcapture { public final class ContentCaptureManager { method public boolean isContentCaptureFeatureEnabled(); method public void setContentCaptureFeatureEnabled(boolean); + field public static final String DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED = "service_explicitly_enabled"; } public final class ViewNode extends android.app.assist.AssistStructure.ViewNode { diff --git a/cmds/incidentd/Android.bp b/cmds/incidentd/Android.bp index 40da583e4f6c..3dc10939fed7 100644 --- a/cmds/incidentd/Android.bp +++ b/cmds/incidentd/Android.bp @@ -94,8 +94,10 @@ cc_test { data: ["testdata/**/*"], - static_libs: ["libgmock"], - + static_libs: [ + "libgmock", + "libplatformprotos", + ], shared_libs: [ "libbase", "libbinder", diff --git a/cmds/incidentd/tests/Reporter_test.cpp b/cmds/incidentd/tests/Reporter_test.cpp index f54f738fb62b..b5e41d767295 100644 --- a/cmds/incidentd/tests/Reporter_test.cpp +++ b/cmds/incidentd/tests/Reporter_test.cpp @@ -35,6 +35,16 @@ using namespace std; using ::testing::StrEq; using ::testing::Test; +namespace { +void getHeaderData(const IncidentHeaderProto& headerProto, vector<uint8_t>* out) { + out->clear(); + auto serialized = headerProto.SerializeAsString(); + if (serialized.empty()) return; + out->resize(serialized.length()); + std::copy(serialized.begin(), serialized.end(), out->begin()); +} +} + class TestListener : public IIncidentReportStatusListener { public: int startInvoked; @@ -143,7 +153,10 @@ TEST_F(ReporterTest, RunReportWithHeaders) { args2.addSection(2); IncidentHeaderProto header; header.set_alert_id(12); - args2.addHeader(header); + + vector<uint8_t> out; + getHeaderData(header, &out); + args2.addHeader(out); sp<ReportRequest> r1 = new ReportRequest(args1, l, tf.fd); sp<ReportRequest> r2 = new ReportRequest(args2, l, tf.fd); @@ -169,8 +182,12 @@ TEST_F(ReporterTest, RunReportToGivenDirectory) { IncidentHeaderProto header1, header2; header1.set_alert_id(12); header2.set_reason("abcd"); - args.addHeader(header1); - args.addHeader(header2); + + vector<uint8_t> out; + getHeaderData(header1, &out); + args.addHeader(out); + getHeaderData(header2, &out); + args.addHeader(out); sp<ReportRequest> r = new ReportRequest(args, l, -1); reporter->batch.add(r); diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp index 9b684a060286..24454ed15d40 100644 --- a/cmds/incidentd/tests/Section_test.cpp +++ b/cmds/incidentd/tests/Section_test.cpp @@ -82,6 +82,16 @@ protected: virtual IBinder* onAsBinder() override { return nullptr; }; }; +namespace { +void getHeaderData(const IncidentHeaderProto& headerProto, vector<uint8_t>* out) { + out->clear(); + auto serialized = headerProto.SerializeAsString(); + if (serialized.empty()) return; + out->resize(serialized.length()); + std::copy(serialized.begin(), serialized.end(), out->begin()); +} +} + TEST_F(SectionTest, HeaderSection) { HeaderSection hs; @@ -94,9 +104,15 @@ TEST_F(SectionTest, HeaderSection) { head1.set_reason("axe"); head2.set_reason("pup"); - args1.addHeader(head1); - args1.addHeader(head2); - args2.addHeader(head2); + vector<uint8_t> out; + getHeaderData(head1, &out); + args1.addHeader(out); + + getHeaderData(head2, &out); + args1.addHeader(out); + + getHeaderData(head2, &out); + args2.addHeader(out); requests.add(new ReportRequest(args1, new SimpleListener(), -1)); requests.add(new ReportRequest(args2, new SimpleListener(), tf.fd)); diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 250f5bfd0685..dd18bd4cc8ad 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -526,9 +526,10 @@ void StatsLogProcessor::WriteMetricsActivationToDisk(int64_t currentTimeNs) { proto.write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_ID, (long long)pair.first.GetId()); proto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_UID, pair.first.GetUid()); - vector<const MetricProducer*> acrtiveMetrics; - pair.second->getActiveMetrics(acrtiveMetrics); - for (const MetricProducer* metric : acrtiveMetrics) { + vector<MetricProducer*> activeMetrics; + pair.second->prepForShutDown(currentTimeNs); + pair.second->getActiveMetrics(activeMetrics); + for (MetricProducer* metric : activeMetrics) { if (metric->isActive()) { uint64_t metricToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_ACTIVE_METRIC); diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index 77d9a2f5f418..caf1a713986d 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -195,6 +195,7 @@ private: FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast); FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge); FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead); + FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot); FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1); FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2); diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp index ad5eae361f1c..6b46b8b3b900 100644 --- a/cmds/statsd/src/anomaly/subscriber_util.cpp +++ b/cmds/statsd/src/anomaly/subscriber_util.cpp @@ -23,7 +23,6 @@ #include "external/Perfetto.h" #include "external/Perfprofd.h" -#include "frameworks/base/libs/incident/proto/android/os/header.pb.h" #include "subscriber/IncidentdReporter.h" #include "subscriber/SubscriberReporter.h" diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 4f17d69f23f2..7ddb783d71e1 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -41,12 +41,13 @@ import "frameworks/base/core/proto/android/service/procstats_enum.proto"; import "frameworks/base/core/proto/android/service/usb.proto"; import "frameworks/base/core/proto/android/stats/enums.proto"; import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto"; +import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto"; +import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy_enums.proto"; import "frameworks/base/core/proto/android/stats/launcher/launcher.proto"; import "frameworks/base/core/proto/android/telecomm/enums.proto"; import "frameworks/base/core/proto/android/telephony/enums.proto"; import "frameworks/base/core/proto/android/view/enums.proto"; -import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy_enums.proto"; -import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto"; +import "frameworks/base/core/proto/android/wifi/enums.proto"; /** * The master atom class. This message defines all of the available @@ -214,7 +215,7 @@ message Atom { SpeechDspStatReported speech_dsp_stat_reported = 145; UsbContaminantReported usb_contaminant_reported = 146; WatchdogRollbackOccurred watchdog_rollback_occurred = 147; - BiometricHalDeathReported biometric_hal_death_reported = 148; + BiometricSystemHealthIssueDetected biometric_system_health_issue_detected = 148; BubbleUIChanged bubble_ui_changed = 149; ScheduledJobConstraintChanged scheduled_job_constraint_changed = 150; BluetoothActiveDeviceChanged bluetooth_active_device_changed = 151; @@ -994,6 +995,9 @@ message WifiLockStateChanged { ON = 1; } optional State state = 2; + + // WifiLock type, from frameworks/base/core/proto/android/wifi/enums.proto. + optional android.net.wifi.WifiModeEnum mode = 3; } /** @@ -2082,9 +2086,9 @@ message BluetoothSocketConnectionStateChanged { // Salt: Randomly generated 256 bit value // Hash algorithm: HMAC-SHA256 // Size: 32 byte - // Default: null or empty if the device identifier is not known + // Default: null or empty if this is a server listener socket optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Port of this socket + // Temporary port of this socket for the current connection or session only // Default 0 when unknown or don't care optional int32 port = 2; // Socket type as mentioned in @@ -2098,6 +2102,14 @@ message BluetoothSocketConnectionStateChanged { optional int64 tx_bytes = 5; // Number of bytes received from remote device during this connection optional int64 rx_bytes = 6; + // Socket owner's UID + optional int32 uid = 7 [(is_uid) = true]; + // Server port of this socket, if any. When both |server_port| and |port| fields are populated, + // |port| must be spawned by |server_port| + // Default 0 when unknown or don't care + optional int32 server_port = 8; + // Whether this is a server listener socket + optional android.bluetooth.SocketRoleEnum is_server = 9; } /** @@ -3046,13 +3058,15 @@ message BiometricErrorOccurred { } /** - * Logs when a biometric HAL has crashed. + * Logs when a system health issue is detected. * Logged from: * frameworks/base/services/core/java/com/android/server/biometrics */ -message BiometricHalDeathReported { +message BiometricSystemHealthIssueDetected { // Biometric modality. optional android.hardware.biometrics.ModalityEnum modality = 1; + // Type of issue detected. + optional android.hardware.biometrics.IssueEnum issue = 2; } message Notification { diff --git a/cmds/statsd/src/external/PullDataReceiver.h b/cmds/statsd/src/external/PullDataReceiver.h index b071682f8a59..d2193f41b80a 100644 --- a/cmds/statsd/src/external/PullDataReceiver.h +++ b/cmds/statsd/src/external/PullDataReceiver.h @@ -32,9 +32,10 @@ class PullDataReceiver : virtual public RefBase{ * @param data The pulled data. * @param pullSuccess Whether the pull succeeded. If the pull does not succeed, the data for the * bucket should be invalidated. + * @param originalPullTimeNs This is when all the pulls have been initiated (elapsed time). */ virtual void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data, - bool pullSuccess) = 0; + bool pullSuccess, int64_t originalPullTimeNs) = 0; }; } // namespace statsd diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index 9b603d6c7957..ecdcd21d44dd 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -174,9 +174,12 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { // Size of specific categories of files. Eg. Music. {android::util::CATEGORY_SIZE, {.puller = new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}}, - // Number of fingerprints registered to each user. + // Number of fingerprints enrolled for each user. {android::util::NUM_FINGERPRINTS_ENROLLED, {.puller = new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS_ENROLLED)}}, + // Number of faces enrolled for each user. + {android::util::NUM_FACES_ENROLLED, + {.puller = new StatsCompanionServicePuller(android::util::NUM_FACES_ENROLLED)}}, // ProcStats. {android::util::PROC_STATS, {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS)}}, @@ -381,7 +384,7 @@ void StatsPullerManager::OnAlarmFired(int64_t elapsedTimeNs) { for (const auto& receiverInfo : pullInfo.second) { sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote(); if (receiverPtr != nullptr) { - receiverPtr->onDataPulled(data, pullSuccess); + receiverPtr->onDataPulled(data, pullSuccess, elapsedTimeNs); // We may have just come out of a coma, compute next pull time. int numBucketsAhead = (elapsedTimeNs - receiverInfo->nextPullTimeNs) / receiverInfo->intervalNs; diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index 37d5ba0e6801..c4034ffeee22 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -423,41 +423,50 @@ void StatsdStats::noteEmptyData(int atomId) { mPulledAtomStats[atomId].emptyData++; } -void StatsdStats::noteHardDimensionLimitReached(int metricId) { +void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) { lock_guard<std::mutex> lock(mLock); getAtomMetricStats(metricId).hardDimensionLimitReached++; } -void StatsdStats::noteLateLogEventSkipped(int metricId) { +void StatsdStats::noteLateLogEventSkipped(int64_t metricId) { lock_guard<std::mutex> lock(mLock); getAtomMetricStats(metricId).lateLogEventSkipped++; } -void StatsdStats::noteSkippedForwardBuckets(int metricId) { +void StatsdStats::noteSkippedForwardBuckets(int64_t metricId) { lock_guard<std::mutex> lock(mLock); getAtomMetricStats(metricId).skippedForwardBuckets++; } -void StatsdStats::noteBadValueType(int metricId) { +void StatsdStats::noteBadValueType(int64_t metricId) { lock_guard<std::mutex> lock(mLock); getAtomMetricStats(metricId).badValueType++; } -void StatsdStats::noteBucketDropped(int metricId) { +void StatsdStats::noteBucketDropped(int64_t metricId) { lock_guard<std::mutex> lock(mLock); getAtomMetricStats(metricId).bucketDropped++; } -void StatsdStats::noteConditionChangeInNextBucket(int metricId) { +void StatsdStats::noteConditionChangeInNextBucket(int64_t metricId) { lock_guard<std::mutex> lock(mLock); getAtomMetricStats(metricId).conditionChangeInNextBucket++; } -void StatsdStats::noteInvalidatedBucket(int metricId) { +void StatsdStats::noteInvalidatedBucket(int64_t metricId) { lock_guard<std::mutex> lock(mLock); getAtomMetricStats(metricId).invalidatedBucket++; } +void StatsdStats::noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs) { + lock_guard<std::mutex> lock(mLock); + AtomMetricStats& pullStats = getAtomMetricStats(metricId); + pullStats.maxBucketBoundaryDelayNs = + std::max(pullStats.maxBucketBoundaryDelayNs, timeDelayNs); + pullStats.minBucketBoundaryDelayNs = + std::min(pullStats.minBucketBoundaryDelayNs, timeDelayNs); +} + StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int metricId) { auto atomMetricStatsIter = mAtomMetricStats.find(metricId); if (atomMetricStatsIter != mAtomMetricStats.end()) { diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 20ea7e5df1fa..2999b649a509 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -342,37 +342,43 @@ public: /** * Hard limit was reached in the cardinality of an atom */ - void noteHardDimensionLimitReached(int atomId); + void noteHardDimensionLimitReached(int64_t metricId); /** * A log event was too late, arrived in the wrong bucket and was skipped */ - void noteLateLogEventSkipped(int atomId); + void noteLateLogEventSkipped(int64_t metricId); /** * Buckets were skipped as time elapsed without any data for them */ - void noteSkippedForwardBuckets(int atomId); + void noteSkippedForwardBuckets(int64_t metricId); /** * An unsupported value type was received */ - void noteBadValueType(int atomId); + void noteBadValueType(int64_t metricId); /** * Buckets were dropped due to reclaim memory. */ - void noteBucketDropped(int metricId); + void noteBucketDropped(int64_t metricId); /** * A condition change was too late, arrived in the wrong bucket and was skipped */ - void noteConditionChangeInNextBucket(int atomId); + void noteConditionChangeInNextBucket(int64_t metricId); /** * A bucket has been tagged as invalid. */ - void noteInvalidatedBucket(int metricId); + void noteInvalidatedBucket(int64_t metricId); + + /** + * For pulls at bucket boundaries, it represents the misalignment between the real timestamp and + * the end of the bucket. + */ + void noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs); /** * Reset the historical stats. Including all stats in icebox, and the tracked stats about @@ -420,6 +426,8 @@ public: long conditionChangeInNextBucket = 0; long invalidatedBucket = 0; long bucketDropped = 0; + int64_t minBucketBoundaryDelayNs = 0; + int64_t maxBucketBoundaryDelayNs = 0; } AtomMetricStats; private: diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index 2609937924ac..d56a355f15d6 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -407,7 +407,7 @@ std::shared_ptr<vector<FieldValue>> GaugeMetricProducer::getGaugeFields(const Lo } void GaugeMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData, - bool pullSuccess) { + bool pullSuccess, int64_t originalPullTimeNs) { std::lock_guard<std::mutex> lock(mMutex); if (!pullSuccess || allData.size() == 0) { return; diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h index d480941ed311..64a18337481b 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.h +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h @@ -68,7 +68,7 @@ public: // Handles when the pulled data arrives. void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data, - bool pullSuccess) override; + bool pullSuccess, int64_t originalPullTimeNs) override; // GaugeMetric needs to immediately trigger another pull when we create the partial bucket. void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid, diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp index b362e37cd194..495138ee9b77 100644 --- a/cmds/statsd/src/metrics/MetricProducer.cpp +++ b/cmds/statsd/src/metrics/MetricProducer.cpp @@ -107,6 +107,10 @@ void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedT if (it == mEventActivationMap.end()) { return; } + if (mActivationType == MetricActivation::ACTIVATE_ON_BOOT) { + it->second.state = ActivationState::kActiveOnBoot; + return; + } it->second.activation_ns = elapsedTimestampNs; it->second.state = ActivationState::kActive; mIsActive = true; @@ -116,12 +120,19 @@ void MetricProducer::setActiveLocked(int64_t currentTimeNs, int64_t remainingTtl if (mEventActivationMap.size() == 0) { return; } - auto& activation = mEventActivationMap.begin()->second; - activation.activation_ns = currentTimeNs + remainingTtlNs - activation.ttl_ns; - activation.state = kActive; - mIsActive = true; - VLOG("setting new activation time to %lld, %lld, %lld", (long long)activation.activation_ns, - (long long)currentTimeNs, (long long)remainingTtlNs); + for (auto& pair : mEventActivationMap) { + auto& activation = pair.second; + if (activation.ttl_ns >= remainingTtlNs) { + activation.activation_ns = currentTimeNs + remainingTtlNs - activation.ttl_ns; + activation.state = kActive; + mIsActive = true; + VLOG("setting new activation time to %lld, %lld, %lld", + (long long)activation.activation_ns, (long long)currentTimeNs, + (long long)remainingTtlNs); + return; + } + } + ALOGE("Required ttl is longer than all possible activations."); } int64_t MetricProducer::getRemainingTtlNsLocked(int64_t currentTimeNs) const { @@ -135,6 +146,19 @@ int64_t MetricProducer::getRemainingTtlNsLocked(int64_t currentTimeNs) const { return maxTtl; } +void MetricProducer::prepActiveForBootIfNecessaryLocked(int64_t currentTimeNs) { + if (mActivationType != MetricActivation::ACTIVATE_ON_BOOT) { + return; + } + for (auto& activation : mEventActivationMap) { + if (activation.second.state == kActiveOnBoot) { + activation.second.state = kActive; + activation.second.activation_ns = currentTimeNs; + mIsActive = true; + } + } +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index ca37bbb73b45..849cb76ec392 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -37,12 +37,13 @@ namespace statsd { // If the metric has no activation requirement, it will be active once the metric producer is // created. // If the metric needs to be activated by atoms, the metric producer will start -// with kNotActive state, turn to kActive when the activation event arrives, become kNotActive -// when it reaches the duration limit (timebomb). If the activation event arrives again before -// or after it expires, the event producer will be re-activated and ttl will be reset. +// with kNotActive state, turn to kActive or kActiveOnBoot when the activation event arrives, become +// kNotActive when it reaches the duration limit (timebomb). If the activation event arrives again +// before or after it expires, the event producer will be re-activated and ttl will be reset. enum ActivationState { kNotActive = 0, kActive = 1, + kActiveOnBoot = 2, }; // A MetricProducer is responsible for compute one single metrics, creating stats log report, and @@ -218,8 +219,17 @@ public: return isActiveLocked(); } + void prepActiveForBootIfNecessary(int64_t currentTimeNs) { + std::lock_guard<std::mutex> lock(mMutex); + prepActiveForBootIfNecessaryLocked(currentTimeNs); + } + void addActivation(int activationTrackerIndex, int64_t ttl_seconds); + inline void setActivationType(const MetricActivation::ActivationType& activationType) { + mActivationType = activationType; + } + void flushIfExpire(int64_t elapsedTimestampNs); protected: @@ -243,6 +253,8 @@ protected: return mIsActive; } + void prepActiveForBootIfNecessaryLocked(int64_t currentTimeNs); + int64_t getRemainingTtlNsLocked(int64_t currentTimeNs) const; void setActiveLocked(int64_t currentTimeNs, int64_t remainingTtlNs); @@ -367,9 +379,12 @@ protected: bool mIsActive; + MetricActivation::ActivationType mActivationType; + FRIEND_TEST(MetricActivationE2eTest, TestCountMetric); FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead); + FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index fdc28ea7f219..cb1cefbf2063 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -132,7 +132,7 @@ public: return mIsActive; } - inline void getActiveMetrics(std::vector<const MetricProducer*>& metrics) const { + inline void getActiveMetrics(std::vector<MetricProducer*>& metrics) const { for (const auto& metric : mAllMetricProducers) { if (metric->isActive()) { metrics.push_back(metric.get()); @@ -140,6 +140,12 @@ public: } } + inline void prepForShutDown(int64_t currentTimeNs) { + for (const auto& metric : mAllMetricProducers) { + metric->prepActiveForBootIfNecessary(currentTimeNs); + } + } + void setActiveMetrics(ActiveConfig config, int64_t currentTimeNs); private: @@ -271,6 +277,7 @@ private: FRIEND_TEST(MetricActivationE2eTest, TestCountMetric); FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead); + FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index 1bd3ef20a578..ac6c27adceaa 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -361,34 +361,8 @@ void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) { invalidateCurrentBucket(); return; } - const int64_t pullDelayNs = getElapsedRealtimeNs() - timestampNs; - StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs); - if (pullDelayNs > mMaxPullDelayNs) { - ALOGE("Pull finish too late for atom %d, longer than %lld", mPullTagId, - (long long)mMaxPullDelayNs); - StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId); - // We are missing one pull from the bucket which means we will not have a complete view of - // what's going on. - invalidateCurrentBucket(); - return; - } - if (timestampNs < mCurrentBucketStartTimeNs) { - // The data will be skipped in onMatchedLogEventInternalLocked, but we don't want to report - // for every event, just the pull - StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId); - } - - for (const auto& data : allData) { - // make a copy before doing and changes - LogEvent localCopy = data->makeCopy(); - localCopy.setElapsedTimestampNs(timestampNs); - if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) == - MatchingState::kMatched) { - onMatchedLogEventLocked(mWhatMatcherIndex, localCopy); - } - } - mHasGlobalBase = true; + accumulateEvents(allData, timestampNs, timestampNs); } int64_t ValueMetricProducer::calcPreviousBucketEndTime(const int64_t currentTimeNs) { @@ -396,7 +370,7 @@ int64_t ValueMetricProducer::calcPreviousBucketEndTime(const int64_t currentTime } void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData, - bool pullSuccess) { + bool pullSuccess, int64_t originalPullTimeNs) { std::lock_guard<std::mutex> lock(mMutex); if (mCondition) { if (!pullSuccess) { @@ -405,11 +379,6 @@ void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEven return; } - if (allData.size() == 0) { - VLOG("Data pulled is empty"); - StatsdStats::getInstance().noteEmptyData(mPullTagId); - return; - } // For scheduled pulled data, the effective event time is snap to the nearest // bucket end. In the case of waking up from a deep sleep state, we will // attribute to the previous bucket end. If the sleep was long but not very long, we @@ -417,33 +386,72 @@ void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEven // we pull at a later time than real bucket end. // If the sleep was very long, we skip more than one bucket before sleep. In this case, // if the diff base will be cleared and this new data will serve as new diff base. - int64_t realEventTime = allData.at(0)->GetElapsedTimestampNs(); - int64_t bucketEndTime = calcPreviousBucketEndTime(realEventTime) - 1; - bool isEventLate = bucketEndTime < mCurrentBucketStartTimeNs; - if (isEventLate) { - VLOG("Skip bucket end pull due to late arrival: %lld vs %lld", (long long)bucketEndTime, - (long long)mCurrentBucketStartTimeNs); - StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId); - } - - for (const auto& data : allData) { - LogEvent localCopy = data->makeCopy(); - if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) == - MatchingState::kMatched) { - localCopy.setElapsedTimestampNs(bucketEndTime); - onMatchedLogEventLocked(mWhatMatcherIndex, localCopy); - } - } - mHasGlobalBase = true; + int64_t bucketEndTime = calcPreviousBucketEndTime(originalPullTimeNs) - 1; + StatsdStats::getInstance().noteBucketBoundaryDelayNs( + mMetricId, originalPullTimeNs - bucketEndTime); + accumulateEvents(allData, originalPullTimeNs, bucketEndTime); // We can probably flush the bucket. Since we used bucketEndTime when calling // #onMatchedLogEventInternalLocked, the current bucket will not have been flushed. - flushIfNeededLocked(realEventTime); + flushIfNeededLocked(originalPullTimeNs); + } else { VLOG("No need to commit data on condition false."); } } +void ValueMetricProducer::accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData, + int64_t originalPullTimeNs, int64_t eventElapsedTimeNs) { + bool isEventLate = eventElapsedTimeNs < mCurrentBucketStartTimeNs; + if (isEventLate) { + VLOG("Skip bucket end pull due to late arrival: %lld vs %lld", + (long long)eventElapsedTimeNs, (long long)mCurrentBucketStartTimeNs); + StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId); + invalidateCurrentBucket(); + return; + } + + const int64_t pullDelayNs = getElapsedRealtimeNs() - originalPullTimeNs; + StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs); + if (pullDelayNs > mMaxPullDelayNs) { + ALOGE("Pull finish too late for atom %d, longer than %lld", mPullTagId, + (long long)mMaxPullDelayNs); + StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId); + // We are missing one pull from the bucket which means we will not have a complete view of + // what's going on. + invalidateCurrentBucket(); + return; + } + + if (allData.size() == 0) { + VLOG("Data pulled is empty"); + StatsdStats::getInstance().noteEmptyData(mPullTagId); + } + + mMatchedMetricDimensionKeys.clear(); + for (const auto& data : allData) { + LogEvent localCopy = data->makeCopy(); + if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) == + MatchingState::kMatched) { + localCopy.setElapsedTimestampNs(eventElapsedTimeNs); + onMatchedLogEventLocked(mWhatMatcherIndex, localCopy); + } + } + // If the new pulled data does not contains some keys we track in our intervals, we need to + // reset the base. + for (auto& slice : mCurrentSlicedBucket) { + bool presentInPulledData = mMatchedMetricDimensionKeys.find(slice.first) + != mMatchedMetricDimensionKeys.end(); + if (!presentInPulledData) { + for (auto& interval : slice.second) { + interval.hasBase = false; + } + } + } + mMatchedMetricDimensionKeys.clear(); + mHasGlobalBase = true; +} + void ValueMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const { if (mCurrentSlicedBucket.size() == 0) { return; @@ -539,6 +547,7 @@ void ValueMetricProducer::onMatchedLogEventInternalLocked(const size_t matcherIn (long long)mCurrentBucketStartTimeNs); return; } + mMatchedMetricDimensionKeys.insert(eventKey); flushIfNeededLocked(eventTimeNs); diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index 0cfefa9e3eb4..d1c2315b28be 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -52,7 +52,7 @@ public: // Process data pulled on bucket boundary. void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data, - bool pullSuccess) override; + bool pullSuccess, int64_t originalPullTimeNs) override; // ValueMetric needs special logic if it's a pulled atom. void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid, @@ -116,6 +116,9 @@ private: // Value fields for matching. std::vector<Matcher> mFieldMatchers; + // Value fields for matching. + std::set<MetricDimensionKey> mMatchedMetricDimensionKeys; + // tagId for pulled data. -1 if this is not pulled const int mPullTagId; @@ -160,6 +163,9 @@ private: void pullAndMatchEventsLocked(const int64_t timestampNs); + void accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData, + int64_t originalPullTimeNs, int64_t eventElapsedTimeNs); + ValueBucket buildPartialBucket(int64_t bucketEndTime, const std::vector<Interval>& intervals); void initCurrentSlicedBucket(); @@ -242,6 +248,10 @@ private: FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed); FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded); FRIEND_TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange); + FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled); + FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged); + FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary); + FRIEND_TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 180a1ae07523..463b5a097585 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -725,6 +725,8 @@ bool initMetricActivations(const ConfigKey& key, const StatsdConfig& config, ALOGE("Invalid metric tracker index."); return false; } + allMetricProducers[metricTrackerIndex]->setActivationType( + metric_activation.activation_type()); metricsWithActivation.push_back(metricTrackerIndex); for (int j = 0; j < metric_activation.event_activation_size(); ++j) { const EventActivation& activation = metric_activation.event_activation(j); diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto index 73aab4847e11..6a07a3f169e0 100644 --- a/cmds/statsd/src/stats_log.proto +++ b/cmds/statsd/src/stats_log.proto @@ -419,6 +419,8 @@ message StatsdStatsReport { optional int64 condition_change_in_next_bucket = 6; optional int64 invalidated_bucket = 7; optional int64 bucket_dropped = 8; + optional int64 min_bucket_boundary_delay_ns = 9; + optional int64 max_bucket_boundary_delay_ns = 10; } repeated AtomMetricStats atom_metric_stats = 17; diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp index f76a9ad78396..aa8cfc508861 100644 --- a/cmds/statsd/src/stats_log_util.cpp +++ b/cmds/statsd/src/stats_log_util.cpp @@ -80,6 +80,8 @@ const int FIELD_ID_BAD_VALUE_TYPE = 5; const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6; const int FIELD_ID_INVALIDATED_BUCKET = 7; const int FIELD_ID_BUCKET_DROPPED = 8; +const int FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS = 9; +const int FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS = 10; namespace { @@ -500,6 +502,10 @@ void writeAtomMetricStatsToStream(const std::pair<int, StatsdStats::AtomMetricSt (long long)pair.second.invalidatedBucket); protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_DROPPED, (long long)pair.second.bucketDropped); + protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS, + (long long)pair.second.minBucketBoundaryDelayNs); + protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS, + (long long)pair.second.maxBucketBoundaryDelayNs); protoOutput->end(token); } diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto index 9d3a66902804..5c6d548ad13a 100644 --- a/cmds/statsd/src/statsd_config.proto +++ b/cmds/statsd/src/statsd_config.proto @@ -379,6 +379,13 @@ message EventActivation { message MetricActivation { optional int64 metric_id = 1; + enum ActivationType { + UNKNOWN = 0; + ACTIVATE_IMMEDIATELY = 1; + ACTIVATE_ON_BOOT = 2; + } + optional ActivationType activation_type = 3; + repeated EventActivation event_activation = 2; } diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp index 6e4b2c86c837..42cac0cc4122 100644 --- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp +++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp @@ -17,32 +17,67 @@ #include "Log.h" #include "IncidentdReporter.h" -#include "frameworks/base/libs/incident/proto/android/os/header.pb.h" #include <android/os/IIncidentManager.h> #include <android/os/IncidentReportArgs.h> +#include <android/util/ProtoOutputStream.h> #include <binder/IBinder.h> #include <binder/IServiceManager.h> +#include <vector> + namespace android { namespace os { namespace statsd { +using android::util::ProtoOutputStream; +using std::vector; + +using util::FIELD_TYPE_MESSAGE; +using util::FIELD_TYPE_INT32; +using util::FIELD_TYPE_INT64; + +// field ids in IncidentHeaderProto +const int FIELD_ID_ALERT_ID = 1; +const int FIELD_ID_CONFIG_KEY = 3; +const int FIELD_ID_CONFIG_KEY_UID = 1; +const int FIELD_ID_CONFIG_KEY_ID = 2; + +namespace { +void getProtoData(const int64_t& rule_id, const ConfigKey& configKey, vector<uint8_t>* protoData) { + ProtoOutputStream headerProto; + headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_ID, (long long)rule_id); + uint64_t token = + headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY); + headerProto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_KEY_UID, configKey.GetUid()); + headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_KEY_ID, (long long)configKey.GetId()); + headerProto.end(token); + + protoData->resize(headerProto.size()); + size_t pos = 0; + auto iter = headerProto.data(); + while (iter.readBuffer() != NULL) { + size_t toRead = iter.currentToRead(); + std::memcpy(&((*protoData)[pos]), iter.readBuffer(), toRead); + pos += toRead; + iter.rp()->move(toRead); + } +} +} // namespace + bool GenerateIncidentReport(const IncidentdDetails& config, const int64_t& rule_id, const ConfigKey& configKey) { if (config.section_size() == 0) { VLOG("The alert %lld contains zero section in config(%d,%lld)", (unsigned long long)rule_id, - configKey.GetUid(), (long long) configKey.GetId()); + configKey.GetUid(), (long long)configKey.GetId()); return false; } IncidentReportArgs incidentReport; - android::os::IncidentHeaderProto header; - header.set_alert_id(rule_id); - header.mutable_config_key()->set_uid(configKey.GetUid()); - header.mutable_config_key()->set_id(configKey.GetId()); - incidentReport.addHeader(header); + vector<uint8_t> protoData; + getProtoData(rule_id, configKey, &protoData); + incidentReport.addHeader(protoData); for (int i = 0; i < config.section_size(); i++) { incidentReport.addSection(config.section(i)); diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp index 64008b50b013..60df165f102c 100644 --- a/cmds/statsd/tests/StatsLogProcessor_test.cpp +++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp @@ -574,6 +574,127 @@ TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) { EXPECT_EQ(timeBase2 + ttl6 - activation1006.ttl_ns, activation1003.activation_ns); } +TEST(StatsLogProcessorTest, TestActivationOnBoot) { + int uid = 1111; + + // Setup a simple config, no activation + StatsdConfig config1; + config1.set_id(12341); + config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); + *config1.add_atom_matcher() = wakelockAcquireMatcher; + + long metricId1 = 1234561; + long metricId2 = 1234562; + auto countMetric1 = config1.add_count_metric(); + countMetric1->set_id(metricId1); + countMetric1->set_what(wakelockAcquireMatcher.id()); + countMetric1->set_bucket(FIVE_MINUTES); + + auto countMetric2 = config1.add_count_metric(); + countMetric2->set_id(metricId2); + countMetric2->set_what(wakelockAcquireMatcher.id()); + countMetric2->set_bucket(FIVE_MINUTES); + + auto metric1Activation = config1.add_metric_activation(); + metric1Activation->set_metric_id(metricId1); + metric1Activation->set_activation_type(MetricActivation::ACTIVATE_ON_BOOT); + auto metric1ActivationTrigger = metric1Activation->add_event_activation(); + metric1ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); + metric1ActivationTrigger->set_ttl_seconds(100); + + ConfigKey cfgKey1(uid, 12341); + long timeBase1 = 1; + sp<StatsLogProcessor> processor = + CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1); + + EXPECT_EQ(1, processor->mMetricsManagers.size()); + auto it = processor->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor->mMetricsManagers.end()); + auto& metricsManager1 = it->second; + EXPECT_TRUE(metricsManager1->isActive()); + + auto metricIt = metricsManager1->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); + auto& metricProducer1 = *metricIt; + EXPECT_FALSE(metricProducer1->isActive()); + + metricIt = metricsManager1->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); + auto& metricProducer2 = *metricIt; + EXPECT_TRUE(metricProducer2->isActive()); + + const auto& activation1 = metricProducer1->mEventActivationMap.begin()->second; + EXPECT_EQ(100 * NS_PER_SEC, activation1.ttl_ns); + EXPECT_EQ(0, activation1.activation_ns); + EXPECT_EQ(kNotActive, activation1.state); + + std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")}; + auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1); + processor->OnLogEvent(event.get()); + + EXPECT_FALSE(metricProducer1->isActive()); + EXPECT_EQ(0, activation1.activation_ns); + EXPECT_EQ(kActiveOnBoot, activation1.state); + + int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; + + processor->WriteMetricsActivationToDisk(shutDownTime); + EXPECT_TRUE(metricProducer1->isActive()); + int64_t ttl1 = metricProducer1->getRemainingTtlNs(shutDownTime); + EXPECT_EQ(100 * NS_PER_SEC, ttl1); + + long timeBase2 = 1000; + sp<StatsLogProcessor> processor2 = + CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); + + EXPECT_EQ(1, processor2->mMetricsManagers.size()); + it = processor2->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor2->mMetricsManagers.end()); + auto& metricsManager1001 = it->second; + EXPECT_TRUE(metricsManager1001->isActive()); + + metricIt = metricsManager1001->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); + auto& metricProducer1001 = *metricIt; + EXPECT_FALSE(metricProducer1001->isActive()); + + metricIt = metricsManager1001->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); + auto& metricProducer1002 = *metricIt; + EXPECT_TRUE(metricProducer1002->isActive()); + + const auto& activation1001 = metricProducer1001->mEventActivationMap.begin()->second; + EXPECT_EQ(100 * NS_PER_SEC, activation1001.ttl_ns); + EXPECT_EQ(0, activation1001.activation_ns); + EXPECT_EQ(kNotActive, activation1001.state); + + processor2->LoadMetricsActivationFromDisk(); + + EXPECT_TRUE(metricProducer1001->isActive()); + EXPECT_EQ(timeBase2 + ttl1 - activation1001.ttl_ns, activation1001.activation_ns); +} + #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp index 1725160c00c7..62868232d8e7 100644 --- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp @@ -133,7 +133,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) { event->init(); allData.push_back(event); - gaugeProducer.onDataPulled(allData, /** succeed */ true); + gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin(); EXPECT_EQ(INT, it->mValue.getType()); @@ -151,7 +151,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) { event2->write(25); event2->init(); allData.push_back(event2); - gaugeProducer.onDataPulled(allData, /** succeed */ true); + gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin(); EXPECT_EQ(INT, it->mValue.getType()); @@ -305,7 +305,7 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) { event->write(1); event->init(); allData.push_back(event); - gaugeProducer.onDataPulled(allData, /** succeed */ true); + gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin() ->second.front() @@ -328,7 +328,7 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) { event->write(3); event->init(); allData.push_back(event); - gaugeProducer.onDataPulled(allData, /** succeed */ true); + gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs); EXPECT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin() @@ -371,7 +371,7 @@ TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) { event->write(1); event->init(); allData.push_back(event); - gaugeProducer.onDataPulled(allData, /** succeed */ true); + gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin() ->second.front() @@ -440,7 +440,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) { event->write(110); event->init(); allData.push_back(event); - gaugeProducer.onDataPulled(allData, /** succeed */ true); + gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin() @@ -541,7 +541,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) { event->write(110); event->init(); allData.push_back(event); - gaugeProducer.onDataPulled(allData, /** succeed */ true); + gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size()); @@ -590,7 +590,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) { event1->write(13); event1->init(); - gaugeProducer.onDataPulled({event1}, /** succeed */ true); + gaugeProducer.onDataPulled({event1}, /** succeed */ true, bucketStartTimeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin() ->second.front() @@ -604,7 +604,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) { event2->write(15); event2->init(); - gaugeProducer.onDataPulled({event2}, /** succeed */ true); + gaugeProducer.onDataPulled({event2}, /** succeed */ true, bucketStartTimeNs + bucketSizeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin() ->second.front() @@ -619,7 +619,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) { event3->write(26); event3->init(); - gaugeProducer.onDataPulled({event3}, /** succeed */ true); + gaugeProducer.onDataPulled({event3}, /** succeed */ true, bucket2StartTimeNs + 2 * bucketSizeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin() ->second.front() @@ -633,7 +633,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) { std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10); event4->write("some value"); event4->init(); - gaugeProducer.onDataPulled({event4}, /** succeed */ true); + gaugeProducer.onDataPulled({event4}, /** succeed */ true, bucketStartTimeNs + 3 * bucketSizeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty()); } diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index 91b98ecffa29..ae3cdbcb5eb4 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -160,7 +160,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -178,7 +178,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { event->write(23); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -198,7 +198,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { event->write(36); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -265,7 +265,7 @@ TEST(ValueMetricProducerTest, TestPartialBucketCreated) { event->write(2); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** success */ true); + valueProducer.onDataPulled(allData, /** success */ true, bucket2StartTimeNs); // Partial buckets created in 2nd bucket. valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1); @@ -327,7 +327,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); ValueMetricProducer::Interval curInterval = @@ -346,7 +346,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { event->write(23); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); // No new data seen, so data has been cleared. EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size()); @@ -363,7 +363,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { event->write(36); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -412,7 +412,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -428,7 +428,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { event->write(10); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -445,7 +445,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { event->write(36); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; EXPECT_EQ(true, curInterval.hasBase); @@ -493,7 +493,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) { event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -509,7 +509,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) { event->write(10); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -524,7 +524,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) { event->write(36); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; EXPECT_EQ(true, curInterval.hasBase); @@ -599,7 +599,7 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { event->write(110); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); @@ -710,7 +710,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1); @@ -725,7 +725,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { event->write(150); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs); EXPECT_EQ(20L, @@ -764,7 +764,7 @@ TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) { event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1); @@ -1068,7 +1068,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -1086,7 +1086,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { event->write(23); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -1107,7 +1107,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { event->write(36); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket6StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; // startUpdated:false sum:12 @@ -1195,7 +1195,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) { event->write(110); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; EXPECT_EQ(false, curInterval.hasBase); @@ -1291,7 +1291,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { EXPECT_EQ(20, curInterval.value.long_value); EXPECT_EQ(0UL, valueProducer.mPastBuckets.size()); - // Now the alarm is delivered, but it is considered late, it has no effect + // Now the alarm is delivered, but it is considered late, the bucket is invalidated. vector<shared_ptr<LogEvent>> allData; allData.clear(); shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 50); @@ -1299,10 +1299,10 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { event->write(110); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; - EXPECT_EQ(true, curInterval.hasBase); + EXPECT_EQ(false, curInterval.hasBase); EXPECT_EQ(130, curInterval.base.long_value); EXPECT_EQ(true, curInterval.hasValue); EXPECT_EQ(20, curInterval.value.long_value); @@ -1752,7 +1752,7 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) { allData.push_back(event1); allData.push_back(event2); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size()); EXPECT_EQ(true, interval1.hasBase); EXPECT_EQ(11, interval1.base.long_value); @@ -1842,7 +1842,7 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { allData.push_back(event1); allData.push_back(event2); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size()); EXPECT_EQ(true, interval1.hasBase); EXPECT_EQ(11, interval1.base.long_value); @@ -1871,7 +1871,7 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { event1->write(5); event1->init(); allData.push_back(event1); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); EXPECT_EQ(true, interval2.hasBase); @@ -1893,7 +1893,7 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { event2->write(5); event2->init(); allData.push_back(event2); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs); EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size()); EXPECT_EQ(true, interval2.hasBase); @@ -1968,7 +1968,7 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { allData.push_back(event1); allData.push_back(event2); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size()); EXPECT_EQ(true, interval1.hasBase); EXPECT_EQ(11, interval1.base.long_value); @@ -2000,7 +2000,7 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { event1->write(5); event1->init(); allData.push_back(event1); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs); // Only one interval left. One was trimmed. EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); @@ -2018,7 +2018,7 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { event1->write(14); event1->init(); allData.push_back(event1); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs); interval2 = valueProducer.mCurrentSlicedBucket.begin()->second[0]; EXPECT_EQ(true, interval2.hasBase); @@ -2078,7 +2078,7 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfB EXPECT_EQ(false, curInterval.hasValue); vector<shared_ptr<LogEvent>> allData; - valueProducer.onDataPulled(allData, /** succeed */ false); + valueProducer.onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); EXPECT_EQ(false, curInterval.hasBase); EXPECT_EQ(false, curInterval.hasValue); @@ -2179,7 +2179,7 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) { valueProducer.mCondition = true; vector<shared_ptr<LogEvent>> allData; - valueProducer.onDataPulled(allData, /** succeed */ false); + valueProducer.onDataPulled(allData, /** succeed */ false, bucketStartTimeNs); EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size()); valueProducer.onConditionChanged(false, bucketStartTimeNs + 1); @@ -2361,7 +2361,7 @@ TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed) { event->write(110); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs); // This will fail and should invalidate the whole bucket since we do not have all the data // needed to compute the metric value when the screen was on. @@ -2375,7 +2375,7 @@ TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed) { event2->write(140); event2->init(); allData.push_back(event2); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); valueProducer.flushIfNeededLocked(bucket2StartTimeNs + 1); @@ -2446,7 +2446,7 @@ TEST(ValueMetricProducerTest, TestInvalidBucketWhenInitialPullFailed) { event->write(110); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ false); + valueProducer.onDataPulled(allData, /** succeed */ false, bucketStartTimeNs); valueProducer.onConditionChanged(false, bucketStartTimeNs + 2); valueProducer.onConditionChanged(true, bucketStartTimeNs + 3); @@ -2458,7 +2458,7 @@ TEST(ValueMetricProducerTest, TestInvalidBucketWhenInitialPullFailed) { event2->write(140); event2->init(); allData.push_back(event2); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); valueProducer.flushIfNeededLocked(bucket2StartTimeNs + 1); @@ -2529,7 +2529,7 @@ TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed) { event->write(110); event->init(); allData.push_back(event); - valueProducer.onDataPulled(allData, /** succeed */ true); + valueProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs); // This will fail and should invalidate the whole bucket since we do not have all the data // needed to compute the metric value when the screen was on. @@ -2543,7 +2543,7 @@ TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed) { event2->write(140); event2->init(); allData.push_back(event2); - valueProducer.onDataPulled(allData, /** succeed */ false); + valueProducer.onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs); valueProducer.flushIfNeededLocked(bucket2StartTimeNs + 1); @@ -2557,6 +2557,268 @@ TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed) { EXPECT_EQ(false, valueProducer.mHasGlobalBase); } +TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + metric.set_max_pull_delay_sec(INT_MAX); + + UidMap uidMap; + SimpleAtomMatcher atomMatcher; + atomMatcher.set_atom_id(tagId); + sp<EventMatcherWizard> eventMatcherWizard = + new EventMatcherWizard({new SimpleLogMatchingTracker( + atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Start bucket. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); + event->write(tagId); + event->write(3); + event->init(); + data->push_back(event); + return true; + })); + + ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, + logEventMatcherIndex, eventMatcherWizard, tagId, + bucketStartTimeNs, bucketStartTimeNs, pullerManager); + + // Bucket 2 start. + vector<shared_ptr<LogEvent>> allData; + allData.clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); + event->write(tagId); + event->write(110); + event->init(); + allData.push_back(event); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); + + // Bucket 3 empty. + allData.clear(); + shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1); + event2->init(); + allData.push_back(event2); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); + // Data has been trimmed. + EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size()); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); +} + +TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(INT_MAX); + + UidMap uidMap; + SimpleAtomMatcher atomMatcher; + atomMatcher.set_atom_id(tagId); + sp<EventMatcherWizard> eventMatcherWizard = + new EventMatcherWizard({new SimpleLogMatchingTracker( + atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // First onConditionChanged + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); + event->write(tagId); + event->write(3); + event->init(); + data->push_back(event); + return true; + })) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + return true; + })); + + ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex, + eventMatcherWizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + + valueProducer.onConditionChanged(true, bucketStartTimeNs + 10); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + ValueMetricProducer::Interval& curInterval = + valueProducer.mCurrentSlicedBucket.begin()->second[0]; + EXPECT_EQ(true, curInterval.hasBase); + EXPECT_EQ(false, curInterval.hasValue); + EXPECT_EQ(true, valueProducer.mHasGlobalBase); + + // Empty pull. + valueProducer.onConditionChanged(false, bucketStartTimeNs + 10); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; + EXPECT_EQ(false, curInterval.hasBase); + EXPECT_EQ(false, curInterval.hasValue); + EXPECT_EQ(false, valueProducer.mHasGlobalBase); +} + +TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(INT_MAX); + + UidMap uidMap; + SimpleAtomMatcher atomMatcher; + atomMatcher.set_atom_id(tagId); + sp<EventMatcherWizard> eventMatcherWizard = + new EventMatcherWizard({new SimpleLogMatchingTracker( + atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // First onConditionChanged + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); + event->write(tagId); + event->write(1); + event->init(); + data->push_back(event); + return true; + })) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); + event->write(tagId); + event->write(2); + event->init(); + data->push_back(event); + return true; + })) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); + event->write(tagId); + event->write(5); + event->init(); + data->push_back(event); + return true; + })); + + ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex, + eventMatcherWizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + + valueProducer.onConditionChanged(true, bucketStartTimeNs + 10); + valueProducer.onConditionChanged(false, bucketStartTimeNs + 11); + valueProducer.onConditionChanged(true, bucketStartTimeNs + 12); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + ValueMetricProducer::Interval& curInterval = + valueProducer.mCurrentSlicedBucket.begin()->second[0]; + EXPECT_EQ(true, curInterval.hasBase); + EXPECT_EQ(true, curInterval.hasValue); + EXPECT_EQ(true, valueProducer.mHasGlobalBase); + + // End of bucket + vector<shared_ptr<LogEvent>> allData; + allData.clear(); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; + // Data is empty, base should be reset. + EXPECT_EQ(false, curInterval.hasBase); + EXPECT_EQ(5, curInterval.base.long_value); + EXPECT_EQ(false, curInterval.hasValue); + EXPECT_EQ(true, valueProducer.mHasGlobalBase); + + EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); + EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value); +} + + +TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + metric.mutable_dimensions_in_what()->set_field(tagId); + metric.mutable_dimensions_in_what()->add_child()->set_field(1); + metric.set_condition(StringToId("SCREEN_ON")); + metric.set_max_pull_delay_sec(INT_MAX); + + UidMap uidMap; + SimpleAtomMatcher atomMatcher; + atomMatcher.set_atom_id(tagId); + sp<EventMatcherWizard> eventMatcherWizard = + new EventMatcherWizard({new SimpleLogMatchingTracker( + atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // First onConditionChanged + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); + event->write(tagId); + event->write(1); + event->write(1); + event->init(); + data->push_back(event); + return true; + })); + + ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex, + eventMatcherWizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + + valueProducer.onConditionChanged(true, bucketStartTimeNs + 10); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + + // End of bucket + vector<shared_ptr<LogEvent>> allData; + allData.clear(); + shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); + event->write(2); + event->write(2); + event->init(); + allData.push_back(event); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + // Key 1 should be reset since in not present in the most pull. + EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size()); + auto iterator = valueProducer.mCurrentSlicedBucket.begin(); + EXPECT_EQ(true, iterator->second[0].hasBase); + EXPECT_EQ(2, iterator->second[0].base.long_value); + EXPECT_EQ(false, iterator->second[0].hasValue); + iterator++; + EXPECT_EQ(false, iterator->second[0].hasBase); + EXPECT_EQ(1, iterator->second[0].base.long_value); + EXPECT_EQ(false, iterator->second[0].hasValue); + + EXPECT_EQ(true, valueProducer.mHasGlobalBase); +} + } // namespace statsd } // namespace os } // namespace android diff --git a/config/hiddenapi-greylist-max-p.txt b/config/hiddenapi-greylist-max-p.txt index 7840b186615f..4c643e1c6831 100644 --- a/config/hiddenapi-greylist-max-p.txt +++ b/config/hiddenapi-greylist-max-p.txt @@ -48,6 +48,8 @@ Landroid/os/WorkSource;->updateLocked(Landroid/os/WorkSource;ZZ)Z Landroid/service/carrier/ICarrierMessagingCallback$Stub;-><init>()V Landroid/service/carrier/ICarrierMessagingService;->filterSms(Landroid/service/carrier/MessagePdu;Ljava/lang/String;IILandroid/service/carrier/ICarrierMessagingCallback;)V Landroid/telephony/CarrierMessagingServiceManager;-><init>()V +Landroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V +Landroid/view/IGraphicsStats$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IGraphicsStats; Landroid/view/IWindowManager;->setInTouchMode(Z)V Landroid/view/IWindowManager;->showStrictModeViolation(Z)V Lcom/android/internal/R$styleable;->AndroidManifestActivityAlias:[I diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index a0d8a1232257..010e4478459d 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -1474,8 +1474,6 @@ Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder; Landroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager; Landroid/view/IAppTransitionAnimationSpecsFuture$Stub;-><init>()V Landroid/view/IDockedStackListener$Stub;-><init>()V -Landroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/view/IGraphicsStats$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IGraphicsStats; Landroid/view/IRecentsAnimationController;->finish(Z)V Landroid/view/IRecentsAnimationController;->screenshotTask(I)Landroid/app/ActivityManager$TaskSnapshot; Landroid/view/IRecentsAnimationController;->setAnimationTargetsBehindSystemBars(Z)V diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 5814e69c36a3..ce7199816726 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -26,6 +26,7 @@ import android.app.ActivityManager.StackInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.graphics.Insets; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.os.RemoteException; @@ -84,6 +85,8 @@ public class ActivityView extends ViewGroup { /** The ActivityView is only allowed to contain one task. */ private final boolean mSingleTaskInstance; + private Insets mForwardedInsets; + @UnsupportedAppUsage public ActivityView(Context context) { this(context, null /* attrs */); @@ -369,11 +372,13 @@ public class ActivityView extends ViewGroup { .build(); try { + // TODO: Find a way to consolidate these calls to the server. wm.reparentDisplayContent(displayId, mRootSurfaceControl); wm.dontOverrideDisplayInfo(displayId); if (mSingleTaskInstance) { mActivityTaskManager.setDisplayToSingleTaskInstance(displayId); } + wm.setForwardedInsets(displayId, mForwardedInsets); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } @@ -454,6 +459,24 @@ public class ActivityView extends ViewGroup { } /** + * Set forwarded insets on the virtual display. + * + * @see IWindowManager#setForwardedInsets + */ + public void setForwardedInsets(Insets insets) { + mForwardedInsets = insets; + if (mVirtualDisplay == null) { + return; + } + try { + final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); + wm.setForwardedInsets(mVirtualDisplay.getDisplay().getDisplayId(), mForwardedInsets); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** * A task change listener that detects background color change of the topmost stack on our * virtual display and updates the background of the surface view. This background will be shown * when surface view is resized, but the app hasn't drawn its content in new size yet. diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index f522d71afd08..17f645dfbf23 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -125,7 +125,7 @@ public class KeyguardManager { public static final int RESULT_ALTERNATE = 1; /** - * @deprecated see {@link BiometricPrompt.Builder#setEnableFallback(boolean)} + * @deprecated see {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} * * Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics * if enrolled) for the current user of the device. The caller is expected to launch this diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 028e3efc9fb8..dc4f3432b6bd 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -8243,6 +8243,7 @@ public class Notification implements Parcelable private void buildIntoRemoteViewContent(RemoteViews remoteViews, RemoteViews customContent, TemplateBindResult result) { + int childIndex = -1; if (customContent != null) { // Need to clone customContent before adding, because otherwise it can no longer be // parceled independently of remoteViews. @@ -8250,7 +8251,11 @@ public class Notification implements Parcelable remoteViews.removeAllViewsExceptId(R.id.notification_main_column, R.id.progress); remoteViews.addView(R.id.notification_main_column, customContent, 0 /* index */); remoteViews.addFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED); + childIndex = 0; } + remoteViews.setIntTag(R.id.notification_main_column, + com.android.internal.R.id.notification_custom_view_index_tag, + childIndex); // also update the end margin if there is an image Resources resources = mBuilder.mContext.getResources(); int endMargin = resources.getDimensionPixelSize( diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING index 78ec8a17e8e8..65859c76a42a 100644 --- a/core/java/android/app/TEST_MAPPING +++ b/core/java/android/app/TEST_MAPPING @@ -6,5 +6,13 @@ { "path": "frameworks/base/services/core/java/com/android/server/wm" } + ], + "presubmit": [ + { + "name": "CtsFragmentTestCases" + }, + { + "name": "CtsFragmentTestCasesSdk26" + } ] } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 3ff6973a09ff..886115103ccf 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -4618,6 +4618,10 @@ public class DevicePolicyManager { * <p>If the installer must have access to the credentials, call * {@link #installKeyPair(ComponentName, PrivateKey, Certificate[], String, boolean)} instead. * + * <p>Note: If the provided {@code alias} is of an existing alias, all former grants that apps + * have been given to access the key and certificates associated with this alias will be + * revoked. + * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if calling from a delegated certificate installer. * @param privKey The private key to install. @@ -4645,6 +4649,10 @@ public class DevicePolicyManager { * immediately, without user approval. It is a best practice not to request this unless strictly * necessary since it opens up additional security vulnerabilities. * + * <p>Note: If the provided {@code alias} is of an existing alias, all former grants that apps + * have been given to access the key and certificates associated with this alias will be + * revoked. + * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if calling from a delegated certificate installer. * @param privKey The private key to install. @@ -4685,6 +4693,10 @@ public class DevicePolicyManager { * <p>Include {@link #INSTALLKEY_SET_USER_SELECTABLE} in the {@code flags} argument to allow * the user to select the key from a dialog. * + * <p>Note: If the provided {@code alias} is of an existing alias, all former grants that apps + * have been given to access the key and certificates associated with this alias will be + * revoked. + * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if calling from a delegated certificate installer. * @param privKey The private key to install. @@ -4761,6 +4773,10 @@ public class DevicePolicyManager { * <p>Because this method might take several seconds to complete, it should only be called from * a worker thread. This method returns {@code null} when called from the main thread. * + * <p>Note: If the provided {@code alias} is of an existing alias, all former grants that apps + * have been given to access the key and certificates associated with this alias will be + * revoked. + * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if calling from a delegated certificate installer. * @param algorithm The key generation algorithm, see {@link java.security.KeyPairGenerator}. @@ -9628,7 +9644,7 @@ public class DevicePolicyManager { * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param enabled {@code true} to enable the backup service, {@code false} to disable it. - * @throws SecurityException if {@code admin} is not a device owner. + * @throws SecurityException if {@code admin} is not a device owner or a profile owner. */ public void setBackupServiceEnabled(@NonNull ComponentName admin, boolean enabled) { throwIfParentInstance("setBackupServiceEnabled"); diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java index fa2a6a1f08e4..04d5c5aaa1d5 100644 --- a/core/java/android/app/role/RoleManager.java +++ b/core/java/android/app/role/RoleManager.java @@ -131,20 +131,20 @@ public final class RoleManager { * TODO: STOPSHIP: Make name of required roles public API * @hide */ - public static final String ROLE_CAR_MODE_DIALER_APP = "android.app.role.CAR_MODE_DIALER_APP"; + public static final String ROLE_CAR_MODE_DIALER = "android.app.role.CAR_MODE_DIALER"; /** - * The name of the proxy calling role. + * The name of the call redirection role. * <p> - * A proxy calling app provides a means to re-write the phone number for an outgoing call to - * place the call through a proxy calling service. + * A call redirection app provides a means to re-write the phone number for an outgoing call to + * place the call through a call redirection service. * * @see android.telecom.CallRedirectionService * * TODO: STOPSHIP: Make name of required roles public API * @hide */ - public static final String ROLE_PROXY_CALLING_APP = "android.app.role.PROXY_CALLING_APP"; + public static final String ROLE_CALL_REDIRECTION = "android.app.role.CALL_REDIRECTION"; /** * The name of the call screening and caller id role. @@ -154,7 +154,7 @@ public final class RoleManager { * TODO: STOPSHIP: Make name of required roles public API * @hide */ - public static final String ROLE_CALL_SCREENING_APP = "android.app.role.CALL_SCREENING_APP"; + public static final String ROLE_CALL_SCREENING = "android.app.role.CALL_SCREENING"; /** * The name of the call companion app role. @@ -170,7 +170,7 @@ public final class RoleManager { * TODO: STOPSHIP: Make name of required roles public API * @hide */ - public static final String ROLE_CALL_COMPANION_APP = "android.app.role.CALL_COMPANION_APP"; + public static final String ROLE_CALL_COMPANION = "android.app.role.CALL_COMPANION"; /** * The name of the assistant app role. diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 6e52b33692c8..eaf6c5a9d1cc 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -715,7 +715,6 @@ public abstract class PackageManager { INSTALL_FORCE_PERMISSION_PROMPT, INSTALL_INSTANT_APP, INSTALL_DONT_KILL_APP, - INSTALL_FORCE_SDK, INSTALL_FULL_APP, INSTALL_ALLOCATE_AGGRESSIVE, INSTALL_VIRTUAL_PRELOAD, @@ -816,15 +815,6 @@ public abstract class PackageManager { public static final int INSTALL_DONT_KILL_APP = 0x00001000; /** - * Flag parameter for {@link #installPackage} to indicate that this package is an - * upgrade to a package that refers to the SDK via release letter or is targeting an SDK via - * release letter that the current build does not support. - * - * @hide - */ - public static final int INSTALL_FORCE_SDK = 0x00002000; - - /** * Flag parameter for {@link #installPackage} to indicate that this package is * to be installed as a heavy weight app. This is fundamentally the opposite of * {@link #INSTALL_INSTANT_APP}. diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 5020a94c3469..96b6eb527002 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -839,7 +839,6 @@ public class PackageParser { public static final int PARSE_IS_SYSTEM_DIR = 1 << 4; public static final int PARSE_COLLECT_CERTIFICATES = 1 << 5; public static final int PARSE_ENFORCE_CODE = 1 << 6; - public static final int PARSE_FORCE_SDK = 1 << 7; public static final int PARSE_CHATTY = 1 << 31; @IntDef(flag = true, prefix = { "PARSE_" }, value = { @@ -847,7 +846,6 @@ public class PackageParser { PARSE_COLLECT_CERTIFICATES, PARSE_ENFORCE_CODE, PARSE_EXTERNAL_STORAGE, - PARSE_FORCE_SDK, PARSE_IGNORE_PROCESSES, PARSE_IS_SYSTEM_DIR, PARSE_MUST_BE_APK, @@ -2684,8 +2682,6 @@ public class PackageParser { * @param platformSdkCodenames array of allowed pre-release SDK codenames * for this platform * @param outError output array to populate with error, if applicable - * @param forceCurrentDev if development target code is not available, use the current - * development version by default. * @return the targetSdkVersion to use at runtime, or -1 if the package is * not compatible with this platform * @hide Exposed for unit testing only. @@ -2693,7 +2689,7 @@ public class PackageParser { @TestApi public static int computeTargetSdkVersion(@IntRange(from = 0) int targetVers, @Nullable String targetCode, @NonNull String[] platformSdkCodenames, - @NonNull String[] outError, boolean forceCurrentDev) { + @NonNull String[] outError) { // If it's a release SDK, return the version number unmodified. if (targetCode == null) { return targetVers; @@ -2701,7 +2697,7 @@ public class PackageParser { // If it's a pre-release SDK and the codename matches this platform, it // definitely targets this SDK. - if (matchTargetCode(platformSdkCodenames, targetCode) || forceCurrentDev) { + if (matchTargetCode(platformSdkCodenames, targetCode)) { return Build.VERSION_CODES.CUR_DEVELOPMENT; } @@ -2768,9 +2764,8 @@ public class PackageParser { return null; } - boolean defaultToCurrentDevBranch = (flags & PARSE_FORCE_SDK) != 0; final int targetSdkVersion = computeTargetSdkVersion(targetVers, - targetCode, SDK_CODENAMES, outError, defaultToCurrentDevBranch); + targetCode, SDK_CODENAMES, outError); if (targetSdkVersion < 0) { return null; } diff --git a/core/java/android/debug/AdbManagerInternal.java b/core/java/android/debug/AdbManagerInternal.java index 4469f0f965c3..51eb7fc2d804 100644 --- a/core/java/android/debug/AdbManagerInternal.java +++ b/core/java/android/debug/AdbManagerInternal.java @@ -16,6 +16,8 @@ package android.debug; +import java.io.File; + /** * This class allows the control of ADB-related functions that should only be called from the system * server. @@ -41,4 +43,14 @@ public abstract class AdbManagerInternal { * Returns {@code true} if ADB debugging is enabled. */ public abstract boolean isAdbEnabled(); + + /** + * Returns the file that contains all of the ADB keys used by the device. + */ + public abstract File getAdbKeysFile(); + + /** + * Returns the file that contains all of the ADB keys and their last used time. + */ + public abstract File getAdbTempKeysFile(); } diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java index c814b7c67817..1cb7eb0d1256 100644 --- a/core/java/android/hardware/biometrics/BiometricConstants.java +++ b/core/java/android/hardware/biometrics/BiometricConstants.java @@ -17,6 +17,7 @@ package android.hardware.biometrics; import android.annotation.UnsupportedAppUsage; +import android.app.KeyguardManager; /** @@ -126,6 +127,13 @@ public interface BiometricConstants { int BIOMETRIC_ERROR_NEGATIVE_BUTTON = 13; /** + * The device does not have pin, pattern, or password set up. See + * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and + * {@link KeyguardManager#isDeviceSecure()} + */ + int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; + + /** * @hide */ @UnsupportedAppUsage diff --git a/core/java/android/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java index b708ef12b210..459ec62d4135 100644 --- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java @@ -16,6 +16,7 @@ package android.hardware.biometrics; +import android.app.KeyguardManager; import android.hardware.face.FaceManager; /** @@ -134,6 +135,13 @@ public interface BiometricFaceConstants { public static final int FACE_ERROR_NEGATIVE_BUTTON = 13; /** + * The device does not have pin, pattern, or password set up. See + * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and + * {@link KeyguardManager#isDeviceSecure()} + */ + public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; + + /** * @hide */ public static final int FACE_ERROR_VENDOR_BASE = 1000; diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java index 041b2e673b96..6cbab471ce23 100644 --- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java @@ -17,6 +17,7 @@ package android.hardware.biometrics; import android.annotation.UnsupportedAppUsage; +import android.app.KeyguardManager; import android.hardware.fingerprint.FingerprintManager; /** @@ -119,6 +120,14 @@ public interface BiometricFingerprintConstants { public static final int FINGERPRINT_ERROR_NEGATIVE_BUTTON = 13; /** + * The device does not have pin, pattern, or password set up. See + * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and + * {@link KeyguardManager#isDeviceSecure()} + * @hide + */ + public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; + + /** * @hide */ @UnsupportedAppUsage diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java index d569a7800c37..baf972b26573 100644 --- a/core/java/android/hardware/biometrics/BiometricPrompt.java +++ b/core/java/android/hardware/biometrics/BiometricPrompt.java @@ -23,6 +23,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.app.KeyguardManager; import android.content.Context; import android.content.DialogInterface; import android.os.Binder; @@ -80,7 +81,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan /** * @hide */ - public static final String KEY_ENABLE_FALLBACK = "enable_fallback"; + public static final String KEY_ALLOW_DEVICE_CREDENTIAL = "allow_device_credential"; /** * Error/help message will show for this amount of time. @@ -203,7 +204,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * "Cancel" button, but may be also used to show an alternative method for authentication, * such as screen that asks for a backup password. * - * Note that this should not be set if {@link #setEnableFallback(boolean)} is set to true. + * Note that this should not be set if {@link #setAllowDeviceCredential(boolean) + * is set to true. * * @param text * @return @@ -250,7 +252,10 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan /** * The user will first be prompted to authenticate with biometrics, but also given the - * option to authenticate with their device PIN, pattern, or password. + * option to authenticate with their device PIN, pattern, or password. Developers should + * first check {@link KeyguardManager#isDeviceSecure()} before enabling this. If the device + * is not secure, {@link BiometricPrompt#BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL} will be + * returned in {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)}} * * Note that {@link #setNegativeButton(CharSequence, Executor, * DialogInterface.OnClickListener)} should not be set if this is set to true. @@ -259,8 +264,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * credentials (PIN, pattern, or password). * @return */ - public Builder setEnableFallback(boolean enable) { - mBundle.putBoolean(KEY_ENABLE_FALLBACK, enable); + public Builder setAllowDeviceCredential(boolean enable) { + mBundle.putBoolean(KEY_ALLOW_DEVICE_CREDENTIAL, enable); return this; } @@ -273,7 +278,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan final CharSequence title = mBundle.getCharSequence(KEY_TITLE); final CharSequence negative = mBundle.getCharSequence(KEY_NEGATIVE_TEXT); final boolean useDefaultTitle = mBundle.getBoolean(KEY_USE_DEFAULT_TITLE); - final boolean enableFallback = mBundle.getBoolean(KEY_ENABLE_FALLBACK); + final boolean enableFallback = mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL); if (TextUtils.isEmpty(title) && !useDefaultTitle) { throw new IllegalArgumentException("Title must be set and non-empty"); @@ -281,7 +286,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan throw new IllegalArgumentException("Negative text must be set and non-empty"); } else if (!TextUtils.isEmpty(negative) && enableFallback) { throw new IllegalArgumentException("Can't have both negative button behavior" - + " and fallback enabled"); + + " and device credential enabled"); } return new BiometricPrompt(mContext, mBundle, mPositiveButtonInfo, mNegativeButtonInfo); } @@ -541,8 +546,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan if (callback == null) { throw new IllegalArgumentException("Must supply a callback"); } - if (mBundle.getBoolean(KEY_ENABLE_FALLBACK)) { - throw new IllegalArgumentException("Fallback not supported with crypto"); + if (mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL)) { + throw new IllegalArgumentException("Device credential not supported with crypto"); } authenticateInternal(crypto, cancel, executor, callback, mContext.getUserId()); } diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl index e4336d171ab6..a20e2bf3d067 100644 --- a/core/java/android/hardware/biometrics/IBiometricService.aidl +++ b/core/java/android/hardware/biometrics/IBiometricService.aidl @@ -54,7 +54,7 @@ interface IBiometricService { // TODO(b/123378871): Remove when moved. // CDCA needs to send results to BiometricService if it was invoked using BiometricPrompt's - // setEnableFallback method, since there's no way for us to intercept onActivityResult. + // setAllowDeviceCredential method, since there's no way for us to intercept onActivityResult. // CDCA is launched from BiometricService (startActivityAsUser) instead of *ForResult. void onConfirmDeviceCredentialSuccess(); // TODO(b/123378871): Remove when moved. diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index c9a7830d50f5..efe24e50272a 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -565,16 +565,16 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan */ public static String getErrorString(Context context, int errMsg, int vendorCode) { switch (errMsg) { - case FACE_ERROR_UNABLE_TO_PROCESS: - return context.getString( - com.android.internal.R.string.face_error_unable_to_process); case FACE_ERROR_HW_UNAVAILABLE: return context.getString( com.android.internal.R.string.face_error_hw_not_available); - case FACE_ERROR_NO_SPACE: - return context.getString(com.android.internal.R.string.face_error_no_space); + case FACE_ERROR_UNABLE_TO_PROCESS: + return context.getString( + com.android.internal.R.string.face_error_unable_to_process); case FACE_ERROR_TIMEOUT: return context.getString(com.android.internal.R.string.face_error_timeout); + case FACE_ERROR_NO_SPACE: + return context.getString(com.android.internal.R.string.face_error_no_space); case FACE_ERROR_CANCELED: return context.getString(com.android.internal.R.string.face_error_canceled); case FACE_ERROR_LOCKOUT: @@ -629,6 +629,24 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan return context.getString(R.string.face_acquired_poor_gaze); case FACE_ACQUIRED_NOT_DETECTED: return context.getString(R.string.face_acquired_not_detected); + case FACE_ACQUIRED_TOO_MUCH_MOTION: + return context.getString(R.string.face_acquired_too_much_motion); + case FACE_ACQUIRED_RECALIBRATE: + return context.getString(R.string.face_acquired_recalibrate); + case FACE_ACQUIRED_TOO_DIFFERENT: + return context.getString(R.string.face_acquired_too_different); + case FACE_ACQUIRED_TOO_SIMILAR: + return context.getString(R.string.face_acquired_too_similar); + case FACE_ACQUIRED_PAN_TOO_EXTREME: + return context.getString(R.string.face_acquired_pan_too_extreme); + case FACE_ACQUIRED_TILT_TOO_EXTREME: + return context.getString(R.string.face_acquired_tilt_too_extreme); + case FACE_ACQUIRED_ROLL_TOO_EXTREME: + return context.getString(R.string.face_acquired_roll_too_extreme); + case FACE_ACQUIRED_FACE_OBSCURED: + return context.getString(R.string.face_acquired_obscured); + case FACE_ACQUIRED_START: + return null; case FACE_ACQUIRED_VENDOR: { String[] msgArray = context.getResources().getStringArray( R.array.face_acquired_vendor); diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index bb9821169a54..80d404d03c75 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -949,17 +949,17 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing */ public static String getErrorString(Context context, int errMsg, int vendorCode) { switch (errMsg) { + case FINGERPRINT_ERROR_HW_UNAVAILABLE: + return context.getString( + com.android.internal.R.string.fingerprint_error_hw_not_available); case FINGERPRINT_ERROR_UNABLE_TO_PROCESS: return context.getString( com.android.internal.R.string.fingerprint_error_unable_to_process); - case FINGERPRINT_ERROR_HW_UNAVAILABLE: - return context.getString( - com.android.internal.R.string.fingerprint_error_hw_not_available); + case FINGERPRINT_ERROR_TIMEOUT: + return context.getString(com.android.internal.R.string.fingerprint_error_timeout); case FINGERPRINT_ERROR_NO_SPACE: return context.getString( com.android.internal.R.string.fingerprint_error_no_space); - case FINGERPRINT_ERROR_TIMEOUT: - return context.getString(com.android.internal.R.string.fingerprint_error_timeout); case FINGERPRINT_ERROR_CANCELED: return context.getString(com.android.internal.R.string.fingerprint_error_canceled); case FINGERPRINT_ERROR_LOCKOUT: diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index d2ab053eb4e6..9e97e375753c 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -526,11 +526,12 @@ public class Process { @Nullable String packageName, @Nullable String[] packagesForUid, @Nullable String[] visibleVols, + @Nullable String sandboxId, @Nullable String[] zygoteArgs) { return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, - packagesForUid, visibleVols, /*useBlastulaPool=*/ true, zygoteArgs); + packagesForUid, visibleVols, sandboxId, /*useBlastulaPool=*/ true, zygoteArgs); } /** @hide */ @@ -547,11 +548,12 @@ public class Process { @Nullable String packageName, @Nullable String[] packagesForUid, @Nullable String[] visibleVols, + @Nullable String sandboxId, @Nullable String[] zygoteArgs) { return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, - packagesForUid, visibleVols, /*useBlastulaPool=*/ false, zygoteArgs); + packagesForUid, visibleVols, sandboxId, /*useBlastulaPool=*/ false, zygoteArgs); } /** diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index e94ad2b8989e..ee3d35427b29 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -324,13 +324,15 @@ public class ZygoteProcess { @Nullable String packageName, @Nullable String[] packagesForUid, @Nullable String[] visibleVols, + @Nullable String sandboxId, boolean useBlastulaPool, @Nullable String[] zygoteArgs) { try { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/false, - packageName, packagesForUid, visibleVols, useBlastulaPool, zygoteArgs); + packageName, packagesForUid, visibleVols, sandboxId, + useBlastulaPool, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); @@ -541,6 +543,7 @@ public class ZygoteProcess { @Nullable String packageName, @Nullable String[] packagesForUid, @Nullable String[] visibleVols, + @Nullable String sandboxId, boolean useBlastulaPool, @Nullable String[] extraArgs) throws ZygoteStartFailedEx { @@ -639,6 +642,10 @@ public class ZygoteProcess { argsForZygote.add(sb.toString()); } + if (sandboxId != null) { + argsForZygote.add("--sandbox-id=" + sandboxId); + } + argsForZygote.add(processClass); if (extraArgs != null) { @@ -1014,7 +1021,7 @@ public class ZygoteProcess { gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo, abi, instructionSet, null /* appDataDir */, null /* invokeWith */, true /* startChildZygote */, null /* packageName */, - null /* packagesForUid */, null /* visibleVolumes */, + null /* packagesForUid */, null /* visibleVolumes */, null /* sandboxId */, false /* useBlastulaPool */, extraArgs); } catch (ZygoteStartFailedEx ex) { throw new RuntimeException("Starting child-zygote through Zygote failed", ex); diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java index f521c683896e..03b2c2c4c6f2 100644 --- a/core/java/android/os/storage/StorageManagerInternal.java +++ b/core/java/android/os/storage/StorageManagerInternal.java @@ -132,4 +132,9 @@ public abstract class StorageManagerInternal { * @param listener The listener that will be notified on reset events. */ public abstract void addResetListener(ResetListener listener); + + /** + * Return the sandboxId for the given package on external storage. + */ + public abstract String getSandboxId(String packageName); } diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 8e7906eb3c06..41d3cbb88f5c 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -72,45 +72,13 @@ public final class DeviceConfig { public static final String NAMESPACE_AUTOFILL = "autofill"; /** - * ContentCapture-related properties definitions. - * - * @hide - */ - @SystemApi - public interface ContentCapture { - String NAMESPACE = "content_capture"; - - /** - * Property used by {@code com.android.server.SystemServer} on start to decide whether - * the Content Capture service should be created or not. - * - * <p>Possible values are: - * - * <ul> - * <li>If set to {@code default}, it will only be set if the OEM provides and defines the - * service name by overlaying {@code config_defaultContentCaptureService} (this is the - * "default" mode) - * <li>If set to {@code always}, it will always be enabled, even when the resource is not - * overlaid (this is useful during development and to run the CTS tests on AOSP builds). - * <li>Otherwise, it's explicitly disabled (this could work as a "kill switch" so OEMs - * can disable it remotely in case of emergency by setting to something else (like - * {@code "false"}); notice that it's also disabled if the OEM doesn't explicitly set one - * of the values above). - * </ul> - * - * @hide - */ - // TODO(b/121153631): revert back to SERVICE_EXPLICITLY_ENABLED approach - String PROPERTY_CONTENTCAPTURE_ENABLED = "enable_contentcapture"; - } - - /** * Namespace for content capture feature used by on-device machine intelligence * to provide suggestions in a privacy-safe manner. * * @hide */ @SystemApi + @TestApi public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; /** @@ -360,6 +328,7 @@ public final class DeviceConfig { * @hide */ @SystemApi + @TestApi @RequiresPermission(READ_DEVICE_CONFIG) public static String getProperty(String namespace, String name) { ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver(); diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 67c840006948..0b3842080a75 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -157,10 +157,6 @@ public final class MediaStore { public static final String PARAM_DELETE_DATA = "deletedata"; /** {@hide} */ - public static final String PARAM_PRIMARY = "primary"; - /** {@hide} */ - public static final String PARAM_SECONDARY = "secondary"; - /** {@hide} */ public static final String PARAM_INCLUDE_PENDING = "includePending"; /** {@hide} */ public static final String PARAM_INCLUDE_TRASHED = "includeTrashed"; @@ -543,7 +539,9 @@ public final class MediaStore { * @see MediaStore#setIncludeTrashed(Uri) * @see MediaStore#trash(Context, Uri) * @see MediaStore#untrash(Context, Uri) + * @removed */ + @Deprecated public static @NonNull Uri setIncludeTrashed(@NonNull Uri uri) { return uri.buildUpon().appendQueryParameter(PARAM_INCLUDE_TRASHED, "1").build(); } @@ -580,14 +578,7 @@ public final class MediaStore { */ public static @NonNull Uri createPending(@NonNull Context context, @NonNull PendingParams params) { - final Uri.Builder builder = params.insertUri.buildUpon(); - if (!TextUtils.isEmpty(params.primaryDirectory)) { - builder.appendQueryParameter(PARAM_PRIMARY, params.primaryDirectory); - } - if (!TextUtils.isEmpty(params.secondaryDirectory)) { - builder.appendQueryParameter(PARAM_SECONDARY, params.secondaryDirectory); - } - return context.getContentResolver().insert(builder.build(), params.insertValues); + return context.getContentResolver().insert(params.insertUri, params.insertValues); } /** @@ -610,10 +601,6 @@ public final class MediaStore { public final Uri insertUri; /** {@hide} */ public final ContentValues insertValues; - /** {@hide} */ - public String primaryDirectory; - /** {@hide} */ - public String secondaryDirectory; /** * Create parameters that describe a pending media item. @@ -655,7 +642,11 @@ public final class MediaStore { * @see MediaColumns#PRIMARY_DIRECTORY */ public void setPrimaryDirectory(@Nullable String primaryDirectory) { - this.primaryDirectory = primaryDirectory; + if (primaryDirectory == null) { + this.insertValues.remove(MediaColumns.PRIMARY_DIRECTORY); + } else { + this.insertValues.put(MediaColumns.PRIMARY_DIRECTORY, primaryDirectory); + } } /** @@ -668,7 +659,11 @@ public final class MediaStore { * @see MediaColumns#SECONDARY_DIRECTORY */ public void setSecondaryDirectory(@Nullable String secondaryDirectory) { - this.secondaryDirectory = secondaryDirectory; + if (secondaryDirectory == null) { + this.insertValues.remove(MediaColumns.SECONDARY_DIRECTORY); + } else { + this.insertValues.put(MediaColumns.SECONDARY_DIRECTORY, secondaryDirectory); + } } /** @@ -797,7 +792,9 @@ public final class MediaStore { * @see MediaStore#setIncludeTrashed(Uri) * @see MediaStore#trash(Context, Uri) * @see MediaStore#untrash(Context, Uri) + * @removed */ + @Deprecated public static void trash(@NonNull Context context, @NonNull Uri uri) { trash(context, uri, 48 * DateUtils.HOUR_IN_MILLIS); } @@ -815,7 +812,9 @@ public final class MediaStore { * @see MediaStore#setIncludeTrashed(Uri) * @see MediaStore#trash(Context, Uri) * @see MediaStore#untrash(Context, Uri) + * @removed */ + @Deprecated public static void trash(@NonNull Context context, @NonNull Uri uri, @DurationMillisLong long timeoutMillis) { if (timeoutMillis < 0) { @@ -837,7 +836,9 @@ public final class MediaStore { * @see MediaStore#setIncludeTrashed(Uri) * @see MediaStore#trash(Context, Uri) * @see MediaStore#untrash(Context, Uri) + * @removed */ + @Deprecated public static void untrash(@NonNull Context context, @NonNull Uri uri) { final ContentValues values = new ContentValues(); values.put(MediaColumns.IS_TRASHED, 0); @@ -884,7 +885,9 @@ public final class MediaStore { * hash is calculated. * <p> * Type: BLOB + * @removed */ + @Deprecated public static final String HASH = "_hash"; /** @@ -921,8 +924,22 @@ public final class MediaStore { public static final String DATE_MODIFIED = "date_modified"; /** - * The MIME type of the file - * <P>Type: TEXT</P> + * The MIME type of the media item. + * <p> + * This is typically defined based on the file extension of the media + * item. However, it may be the value of the {@code format} attribute + * defined by the <em>Dublin Core Media Initiative</em> standard, + * extracted from any XMP metadata contained within this media item. + * <p class="note"> + * Note: the {@code format} attribute may be ignored if the top-level + * MIME type disagrees with the file extension. For example, it's + * reasonable for an {@code image/jpeg} file to declare a {@code format} + * of {@code image/vnd.google.panorama360+jpg}, but declaring a + * {@code format} of {@code audio/ogg} would be ignored. + * <p> + * This is a read-only column that is automatically computed. + * <p> + * Type: TEXT */ public static final String MIME_TYPE = "mime_type"; @@ -965,7 +982,9 @@ public final class MediaStore { * @see MediaStore#setIncludeTrashed(Uri) * @see MediaStore#trash(Context, Uri) * @see MediaStore#untrash(Context, Uri) + * @removed */ + @Deprecated public static final String IS_TRASHED = "is_trashed"; /** @@ -974,7 +993,9 @@ public final class MediaStore { * {@link #IS_PENDING} or {@link #IS_TRASHED}. * <p> * Type: INTEGER + * @removed */ + @Deprecated public static final String DATE_EXPIRES = "date_expires"; /** @@ -991,6 +1012,8 @@ public final class MediaStore { * Package name that contributed this media. The value may be * {@code NULL} if ownership cannot be reliably determined. * <p> + * This is a read-only column that is automatically computed. + * <p> * Type: TEXT */ public static final String OWNER_PACKAGE_NAME = "owner_package_name"; @@ -1014,6 +1037,52 @@ public final class MediaStore { * @see PendingParams#setSecondaryDirectory(String) */ public static final String SECONDARY_DIRECTORY = "secondary_directory"; + + /** + * The "document ID" GUID as defined by the <em>XMP Media + * Management</em> standard, extracted from any XMP metadata contained + * within this media item. The value is {@code null} when no metadata + * was found. + * <p> + * Each "document ID" is created once for each new resource. Different + * renditions of that resource are expected to have different IDs. + * <p> + * This is a read-only column that is automatically computed. + * <p> + * Type: TEXT + */ + public static final String DOCUMENT_ID = "document_id"; + + /** + * The "instance ID" GUID as defined by the <em>XMP Media + * Management</em> standard, extracted from any XMP metadata contained + * within this media item. The value is {@code null} when no metadata + * was found. + * <p> + * This "instance ID" changes with each save operation of a specific + * "document ID". + * <p> + * This is a read-only column that is automatically computed. + * <p> + * Type: TEXT + */ + public static final String INSTANCE_ID = "instance_id"; + + /** + * The "original document ID" GUID as defined by the <em>XMP Media + * Management</em> standard, extracted from any XMP metadata contained + * within this media item. + * <p> + * This "original document ID" links a resource to its original source. + * For example, when you save a PSD document as a JPEG, then convert the + * JPEG to GIF format, the "original document ID" of both the JPEG and + * GIF files is the "document ID" of the original PSD file. + * <p> + * This is a read-only column that is automatically computed. + * <p> + * Type: TEXT + */ + public static final String ORIGINAL_DOCUMENT_ID = "original_document_id"; } /** @@ -3097,20 +3166,29 @@ public final class MediaStore { final ArrayList<File> res = new ArrayList<>(); if (VOLUME_INTERNAL.equals(volumeName)) { - res.add(new File(Environment.getRootDirectory(), "media")); - res.add(new File(Environment.getOemDirectory(), "media")); - res.add(new File(Environment.getProductDirectory(), "media")); + addCanoncialFile(res, new File(Environment.getRootDirectory(), "media")); + addCanoncialFile(res, new File(Environment.getOemDirectory(), "media")); + addCanoncialFile(res, new File(Environment.getProductDirectory(), "media")); } else { - res.add(getVolumePath(volumeName)); + addCanoncialFile(res, getVolumePath(volumeName)); final UserManager um = AppGlobals.getInitialApplication() .getSystemService(UserManager.class); if (VOLUME_EXTERNAL.equals(volumeName) && um.isDemoUser()) { - res.add(Environment.getDataPreloadsMediaDirectory()); + addCanoncialFile(res, Environment.getDataPreloadsMediaDirectory()); } } return res; } + private static void addCanoncialFile(List<File> list, File file) { + try { + list.add(file.getCanonicalFile()); + } catch (IOException e) { + Log.w(TAG, "Failed to resolve " + file + ": " + e); + list.add(file); + } + } + /** * Uri for querying the state of the media scanner. */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e95d60465371..de84e713a6f7 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8289,6 +8289,7 @@ public final class Settings { * The value is boolean (1 or 0). * @hide */ + @TestApi public static final String NOTIFICATION_BADGING = "notification_badging"; private static final Validator NOTIFICATION_BADGING_VALIDATOR = BOOLEAN_VALIDATOR; diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 03e8a0fc0d39..c64386e8db79 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -133,7 +133,7 @@ public final class Choreographer { }; // Enable/disable vsync for animations and drawing. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769497) private static final boolean USE_VSYNC = SystemProperties.getBoolean( "debug.choreographer.vsync", true); diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index e3a6bd7a6949..49bae280321e 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -32,6 +32,7 @@ import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; @@ -495,7 +496,7 @@ public final class Display { * @return True if the display is still valid. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public boolean getDisplayInfo(DisplayInfo outDisplayInfo) { synchronized (this) { updateDisplayInfoLocked(); diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index ff4ee9ce7ded..ad8fee978c9a 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -158,8 +158,9 @@ public final class DisplayInfo implements Parcelable { * * @hide */ + // Remark on @UnsupportedAppUsage: Display.getCutout should be used instead @Nullable - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public DisplayCutout displayCutout; /** diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 8ae4757f5de6..2ef7c4b16d9d 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -25,6 +25,7 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.GraphicBuffer; +import android.graphics.Insets; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; @@ -380,6 +381,16 @@ interface IWindowManager void getStableInsets(int displayId, out Rect outInsets); /** + * Set the forwarded insets on the display. + * <p> + * This is only used in case a virtual display is displayed on another display that has insets, + * and the bounds of the virtual display is overlapping with the insets from the host display. + * In that case, the contents on the virtual display won't be placed over the forwarded insets. + * Only the owner of the display is permitted to set the forwarded insets on it. + */ + void setForwardedInsets(int displayId, in Insets insets); + + /** * Register shortcut key. Shortcut code is packed as: * (MetaState << Integer.SIZE) | KeyCode * @hide diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java index 583651dee379..dd88e3c34d30 100644 --- a/core/java/android/view/InsetsAnimationControlImpl.java +++ b/core/java/android/view/InsetsAnimationControlImpl.java @@ -33,6 +33,7 @@ import android.util.SparseSetArray; import android.view.InsetsState.InsetSide; import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; import android.view.WindowInsets.Type.InsetType; +import android.view.WindowManager.LayoutParams; import com.android.internal.annotations.VisibleForTesting; @@ -165,7 +166,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll @Nullable @InsetSide SparseIntArray typeSideMap) { return state.calculateInsets(frame, false /* isScreenRound */, false /* alwaysConsumerNavBar */, null /* displayCutout */, - null /* legacyContentInsets */, null /* legacyStableInsets */, typeSideMap) + null /* legacyContentInsets */, null /* legacyStableInsets */, + LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/, typeSideMap) .getInsets(mTypes); } diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 7ad97a6d393e..258600019e71 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -112,6 +112,8 @@ public class InsetsController implements WindowInsetsController { private int mPendingTypesToShow; + private int mLastLegacySoftInputMode; + public InsetsController(ViewRootImpl viewRoot) { mViewRoot = viewRoot; mAnimCallback = () -> { @@ -126,13 +128,17 @@ public class InsetsController implements WindowInsetsController { } WindowInsets insets = state.calculateInsets(mFrame, mLastInsets.isRound(), mLastInsets.shouldAlwaysConsumeNavBar(), mLastInsets.getDisplayCutout(), - mLastLegacyContentInsets, mLastLegacyStableInsets, + mLastLegacyContentInsets, mLastLegacyStableInsets, mLastLegacySoftInputMode, null /* typeSideMap */); mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets); }; } void onFrameChanged(Rect frame) { + if (mFrame.equals(frame)) { + return; + } + mViewRoot.notifyInsetsChanged(); mFrame.set(frame); } @@ -160,11 +166,12 @@ public class InsetsController implements WindowInsetsController { @VisibleForTesting public WindowInsets calculateInsets(boolean isScreenRound, boolean alwaysConsumeNavBar, DisplayCutout cutout, Rect legacyContentInsets, - Rect legacyStableInsets) { + Rect legacyStableInsets, int legacySoftInputMode) { mLastLegacyContentInsets.set(legacyContentInsets); mLastLegacyStableInsets.set(legacyStableInsets); + mLastLegacySoftInputMode = legacySoftInputMode; mLastInsets = mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeNavBar, cutout, - legacyContentInsets, legacyStableInsets, + legacyContentInsets, legacyStableInsets, legacySoftInputMode, null /* typeSideMap */); return mLastInsets; } @@ -257,11 +264,21 @@ public class InsetsController implements WindowInsetsController { private void controlWindowInsetsAnimation(@InsetType int types, WindowInsetsAnimationControlListener listener, boolean fromIme) { + // If the frame of our window doesn't span the entire display, the control API makes very + // little sense, as we don't deal with negative insets. So just cancel immediately. + if (!mState.getDisplayFrame().equals(mFrame)) { + listener.onCancelled(); + return; + } + controlAnimationUnchecked(types, listener, mFrame, fromIme); + } + + private void controlAnimationUnchecked(@InsetType int types, + WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme) { if (types == 0) { // nothing to animate. return; } - // TODO: Check whether we already have a controller. final ArraySet<Integer> internalTypes = mState.toInternalType(types); final SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>(); @@ -285,7 +302,7 @@ public class InsetsController implements WindowInsetsController { } final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(consumers, - mFrame, mState, listener, typesReady, + frame, mState, listener, typesReady, () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this); mAnimationControls.add(controller); } @@ -436,6 +453,7 @@ public class InsetsController implements WindowInsetsController { // nothing to animate. return; } + WindowInsetsAnimationControlListener listener = new WindowInsetsAnimationControlListener() { @Override public void onReady(WindowInsetsAnimationController controller, int types) { @@ -479,7 +497,10 @@ public class InsetsController implements WindowInsetsController { // TODO: Instead of clearing this here, properly wire up // InsetsAnimationControlImpl.finish() to remove this from mAnimationControls. mAnimationControls.clear(); - controlWindowInsetsAnimation(types, listener, fromIme); + + // Show/hide animations always need to be relative to the display frame, in order that shown + // and hidden state insets are correct. + controlAnimationUnchecked(types, listener, mState.getDisplayFrame(), fromIme); } private void hideDirectly(@InsetType int types) { diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 4f809fe6d54a..69f86aa5b37e 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -19,6 +19,7 @@ package android.view; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME; import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; +import static android.view.WindowInsets.Type.IME; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.indexOf; @@ -34,11 +35,13 @@ import android.util.SparseArray; import android.util.SparseIntArray; import android.view.WindowInsets.Type; import android.view.WindowInsets.Type.InsetType; +import android.view.WindowManager.LayoutParams; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Objects; /** * Holder for state of system windows that cause window insets for all other windows in the system. @@ -104,6 +107,11 @@ public class InsetsState implements Parcelable { private final ArrayMap<Integer, InsetsSource> mSources = new ArrayMap<>(); + /** + * The frame of the display these sources are relative to. + */ + private final Rect mDisplayFrame = new Rect(); + public InsetsState() { } @@ -124,7 +132,7 @@ public class InsetsState implements Parcelable { public WindowInsets calculateInsets(Rect frame, boolean isScreenRound, boolean alwaysConsumeNavBar, DisplayCutout cutout, @Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets, - @Nullable @InsetSide SparseIntArray typeSideMap) { + int legacySoftInputMode, @Nullable @InsetSide SparseIntArray typeSideMap) { Insets[] typeInsetsMap = new Insets[Type.SIZE]; Insets[] typeMaxInsetsMap = new Insets[Type.SIZE]; boolean[] typeVisibilityMap = new boolean[SIZE]; @@ -140,8 +148,12 @@ public class InsetsState implements Parcelable { if (source == null) { continue; } - if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL - && (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR)) { + + boolean skipSystemBars = ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL + && (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR); + boolean skipIme = source.getType() == TYPE_IME + && (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0; + if (skipSystemBars || skipIme) { typeVisibilityMap[indexOf(toPublicType(type))] = source.isVisible(); continue; } @@ -209,6 +221,14 @@ public class InsetsState implements Parcelable { return mSources.computeIfAbsent(type, InsetsSource::new); } + public void setDisplayFrame(Rect frame) { + mDisplayFrame.set(frame); + } + + public Rect getDisplayFrame() { + return mDisplayFrame; + } + /** * Modifies the state of this class to exclude a certain type to make it ready for dispatching * to the client. @@ -224,6 +244,7 @@ public class InsetsState implements Parcelable { } public void set(InsetsState other, boolean copySources) { + mDisplayFrame.set(other.mDisplayFrame); mSources.clear(); if (copySources) { for (int i = 0; i < other.mSources.size(); i++) { @@ -323,6 +344,9 @@ public class InsetsState implements Parcelable { InsetsState state = (InsetsState) o; + if (!mDisplayFrame.equals(state.mDisplayFrame)) { + return false; + } if (mSources.size() != state.mSources.size()) { return false; } @@ -341,7 +365,7 @@ public class InsetsState implements Parcelable { @Override public int hashCode() { - return mSources.hashCode(); + return Objects.hash(mDisplayFrame, mSources); } public InsetsState(Parcel in) { @@ -355,9 +379,10 @@ public class InsetsState implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mDisplayFrame, flags); dest.writeInt(mSources.size()); for (int i = 0; i < mSources.size(); i++) { - dest.writeParcelable(mSources.valueAt(i), 0 /* flags */); + dest.writeParcelable(mSources.valueAt(i), flags); } } @@ -374,6 +399,7 @@ public class InsetsState implements Parcelable { public void readFromParcel(Parcel in) { mSources.clear(); + mDisplayFrame.set(in.readParcelable(null /* loader */)); final int size = in.readInt(); for (int i = 0; i < size; i++) { final InsetsSource source = in.readParcelable(null /* loader */); diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index 6a290b7fe045..3f18d8b46e2a 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -42,14 +42,16 @@ import android.widget.FrameLayout; import com.android.internal.R; import dalvik.system.PathClassLoader; -import java.io.File; -import java.lang.reflect.Method; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.util.HashMap; +import java.util.Objects; /** * Instantiates a layout XML file into its corresponding {@link android.view.View} @@ -110,7 +112,12 @@ public abstract class LayoutInflater { // The classloader includes the generated compiled_view.dex file. private ClassLoader mPrecompiledClassLoader; - @UnsupportedAppUsage + /** + * This is not a public API. Two APIs are now available to alleviate the need to access + * this directly: {@link #createView(Context, String, String, AttributeSet)} and + * {@link #onCreateView(Context, View, String, AttributeSet)}. + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) final Object[] mConstructorArgs = new Object[2]; @UnsupportedAppUsage @@ -721,6 +728,32 @@ public abstract class LayoutInflater { } while (cl != null); return false; } + /** + * Low-level function for instantiating a view by name. This attempts to + * instantiate a view class of the given <var>name</var> found in this + * LayoutInflater's ClassLoader. To use an explicit Context in the View + * constructor, use {@link #createView(Context, String, String, AttributeSet)} instead. + * + * <p> + * There are two things that can happen in an error case: either the + * exception describing the error will be thrown, or a null will be + * returned. You must deal with both possibilities -- the former will happen + * the first time createView() is called for a class of a particular name, + * the latter every time there-after for that class name. + * + * @param name The full name of the class to be instantiated. + * @param attrs The XML attributes supplied for this instance. + * + * @return View The newly instantiated view, or null. + */ + public final View createView(String name, String prefix, AttributeSet attrs) + throws ClassNotFoundException, InflateException { + Context context = (Context) mConstructorArgs[0]; + if (context == null) { + context = mContext; + } + return createView(context, name, prefix, attrs); + } /** * Low-level function for instantiating a view by name. This attempts to @@ -734,13 +767,18 @@ public abstract class LayoutInflater { * the first time createView() is called for a class of a particular name, * the latter every time there-after for that class name. * + * @param viewContext The context used as the context parameter of the View constructor * @param name The full name of the class to be instantiated. * @param attrs The XML attributes supplied for this instance. * * @return View The newly instantiated view, or null. */ - public final View createView(String name, String prefix, AttributeSet attrs) + @Nullable + public final View createView(@NonNull Context viewContext, @NonNull String name, + @Nullable String prefix, @Nullable AttributeSet attrs) throws ClassNotFoundException, InflateException { + Objects.requireNonNull(viewContext); + Objects.requireNonNull(name); Constructor<? extends View> constructor = sConstructorMap.get(name); if (constructor != null && !verifyClassLoader(constructor)) { constructor = null; @@ -787,22 +825,21 @@ public abstract class LayoutInflater { } Object lastContext = mConstructorArgs[0]; - if (mConstructorArgs[0] == null) { - // Fill in the context if not already within inflation. - mConstructorArgs[0] = mContext; - } + mConstructorArgs[0] = viewContext; Object[] args = mConstructorArgs; args[1] = attrs; - final View view = constructor.newInstance(args); - if (view instanceof ViewStub) { - // Use the same context when inflating ViewStub later. - final ViewStub viewStub = (ViewStub) view; - viewStub.setLayoutInflater(cloneInContext((Context) args[0])); + try { + final View view = constructor.newInstance(args); + if (view instanceof ViewStub) { + // Use the same context when inflating ViewStub later. + final ViewStub viewStub = (ViewStub) view; + viewStub.setLayoutInflater(cloneInContext((Context) args[0])); + } + return view; + } finally { + mConstructorArgs[0] = lastContext; } - mConstructorArgs[0] = lastContext; - return view; - } catch (NoSuchMethodException e) { final InflateException ie = new InflateException(attrs.getPositionDescription() + ": Error inflating class " + (prefix != null ? (prefix + name) : name), e); @@ -871,6 +908,26 @@ public abstract class LayoutInflater { } /** + * Version of {@link #onCreateView(View, String, AttributeSet)} that also + * takes the inflation context. The default + * implementation simply calls {@link #onCreateView(View, String, AttributeSet)}. + * + * @param viewContext The Context to be used as a constructor parameter for the View + * @param parent The future parent of the returned view. <em>Note that + * this may be null.</em> + * @param name The fully qualified class name of the View to be create. + * @param attrs An AttributeSet of attributes to apply to the View. + * + * @return View The View created. + */ + @Nullable + public View onCreateView(@NonNull Context viewContext, @Nullable View parent, + @NonNull String name, @Nullable AttributeSet attrs) + throws ClassNotFoundException { + return onCreateView(parent, name, attrs); + } + + /** * Convenience method for calling through to the five-arg createViewFromTag * method. This method passes {@code false} for the {@code ignoreThemeAttr} * argument and should be used for everything except {@code >include>} @@ -921,9 +978,9 @@ public abstract class LayoutInflater { mConstructorArgs[0] = context; try { if (-1 == name.indexOf('.')) { - view = onCreateView(parent, name, attrs); + view = onCreateView(context, parent, name, attrs); } else { - view = createView(name, null, attrs); + view = createView(context, name, null, attrs); } } finally { mConstructorArgs[0] = lastContext; diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index b6a4a095066f..b6c4cbbbe54d 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -24,6 +24,7 @@ import android.annotation.IntDef; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.graphics.Matrix; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -1513,7 +1514,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { } // Pointer to the native MotionEvent object that contains the actual data. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private long mNativePtr; private MotionEvent mNext; diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index dc11d3ddd1d6..c24b8b2a5ee3 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -18,7 +18,6 @@ package android.view; import android.annotation.UnsupportedAppUsage; import android.content.Context; -import android.content.res.Resources; import android.os.Build; import android.os.Handler; @@ -145,7 +144,7 @@ public class ScaleGestureDetector { private boolean mInProgress; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768938) private int mSpanSlop; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768938) private int mMinSpan; private final Handler mHandler; @@ -200,10 +199,9 @@ public class ScaleGestureDetector { Handler handler) { mContext = context; mListener = listener; - mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2; - - final Resources res = context.getResources(); - mMinSpan = res.getDimensionPixelSize(com.android.internal.R.dimen.config_minScalingSpan); + final ViewConfiguration viewConfiguration = ViewConfiguration.get(context); + mSpanSlop = viewConfiguration.getScaledTouchSlop() * 2; + mMinSpan = viewConfiguration.getScaledMinScalingSpan(); mHandler = handler; // Quick scale is enabled by default after JB_MR2 final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion; diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 8028715219cc..1212df0c397a 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -62,6 +62,7 @@ import libcore.util.NativeAllocationRegistry; import java.io.Closeable; import java.nio.ByteBuffer; +import java.nio.ByteOrder; /** * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is @@ -711,8 +712,10 @@ public final class SurfaceControl implements Parcelable { for (int i = 0; i < metadata.size(); ++i) { metaParcel.writeInt(metadata.keyAt(i)); metaParcel.writeByteArray( - ByteBuffer.allocate(4).putInt(metadata.valueAt(i)).array()); + ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()) + .putInt(metadata.valueAt(i)).array()); } + metaParcel.setDataPosition(0); } mNativeObject = nativeCreate(session, name, w, h, format, flags, parent != null ? parent.mNativeObject : 0, metaParcel); diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 6beae37d6b46..bb29ed6c5339 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -293,12 +293,14 @@ public class ViewConfiguration { */ private static final float AMBIGUOUS_GESTURE_MULTIPLIER = 2f; + private final boolean mConstructedWithContext; private final int mEdgeSlop; private final int mFadingEdgeLength; private final int mMinimumFlingVelocity; private final int mMaximumFlingVelocity; private final int mScrollbarSize; private final int mTouchSlop; + private final int mMinScalingSpan; private final int mHoverSlop; private final int mMinScrollbarTouchTarget; private final int mDoubleTapTouchSlop; @@ -329,6 +331,7 @@ public class ViewConfiguration { */ @Deprecated public ViewConfiguration() { + mConstructedWithContext = false; mEdgeSlop = EDGE_SLOP; mFadingEdgeLength = FADING_EDGE_LENGTH; mMinimumFlingVelocity = MINIMUM_FLING_VELOCITY; @@ -350,6 +353,10 @@ public class ViewConfiguration { mHorizontalScrollFactor = HORIZONTAL_SCROLL_FACTOR; mVerticalScrollFactor = VERTICAL_SCROLL_FACTOR; mShowMenuShortcutsWhenKeyboardPresent = false; + + // Getter throws if mConstructedWithContext is false so doesn't matter what + // this value is. + mMinScalingSpan = 0; } /** @@ -363,6 +370,7 @@ public class ViewConfiguration { * @see android.util.DisplayMetrics */ private ViewConfiguration(Context context) { + mConstructedWithContext = true; final Resources res = context.getResources(); final DisplayMetrics metrics = res.getDisplayMetrics(); final Configuration config = res.getConfiguration(); @@ -447,6 +455,8 @@ public class ViewConfiguration { mShowMenuShortcutsWhenKeyboardPresent = res.getBoolean( com.android.internal.R.bool.config_showMenuShortcutsWhenKeyboardPresent); + mMinScalingSpan = res.getDimensionPixelSize( + com.android.internal.R.dimen.config_minScalingSpan); } /** @@ -959,6 +969,26 @@ public class ViewConfiguration { } /** + * Retrieves the distance in pixels between touches that must be reached for a gesture to be + * interpreted as scaling. + * + * In general, scaling shouldn't start until this distance has been met or surpassed, and + * scaling should end when the distance in pixels between touches drops below this distance. + * + * @return The distance in pixels + * @throws IllegalStateException if this method is called on a ViewConfiguration that was + * instantiated using a constructor with no Context parameter. + */ + public int getScaledMinScalingSpan() { + if (!mConstructedWithContext) { + throw new IllegalStateException("Min scaling span cannot be determined when this " + + "method is called on a ViewConfiguration that was instantiated using a " + + "constructor with no Context parameter"); + } + return mMinScalingSpan; + } + + /** * @hide * @return Whether or not marquee should use fading edges. */ diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 156972f6ecbb..1a782ee5d3dd 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1887,7 +1887,7 @@ public final class ViewRootImpl implements ViewParent, mLastWindowInsets = mInsetsController.calculateInsets( mContext.getResources().getConfiguration().isScreenRound(), mAttachInfo.mAlwaysConsumeNavBar, displayCutout, - contentInsets, stableInsets); + contentInsets, stableInsets, mWindowAttributes.softInputMode); } else { mLastWindowInsets = new WindowInsets(contentInsets, stableInsets, mContext.getResources().getConfiguration().isScreenRound(), diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 46aea80efe7a..e3833c01eeaf 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -520,7 +520,7 @@ public final class WindowManagerGlobal { return false; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public void trimMemory(int level) { if (ThreadedRenderer.isAvailable()) { if (shouldDestroyEglContext(level)) { diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 2512b95fe0ec..634443d78b49 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -66,6 +66,25 @@ public final class ContentCaptureManager { */ private static final int SYNC_CALLS_TIMEOUT_MS = 5000; + /** + * DeviceConfig property used by {@code com.android.server.SystemServer} on start to decide + * whether the Content Capture service should be created or not + * + * <p>By default it should *NOT* be set (or set to {@code "default"}, so the decision is based + * on whether the OEM provides an implementation for the service), but it can be overridden to: + * + * <ul> + * <li>Provide a "kill switch" so OEMs can disable it remotely in case of emergency (when + * it's set to {@code "false"}). + * <li>Enable the CTS tests to be run on AOSP builds (when it's set to {@code "true"}). + * </ul> + * + * @hide + */ + @TestApi + public static final String DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED = + "service_explicitly_enabled"; + private final Object mLock = new Object(); @NonNull diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index eb945b55bd7e..810c967ce2c8 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -303,6 +303,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text=" + getSanitizedString(event.getText())); } + // TODO(b/124107816): should call lastEvent.merge(event) instead lastEvent.setText(event.getText()); addEvent = false; } @@ -316,7 +317,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { Log.v(TAG, "Buffering TYPE_VIEW_DISAPPEARED events for session " + lastEvent.getSessionId()); } - lastEvent.addAutofillId(event.getId()); + mergeViewsDisappearedEvent(lastEvent, event); addEvent = false; } } @@ -364,6 +365,30 @@ public final class MainContentCaptureSession extends ContentCaptureSession { flush(flushReason); } + // TODO(b/124107816): should be ContentCaptureEvent Event.merge(event) instead (which would + // replace the addAutofillId() method - we would also need unit tests on ContentCaptureEventTest + // to check these scenarios) + private void mergeViewsDisappearedEvent(@NonNull ContentCaptureEvent lastEvent, + @NonNull ContentCaptureEvent event) { + final List<AutofillId> ids = event.getIds(); + final AutofillId id = event.getId(); + if (ids != null) { + if (id != null) { + Log.w(TAG, "got TYPE_VIEW_DISAPPEARED event with both id and ids: " + event); + } + for (int i = 0; i < ids.size(); i++) { + lastEvent.addAutofillId(ids.get(i)); + } + return; + } + if (id != null) { + lastEvent.addAutofillId(id); + return; + } + throw new IllegalArgumentException( + "got TYPE_VIEW_DISAPPEARED event with neither id or ids: " + event); + } + @UiThread private boolean hasStarted() { return mState != UNKNOWN_STATE; diff --git a/core/java/android/view/textclassifier/ConversationAction.java b/core/java/android/view/textclassifier/ConversationAction.java index 1a6e5d8e8b03..ae6a645c90a1 100644 --- a/core/java/android/view/textclassifier/ConversationAction.java +++ b/core/java/android/view/textclassifier/ConversationAction.java @@ -92,6 +92,9 @@ public final class ConversationAction implements Parcelable { */ public static final String TYPE_SHARE_LOCATION = "share_location"; + /** @hide **/ + public static final String TYPE_ADD_CONTACT = "add_contact"; + public static final Creator<ConversationAction> CREATOR = new Creator<ConversationAction>() { @Override diff --git a/core/java/android/view/textclassifier/ExtrasUtils.java b/core/java/android/view/textclassifier/ExtrasUtils.java index 602455c65beb..b0e7ad5d7264 100644 --- a/core/java/android/view/textclassifier/ExtrasUtils.java +++ b/core/java/android/view/textclassifier/ExtrasUtils.java @@ -85,15 +85,16 @@ public final class ExtrasUtils { } /** - * Returns the first "translate" action found in the {@code classification} object. + * Returns the first action found in the {@code classification} object with an intent + * action string, {@code intentAction}. */ @Nullable - public static RemoteAction findTranslateAction(TextClassification classification) { + public static RemoteAction findAction(TextClassification classification, String intentAction) { final ArrayList<Intent> actionIntents = getActionsIntents(classification); if (actionIntents != null) { final int size = actionIntents.size(); for (int i = 0; i < size; i++) { - if (Intent.ACTION_TRANSLATE.equals(actionIntents.get(i).getAction())) { + if (intentAction.equals(actionIntents.get(i).getAction())) { return classification.getActions().get(i); } } @@ -102,6 +103,14 @@ public final class ExtrasUtils { } /** + * Returns the first "translate" action found in the {@code classification} object. + */ + @Nullable + public static RemoteAction findTranslateAction(TextClassification classification) { + return findAction(classification, Intent.ACTION_TRANSLATE); + } + + /** * Returns the entity type contained in the {@code extra}. */ @Nullable diff --git a/core/java/android/view/textclassifier/LegacyIntentFactory.java b/core/java/android/view/textclassifier/LegacyIntentFactory.java index b6e5b3e26b16..2d0d032cfef3 100644 --- a/core/java/android/view/textclassifier/LegacyIntentFactory.java +++ b/core/java/android/view/textclassifier/LegacyIntentFactory.java @@ -182,7 +182,8 @@ public final class LegacyIntentFactory implements IntentFactory { actions.add(new LabeledIntent( context.getString(com.android.internal.R.string.browse), context.getString(com.android.internal.R.string.browse_desc), - new Intent(Intent.ACTION_VIEW, Uri.parse(text)) + new Intent(Intent.ACTION_VIEW) + .setDataAndNormalize(Uri.parse(text)) .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()), LabeledIntent.DEFAULT_REQUEST_CODE)); return actions; diff --git a/core/java/android/view/textclassifier/TemplateIntentFactory.java b/core/java/android/view/textclassifier/TemplateIntentFactory.java index 52788436b3ea..95f88c7de146 100644 --- a/core/java/android/view/textclassifier/TemplateIntentFactory.java +++ b/core/java/android/view/textclassifier/TemplateIntentFactory.java @@ -49,20 +49,18 @@ public final class TemplateIntentFactory { } final List<TextClassifierImpl.LabeledIntent> labeledIntents = new ArrayList<>(); for (RemoteActionTemplate remoteActionTemplate : remoteActionTemplates) { - Intent intent = createIntent(remoteActionTemplate); - if (intent == null) { + if (!isValidTemplate(remoteActionTemplate)) { + Log.w(TAG, "Invalid RemoteActionTemplate skipped."); continue; } - TextClassifierImpl.LabeledIntent - labeledIntent = new TextClassifierImpl.LabeledIntent( - remoteActionTemplate.title, - remoteActionTemplate.description, - intent, - remoteActionTemplate.requestCode == null - ? TextClassifierImpl.LabeledIntent.DEFAULT_REQUEST_CODE - : remoteActionTemplate.requestCode - ); - labeledIntents.add(labeledIntent); + labeledIntents.add( + new TextClassifierImpl.LabeledIntent( + remoteActionTemplate.title, + remoteActionTemplate.description, + createIntent(remoteActionTemplate), + remoteActionTemplate.requestCode == null + ? TextClassifierImpl.LabeledIntent.DEFAULT_REQUEST_CODE + : remoteActionTemplate.requestCode)); } labeledIntents.forEach( action -> action.getIntent() @@ -70,29 +68,43 @@ public final class TemplateIntentFactory { return labeledIntents; } - @Nullable - private static Intent createIntent(RemoteActionTemplate remoteActionTemplate) { - Intent intent = new Intent(); - if (!TextUtils.isEmpty(remoteActionTemplate.packageName)) { - Log.w(TAG, "A RemoteActionTemplate is skipped as package name is set."); - return null; + private static boolean isValidTemplate(@Nullable RemoteActionTemplate remoteActionTemplate) { + if (remoteActionTemplate == null) { + Log.w(TAG, "Invalid RemoteActionTemplate: is null"); + return false; } - if (!TextUtils.isEmpty(remoteActionTemplate.action)) { - intent.setAction(remoteActionTemplate.action); + if (TextUtils.isEmpty(remoteActionTemplate.title)) { + Log.w(TAG, "Invalid RemoteActionTemplate: title is null"); + return false; } - Uri data = null; - if (!TextUtils.isEmpty(remoteActionTemplate.data)) { - data = Uri.parse(remoteActionTemplate.data); + if (TextUtils.isEmpty(remoteActionTemplate.description)) { + Log.w(TAG, "Invalid RemoteActionTemplate: description is null"); + return false; } - if (data != null || !TextUtils.isEmpty(remoteActionTemplate.type)) { - intent.setDataAndType(data, remoteActionTemplate.type); + if (!TextUtils.isEmpty(remoteActionTemplate.packageName)) { + Log.w(TAG, "Invalid RemoteActionTemplate: package name is set"); + return false; } - if (remoteActionTemplate.flags != null) { - intent.setFlags(remoteActionTemplate.flags); + if (TextUtils.isEmpty(remoteActionTemplate.action)) { + Log.w(TAG, "Invalid RemoteActionTemplate: intent action not set"); + return false; } + return true; + } + + private static Intent createIntent(RemoteActionTemplate remoteActionTemplate) { + final Intent intent = new Intent(remoteActionTemplate.action); + final Uri uri = TextUtils.isEmpty(remoteActionTemplate.data) + ? null : Uri.parse(remoteActionTemplate.data).normalizeScheme(); + final String type = TextUtils.isEmpty(remoteActionTemplate.type) + ? null : Intent.normalizeMimeType(remoteActionTemplate.type); + intent.setDataAndType(uri, type); + intent.setFlags(remoteActionTemplate.flags == null ? 0 : remoteActionTemplate.flags); if (remoteActionTemplate.category != null) { for (String category : remoteActionTemplate.category) { - intent.addCategory(category); + if (category != null) { + intent.addCategory(category); + } } } intent.putExtras(createExtras(remoteActionTemplate.extras)); @@ -105,6 +117,9 @@ public final class TemplateIntentFactory { } Bundle bundle = new Bundle(); for (NamedVariant namedVariant : namedVariants) { + if (namedVariant == null) { + continue; + } switch (namedVariant.getType()) { case NamedVariant.TYPE_INT: bundle.putInt(namedVariant.getName(), namedVariant.getInt()); diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java index ee9e04e5329a..2ef8d04939bd 100644 --- a/core/java/android/view/textclassifier/TextClassificationConstants.java +++ b/core/java/android/view/textclassifier/TextClassificationConstants.java @@ -131,6 +131,7 @@ public final class TextClassificationConstants { .add(ConversationAction.TYPE_TRACK_FLIGHT) .add(ConversationAction.TYPE_VIEW_CALENDAR) .add(ConversationAction.TYPE_VIEW_MAP) + .add(ConversationAction.TYPE_ADD_CONTACT) .toString(); /** * < 0 : Not set. Use value from LangId model. diff --git a/core/java/android/webkit/OWNERS b/core/java/android/webkit/OWNERS index 00e540a46ab2..b33da57c42e3 100644 --- a/core/java/android/webkit/OWNERS +++ b/core/java/android/webkit/OWNERS @@ -1,3 +1,4 @@ changwan@google.com +ntfschr@google.com tobiasjs@google.com torne@google.com diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 60393502bbe7..2171fc52a0ba 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -61,6 +61,7 @@ import android.view.accessibility.AccessibilityNodeProvider; import android.view.autofill.AutofillValue; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import android.view.inspector.InspectableProperty; import android.view.textclassifier.TextClassifier; import android.widget.AbsoluteLayout; @@ -1239,6 +1240,7 @@ public class WebView extends AbsoluteLayout * * @return the URL for the current page */ + @InspectableProperty(hasAttributeId = false) @ViewDebug.ExportedProperty(category = "webview") public String getUrl() { checkThread(); @@ -1254,6 +1256,7 @@ public class WebView extends AbsoluteLayout * * @return the URL that was originally requested for the current page */ + @InspectableProperty(hasAttributeId = false) @ViewDebug.ExportedProperty(category = "webview") public String getOriginalUrl() { checkThread(); @@ -1266,6 +1269,7 @@ public class WebView extends AbsoluteLayout * * @return the title for the current page */ + @InspectableProperty(hasAttributeId = false) @ViewDebug.ExportedProperty(category = "webview") public String getTitle() { checkThread(); @@ -1278,6 +1282,7 @@ public class WebView extends AbsoluteLayout * * @return the favicon for the current page */ + @InspectableProperty(hasAttributeId = false) public Bitmap getFavicon() { checkThread(); return mProvider.getFavicon(); @@ -1300,6 +1305,7 @@ public class WebView extends AbsoluteLayout * * @return the progress for the current page between 0 and 100 */ + @InspectableProperty(hasAttributeId = false) public int getProgress() { checkThread(); return mProvider.getProgress(); @@ -1310,6 +1316,7 @@ public class WebView extends AbsoluteLayout * * @return the height of the HTML content */ + @InspectableProperty(hasAttributeId = false) @ViewDebug.ExportedProperty(category = "webview") public int getContentHeight() { checkThread(); @@ -2276,6 +2283,11 @@ public class WebView extends AbsoluteLayout * * @return the requested renderer priority policy. */ + @InspectableProperty(hasAttributeId = false, enumMapping = { + @InspectableProperty.EnumMap(name = "waived", value = RENDERER_PRIORITY_WAIVED), + @InspectableProperty.EnumMap(name = "bound", value = RENDERER_PRIORITY_BOUND), + @InspectableProperty.EnumMap(name = "important", value = RENDERER_PRIORITY_IMPORTANT) + }) @RendererPriority public int getRendererRequestedPriority() { return mProvider.getRendererRequestedPriority(); @@ -2288,6 +2300,7 @@ public class WebView extends AbsoluteLayout * @return whether this WebView requests a priority of * {@link #RENDERER_PRIORITY_WAIVED} when not visible. */ + @InspectableProperty(hasAttributeId = false) public boolean getRendererPriorityWaivedWhenNotVisible() { return mProvider.getRendererPriorityWaivedWhenNotVisible(); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 1f8a9086ccb6..9d7a482aa611 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -338,7 +338,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * The data set used to store unused views that should be reused during the next layout * to avoid creating new ones */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769398) final RecycleBin mRecycler = new RecycleBin(); /** @@ -421,7 +421,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * One of TOUCH_MODE_REST, TOUCH_MODE_DOWN, TOUCH_MODE_TAP, TOUCH_MODE_SCROLL, or * TOUCH_MODE_DONE_WAITING */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769413) int mTouchMode = TOUCH_MODE_REST; /** @@ -634,7 +634,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Helper object that renders and controls the fast scroll thumb. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768941) private FastScroller mFastScroll; /** @@ -700,7 +700,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Maximum distance to overfling during edge effects */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769379) int mOverflingDistance; // These two EdgeGlows are always set and used together. @@ -4613,7 +4613,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * * @param newState The new scroll state. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769710) void reportScrollStateChange(int newState) { if (newState != mLastScrollState) { if (mOnScrollListener != null) { @@ -5156,7 +5156,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @param incrementalDeltaY Change in deltaY from the previous event. * @return true if we're already at the beginning/end of the list and have nothing to do. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124051739) boolean trackMotionScroll(int deltaY, int incrementalDeltaY) { final int childCount = getChildCount(); if (childCount == 0) { diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index ddff8581d568..c55f7d654548 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.DataSetObserver; +import android.os.Build; import android.os.Parcelable; import android.os.SystemClock; import android.util.AttributeSet; @@ -152,7 +153,7 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { /** * True if the data has changed since the last layout */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768524) boolean mDataChanged; /** diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 9bc055e7111b..7ed7aa293f21 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -126,7 +126,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe private boolean mDropDownDismissedOnCompletion = true; private int mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN; - private boolean mOpenBefore; + private MyWatcher mAutoCompleteTextWatcher; private Validator mValidator = null; @@ -302,7 +302,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe setFocusable(true); - addTextChangedListener(new MyWatcher()); + mAutoCompleteTextWatcher = new MyWatcher(); + addTextChangedListener(mAutoCompleteTextWatcher); mPassThroughClickListener = new PassThroughClickListener(); super.setOnClickListener(mPassThroughClickListener); @@ -872,45 +873,66 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe return getText().length() >= mThreshold; } - /** - * This is used to watch for edits to the text view. Note that we call - * to methods on the auto complete text view class so that we can access - * private vars without going through thunks. - */ + + + /** This is used to watch for edits to the text view. */ private class MyWatcher implements TextWatcher { - public void afterTextChanged(Editable s) { - doAfterTextChanged(); - } + private boolean mOpenBefore; + public void beforeTextChanged(CharSequence s, int start, int count, int after) { - doBeforeTextChanged(); + if (mBlockCompletion) return; + + // when text is changed, inserted or deleted, we attempt to show + // the drop down + mOpenBefore = isPopupShowing(); + if (DEBUG) Log.v(TAG, "before text changed: open=" + mOpenBefore); + } + + public void afterTextChanged(Editable s) { + if (mBlockCompletion) return; + + // if the list was open before the keystroke, but closed afterwards, + // then something in the keystroke processing (an input filter perhaps) + // called performCompletion() and we shouldn't do any more processing. + if (DEBUG) { + Log.v(TAG, "after text changed: openBefore=" + mOpenBefore + + " open=" + isPopupShowing()); + } + + if (mOpenBefore && !isPopupShowing()) return; + + refreshAutoCompleteResults(); } + public void onTextChanged(CharSequence s, int start, int before, int count) { } } - @UnsupportedAppUsage + /** + * This function is deprecated. Please use {@link #refreshAutoCompleteResults} instead. + * Note: Remove {@link #mAutoCompleteTextWatcher} after removing this function. + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) void doBeforeTextChanged() { - if (mBlockCompletion) return; - - // when text is changed, inserted or deleted, we attempt to show - // the drop down - mOpenBefore = isPopupShowing(); - if (DEBUG) Log.v(TAG, "before text changed: open=" + mOpenBefore); + mAutoCompleteTextWatcher.beforeTextChanged(null, 0, 0, 0); } - @UnsupportedAppUsage + /** + * This function is deprecated. Please use {@link #refreshAutoCompleteResults} instead. + * Note: Remove {@link #mAutoCompleteTextWatcher} after removing this function. + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) void doAfterTextChanged() { - if (mBlockCompletion) return; - - // if the list was open before the keystroke, but closed afterwards, - // then something in the keystroke processing (an input filter perhaps) - // called performCompletion() and we shouldn't do any more processing. - if (DEBUG) Log.v(TAG, "after text changed: openBefore=" + mOpenBefore - + " open=" + isPopupShowing()); - if (mOpenBefore && !isPopupShowing()) { - return; - } + mAutoCompleteTextWatcher.afterTextChanged(null); + } + /** + * Refreshes the auto complete results. You usually shouldn't have to manually refresh the + * AutoCompleteResults as this is done automatically whenever the text changes. However if the + * results are not available and have to be fetched, you can call this function after fetching + * the results. + */ + public final void refreshAutoCompleteResults() { // the drop down is shown only when a minimum number of characters // was typed in the text view if (enoughToFilter()) { diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index e9c31db8110b..800b19cdd77e 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -138,7 +138,7 @@ public class ImageView extends View { private int mDrawableWidth; @UnsupportedAppUsage private int mDrawableHeight; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124051687) private Matrix mDrawMatrix = null; // Avoid allocations... diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index f9564b44e825..25e5dd32c6b2 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -471,11 +471,24 @@ public class ListPopupWindow implements ShowableListMenu { * Specifies the anchor-relative bounds of the popup's transition * epicenter. * - * @param bounds anchor-relative bounds - * @hide + * @param bounds anchor-relative bounds, or {@code null} to use default epicenter + * + * @see #getEpicenterBounds() + */ + public void setEpicenterBounds(@Nullable Rect bounds) { + mEpicenterBounds = bounds != null ? new Rect(bounds) : null; + } + + /** + * Returns bounds which are used as a popup's epicenter + * of the enter and exit transitions. + * + * @return bounds relative to anchor view, or {@code null} if not set + * @see #setEpicenterBounds(Rect) */ - public void setEpicenterBounds(Rect bounds) { - mEpicenterBounds = bounds; + @Nullable + public Rect getEpicenterBounds() { + return mEpicenterBounds != null ? new Rect(mEpicenterBounds) : null; } /** diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 705a371e483e..279829672c57 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -264,7 +264,7 @@ public class PopupWindow { private WeakReference<View> mAnchorRoot; private boolean mIsAnchorRootAttached; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private final OnScrollChangedListener mOnScrollChangedListener = this::alignToAnchor; private final View.OnLayoutChangeListener mOnLayoutChangeListener = @@ -476,23 +476,40 @@ public class PopupWindow { } /** - * Sets the bounds used as the epicenter of the enter and exit transitions. - * <p> - * Transitions use a point or Rect, referred to as the epicenter, to orient + * <p>Returns bounds which are used as a center of the enter and exit transitions.<p/> + * + * <p>Transitions use Rect, referred to as the epicenter, to orient * the direction of travel. For popup windows, the anchor view bounds are - * used as the default epicenter. - * <p> - * See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more - * information about how transition epicenters. + * used as the default epicenter.</p> + * + * <p>See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more + * information about how transition epicenters work.</p> + * + * @return bounds relative to anchor view, or {@code null} if not set + * @see #setEpicenterBounds(Rect) + */ + @Nullable + public Rect getEpicenterBounds() { + return mEpicenterBounds != null ? new Rect(mEpicenterBounds) : null; + } + + /** + * <p>Sets the bounds used as the epicenter of the enter and exit transitions.</p> + * + * <p>Transitions use Rect, referred to as the epicenter, to orient + * the direction of travel. For popup windows, the anchor view bounds are + * used as the default epicenter.</p> + * + * <p>See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more + * information about how transition epicenters work.</p> * * @param bounds the epicenter bounds relative to the anchor view, or * {@code null} to use the default epicenter - * @see #getTransitionEpicenter() - * @hide + * + * @see #getEpicenterBounds() */ - @UnsupportedAppUsage - public void setEpicenterBounds(Rect bounds) { - mEpicenterBounds = bounds; + public void setEpicenterBounds(@Nullable Rect bounds) { + mEpicenterBounds = bounds != null ? new Rect(bounds) : null; } private Transition getTransition(int resId) { @@ -865,12 +882,28 @@ public class PopupWindow { } /** - * Clip this popup window to the screen, but not to the containing window. + * <p>Indicates whether this popup will be clipped to the screen and not to the + * containing window<p/> * - * @param enabled True to clip to the screen. - * @hide + * @return true if popup will be clipped to the screen instead of the window, false otherwise + * + * @see #setClipToScreenEnabled(boolean) + */ + public boolean isClipToScreenEnabled() { + return mClipToScreen; + } + + /** + * <p>Clip this popup window to the screen, but not to the containing window.</p> + * + * <p>If the popup is showing, calling this method will take effect only + * the next time the popup is shown or through a manual call to one of + * the {@link #update()} methods.</p> + * + * @param enabled true to clip to the screen. + * + * @see #isClipToScreenEnabled() */ - @UnsupportedAppUsage public void setClipToScreenEnabled(boolean enabled) { mClipToScreen = enabled; } @@ -927,7 +960,8 @@ public class PopupWindow { * for positioning.</p> * * @return true if the window will always be positioned in screen coordinates. - * @hide + * + * @see #setLayoutInScreenEnabled(boolean) */ public boolean isLayoutInScreenEnabled() { return mLayoutInScreen; @@ -939,9 +973,9 @@ public class PopupWindow { * This will cause the popup to be positioned in absolute screen coordinates.</p> * * @param enabled true if the popup should always be positioned in screen coordinates - * @hide + * + * @see #isLayoutInScreenEnabled() */ - @UnsupportedAppUsage public void setLayoutInScreenEnabled(boolean enabled) { mLayoutInScreen = enabled; } @@ -1021,11 +1055,30 @@ public class PopupWindow { } /** - * Set whether this window is touch modal or if outside touches will be sent to - * other windows behind it. - * @hide + * <p>Indicates whether outside touches will be sent to this window + * or other windows behind it<p/> + * + * @return true if touches will be sent to this window, false otherwise + * + * @see #setTouchModal(boolean) + */ + public boolean isTouchModal() { + return !mNotTouchModal; + } + + /** + * <p>Set whether this window is touch modal or if outside touches will be sent to + * other windows behind it.<p/> + * + * <p>If the popup is showing, calling this method will take effect only + * the next time the popup is shown or through a manual call to one of + * the {@link #update()} methods.</p> + * + * @param touchModal true to sent all outside touches to this window, + * false to other windows behind it + * + * @see #isTouchModal() */ - @UnsupportedAppUsage public void setTouchModal(boolean touchModal) { mNotTouchModal = !touchModal; } @@ -1454,7 +1507,7 @@ public class PopupWindow { * * @param p the layout parameters of the popup's content view */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private void invokePopup(WindowManager.LayoutParams p) { if (mContext != null) { p.packageName = mContext.getPackageName(); @@ -2060,6 +2113,8 @@ public class PopupWindow { * <li>{@link #setInputMethodMode(int)}</li> * <li>{@link #setTouchable(boolean)}</li> * <li>{@link #setAnimationStyle(int)}</li> + * <li>{@link #setTouchModal(boolean)} (boolean)}</li> + * <li>{@link #setClipToScreenEnabled(boolean)}</li> * </ul> */ public void update() { diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 24bc9f1e4985..c3609038b08f 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -141,13 +141,13 @@ public class ScrollView extends FrameLayout { private boolean mSmoothScrollingEnabled = true; private int mTouchSlop; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124051125) private int mMinimumVelocity; private int mMaximumVelocity; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = VERSION_CODES.P, trackingBug = 124050903) private int mOverscrollDistance; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = VERSION_CODES.P, trackingBug = 124050903) private int mOverflingDistance; private float mVerticalScrollFactor; diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java index c171fa6b25fd..258d081c6ad8 100644 --- a/core/java/com/android/internal/colorextraction/ColorExtractor.java +++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java @@ -22,7 +22,6 @@ import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; import android.os.Trace; -import android.os.UserHandle; import android.util.Log; import android.util.SparseArray; @@ -32,7 +31,6 @@ import com.android.internal.colorextraction.types.Tonal; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Iterator; /** * Class to process wallpaper colors and generate a tonal palette based on them. @@ -222,6 +220,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener public static class GradientColors { private int mMainColor; private int mSecondaryColor; + private int[] mColorPalette; private boolean mSupportsDarkText; public void setMainColor(int mainColor) { @@ -232,6 +231,10 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener mSecondaryColor = secondaryColor; } + public void setColorPalette(int[] colorPalette) { + mColorPalette = colorPalette; + } + public void setSupportsDarkText(boolean supportsDarkText) { mSupportsDarkText = supportsDarkText; } @@ -239,6 +242,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener public void set(GradientColors other) { mMainColor = other.mMainColor; mSecondaryColor = other.mSecondaryColor; + mColorPalette = other.mColorPalette; mSupportsDarkText = other.mSupportsDarkText; } @@ -250,6 +254,10 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener return mSecondaryColor; } + public int[] getColorPalette() { + return mColorPalette; + } + public boolean supportsDarkText() { return mSupportsDarkText; } @@ -283,4 +291,4 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener public interface OnColorsChangedListener { void onColorsChanged(ColorExtractor colorExtractor, int which); } -}
\ No newline at end of file +} diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java index 3fd88dbb8704..d6a8934566b2 100644 --- a/core/java/com/android/internal/colorextraction/types/Tonal.java +++ b/core/java/com/android/internal/colorextraction/types/Tonal.java @@ -173,6 +173,7 @@ public class Tonal implements ExtractionType { Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY); float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f); float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f); + int[] colorPalette = getColorPalette(h, s, l); if (DEBUG) { StringBuilder builder = new StringBuilder("Tonal Palette - index: " + fitIndex + @@ -209,6 +210,7 @@ public class Tonal implements ExtractionType { // Normal colors: outColorsNormal.setMainColor(mainColor); outColorsNormal.setSecondaryColor(mainColor); + outColorsNormal.setColorPalette(colorPalette); // Dark colors: // Stops at 4th color, only lighter if dark text is supported @@ -222,6 +224,7 @@ public class Tonal implements ExtractionType { mainColor = getColorInt(primaryIndex, h, s, l); outColorsDark.setMainColor(mainColor); outColorsDark.setSecondaryColor(mainColor); + outColorsDark.setColorPalette(colorPalette); // Extra Dark: // Stay close to dark colors until dark text is supported @@ -235,6 +238,7 @@ public class Tonal implements ExtractionType { mainColor = getColorInt(primaryIndex, h, s, l); outColorsExtraDark.setMainColor(mainColor); outColorsExtraDark.setSecondaryColor(mainColor); + outColorsExtraDark.setColorPalette(colorPalette); outColorsNormal.setSupportsDarkText(supportsDarkText); outColorsDark.setSupportsDarkText(supportsDarkText); @@ -262,16 +266,19 @@ public class Tonal implements ExtractionType { * @param inWallpaperColors Colors to read. * @param outGradientColors Destination. */ - public static void applyFallback(@Nullable WallpaperColors inWallpaperColors, + public void applyFallback(@Nullable WallpaperColors inWallpaperColors, @NonNull GradientColors outGradientColors) { boolean light = inWallpaperColors != null && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0; final int color = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK; + final float[] hsl = new float[3]; + ColorUtils.colorToHSL(color, hsl); outGradientColors.setMainColor(color); outGradientColors.setSecondaryColor(color); outGradientColors.setSupportsDarkText(light); + outGradientColors.setColorPalette(getColorPalette(findTonalPalette(hsl[0], hsl[1]))); } private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) { @@ -281,6 +288,19 @@ public class Tonal implements ExtractionType { return ColorUtils.HSLToColor(mTmpHSL); } + private int[] getColorPalette(float[] h, float[] s, float[] l) { + int[] colorPalette = new int[h.length]; + for (int i = 0; i < colorPalette.length; i++) { + colorPalette[i] = getColorInt(i, h, s, l); + } + return colorPalette; + } + + private int[] getColorPalette(TonalPalette palette) { + return getColorPalette(palette.h, palette.s, palette.l); + } + + /** * Checks if a given color exists in the blacklist * @param hsl float array with 3 components (H 0..360, S 0..1 and L 0..1) @@ -598,4 +618,4 @@ public class Tonal implements ExtractionType { return numbers; } } -}
\ No newline at end of file +} diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 650a19426d8e..52e1748c621c 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -6117,8 +6117,6 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<N; i++) { final int uid = mapUid(ws.get(i)); noteFullWifiLockAcquiredLocked(uid); - StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i), - StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -6127,9 +6125,6 @@ public class BatteryStatsImpl extends BatteryStats { final WorkChain workChain = workChains.get(i); final int uid = mapUid(workChain.getAttributionUid()); noteFullWifiLockAcquiredLocked(uid); - StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED, - workChain.getUids(), workChain.getTags(), - StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON); } } } @@ -6139,8 +6134,6 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<N; i++) { final int uid = mapUid(ws.get(i)); noteFullWifiLockReleasedLocked(uid); - StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i), - StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -6149,9 +6142,6 @@ public class BatteryStatsImpl extends BatteryStats { final WorkChain workChain = workChains.get(i); final int uid = mapUid(workChain.getAttributionUid()); noteFullWifiLockReleasedLocked(uid); - StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED, - workChain.getUids(), workChain.getTags(), - StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF); } } } diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 8b669d5db8df..40d78688cb4c 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -254,14 +254,14 @@ public final class Zygote { public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir, - String packageName, String[] packagesForUID, String[] visibleVolIDs) { + String packageName, String[] packagesForUID, String[] visibleVolIDs, String sandboxId) { ZygoteHooks.preFork(); // Resets nice priority for zygote process. resetNicePriority(); int pid = nativeForkAndSpecialize( uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName, - packagesForUID, visibleVolIDs); + packagesForUID, visibleVolIDs, sandboxId); // Enable tracing as soon as possible for the child process. if (pid == 0) { Trace.setTracingEnabled(true, runtimeFlags); @@ -276,7 +276,8 @@ public final class Zygote { private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet, - String appDataDir, String packageName, String[] packagesForUID, String[] visibleVolIDs); + String appDataDir, String packageName, String[] packagesForUID, String[] visibleVolIDs, + String sandboxId); /** * Specialize a Blastula instance. The current VM must have been started @@ -302,11 +303,11 @@ public final class Zygote { public static void specializeBlastula(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, boolean startChildZygote, String instructionSet, String appDataDir, String packageName, - String[] packagesForUID, String[] visibleVolIDs) { + String[] packagesForUID, String[] visibleVolIDs, String sandboxId) { nativeSpecializeBlastula(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, startChildZygote, instructionSet, appDataDir, - packageName, packagesForUID, visibleVolIDs); + packageName, packagesForUID, visibleVolIDs, sandboxId); // Enable tracing as soon as possible for the child process. Trace.setTracingEnabled(true, runtimeFlags); @@ -326,7 +327,7 @@ public final class Zygote { private static native void nativeSpecializeBlastula(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, boolean startChildZygote, String instructionSet, String appDataDir, String packageName, - String[] packagesForUID, String[] visibleVolIDs); + String[] packagesForUID, String[] visibleVolIDs, String sandboxId); /** * Called to do any initialization before starting an application. @@ -638,7 +639,7 @@ public final class Zygote { args.mRuntimeFlags, rlimits, args.mMountExternal, args.mSeInfo, args.mNiceName, args.mStartChildZygote, args.mInstructionSet, args.mAppDataDir, args.mPackageName, - args.mPackagesForUid, args.mVisibleVolIds); + args.mPackagesForUid, args.mVisibleVolIds, args.mSandboxId); if (args.mNiceName != null) { Process.setArgV0(args.mNiceName); diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java index 24a08ca5b1e0..e6bcd37ad3e5 100644 --- a/core/java/com/android/internal/os/ZygoteArguments.java +++ b/core/java/com/android/internal/os/ZygoteArguments.java @@ -119,6 +119,9 @@ class ZygoteArguments { /** from --visible-vols */ String[] mVisibleVolIds; + /** from --sandbox-id */ + String mSandboxId; + /** * Any args after and including the first non-option arg (or after a '--') */ @@ -385,6 +388,11 @@ class ZygoteArguments { mPackagesForUid = arg.substring(arg.indexOf('=') + 1).split(","); } else if (arg.startsWith("--visible-vols=")) { mVisibleVolIds = arg.substring(arg.indexOf('=') + 1).split(","); + } else if (arg.startsWith("--sandbox-id=")) { + if (mSandboxId != null) { + throw new IllegalArgumentException("Duplicate arg specified"); + } + mSandboxId = arg.substring(arg.indexOf('=') + 1); } else { break; } diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 4ac7f5012613..9cf7e2770e86 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -258,7 +258,7 @@ class ZygoteConnection { parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote, parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mPackageName, - parsedArgs.mPackagesForUid, parsedArgs.mVisibleVolIds); + parsedArgs.mPackagesForUid, parsedArgs.mVisibleVolIds, parsedArgs.mSandboxId); try { if (pid == 0) { diff --git a/core/jni/android_opengl_EGL15.cpp b/core/jni/android_opengl_EGL15.cpp index b52f137da7d6..2abd95020f1c 100644 --- a/core/jni/android_opengl_EGL15.cpp +++ b/core/jni/android_opengl_EGL15.cpp @@ -194,6 +194,7 @@ fromEGLHandle(JNIEnv *_env, jmethodID mid, jobject obj) { if (obj == NULL){ jniThrowException(_env, "java/lang/IllegalArgumentException", "Object is set to null."); + return nullptr; } jlong handle = _env->CallLongMethod(obj, mid); @@ -254,6 +255,7 @@ exit: } if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); + return nullptr; } return toEGLHandle(_env, eglsyncClass, eglsyncConstructor, _returnValue); } @@ -335,6 +337,7 @@ exit: } if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); + return false; } return (jboolean)_returnValue; } @@ -381,6 +384,7 @@ exit: } if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); + return nullptr; } return toEGLHandle(_env, egldisplayClass, egldisplayConstructor, _returnValue); } @@ -448,6 +452,7 @@ exit: } if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); + return nullptr; } return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue); } @@ -456,8 +461,11 @@ exit: static jobject android_eglCreatePlatformPixmapSurface (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject native_pixmap_buf, jlongArray attrib_list_ref, jint offset) { - jniThrowException(_env, "java/lang/UnsupportedOperationException", - "eglCreatePlatformPixmapSurface"); + if ((true)) { + jniThrowException(_env, "java/lang/UnsupportedOperationException", + "eglCreatePlatformPixmapSurface"); + return nullptr; + } return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, (EGLSurface) 0); } @@ -523,6 +531,7 @@ exit: } if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); + return nullptr; } return toEGLHandle(_env, eglimageClass, eglimageConstructor, _returnValue); } diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 0ef4f874f583..d04db92294d7 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -598,72 +598,80 @@ static int UnmountTree(const char* path) { return 0; } +static void CreateDir(const std::string& dir, + mode_t mode, uid_t uid, gid_t gid, + fail_fn_t fail_fn) { + if (TEMP_FAILURE_RETRY(access(dir.c_str(), F_OK)) == 0) { + return; + } else if (errno != ENOENT) { + fail_fn(CREATE_ERROR("Failed to stat %s: %s", dir.c_str(), strerror(errno))); + } + if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) { + fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s: %s", + dir.c_str(), strerror(errno))); + } +} + static void CreatePkgSandbox(uid_t uid, const std::string& package_name, fail_fn_t fail_fn) { // Create /mnt/user/0/package/<package-name> userid_t user_id = multiuser_get_user_id(uid); std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", user_id); - if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0751, AID_ROOT, AID_ROOT) != 0) { - fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str())); - } + CreateDir(pkg_sandbox_dir, 0751, AID_ROOT, AID_ROOT, fail_fn); StringAppendF(&pkg_sandbox_dir, "/package"); - if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { - fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str())); - } + CreateDir(pkg_sandbox_dir, 0700, AID_ROOT, AID_ROOT, fail_fn); StringAppendF(&pkg_sandbox_dir, "/%s", package_name.c_str()); - if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0755, uid, uid) != 0) { - fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str())); - } + CreateDir(pkg_sandbox_dir, 0700, AID_ROOT, AID_ROOT, fail_fn); } static void BindMount(const std::string& sourceDir, const std::string& targetDir, fail_fn_t fail_fn) { if (TEMP_FAILURE_RETRY(mount(sourceDir.c_str(), targetDir.c_str(), nullptr, - MS_BIND | MS_REC, nullptr)) == -1) { + MS_BIND, nullptr)) == -1) { fail_fn(CREATE_ERROR("Failed to mount %s to %s: %s", sourceDir.c_str(), targetDir.c_str(), strerror(errno))); } - - if (TEMP_FAILURE_RETRY(mount(nullptr, targetDir.c_str(), nullptr, - MS_SLAVE | MS_REC, nullptr)) == -1) { - fail_fn(CREATE_ERROR("Failed to set MS_SLAVE for %s", targetDir.c_str())); - } } static void MountPkgSpecificDir(const std::string& mntSourceRoot, const std::string& mntTargetRoot, const std::string& packageName, + uid_t uid, const char* dirName, fail_fn_t fail_fn) { std::string mntSourceDir = StringPrintf("%s/Android/%s/%s", mntSourceRoot.c_str(), dirName, packageName.c_str()); + CreateDir(mntSourceDir, 0755, uid, uid, fail_fn); + std::string mntTargetDir = StringPrintf("%s/Android/%s/%s", mntTargetRoot.c_str(), dirName, packageName.c_str()); + CreateDir(mntTargetDir, 0755, uid, uid, fail_fn); BindMount(mntSourceDir, mntTargetDir, fail_fn); } + +static void createPkgSpecificDirRoots(const std::string& parentDir, + bool createSandbox, + mode_t mode, uid_t uid, gid_t gid, + fail_fn_t fail_fn) { + std::string androidDir = StringPrintf("%s/Android", parentDir.c_str()); + CreateDir(androidDir, mode, uid, gid, fail_fn); + std::vector<std::string> dirs = {"data", "media", "obb"}; + if (createSandbox) { + dirs.push_back("sandbox"); + } + for (auto& dir : dirs) { + std::string path = StringPrintf("%s/%s", androidDir.c_str(), dir.c_str()); + CreateDir(path, mode, uid, gid, fail_fn); + } +} + static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames, const std::vector<std::string>& volumeLabels, - bool mountAllObbs, userid_t userId, fail_fn_t fail_fn) { - if (volumeLabels.size() > 0) { - std::string sandboxDataDir = StringPrintf("/storage/%s", volumeLabels[0].c_str()); - if (volumeLabels[0] == "emulated") { - StringAppendF(&sandboxDataDir, "/%d", userId); - } - StringAppendF(&sandboxDataDir, "/Android/data/%s", packageNames[0].c_str()); - struct stat sb; - if (TEMP_FAILURE_RETRY(lstat(sandboxDataDir.c_str(), &sb)) == -1) { - if (errno == ENOENT) { - ALOGD("Sandbox not fully prepared for %s", sandboxDataDir.c_str()); - return; - } else { - fail_fn(CREATE_ERROR("Failed to lstat %s: %s", - sandboxDataDir.c_str(), strerror(errno))); - } - } - } + bool mountAllObbs, const std::string& sandboxId, + userid_t userId, uid_t uid, fail_fn_t fail_fn) { for (auto& label : volumeLabels) { std::string mntSource = StringPrintf("/mnt/runtime/write/%s", label.c_str()); std::string mntTarget = StringPrintf("/storage/%s", label.c_str()); @@ -672,11 +680,26 @@ static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames, StringAppendF(&mntTarget, "/%d", userId); } + if (TEMP_FAILURE_RETRY(access(mntSource.c_str(), F_OK)) < 0) { + ALOGE("Can't access %s: %s", mntSource.c_str(), strerror(errno)); + continue; + } + + // Create /mnt/runtime/write/emulated/0/Android/{data,media,obb,sandbox} + createPkgSpecificDirRoots(mntSource, true, 0700, AID_ROOT, AID_ROOT, fail_fn); + + std::string sandboxSource = StringPrintf("%s/Android/sandbox/%s", + mntSource.c_str(), sandboxId.c_str()); + CreateDir(sandboxSource, 0755, uid, uid, fail_fn); + BindMount(sandboxSource, mntTarget, fail_fn); + + // Create /storage/emulated/0/Android/{data,media,obb} + createPkgSpecificDirRoots(mntTarget, false, 0755, uid, uid, fail_fn); for (auto& package : packageNames) { - MountPkgSpecificDir(mntSource, mntTarget, package, "data", fail_fn); - MountPkgSpecificDir(mntSource, mntTarget, package, "media", fail_fn); + MountPkgSpecificDir(mntSource, mntTarget, package, uid, "data", fail_fn); + MountPkgSpecificDir(mntSource, mntTarget, package, uid, "media", fail_fn); if (!mountAllObbs) { - MountPkgSpecificDir(mntSource, mntTarget, package, "obb", fail_fn); + MountPkgSpecificDir(mntSource, mntTarget, package, uid, "obb", fail_fn); } } @@ -693,7 +716,8 @@ static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames, static void MountEmulatedStorage(uid_t uid, jint mount_mode, bool force_mount_namespace, const std::string& package_name, const std::vector<std::string>& packages_for_uid, - const std::vector<std::string>& visible_vol_ids, fail_fn_t fail_fn) { + const std::vector<std::string>& visible_vol_ids, const std::string& sandbox_id, + fail_fn_t fail_fn) { // See storage config details at http://source.android.com/tech/storage/ String8 storageSource; @@ -744,7 +768,7 @@ static void MountEmulatedStorage(uid_t uid, jint mount_mode, strerror(errno))); } } else { - if (package_name.empty()) { + if (package_name.empty() || sandbox_id.empty()) { return; } @@ -790,7 +814,7 @@ static void MountEmulatedStorage(uid_t uid, jint mount_mode, // care of by vold later. if (sandboxAlreadyCreated) { PreparePkgSpecificDirs(packages_for_uid, visible_vol_ids, - mount_mode == MOUNT_EXTERNAL_INSTALLER, user_id, fail_fn); + mount_mode == MOUNT_EXTERNAL_INSTALLER, sandbox_id, user_id, uid, fail_fn); } } } else { @@ -1127,7 +1151,7 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, bool is_child_zygote, jstring managed_instruction_set, jstring managed_app_data_dir, jstring managed_package_name, jobjectArray managed_pacakges_for_uid, - jobjectArray managed_visible_vol_ids) { + jobjectArray managed_visible_vol_ids, jstring managed_sandbox_id) { const char* process_name = is_system_server ? "system_server" : "zygote"; auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1); auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1); @@ -1137,6 +1161,7 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, auto instruction_set = extract_fn(managed_instruction_set); auto app_data_dir = extract_fn(managed_app_data_dir); auto package_name = extract_fn(managed_package_name); + auto sandbox_id = extract_fn(managed_sandbox_id); // Keep capabilities across UID change, unless we're staying root. if (uid != 0) { @@ -1179,7 +1204,7 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, value_or(std::vector<std::string>()); MountEmulatedStorage(uid, mount_external, use_native_bridge, package_name.value(), - packages_for_uid, visible_vol_ids, fail_fn); + packages_for_uid, visible_vol_ids, sandbox_id.value_or(""), fail_fn); // If this zygote isn't root, it won't be able to create a process group, // since the directory is owned by root. @@ -1479,7 +1504,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( jint mount_external, jstring se_info, jstring nice_name, jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, jstring package_name, - jobjectArray packages_for_uid, jobjectArray visible_vol_ids) { + jobjectArray packages_for_uid, jobjectArray visible_vol_ids, jstring sandbox_id) { jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote); if (UNLIKELY(managed_fds_to_close == nullptr)) { @@ -1511,7 +1536,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( capabilities, capabilities, mount_external, se_info, nice_name, false, is_child_zygote == JNI_TRUE, instruction_set, app_data_dir, - package_name, packages_for_uid, visible_vol_ids); + package_name, packages_for_uid, visible_vol_ids, sandbox_id); } return pid; } @@ -1537,7 +1562,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true, - false, nullptr, nullptr, nullptr, nullptr, nullptr); + false, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); } else if (pid > 0) { // The zygote process checks whether the child process has died or not. ALOGI("System server process %d has been created", pid); @@ -1691,14 +1716,15 @@ static void com_android_internal_os_Zygote_nativeSpecializeBlastula( jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, - jstring package_name, jobjectArray packages_for_uid, jobjectArray visible_vol_ids) { + jstring package_name, jobjectArray packages_for_uid, jobjectArray visible_vol_ids, + jstring sandbox_id) { jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote); SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, capabilities, capabilities, mount_external, se_info, nice_name, false, is_child_zygote == JNI_TRUE, instruction_set, app_data_dir, - package_name, packages_for_uid, visible_vol_ids); + package_name, packages_for_uid, visible_vol_ids, sandbox_id); } /** @@ -1789,7 +1815,7 @@ static const JNINativeMethod gMethods[] = { { "nativeSecurityInit", "()V", (void *) com_android_internal_os_Zygote_nativeSecurityInit }, { "nativeForkAndSpecialize", - "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)I", + "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I", (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize }, { "nativeForkSystemServer", "(II[II[[IJJ)I", (void *) com_android_internal_os_Zygote_nativeForkSystemServer }, @@ -1804,7 +1830,7 @@ static const JNINativeMethod gMethods[] = { { "nativeForkBlastula", "(II[I)I", (void *) com_android_internal_os_Zygote_nativeForkBlastula }, { "nativeSpecializeBlastula", - "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V", + "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V", (void *) com_android_internal_os_Zygote_nativeSpecializeBlastula }, { "nativeGetSocketFDs", "(Z)V", (void *) com_android_internal_os_Zygote_nativeGetSocketFDs }, diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto index 5b5c9c28b4a0..b4f3d1ea5ae4 100644 --- a/core/proto/android/bluetooth/enums.proto +++ b/core/proto/android/bluetooth/enums.proto @@ -132,3 +132,9 @@ enum SocketConnectionstateEnum { // This socket is closed SOCKET_CONNECTION_STATE_DISCONNECTED = 5; } + +enum SocketRoleEnum { + SOCKET_ROLE_UNKNOWN = 0; + SOCKET_ROLE_LISTEN = 1; + SOCKET_ROLE_CONNECTION = 2; +} diff --git a/core/proto/android/hardware/biometrics/enums.proto b/core/proto/android/hardware/biometrics/enums.proto index 91f2acbbaf03..973e3e65cf1a 100644 --- a/core/proto/android/hardware/biometrics/enums.proto +++ b/core/proto/android/hardware/biometrics/enums.proto @@ -43,4 +43,16 @@ enum ActionEnum { ACTION_AUTHENTICATE = 2; ACTION_ENUMERATE = 3; ACTION_REMOVE = 4; +} + +enum IssueEnum { + ISSUE_UNKNOWN = 0; + // When a biometric HAL has crashed. + ISSUE_HAL_DEATH = 1; + // When Android Framework has a template that doesn't exist in the HAL. The framework + // is expected to remove its template to stay in sync with the HAL. + ISSUE_UNKNOWN_TEMPLATE_ENROLLED_FRAMEWORK = 2; + // When the HAL has a template that doesn't exist in Android Framework. The framework + // is expected to notify the HAL to remove this template to stay in sync with the framework. + ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL = 3; }
\ No newline at end of file diff --git a/core/proto/android/wifi/enums.proto b/core/proto/android/wifi/enums.proto new file mode 100644 index 000000000000..315c5792c1de --- /dev/null +++ b/core/proto/android/wifi/enums.proto @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +package android.net.wifi; + +option java_outer_classname = "WifiProtoEnums"; +option java_multiple_files = true; + +/** + * Wifi Lock modes, primarily used in + * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiLockManager.java. + */ +enum WifiModeEnum { + /** + * Deprecated. + * Wi-Fi will be kept active, and will behave normally. + */ + WIFI_MODE_FULL = 1 [deprecated=true]; + + /** + * Deprecated. + * Wi-Fi will be kept active, but the only operation that will be supported is initiation of + * scans, and the subsequent reporting of scan results. + */ + WIFI_MODE_SCAN_ONLY = 2 [deprecated=true]; + + /** + * Wi-Fi will not go to power save. + */ + WIFI_MODE_FULL_HIGH_PERF = 3; + + /** + * Wi-Fi will operate with a priority to achieve low latency. + */ + WIFI_MODE_FULL_LOW_LATENCY = 4; +} diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 07dd26e4969b..34ec92e68511 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2267,7 +2267,7 @@ <!-- Allows an application to start activities from background @hide --> <permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" - android:protectionLevel="signature|privileged|vendorPrivileged|oem" /> + android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier" /> <!-- @SystemApi Must be required by activities that handle the intent action {@link Intent#ACTION_SEND_SHOW_SUSPENDED_APP_DETAILS}. This is for use by apps that diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index ec53811a6983..a501ae2661c6 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1921,8 +1921,6 @@ cell broadcasting sms, and MMS. --> <bool name="config_sms_capable">true</bool> - <!-- TODO: STOPSHIP(b/110557011): Remove this from framework and overlays as we use - config_defaultRoleHolders now. --> <!-- Default SMS Application. This will be the default SMS application when the phone first boots. The user can then change the default app to one of their choosing. @@ -1930,15 +1928,29 @@ application is desired. If this string is empty or the specified package does not exist, then - the platform will search for an SMS app and use that (if there is one)--> + the platform will search for an SMS app and use that (if there is one) + + Note: This config is deprecated, please use config_defaultSms instead. --> <string name="default_sms_application" translatable="false">com.android.messaging</string> - <!-- Default role holders. This will be an array of roles and package names of their default - holders, with each item in the format of "ROLE_NAME: PACKAGE_NAME_1, PACKAGE_NAME_2". --> - <string-array name="config_defaultRoleHolders" translatable="false"> - <item>android.app.role.SMS: com.android.messaging</item> - <item>android.app.role.DIALER: com.android.phone</item> - </string-array> + <!-- Default web browser. This is the package name of the application that will + be the default browser when the device first boots. Afterwards the user + can select whatever browser app they wish to use as the default. + + If this string is empty or the specified package does not exist, then + the behavior will be as though no app was named as an explicit default. + + Note: This config is deprecated, please use config_defaultBrowser instead. --> + <string name="default_browser" translatable="false"></string> + + <!-- The name of the package that will hold the assistant role by default. --> + <string name="config_defaultAssistant" translatable="false" /> + <!-- The name of the package that will hold the browser role by default. --> + <string name="config_defaultBrowser" translatable="false">@string/default_browser</string> + <!-- The name of the package that will hold the dialer role by default. --> + <string name="config_defaultDialer" translatable="false">com.android.phone</string> + <!-- The name of the package that will hold the SMS role by default. --> + <string name="config_defaultSms" translatable="false">@string/default_sms_application</string> <!-- Enable/disable default bluetooth profiles: HSP_AG, ObexObjectPush, Audio, NAP --> diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml index bbe3ff995ac3..ce7995a93f7f 100644 --- a/core/res/res/values/ids.xml +++ b/core/res/res/values/ids.xml @@ -193,4 +193,7 @@ <!-- A tag used to save the notification action object --> <item type="id" name="notification_action_index_tag" /> + + <!-- A tag used to save the index where the custom view is stored --> + <item type="id" name="notification_custom_view_index_tag" /> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index e6d478aadae0..d5cefc4e4818 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2971,6 +2971,14 @@ <public name="config_feedbackIntentExtraKey" /> <!-- @hide @SystemApi --> <public name="config_feedbackIntentNameKey" /> + <!-- @hide @SystemApi @TestApi --> + <public name="config_defaultAssistant" /> + <!-- @hide @SystemApi --> + <public name="config_defaultBrowser" /> + <!-- @hide @SystemApi @TestApi --> + <public name="config_defaultDialer" /> + <!-- @hide @SystemApi --> + <public name="config_defaultSms" /> </public-group> <public-group type="bool" first-id="0x01110000"> @@ -2990,11 +2998,6 @@ <public name="system_notification_accent_color" /> </public-group> - <public-group type="array" first-id="0x01070006"> - <!-- @hide @TestApi @SystemApi --> - <public name="config_defaultRoleHolders" /> - </public-group> - <!-- =============================================================== DO NOT ADD UN-GROUPED ITEMS HERE diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index fadb28f05ef7..6d5bd4ba1645 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1471,6 +1471,8 @@ <string name="biometric_not_recognized">Not recognized</string> <!-- Message shown when biometric authentication has been canceled [CHAR LIMIT=50] --> <string name="biometric_error_canceled">Authentication canceled</string> + <!-- Message returned to applications if BiometricPrompt setAllowDeviceCredentials is enabled but no pin, pattern, or password is set. [CHAR LIMIT=NONE] --> + <string name="biometric_error_device_not_secured">No pin, pattern, or password set</string> <!-- Message shown during fingerprint acquisision when the fingerprint cannot be recognized --> <string name="fingerprint_acquired_partial">Partial fingerprint detected. Please try again.</string> @@ -1512,7 +1514,7 @@ <!-- Generic error message shown when the user has no enrolled fingerprints --> <string name="fingerprint_error_no_fingerprints">No fingerprints enrolled.</string> <!-- Generic error message shown when the app requests fingerprint authentication on a device without a sensor --> - <string name="fingerprint_error_hw_not_present">This device does not have a fingerprint sensor</string> + <string name="fingerprint_error_hw_not_present">This device does not have a fingerprint sensor.</string> <!-- Template to be used to name enrolled fingerprints by default. --> <string name="fingerprint_name_template">Finger <xliff:g id="fingerId" example="1">%d</xliff:g></string> @@ -1555,8 +1557,22 @@ <string name="face_acquired_poor_gaze">Please look at the sensor.</string> <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] --> <string name="face_acquired_not_detected">No face detected.</string> - <!-- Message shown during face acquisition when the face is not kept steady infront of device [CHAR LIMIT=50] --> - <string name="face_acquired_not_steady">Keep face steady infront of device.</string> + <!-- Message shown during face acquisition when the device is not steady [CHAR LIMIT=50] --> + <string name="face_acquired_too_much_motion">Too much motion.</string> + <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=50] --> + <string name="face_acquired_recalibrate">Please re-enroll your face.</string> + <!-- Message shown during face enrollment when a different person's face is detected [CHAR LIMIT=50] --> + <string name="face_acquired_too_different">Different face detected.</string> + <!-- Message shown during face enrollment when the face is too similar to a previous acquisition [CHAR LIMIT=50] --> + <string name="face_acquired_too_similar">Too similar, please change your pose.</string> + <!-- Message shown during acqusition when the user's face is turned too far left or right [CHAR LIMIT=50] --> + <string name="face_acquired_pan_too_extreme">Please look more directly at the camera.</string> + <!-- Message shown during acqusition when the user's face is tilted too high or too low [CHAR LIMIT=50] --> + <string name="face_acquired_tilt_too_extreme">Please look more directly at the camera.</string> + <!-- Message shown during acquisiton when the user's face is tilted too far left or right [CHAR LIMIT=50] --> + <string name="face_acquired_roll_too_extreme">Please straighten your head vertically.</string> + <!-- Message shown during acquisition when the user's face is obscured [CHAR LIMIT=50] --> + <string name="face_acquired_obscured">Please uncover your face.</string> <!-- Array containing custom messages shown during face acquisition from vendor. Vendor is expected to add and translate these strings --> <string-array name="face_acquired_vendor"> </string-array> @@ -1580,7 +1596,7 @@ <!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=50] --> <string name="face_error_not_enrolled">No face enrolled.</string> <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=60] --> - <string name="face_error_hw_not_present">This device does not have a face authentication sensor</string> + <string name="face_error_hw_not_present">This device does not have a face authentication sensor.</string> <!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] --> <string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 1da91494306d..410a8c168b5d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1034,6 +1034,7 @@ <java-symbol type="string" name="sipAddressTypeOther" /> <java-symbol type="string" name="sipAddressTypeWork" /> <java-symbol type="string" name="default_sms_application" /> + <java-symbol type="string" name="default_browser" /> <java-symbol type="string" name="sms_control_message" /> <java-symbol type="string" name="sms_control_title" /> <java-symbol type="string" name="sms_control_no" /> @@ -2472,6 +2473,7 @@ <java-symbol type="string" name="biometric_error_user_canceled" /> <java-symbol type="string" name="biometric_not_recognized" /> <java-symbol type="string" name="biometric_error_canceled" /> + <java-symbol type="string" name="biometric_error_device_not_secured" /> <!-- Fingerprint messages --> <java-symbol type="string" name="fingerprint_error_unable_to_process" /> @@ -2521,6 +2523,14 @@ <java-symbol type="string" name="face_acquired_too_left" /> <java-symbol type="string" name="face_acquired_poor_gaze" /> <java-symbol type="string" name="face_acquired_not_detected" /> + <java-symbol type="string" name="face_acquired_too_much_motion" /> + <java-symbol type="string" name="face_acquired_recalibrate" /> + <java-symbol type="string" name="face_acquired_too_different" /> + <java-symbol type="string" name="face_acquired_too_similar" /> + <java-symbol type="string" name="face_acquired_pan_too_extreme" /> + <java-symbol type="string" name="face_acquired_tilt_too_extreme" /> + <java-symbol type="string" name="face_acquired_roll_too_extreme" /> + <java-symbol type="string" name="face_acquired_obscured" /> <java-symbol type="array" name="face_acquired_vendor" /> <java-symbol type="string" name="face_name_template" /> <java-symbol type="string" name="face_authenticated_no_confirmation_required" /> @@ -3585,6 +3595,7 @@ <java-symbol type="bool" name="config_useSmsAppService" /> <java-symbol type="id" name="transition_overlay_view_tag" /> + <java-symbol type="id" name="notification_custom_view_index_tag" /> <java-symbol type="dimen" name="rounded_corner_radius" /> <java-symbol type="dimen" name="rounded_corner_radius_top" /> diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java index 300394d426e4..aa0e0cdae265 100644 --- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java +++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java @@ -162,14 +162,13 @@ public class PackageParserTest { } private void verifyComputeTargetSdkVersion(int targetSdkVersion, String targetSdkCodename, - boolean isPlatformReleased, int expectedTargetSdk, boolean forceCurrentDev) { + boolean isPlatformReleased, int expectedTargetSdk) { final String[] outError = new String[1]; final int result = PackageParser.computeTargetSdkVersion( targetSdkVersion, targetSdkCodename, isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE, - outError, - forceCurrentDev); + outError); assertEquals(result, expectedTargetSdk); @@ -185,28 +184,23 @@ public class PackageParserTest { // Do allow older release targetSdkVersion on pre-release platform. // APP: Released API 10 // DEV: Pre-release API 20 - verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION); // Do allow same release targetSdkVersion on pre-release platform. // APP: Released API 20 // DEV: Pre-release API 20 - verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION); // Do allow newer release targetSdkVersion on pre-release platform. // APP: Released API 30 // DEV: Pre-release API 20 - verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, false, NEWER_VERSION, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, false, NEWER_VERSION); // Don't allow older pre-release targetSdkVersion on pre-release platform. // APP: Pre-release API 10 // DEV: Pre-release API 20 - verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1, - false /* forceCurrentDev */); - verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false, -1, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1); + verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false, -1); // Do allow same pre-release targetSdkVersion on pre-release platform, @@ -214,27 +208,16 @@ public class PackageParserTest { // APP: Pre-release API 20 // DEV: Pre-release API 20 verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false, - Build.VERSION_CODES.CUR_DEVELOPMENT, false /* forceCurrentDev */); + Build.VERSION_CODES.CUR_DEVELOPMENT); verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, false, - Build.VERSION_CODES.CUR_DEVELOPMENT, false /* forceCurrentDev */); + Build.VERSION_CODES.CUR_DEVELOPMENT); // Don't allow newer pre-release targetSdkVersion on pre-release platform. // APP: Pre-release API 30 // DEV: Pre-release API 20 - verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1, - false /* forceCurrentDev */); - verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false, -1, - false /* forceCurrentDev */); - - - // Force newer pre-release targetSdkVersion to current pre-release platform. - // APP: Pre-release API 30 - // DEV: Pre-release API 20 - verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, - Build.VERSION_CODES.CUR_DEVELOPMENT, true /* forceCurrentDev */); - verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false, - Build.VERSION_CODES.CUR_DEVELOPMENT, true /* forceCurrentDev */); + verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1); + verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false, -1); } @Test @@ -242,45 +225,36 @@ public class PackageParserTest { // Do allow older release targetSdkVersion on released platform. // APP: Released API 10 // DEV: Released API 20 - verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION); // Do allow same release targetSdkVersion on released platform. // APP: Released API 20 // DEV: Released API 20 - verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION); // Do allow newer release targetSdkVersion on released platform. // APP: Released API 30 // DEV: Released API 20 - verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, true, NEWER_VERSION, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, true, NEWER_VERSION); // Don't allow older pre-release targetSdkVersion on released platform. // APP: Pre-release API 10 // DEV: Released API 20 - verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1, - false /* forceCurrentDev */); - verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, true, -1, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1); + verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, true, -1); // Don't allow same pre-release targetSdkVersion on released platform. // APP: Pre-release API 20 // DEV: Released API 20 - verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1, - false /* forceCurrentDev */); - verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, -1, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1); + verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, -1); // Don't allow newer pre-release targetSdkVersion on released platform. // APP: Pre-release API 30 // DEV: Released API 20 - verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1, - false /* forceCurrentDev */); - verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true, -1, - false /* forceCurrentDev */); + verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1); + verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true, -1); } /** diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java index da81d176de8a..80b1f9cb35ae 100644 --- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java +++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java @@ -19,6 +19,7 @@ package android.view; import static android.view.ImeInsetsSourceConsumer.areEditorsSimilar; import static android.view.InsetsState.TYPE_IME; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; @@ -73,7 +74,7 @@ public class ImeInsetsSourceConsumerTest { false, new DisplayCutout( Insets.of(10, 10, 10, 10), rect, rect, rect, rect), - rect, rect); + rect, rect, SOFT_INPUT_ADJUST_RESIZE); mImeConsumer = new ImeInsetsSourceConsumer( new InsetsState(), Transaction::new, mController); }); diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index 6dad6a22f7ea..731d5644504b 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -20,10 +20,16 @@ import static android.view.InsetsState.TYPE_IME; import static android.view.InsetsState.TYPE_NAVIGATION_BAR; import static android.view.InsetsState.TYPE_TOP_BAR; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import android.content.Context; import android.graphics.Insets; @@ -73,7 +79,7 @@ public class InsetsControllerTest { false, new DisplayCutout( Insets.of(10, 10, 10, 10), rect, rect, rect, rect), - rect, rect); + rect, rect, SOFT_INPUT_ADJUST_RESIZE); }); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); } @@ -95,6 +101,17 @@ public class InsetsControllerTest { } @Test + public void testFrameDoesntMatchDisplay() { + mController.onFrameChanged(new Rect(0, 0, 100, 100)); + mController.getState().setDisplayFrame(new Rect(0, 0, 200, 200)); + WindowInsetsAnimationControlListener controlListener = + mock(WindowInsetsAnimationControlListener.class); + mController.controlWindowInsetsAnimation(0, controlListener); + verify(controlListener).onCancelled(); + verify(controlListener, never()).onReady(any(), anyInt()); + } + + @Test public void testAnimationEndState() { InsetsSourceControl[] controls = prepareControls(); InsetsSourceControl navBar = controls[0]; diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java index 03af67df13d0..bd036b01c0cf 100644 --- a/core/tests/coretests/src/android/view/InsetsStateTest.java +++ b/core/tests/coretests/src/android/view/InsetsStateTest.java @@ -25,6 +25,8 @@ import static android.view.InsetsState.TYPE_SIDE_BAR_2; import static android.view.InsetsState.TYPE_SIDE_BAR_3; import static android.view.InsetsState.TYPE_TOP_BAR; +import static android.view.WindowInsets.Type.ime; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; @@ -37,6 +39,7 @@ import android.os.Parcel; import android.platform.test.annotations.Presubmit; import android.util.SparseIntArray; import android.view.WindowInsets.Type; +import android.view.test.InsetsModeSession; import androidx.test.filters.FlakyTest; import androidx.test.runner.AndroidJUnit4; @@ -53,49 +56,70 @@ public class InsetsStateTest { private InsetsState mState2 = new InsetsState(); @Test - public void testCalculateInsets() { - mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100)); - mState.getSource(TYPE_TOP_BAR).setVisible(true); - mState.getSource(TYPE_IME).setFrame(new Rect(0, 200, 100, 300)); - mState.getSource(TYPE_IME).setVisible(true); - SparseIntArray typeSideMap = new SparseIntArray(); - WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false, - DisplayCutout.NO_CUTOUT, null, null, typeSideMap); - assertEquals(Insets.of(0, 100, 0, 100), insets.getSystemWindowInsets()); - assertEquals(Insets.of(0, 100, 0, 100), insets.getInsets(Type.all())); - assertEquals(INSET_SIDE_TOP, typeSideMap.get(TYPE_TOP_BAR)); - assertEquals(INSET_SIDE_BOTTOM, typeSideMap.get(TYPE_IME)); - assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.topBar())); - assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(Type.ime())); + public void testCalculateInsets() throws Exception { + try (final InsetsModeSession session = + new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) { + mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100)); + mState.getSource(TYPE_TOP_BAR).setVisible(true); + mState.getSource(TYPE_IME).setFrame(new Rect(0, 200, 100, 300)); + mState.getSource(TYPE_IME).setVisible(true); + SparseIntArray typeSideMap = new SparseIntArray(); + WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false, + DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, typeSideMap); + assertEquals(Insets.of(0, 100, 0, 100), insets.getSystemWindowInsets()); + assertEquals(Insets.of(0, 100, 0, 100), insets.getInsets(Type.all())); + assertEquals(INSET_SIDE_TOP, typeSideMap.get(TYPE_TOP_BAR)); + assertEquals(INSET_SIDE_BOTTOM, typeSideMap.get(TYPE_IME)); + assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.topBar())); + assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(Type.ime())); + } } @Test - public void testCalculateInsets_imeAndNav() { - mState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(0, 200, 100, 300)); - mState.getSource(TYPE_NAVIGATION_BAR).setVisible(true); - mState.getSource(TYPE_IME).setFrame(new Rect(0, 100, 100, 300)); - mState.getSource(TYPE_IME).setVisible(true); - WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false, - DisplayCutout.NO_CUTOUT, null, null, null); - assertEquals(100, insets.getStableInsetBottom()); - assertEquals(Insets.of(0, 0, 0, 100), insets.getMaxInsets(Type.all())); - assertEquals(Insets.of(0, 0, 0, 200), insets.getSystemWindowInsets()); - assertEquals(Insets.of(0, 0, 0, 200), insets.getInsets(Type.all())); - assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(Type.sideBars())); - assertEquals(Insets.of(0, 0, 0, 200), insets.getInsets(Type.ime())); + public void testCalculateInsets_imeAndNav() throws Exception{ + try (final InsetsModeSession session = + new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) { + mState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(0, 200, 100, 300)); + mState.getSource(TYPE_NAVIGATION_BAR).setVisible(true); + mState.getSource(TYPE_IME).setFrame(new Rect(0, 100, 100, 300)); + mState.getSource(TYPE_IME).setVisible(true); + WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false, + DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, null); + assertEquals(100, insets.getStableInsetBottom()); + assertEquals(Insets.of(0, 0, 0, 100), insets.getMaxInsets(Type.systemBars())); + assertEquals(Insets.of(0, 0, 0, 200), insets.getSystemWindowInsets()); + assertEquals(Insets.of(0, 0, 0, 200), insets.getInsets(Type.all())); + assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(Type.sideBars())); + assertEquals(Insets.of(0, 0, 0, 200), insets.getInsets(Type.ime())); + } } @Test - public void testCalculateInsets_navRightStatusTop() { + public void testCalculateInsets_navRightStatusTop() throws Exception { + try (final InsetsModeSession session = + new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) { + mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100)); + mState.getSource(TYPE_TOP_BAR).setVisible(true); + mState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300)); + mState.getSource(TYPE_NAVIGATION_BAR).setVisible(true); + WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false, + DisplayCutout.NO_CUTOUT, null, null, 0, null); + assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets()); + assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.topBar())); + assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.sideBars())); + } + } + + @Test + public void testCalculateInsets_imeIgnoredWithoutAdjustResize() { mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100)); mState.getSource(TYPE_TOP_BAR).setVisible(true); - mState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300)); - mState.getSource(TYPE_NAVIGATION_BAR).setVisible(true); + mState.getSource(TYPE_IME).setFrame(new Rect(0, 200, 100, 300)); + mState.getSource(TYPE_IME).setVisible(true); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false, - DisplayCutout.NO_CUTOUT, null, null, null); - assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets()); - assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.topBar())); - assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.sideBars())); + DisplayCutout.NO_CUTOUT, null, null, 0, null); + assertEquals(0, insets.getSystemWindowInsetBottom()); + assertTrue(insets.isVisible(ime())); } @Test @@ -106,7 +130,7 @@ public class InsetsStateTest { mState.getSource(TYPE_IME).setVisible(true); mState.removeSource(TYPE_IME); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false, - DisplayCutout.NO_CUTOUT, null, null, null); + DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, null); assertEquals(0, insets.getSystemWindowInsetBottom()); } @@ -114,14 +138,14 @@ public class InsetsStateTest { public void testEquals_differentRect() { mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100)); mState2.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 10, 10)); - assertNotEquals(mState, mState2); + assertNotEqualsAndHashCode(); } @Test public void testEquals_differentSource() { mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100)); mState2.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100)); - assertNotEquals(mState, mState2); + assertNotEqualsAndHashCode(); } @Test @@ -130,7 +154,7 @@ public class InsetsStateTest { mState.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100)); mState2.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100)); mState2.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100)); - assertEquals(mState, mState2); + assertEqualsAndHashCode(); } @Test @@ -138,7 +162,21 @@ public class InsetsStateTest { mState.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100)); mState.getSource(TYPE_IME).setVisible(true); mState2.getSource(TYPE_IME).setFrame(new Rect(0, 0, 100, 100)); - assertNotEquals(mState, mState2); + assertNotEqualsAndHashCode(); + } + + @Test + public void testEquals_differentFrame() { + mState.setDisplayFrame(new Rect(0, 1, 2, 3)); + mState.setDisplayFrame(new Rect(4, 5, 6, 7)); + assertNotEqualsAndHashCode(); + } + + @Test + public void testEquals_sameFrame() { + mState.setDisplayFrame(new Rect(0, 1, 2, 3)); + mState2.setDisplayFrame(new Rect(0, 1, 2, 3)); + assertEqualsAndHashCode(); } @Test @@ -148,6 +186,7 @@ public class InsetsStateTest { mState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 100, 100)); Parcel p = Parcel.obtain(); mState.writeToParcel(p, 0 /* flags */); + p.setDataPosition(0); mState2.readFromParcel(p); p.recycle(); assertEquals(mState, mState2); @@ -161,4 +200,14 @@ public class InsetsStateTest { assertTrue(InsetsState.getDefaultVisibility(TYPE_SIDE_BAR_3)); assertFalse(InsetsState.getDefaultVisibility(TYPE_IME)); } + + private void assertEqualsAndHashCode() { + assertEquals(mState, mState2); + assertEquals(mState.hashCode(), mState2.hashCode()); + } + + private void assertNotEqualsAndHashCode() { + assertNotEquals(mState, mState2); + assertNotEquals(mState.hashCode(), mState2.hashCode()); + } } diff --git a/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java index 08ad62ab843d..d9dac314fc7c 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java @@ -41,6 +41,7 @@ public class TemplateClassificationIntentFactoryTest { private static final String TEXT = "text"; private static final String TITLE = "Map"; + private static final String DESCRIPTION = "Opens in Maps"; private static final String ACTION = Intent.ACTION_VIEW; @Mock @@ -57,19 +58,6 @@ public class TemplateClassificationIntentFactoryTest { @Test public void create_foreignText() { - RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate( - TITLE, - null, - ACTION, - null, - null, - null, - null, - null, - null, - null - ); - AnnotatorModel.ClassificationResult classificationResult = new AnnotatorModel.ClassificationResult( TextClassifier.TYPE_ADDRESS, @@ -81,7 +69,7 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - new RemoteActionTemplate[]{remoteActionTemplate}); + createRemoteActionTemplates()); List<TextClassifierImpl.LabeledIntent> intents = mTemplateClassificationIntentFactory.create( @@ -106,19 +94,6 @@ public class TemplateClassificationIntentFactoryTest { @Test public void create_notForeignText() { - RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate( - TITLE, - null, - ACTION, - null, - null, - null, - null, - null, - null, - null - ); - AnnotatorModel.ClassificationResult classificationResult = new AnnotatorModel.ClassificationResult( TextClassifier.TYPE_ADDRESS, @@ -130,7 +105,7 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - new RemoteActionTemplate[]{remoteActionTemplate}); + createRemoteActionTemplates()); List<TextClassifierImpl.LabeledIntent> intents = mTemplateClassificationIntentFactory.create( @@ -147,4 +122,21 @@ public class TemplateClassificationIntentFactoryTest { assertThat(intent.getAction()).isEqualTo(ACTION); assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue(); } + + private static RemoteActionTemplate[] createRemoteActionTemplates() { + return new RemoteActionTemplate[]{ + new RemoteActionTemplate( + TITLE, + DESCRIPTION, + ACTION, + null, + null, + null, + null, + null, + null, + null + ) + }; + } } diff --git a/core/tests/coretests/src/android/view/textclassifier/TemplateIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/TemplateIntentFactoryTest.java index 0d364a329de4..a1158a7cbb6c 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TemplateIntentFactoryTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TemplateIntentFactoryTest.java @@ -81,7 +81,6 @@ public class TemplateIntentFactoryTest { REQUEST_CODE ); - List<TextClassifierImpl.LabeledIntent> intents = mTemplateIntentFactory.create(new RemoteActionTemplate[]{remoteActionTemplate}); @@ -97,23 +96,22 @@ public class TemplateIntentFactoryTest { assertThat(intent.getFlags()).isEqualTo(FLAG); assertThat(intent.getCategories()).containsExactly((Object[]) CATEGORY); assertThat(intent.getPackage()).isNull(); - assertThat( - intent.getStringExtra(KEY_ONE)).isEqualTo(VALUE_ONE); + assertThat(intent.getStringExtra(KEY_ONE)).isEqualTo(VALUE_ONE); assertThat(intent.getIntExtra(KEY_TWO, 0)).isEqualTo(VALUE_TWO); assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue(); } @Test - public void create_packageIsNotNull() { + public void normalizesScheme() { RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate( TITLE, DESCRIPTION, ACTION, - DATA, + "HTTp://www.android.com", TYPE, FLAG, CATEGORY, - PACKAGE_NAME, + /* packageName */ null, NAMED_VARIANTS, REQUEST_CODE ); @@ -121,15 +119,16 @@ public class TemplateIntentFactoryTest { List<TextClassifierImpl.LabeledIntent> intents = mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate}); - assertThat(intents).hasSize(0); + String data = intents.get(0).getIntent().getData().toString(); + assertThat(data).isEqualTo("http://www.android.com"); } @Test public void create_minimal() { RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate( - null, - null, - null, + TITLE, + DESCRIPTION, + ACTION, null, null, null, @@ -142,15 +141,14 @@ public class TemplateIntentFactoryTest { List<TextClassifierImpl.LabeledIntent> intents = mTemplateIntentFactory.create(new RemoteActionTemplate[]{remoteActionTemplate}); - assertThat(intents).hasSize(1); TextClassifierImpl.LabeledIntent labeledIntent = intents.get(0); - assertThat(labeledIntent.getTitle()).isNull(); - assertThat(labeledIntent.getDescription()).isNull(); + assertThat(labeledIntent.getTitle()).isEqualTo(TITLE); + assertThat(labeledIntent.getDescription()).isEqualTo(DESCRIPTION); assertThat(labeledIntent.getRequestCode()).isEqualTo( TextClassifierImpl.LabeledIntent.DEFAULT_REQUEST_CODE); Intent intent = labeledIntent.getIntent(); - assertThat(intent.getAction()).isNull(); + assertThat(intent.getAction()).isEqualTo(ACTION); assertThat(intent.getData()).isNull(); assertThat(intent.getType()).isNull(); assertThat(intent.getFlags()).isEqualTo(0); @@ -158,4 +156,98 @@ public class TemplateIntentFactoryTest { assertThat(intent.getPackage()).isNull(); assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue(); } + + @Test + public void invalidTemplate_nullTemplate() { + RemoteActionTemplate remoteActionTemplate = null; + + List<TextClassifierImpl.LabeledIntent> intents = + mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate}); + + assertThat(intents).isEmpty(); + } + + @Test + public void invalidTemplate_nonEmptyPackageName() { + RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate( + TITLE, + DESCRIPTION, + ACTION, + DATA, + TYPE, + FLAG, + CATEGORY, + PACKAGE_NAME, + NAMED_VARIANTS, + REQUEST_CODE + ); + + List<TextClassifierImpl.LabeledIntent> intents = + mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate}); + + assertThat(intents).isEmpty(); + } + + @Test + public void invalidTemplate_emptyTitle() { + RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate( + null, + DESCRIPTION, + ACTION, + null, + null, + null, + null, + null, + null, + null + ); + + List<TextClassifierImpl.LabeledIntent> intents = + mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate}); + + assertThat(intents).isEmpty(); + } + + @Test + public void invalidTemplate_emptyDescription() { + RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate( + TITLE, + null, + ACTION, + null, + null, + null, + null, + null, + null, + null + ); + + List<TextClassifierImpl.LabeledIntent> intents = + mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate}); + + assertThat(intents).isEmpty(); + } + + @Test + public void invalidTemplate_emptyIntentAction() { + RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate( + TITLE, + DESCRIPTION, + null, + null, + null, + null, + null, + null, + null, + null + ); + + List<TextClassifierImpl.LabeledIntent> intents = + mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate}); + + assertThat(intents).isEmpty(); + } } diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java index 32bafec4081a..fe2a6608c781 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java @@ -195,11 +195,13 @@ public class TextClassificationConstantsTest { assertWithMessage("in_app_conversation_action_types_default") .that(constants.getInAppConversationActionTypes()) .containsExactly("text_reply", "create_reminder", "call_phone", "open_url", - "send_email", "send_sms", "track_flight", "view_calendar", "view_map"); + "send_email", "send_sms", "track_flight", "view_calendar", "view_map", + "add_contact"); assertWithMessage("notification_conversation_action_types_default") .that(constants.getNotificationConversationActionTypes()) .containsExactly("text_reply", "create_reminder", "call_phone", "open_url", - "send_email", "send_sms", "track_flight", "view_calendar", "view_map"); + "send_email", "send_sms", "track_flight", "view_calendar", "view_map", + "add_contact"); assertWithMessage("lang_id_threshold_override") .that(constants.getLangIdThresholdOverride()).isWithin(EPSILON).of(-1f); } diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java index 582be9d51731..bdd03707c1f1 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java @@ -176,6 +176,7 @@ public class TextClassifierTest { TextClassification classification = mClassifier.classifyText(request); assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_URL)); + assertThat(classification, containsIntentWithAction(Intent.ACTION_VIEW)); } @Test @@ -207,6 +208,7 @@ public class TextClassifierTest { TextClassification classification = mClassifier.classifyText(request); assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_URL)); + assertThat(classification, containsIntentWithAction(Intent.ACTION_VIEW)); } @Test @@ -517,6 +519,24 @@ public class TextClassifierTest { }; } + private static Matcher<TextClassification> containsIntentWithAction(final String action) { + return new BaseMatcher<TextClassification>() { + @Override + public boolean matches(Object o) { + if (o instanceof TextClassification) { + TextClassification result = (TextClassification) o; + return ExtrasUtils.findAction(result, action) != null; + } + return false; + } + + @Override + public void describeTo(Description description) { + description.appendText("intent action=").appendValue(action); + } + }; + } + private static Matcher<TextLanguage> isTextLanguage(final String languageTag) { return new BaseMatcher<TextLanguage>() { @Override diff --git a/core/tests/coretests/src/android/view/textclassifier/logging/TextClassifierEventTronLoggerTest.java b/core/tests/coretests/src/android/view/textclassifier/logging/TextClassifierEventTronLoggerTest.java index 73af56743b5f..1980a604fdd2 100644 --- a/core/tests/coretests/src/android/view/textclassifier/logging/TextClassifierEventTronLoggerTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/logging/TextClassifierEventTronLoggerTest.java @@ -91,8 +91,8 @@ public class TextClassifierEventTronLoggerTest { .isEqualTo(ConversationAction.TYPE_CALL_PHONE); assertThat((float) logMaker.getTaggedData(FIELD_TEXT_CLASSIFIER_SCORE)) .isWithin(0.00001f).of(0.5f); - assertThat(logMaker.getTaggedData(FIELD_TEXT_CLASSIFIER_EVENT_TIME)) - .isEqualTo(EVENT_TIME); + // Never write event time. + assertThat(logMaker.getTaggedData(FIELD_TEXT_CLASSIFIER_EVENT_TIME)).isNull(); assertThat(logMaker.getPackageName()).isEqualTo(PACKAGE_NAME); assertThat(logMaker.getTaggedData(FIELD_TEXT_CLASSIFIER_WIDGET_TYPE)) .isEqualTo(WIDGET_TYPE); diff --git a/graphics/java/android/graphics/Insets.aidl b/graphics/java/android/graphics/Insets.aidl new file mode 100644 index 000000000000..e65e72d27f49 --- /dev/null +++ b/graphics/java/android/graphics/Insets.aidl @@ -0,0 +1,20 @@ +/* //device/java/android/android/graphics/Insets.aidl +** +** Copyright 2019, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.graphics; + +parcelable Insets; diff --git a/graphics/java/android/graphics/Insets.java b/graphics/java/android/graphics/Insets.java index 8258b575d63f..c64c7893564c 100644 --- a/graphics/java/android/graphics/Insets.java +++ b/graphics/java/android/graphics/Insets.java @@ -18,6 +18,8 @@ package android.graphics; import android.annotation.NonNull; import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; /** * An Insets instance holds four integer offsets which describe changes to the four @@ -27,7 +29,7 @@ import android.annotation.Nullable; * Insets are immutable so may be treated as values. * */ -public final class Insets { +public final class Insets implements Parcelable { public static final Insets NONE = new Insets(0, 0, 0, 0); public final int left; @@ -73,7 +75,7 @@ public final class Insets { } /** - * Returns a Rect intance with the appropriate values. + * Returns a Rect instance with the appropriate values. * * @hide */ @@ -168,4 +170,29 @@ public final class Insets { ", bottom=" + bottom + '}'; } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(left); + out.writeInt(top); + out.writeInt(right); + out.writeInt(bottom); + } + + public static final Parcelable.Creator<Insets> CREATOR = new Parcelable.Creator<Insets>() { + @Override + public Insets createFromParcel(Parcel in) { + return new Insets(in.readInt(), in.readInt(), in.readInt(), in.readInt()); + } + + @Override + public Insets[] newArray(int size) { + return new Insets[size]; + } + }; } diff --git a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java index c0c6a4f424a1..5181d8992be5 100644 --- a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java @@ -157,28 +157,22 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac @Override public void invalidateDrawable(Drawable who) { - final Callback callback = getCallback(); - - if (callback != null) { - callback.invalidateDrawable(who); + if (who == mColorDrawable && getCallback() != null) { + getCallback().invalidateDrawable(this); } } @Override public void scheduleDrawable(Drawable who, Runnable what, long when) { - final Callback callback = getCallback(); - - if (callback != null) { - callback.scheduleDrawable(who, what, when); + if (who == mColorDrawable && getCallback() != null) { + getCallback().scheduleDrawable(this, what, when); } } @Override public void unscheduleDrawable(Drawable who, Runnable what) { - final Callback callback = getCallback(); - - if (callback != null) { - callback.unscheduleDrawable(who, what); + if (who == mColorDrawable && getCallback() != null) { + getCallback().unscheduleDrawable(this, what); } } diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java index 5d5e40fd3ac3..eb169be06025 100644 --- a/keystore/java/android/security/KeyChain.java +++ b/keystore/java/android/security/KeyChain.java @@ -18,8 +18,8 @@ package android.security; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; -import android.annotation.WorkerThread; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.WorkerThread; import android.app.Activity; import android.app.PendingIntent; import android.app.Service; @@ -29,7 +29,6 @@ import android.content.Intent; import android.content.ServiceConnection; import android.net.Uri; import android.os.Binder; -import android.os.Build; import android.os.IBinder; import android.os.Looper; import android.os.Process; @@ -38,6 +37,8 @@ import android.os.UserHandle; import android.security.keystore.AndroidKeyStoreProvider; import android.security.keystore.KeyProperties; +import com.android.org.conscrypt.TrustedCertificateStore; + import java.io.ByteArrayInputStream; import java.io.Closeable; import java.io.Serializable; @@ -58,8 +59,6 @@ import java.util.concurrent.LinkedBlockingQueue; import javax.security.auth.x500.X500Principal; -import com.android.org.conscrypt.TrustedCertificateStore; - /** * The {@code KeyChain} class provides access to private keys and * their corresponding certificate chains in credential storage. @@ -214,8 +213,8 @@ public final class KeyChain { * * @deprecated Use {@link #ACTION_KEYCHAIN_CHANGED}, {@link #ACTION_TRUST_STORE_CHANGED} or * {@link #ACTION_KEY_ACCESS_CHANGED}. Apps that target a version higher than - * {@link Build.VERSION_CODES#N_MR1} will only receive this broadcast if they register for it - * at runtime. + * {@link android.os.Build.VERSION_CODES#N_MR1} will only receive this broadcast if they + * register for it at runtime. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_STORAGE_CHANGED = "android.security.STORAGE_CHANGED"; @@ -532,8 +531,8 @@ public final class KeyChain { } /** - * Returns the {@code PrivateKey} for the requested alias, or null - * if there is no result. + * Returns the {@code PrivateKey} for the requested alias, or null if the alias does not exist + * or the caller has no permission to access it (see note on exceptions below). * * <p> This method may block while waiting for a connection to another process, and must never * be called from the main thread. @@ -541,6 +540,15 @@ public final class KeyChain { * at any time from the main thread, it is safer to rely on a long-lived context such as one * returned from {@link Context#getApplicationContext()}. * + * <p> If the caller provides a valid alias to which it was not granted access, then the + * caller must invoke {@link #choosePrivateKeyAlias} again to get another valid alias + * or a grant to access the same alias. + * <p>On Android versions prior to Q, when a key associated with the specified alias is + * unavailable, the method will throw a {@code KeyChainException} rather than return null. + * If the exception's cause (as obtained by calling {@code KeyChainException.getCause()}) + * is a throwable of type {@code IllegalStateException} then the caller lacks a grant + * to access the key and certificates associated with this alias. + * * @param alias The alias of the desired private key, typically returned via * {@link KeyChainAliasCallback#alias}. * @throws KeyChainException if the alias was valid but there was some problem accessing it. @@ -591,8 +599,10 @@ public final class KeyChain { } /** - * Returns the {@code X509Certificate} chain for the requested - * alias, or null if there is no result. + * Returns the {@code X509Certificate} chain for the requested alias, or null if the alias + * does not exist or the caller has no permission to access it (see note on exceptions + * in {@link #getPrivateKey}). + * * <p> * <strong>Note:</strong> If a certificate chain was explicitly specified when the alias was * installed, this method will return that chain. If only the client certificate was specified @@ -604,6 +614,9 @@ public final class KeyChain { * <p> As {@link Activity} and {@link Service} contexts are short-lived and can be destroyed * at any time from the main thread, it is safer to rely on a long-lived context such as one * returned from {@link Context#getApplicationContext()}. + * <p> In case the caller specifies an alias for which it lacks a grant, it must call + * {@link #choosePrivateKeyAlias} again. See {@link #getPrivateKey} for more details on + * coping with this scenario. * * @param alias The alias of the desired certificate chain, typically * returned via {@link KeyChainAliasCallback#alias}. diff --git a/libs/incident/Android.bp b/libs/incident/Android.bp index 0619a9c100dd..905e3039ff88 100644 --- a/libs/incident/Android.bp +++ b/libs/incident/Android.bp @@ -36,7 +36,6 @@ cc_library_shared { srcs: [ ":libincident_aidl", - "proto/android/os/header.proto", "proto/android/os/metadata.proto", "src/IncidentReportArgs.cpp", ], @@ -47,4 +46,4 @@ cc_library_shared { }, export_include_dirs: ["include"], -} +}
\ No newline at end of file diff --git a/libs/incident/include/android/os/IncidentReportArgs.h b/libs/incident/include/android/os/IncidentReportArgs.h index ee1e33c43b89..5e8eac1833ce 100644 --- a/libs/incident/include/android/os/IncidentReportArgs.h +++ b/libs/incident/include/android/os/IncidentReportArgs.h @@ -24,8 +24,6 @@ #include <set> #include <vector> -#include "frameworks/base/libs/incident/proto/android/os/header.pb.h" - namespace android { namespace os { @@ -49,7 +47,7 @@ public: void setAll(bool all); void setDest(int dest); void addSection(int section); - void addHeader(const IncidentHeaderProto& headerProto); + void addHeader(const vector<uint8_t>& headerProto); inline bool all() const { return mAll; } bool containsSection(int section) const; diff --git a/libs/incident/src/IncidentReportArgs.cpp b/libs/incident/src/IncidentReportArgs.cpp index 26261ef929ae..06b7a5b682b1 100644 --- a/libs/incident/src/IncidentReportArgs.cpp +++ b/libs/incident/src/IncidentReportArgs.cpp @@ -161,15 +161,9 @@ IncidentReportArgs::addSection(int section) } void -IncidentReportArgs::addHeader(const IncidentHeaderProto& headerProto) +IncidentReportArgs::addHeader(const vector<uint8_t>& headerProto) { - vector<uint8_t> header; - auto serialized = headerProto.SerializeAsString(); - if (serialized.empty()) return; - for (auto it = serialized.begin(); it != serialized.end(); it++) { - header.push_back((uint8_t)*it); - } - mHeaders.push_back(header); + mHeaders.push_back(headerProto); } bool diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 751d57bbdc81..4bc3897c4477 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -1614,29 +1614,59 @@ public final class MediaCodecInfo { } /** - * Video performance points are a set of standard performance points defined by pixel rate. + * Video performance points are a set of standard performance points defined by number of + * pixels, pixel rate and frame rate. Performance point represents an upper bound. This + * means that it covers all performance points with fewer pixels, pixel rate and frame + * rate. */ public static final class PerformancePoint { /** - * Frame width in pixels. + * (Maximum) number of macroblocks in the frame. + * + * Video frames are conceptually divided into 16-by-16 pixel blocks called macroblocks. + * Most coding standards operate on these 16-by-16 pixel blocks; thus, codec performance + * is characterized using such blocks. */ - public final int width; + public final int macroBlocks; /** - * Frame height in pixels. + * (Maximum) frame rate in frames per second. */ - public final int height; + public final int frameRate; /** - * Frame rate in frames per second. + * (Maximum) number of macroblocks processed per second. */ - public final int frameRate; + public final long macroBlockRate; /* package private */ - PerformancePoint(int width_, int height_, int frameRate_) { - width = width_; - height = height_; - frameRate = frameRate_; + PerformancePoint(int width_, int height_, int frameRate_, int maxFrameRate_) { + macroBlocks = saturateLongToInt( + ((Math.max(1, (long)width_) + 15) / 16) + * ((Math.max(1, (long)height_) + 15) / 16)); + frameRate = Math.max(1, frameRate_); + macroBlockRate = Math.max(maxFrameRate_, frameRate) * macroBlocks; + } + + /** + * Create a performance point for a given frame size and frame rate. + * + * @param width_ width of the frame in pixels + * @param height_ height of the frame in pixels + * @param frameRate_ frame rate in frames per second + */ + public PerformancePoint(int width_, int height_, int frameRate_) { + this(width_, height_, frameRate_, frameRate_ /* maxFrameRate */); + } + + private int saturateLongToInt(long value) { + if (value < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } else if (value > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } else { + return (int)value; + } } /** @@ -1647,26 +1677,40 @@ public final class MediaCodecInfo { * @return {@code true} if the performance point covers the format. */ public boolean covers(@NonNull MediaFormat format) { - // for simplicity, this code assumes a 16x16 block size. - long macroBlocks = ((width + 15) / 16) * (long)((height + 15) / 16); - long mbps = macroBlocks * frameRate; + PerformancePoint other = new PerformancePoint( + format.getInteger(MediaFormat.KEY_WIDTH, 0), + format.getInteger(MediaFormat.KEY_HEIGHT, 0), + // safely convert ceil(double) to int through float case and Math.round + Math.round((float)( + Math.ceil(format.getNumber(MediaFormat.KEY_FRAME_RATE, 0) + .doubleValue())))); + return covers(other); + } - long formatMacroBlocks = - (long)((format.getInteger(MediaFormat.KEY_WIDTH, 0) + 15) / 16) - * ((format.getInteger(MediaFormat.KEY_HEIGHT, 0) + 15) / 16); - double formatMbps = - Math.ceil(formatMacroBlocks - * format.getNumber(MediaFormat.KEY_FRAME_RATE, 0).doubleValue()); - return formatMacroBlocks > 0 && formatMacroBlocks <= macroBlocks - && formatMbps <= mbps; + /** + * Checks whether the performance point covers another performance point. Use this + * method to determine if a performance point advertised by a codec covers the + * performance point required. This method can also be used for lose ordering as this + * method is transitive. + * + * @param other other performance point considered + * + * @return {@code true} if the performance point covers the other. + */ + public boolean covers(@NonNull PerformancePoint other) { + return (macroBlocks >= other.macroBlocks + && frameRate >= other.frameRate + && macroBlockRate >= other.macroBlockRate); } + @Override public boolean equals(Object o) { if (o instanceof PerformancePoint) { PerformancePoint other = (PerformancePoint)o; - return ((long)width * height) == ((long)other.width * other.height) - && frameRate == other.frameRate; + return (macroBlocks == other.macroBlocks + && frameRate == other.frameRate + && macroBlockRate == other.macroBlockRate); } return false; } @@ -1931,7 +1975,8 @@ public final class MediaCodecInfo { continue; } ret.add(new PerformancePoint( - size.getWidth(), size.getHeight(), range.getLower().intValue())); + size.getWidth(), size.getHeight(), range.getLower().intValue(), + range.getUpper().intValue())); } // check if the component specified no performance point indication if (ret.size() == 0) { @@ -1939,9 +1984,12 @@ public final class MediaCodecInfo { } // sort reversed by area first, then by frame rate - ret.sort((a, b) -> (a.width * a.height != b.width * b.height ? - (b.width * b.height - a.width * a.height) : - (b.frameRate - a.frameRate))); + ret.sort((a, b) -> -((a.macroBlocks != b.macroBlocks) ? + (a.macroBlocks < b.macroBlocks ? -1 : 1) : + (a.macroBlockRate != b.macroBlockRate) ? + (a.macroBlockRate < b.macroBlockRate ? -1 : 1) : + (a.frameRate != b.frameRate) ? + (a.frameRate < b.frameRate ? -1 : 1) : 0)); return ret; } @@ -2363,39 +2411,45 @@ public final class MediaCodecInfo { boolean supported = true; switch (profileLevel.level) { case CodecProfileLevel.AVCLevel1: - MBPS = 1485; FS = 99; BR = 64; DPB = 396; break; + MBPS = 1485; FS = 99; BR = 64; DPB = 396; break; case CodecProfileLevel.AVCLevel1b: - MBPS = 1485; FS = 99; BR = 128; DPB = 396; break; + MBPS = 1485; FS = 99; BR = 128; DPB = 396; break; case CodecProfileLevel.AVCLevel11: - MBPS = 3000; FS = 396; BR = 192; DPB = 900; break; + MBPS = 3000; FS = 396; BR = 192; DPB = 900; break; case CodecProfileLevel.AVCLevel12: - MBPS = 6000; FS = 396; BR = 384; DPB = 2376; break; + MBPS = 6000; FS = 396; BR = 384; DPB = 2376; break; case CodecProfileLevel.AVCLevel13: - MBPS = 11880; FS = 396; BR = 768; DPB = 2376; break; + MBPS = 11880; FS = 396; BR = 768; DPB = 2376; break; case CodecProfileLevel.AVCLevel2: - MBPS = 11880; FS = 396; BR = 2000; DPB = 2376; break; + MBPS = 11880; FS = 396; BR = 2000; DPB = 2376; break; case CodecProfileLevel.AVCLevel21: - MBPS = 19800; FS = 792; BR = 4000; DPB = 4752; break; + MBPS = 19800; FS = 792; BR = 4000; DPB = 4752; break; case CodecProfileLevel.AVCLevel22: - MBPS = 20250; FS = 1620; BR = 4000; DPB = 8100; break; + MBPS = 20250; FS = 1620; BR = 4000; DPB = 8100; break; case CodecProfileLevel.AVCLevel3: - MBPS = 40500; FS = 1620; BR = 10000; DPB = 8100; break; + MBPS = 40500; FS = 1620; BR = 10000; DPB = 8100; break; case CodecProfileLevel.AVCLevel31: - MBPS = 108000; FS = 3600; BR = 14000; DPB = 18000; break; + MBPS = 108000; FS = 3600; BR = 14000; DPB = 18000; break; case CodecProfileLevel.AVCLevel32: - MBPS = 216000; FS = 5120; BR = 20000; DPB = 20480; break; + MBPS = 216000; FS = 5120; BR = 20000; DPB = 20480; break; case CodecProfileLevel.AVCLevel4: - MBPS = 245760; FS = 8192; BR = 20000; DPB = 32768; break; + MBPS = 245760; FS = 8192; BR = 20000; DPB = 32768; break; case CodecProfileLevel.AVCLevel41: - MBPS = 245760; FS = 8192; BR = 50000; DPB = 32768; break; + MBPS = 245760; FS = 8192; BR = 50000; DPB = 32768; break; case CodecProfileLevel.AVCLevel42: - MBPS = 522240; FS = 8704; BR = 50000; DPB = 34816; break; + MBPS = 522240; FS = 8704; BR = 50000; DPB = 34816; break; case CodecProfileLevel.AVCLevel5: - MBPS = 589824; FS = 22080; BR = 135000; DPB = 110400; break; + MBPS = 589824; FS = 22080; BR = 135000; DPB = 110400; break; case CodecProfileLevel.AVCLevel51: - MBPS = 983040; FS = 36864; BR = 240000; DPB = 184320; break; + MBPS = 983040; FS = 36864; BR = 240000; DPB = 184320; break; case CodecProfileLevel.AVCLevel52: - MBPS = 2073600; FS = 36864; BR = 240000; DPB = 184320; break; + MBPS = 2073600; FS = 36864; BR = 240000; DPB = 184320; break; + case CodecProfileLevel.AVCLevel6: + MBPS = 4177920; FS = 139264; BR = 240000; DPB = 696320; break; + case CodecProfileLevel.AVCLevel61: + MBPS = 8355840; FS = 139264; BR = 480000; DPB = 696320; break; + case CodecProfileLevel.AVCLevel62: + MBPS = 16711680; FS = 139264; BR = 800000; DPB = 696320; break; default: Log.w(TAG, "Unrecognized level " + profileLevel.level + " for " + mime); diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index a76cf1f6ba25..12e02e7b73cd 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -1520,6 +1520,7 @@ public final class MediaFormat { * Create a copy of a media format object. */ public MediaFormat(@NonNull MediaFormat other) { + this(); mMap.putAll(other.mMap); } diff --git a/packages/CaptivePortalLogin/res/values-gl/strings.xml b/packages/CaptivePortalLogin/res/values-gl/strings.xml index f6f4aea0c639..64195168f76f 100644 --- a/packages/CaptivePortalLogin/res/values-gl/strings.xml +++ b/packages/CaptivePortalLogin/res/values-gl/strings.xml @@ -13,7 +13,7 @@ <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do sitio non coincide co nome que aparece no certificado."</string> <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado caducou."</string> <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado aínda non é válido."</string> - <string name="ssl_error_date_invalid" msgid="88425990680059223">"Este certificado ten unha data non-válida."</string> + <string name="ssl_error_date_invalid" msgid="88425990680059223">"Este certificado ten unha data non válida."</string> <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado non é válido."</string> <string name="ssl_error_unknown" msgid="4405203446079465859">"Produciuse un erro descoñecido relacionado co certificado."</string> <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertencia de seguranza"</string> diff --git a/packages/CarSystemUI/res/values/colors_car.xml b/packages/CarSystemUI/res/values/colors_car.xml index 2f720f5aba65..08e16cdbe3b3 100644 --- a/packages/CarSystemUI/res/values/colors_car.xml +++ b/packages/CarSystemUI/res/values/colors_car.xml @@ -26,6 +26,4 @@ <color name="car_user_switcher_add_user_background_color">@color/car_dark_blue_grey_600</color> <color name="car_user_switcher_add_user_add_sign_color">@color/car_body1_light</color> - <!-- colors for volume dialog tint --> - <color name="car_volume_dialog_tint">@color/car_tint</color> </resources> diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java index 85dab57b5f21..10a0ae5a924c 100644 --- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java +++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java @@ -554,8 +554,7 @@ public class CarVolumeDialogImpl implements VolumeDialog { // Adding the items which are not coming from the default item. VolumeItem volumeItem = mAvailableVolumeItems.get(groupId); if (volumeItem.defaultItem) { - // Set progress here due to the progress of seekbar may not be updated. - volumeItem.listItem.setProgress(volumeItem.progress); + updateDefaultVolumeItem(volumeItem.listItem); } else { addSeekbarListItem(volumeItem, groupId, 0, null); } @@ -572,8 +571,7 @@ public class CarVolumeDialogImpl implements VolumeDialog { if (!volumeItem.defaultItem) { itr.remove(); } else { - // Set progress here due to the progress of seekbar may not be updated. - seekbarListItem.setProgress(volumeItem.progress); + updateDefaultVolumeItem(seekbarListItem); } } inAnimator = AnimatorInflater.loadAnimator( @@ -595,6 +593,21 @@ public class CarVolumeDialogImpl implements VolumeDialog { mPagedListAdapter.notifyDataSetChanged(); } + private void updateDefaultVolumeItem(SeekbarListItem seekbarListItem){ + VolumeItem volumeItem = findVolumeItem(seekbarListItem); + + // When volume dialog is expanded or collapsed the default list item is never + // reset. Whereas all other list items are removed when the dialog is collapsed and then + // added when the dialog is expanded using {@link CarVolumeDialogImpl#addSeekbarListItem}. + // This sets the progressbar and the tint color of icons for all items other than default + // if they were changed. For default list item it should be done manually here. + int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint); + Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon); + primaryIcon.mutate().setTint(color); + volumeItem.listItem.setPrimaryActionIcon(primaryIcon); + volumeItem.listItem.setProgress(volumeItem.progress); + } + private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener { private final int mVolumeGroupId; diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index dbeee1c4b2ca..26ea6ab2e8be 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -220,4 +220,7 @@ <!-- Default for Settings.Secure.CHARGING_SOUNDS_ENABLED --> <bool name="def_charging_sounds_enabled">true</bool> + + <!-- Default for Settings.Secure.NOTIFICATION_BUBBLES --> + <bool name="def_notification_bubbles">true</bool> </resources> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 23e5f0eea46d..a7ad2239b402 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -3232,7 +3232,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 173; + private static final int SETTINGS_VERSION = 174; private final int mUserId; @@ -4252,6 +4252,24 @@ public class SettingsProvider extends ContentProvider { currentVersion = 173; } + if (currentVersion == 173) { + // Version 173: Set the default value for Secure Settings: NOTIFICATION_BUBBLES + + final SettingsState secureSettings = getSecureSettingsLocked(userId); + + final Setting bubblesSetting = secureSettings.getSettingLocked( + Secure.NOTIFICATION_BUBBLES); + + if (bubblesSetting.isNull()) { + secureSettings.insertSettingLocked(Secure.NOTIFICATION_BUBBLES, + getContext().getResources().getBoolean( + R.bool.def_notification_bubbles) ? "1" : "0", null, + true, SettingsState.SYSTEM_PACKAGE_NAME); + } + + currentVersion = 174; + } + // vXXX: Add new settings above this point. if (currentVersion != newVersion) { diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java index ac6904300f71..38bf77d5eb0e 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java @@ -55,9 +55,16 @@ public interface ClockPlugin extends Plugin { void setTextColor(int color); /** + * Sets the color palette for the clock face. + * @param supportsDarkText Whether dark text can be displayed. + * @param colors Colors that should be used on the clock face, ordered from darker to lighter. + */ + default void setColorPalette(boolean supportsDarkText, int[] colors) {} + + /** * Notifies that time tick alarm from doze service fired. */ - default void dozeTimeTick() { } + default void dozeTimeTick() {} /** * Set the amount (ratio) that the device has transitioned to doze. diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java new file mode 100644 index 000000000000..3ee69b4c3224 --- /dev/null +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.plugins.statusbar; + +import com.android.systemui.plugins.annotations.DependsOn; +import com.android.systemui.plugins.annotations.ProvidesInterface; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; + + +/** + * Sends updates to {@link StateListener}s about changes to the status bar state and dozing state + */ +@ProvidesInterface(version = StatusBarStateController.VERSION) +@DependsOn(target = StatusBarStateController.StateListener.class) +public interface StatusBarStateController { + int VERSION = 1; + + /** + * Current status bar state + */ + int getState(); + + /** + * Is device dozing + */ + boolean isDozing(); + + /** + * Adds a state listener + */ + void addCallback(StateListener listener); + + /** + * Removes callback from listeners + */ + void removeCallback(StateListener listener); + + /** + * Get amount of doze + */ + float getDozeAmount(); + + /** + * Listener for StatusBarState updates + */ + @ProvidesInterface(version = StateListener.VERSION) + public interface StateListener { + int VERSION = 1; + + /** + * Callback before the new state is applied, for those who need to preempt the change. + */ + default void onStatePreChange(int oldState, int newState) { + } + + /** + * Callback after all listeners have had a chance to update based on the state change + */ + default void onStatePostChange() { + } + + /** + * Required callback. Get the new state and do what you will with it. Keep in mind that + * other listeners are typically unordered and don't rely on your work being done before + * other peers. + * + * Only called if the state is actually different. + */ + default void onStateChanged(int newState) { + } + + /** + * Callback to be notified when Dozing changes. Dozing is stored separately from state. + */ + default void onDozingChanged(boolean isDozing) {} + + /** + * Callback to be notified when the doze amount changes. Useful for animations. + * Note: this will be called for each animation frame. Please be careful to avoid + * performance regressions. + */ + default void onDozeAmountChanged(float linear, float eased) {} + } +} diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml index da11db39bd02..54537e5ee7a2 100644 --- a/packages/SystemUI/res-keyguard/values-af/strings.xml +++ b/packages/SystemUI/res-keyguard/values-af/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Jy het <xliff:g id="_NUMBER_1">%d</xliff:g> pogings oor voordat die SIM permanent onbruikbaar word. Kontak die diensverskaffer vir besonderhede.</item> <item quantity="one">SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Jy het <xliff:g id="_NUMBER_0">%d</xliff:g> poging oor voordat die SIM permanent onbruikbaar word. Kontak die diensverskaffer vir besonderhede.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Dit is"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Twaalf"</item> <item msgid="7389464214252023751">"Een"</item> diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml index 0d154f552e19..379838dc2a61 100644 --- a/packages/SystemUI/res-keyguard/values-am/strings.xml +++ b/packages/SystemUI/res-keyguard/values-am/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም እስከመጨረሻው መጠቀም የማይቻል ከመሆኑ በፊት <xliff:g id="_NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።</item> <item quantity="other">ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም እስከመጨረሻው መጠቀም የማይቻል ከመሆኑ በፊት <xliff:g id="_NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ነው"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"አስራ ሁለት"</item> <item msgid="7389464214252023751">"አንድ"</item> diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index 826f2f05f2ad..2fef0270b15c 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -182,7 +182,7 @@ <item quantity="other">تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك <xliff:g id="_NUMBER_1">%d</xliff:g> محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item> <item quantity="one">تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك محاولة واحدة (<xliff:g id="_NUMBER_0">%d</xliff:g>) قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"الساعة"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"الثانية عشرة"</item> <item msgid="7389464214252023751">"الواحدة"</item> diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml index f67e009ca58e..63d0512ca870 100644 --- a/packages/SystemUI/res-keyguard/values-as/strings.xml +++ b/packages/SystemUI/res-keyguard/values-as/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">ছিমখন অক্ষম হ’ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item> <item quantity="other">ছিমখন অক্ষম হ’ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"সময়"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"বাৰ"</item> <item msgid="7389464214252023751">"এক"</item> diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml index 50f1b1f3d7bc..3714ec6e98ca 100644 --- a/packages/SystemUI/res-keyguard/values-az/strings.xml +++ b/packages/SystemUI/res-keyguard/values-az/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM indi deaktivdir. Davam etmək üçün PUK kodunu daxil edin. SIM birdəfəlik yararsız olmadan öncə <xliff:g id="_NUMBER_1">%d</xliff:g> cəhdiniz qalır. Ətraflı məlumat üçün operatorla əlaqə saxlayın.</item> <item quantity="one">SIM indi deaktivdir. Davam etmək üçün PUK kodunu daxil edin. SIM birdəfəlik yararsız olmadan öncə <xliff:g id="_NUMBER_0">%d</xliff:g> cəhdiniz qalır. Ətraflı məlumat üçün operatorla əlaqə saxlayın.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Saat"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"On iki"</item> <item msgid="7389464214252023751">"Bir"</item> diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml index a5fceef4f97b..327231305c3c 100644 --- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml @@ -158,7 +158,7 @@ <item quantity="few">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.</item> <item quantity="other">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Sada je"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"dvanaest"</item> <item msgid="7389464214252023751">"jedan"</item> diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml index 872cd7b997cd..aaa4cb65d37d 100644 --- a/packages/SystemUI/res-keyguard/values-be/strings.xml +++ b/packages/SystemUI/res-keyguard/values-be/strings.xml @@ -166,7 +166,7 @@ <item quantity="many">SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ <xliff:g id="_NUMBER_1">%d</xliff:g> спроб, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.</item> <item quantity="other">SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ <xliff:g id="_NUMBER_1">%d</xliff:g> спробы, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Зараз"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Дванаццаць"</item> <item msgid="7389464214252023751">"Адна"</item> diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml index 741834feca3c..d89dd41c0f72 100644 --- a/packages/SystemUI/res-keyguard/values-bg/strings.xml +++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Остават ви <xliff:g id="_NUMBER_1">%d</xliff:g> опита, преди SIM картата да стане неизползваема завинаги. Свържете се с оператора за подробности.</item> <item quantity="one">SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Остава ви <xliff:g id="_NUMBER_0">%d</xliff:g> опит, преди SIM картата да стане неизползваема завинаги. Свържете се с оператора за подробности.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Часът е"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"дванайсет"</item> <item msgid="7389464214252023751">"един"</item> diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml index 25346a53a049..d0794c3e2995 100644 --- a/packages/SystemUI/res-keyguard/values-bn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">সিম অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আর <xliff:g id="_NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন, তারপরে এই সিমটি আর একেবারেই ব্যবহার করা যাবে না। বিশদে জানতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।</item> <item quantity="other">সিম অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আর <xliff:g id="_NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন, তারপরে এই সিমটি আর একেবারেই ব্যবহার করা যাবে না। বিশদে জানতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"এখন"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"বারো"</item> <item msgid="7389464214252023751">"এক"</item> diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml index 9396ef1ff411..72e4603ba8db 100644 --- a/packages/SystemUI/res-keyguard/values-bs/strings.xml +++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml @@ -158,7 +158,7 @@ <item quantity="few">SIM kartica je onemogućena. Unesite PUK kôd da nastavite. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Za više informacija kontaktirajte mobilnog operatera.</item> <item quantity="other">SIM kartica je onemogućena. Unesite PUK kôd da nastavite. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Za više informacija kontaktirajte mobilnog operatera.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Sada je"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dvanaest"</item> <item msgid="7389464214252023751">"Jedan"</item> diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml index 2fa08975cd8a..185a3f3e39ed 100644 --- a/packages/SystemUI/res-keyguard/values-ca/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queden <xliff:g id="_NUMBER_1">%d</xliff:g> intents; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador de telefonia mòbil per obtenir-ne més informació.</item> <item quantity="one">La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queda <xliff:g id="_NUMBER_0">%d</xliff:g> intent; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador de telefonia mòbil per obtenir-ne més informació.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Són les"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"i dotze"</item> <item msgid="7389464214252023751">"Una"</item> diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml index 2708f8f439f8..bb01b7e91852 100644 --- a/packages/SystemUI/res-keyguard/values-cs/strings.xml +++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml @@ -166,7 +166,7 @@ <item quantity="other">SIM karta je teď zablokována. Chcete-li pokračovat, zadejte kód PUK. Máte ještě <xliff:g id="_NUMBER_1">%d</xliff:g> pokusů, poté bude SIM karta natrvalo zablokována. Podrobnosti vám poskytne operátor.</item> <item quantity="one">SIM karta je teď zablokována. Chcete-li pokračovat, zadejte kód PUK. Máte ještě <xliff:g id="_NUMBER_0">%d</xliff:g> pokus, poté bude SIM karta natrvalo zablokována. Podrobnosti vám poskytne operátor.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Je"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dvanáct"</item> <item msgid="7389464214252023751">"Jedna"</item> diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml index 34c248d5c6f6..fbdaf0f5eb7e 100644 --- a/packages/SystemUI/res-keyguard/values-da/strings.xml +++ b/packages/SystemUI/res-keyguard/values-da/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.</item> <item quantity="other">SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Den er"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Tolv"</item> <item msgid="7389464214252023751">"Et"</item> diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml index d8daf83f34d9..b6127df02f1d 100644 --- a/packages/SystemUI/res-keyguard/values-de/strings.xml +++ b/packages/SystemUI/res-keyguard/values-de/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Du hast noch <xliff:g id="_NUMBER_1">%d</xliff:g> Versuche, bevor die SIM-Karte endgültig gesperrt wird. Weitere Informationen erhältst du von deinem Mobilfunkanbieter.</item> <item quantity="one">Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Du hast noch <xliff:g id="_NUMBER_0">%d</xliff:g> Versuch, bevor die SIM-Karte endgültig gesperrt wird. Weitere Informationen erhältst du von deinem Mobilfunkanbieter.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Es ist"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"zwölf Uhr"</item> <item msgid="7389464214252023751">"ein Uhr"</item> diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml index 6c0916c1d912..402e29765a3a 100644 --- a/packages/SystemUI/res-keyguard/values-el/strings.xml +++ b/packages/SystemUI/res-keyguard/values-el/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">Η κάρτα SIM απενεργοποιήθηκε. Καταχωρίστε τον κωδικό PUK, για να συνεχίσετε. Απομένουν <xliff:g id="_NUMBER_1">%d</xliff:g> ακόμη προσπάθειες προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας για λεπτομέρειες.</item> <item quantity="one">Η κάρτα SIM απενεργοποιήθηκε. Καταχωρίστε τον κωδικό PUK, για να συνεχίσετε. Απομένει <xliff:g id="_NUMBER_0">%d</xliff:g> ακόμη προσπάθεια προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας για λεπτομέρειες.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Είναι"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Δώδεκα"</item> <item msgid="7389464214252023751">"Μία"</item> diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml index 80c9b82e984a..72b8085c9da3 100644 --- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item> <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"It’s"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Twelve"</item> <item msgid="7389464214252023751">"One"</item> diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml index 20c4d56bf2eb..ecc0f71ffcd5 100644 --- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item> <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"It’s"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Twelve"</item> <item msgid="7389464214252023751">"One"</item> diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml index 80c9b82e984a..72b8085c9da3 100644 --- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item> <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"It’s"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Twelve"</item> <item msgid="7389464214252023751">"One"</item> diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml index 80c9b82e984a..72b8085c9da3 100644 --- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item> <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"It’s"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Twelve"</item> <item msgid="7389464214252023751">"One"</item> diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml index a33d81741256..501dcb755b57 100644 --- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item> <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact carrier for details.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"It’s"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Twelve"</item> <item msgid="7389464214252023751">"One"</item> diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml index 98453a7c2a79..f93d93305621 100644 --- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml +++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">Se inhabilitó la SIM. Para continuar, ingresa el código PUK. Te quedan <xliff:g id="_NUMBER_1">%d</xliff:g> intentos más antes de que la SIM quede inutilizable permanentemente. Comunícate con tu proveedor para obtener más detalles.</item> <item quantity="one">Se inhabilitó la SIM. Para continuar, ingresa el código PUK. Te queda <xliff:g id="_NUMBER_0">%d</xliff:g> intento más antes de que la SIM quede inutilizable permanentemente. Comunícate con tu proveedor para obtener más detalles.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Son las"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Doce"</item> <item msgid="7389464214252023751">"Una"</item> diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml index 00bdd913a582..9c189d9f1245 100644 --- a/packages/SystemUI/res-keyguard/values-es/strings.xml +++ b/packages/SystemUI/res-keyguard/values-es/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">La tarjeta SIM está inhabilitada. Introduce el código PUK para continuar. Te quedan <xliff:g id="_NUMBER_1">%d</xliff:g> intentos para que la tarjeta SIM quede inservible de forma permanente. Ponte en contacto con tu operador para obtener más información.</item> <item quantity="one">La tarjeta SIM está inhabilitada. Introduce el código PUK para continuar. Te queda <xliff:g id="_NUMBER_0">%d</xliff:g> intento para que la tarjeta SIM quede inservible de forma permanente. Ponte en contacto con tu operador para obtener más información.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Son las"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Doce"</item> <item msgid="7389464214252023751">"Uno"</item> diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml index e77880403b79..759453732db9 100644 --- a/packages/SystemUI/res-keyguard/values-et/strings.xml +++ b/packages/SystemUI/res-keyguard/values-et/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Teil on jäänud veel <xliff:g id="_NUMBER_1">%d</xliff:g> katset enne, kui SIM-kaart püsivalt lukustatakse. Lisateavet küsige operaatorilt.</item> <item quantity="one">SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Teil on jäänud veel <xliff:g id="_NUMBER_0">%d</xliff:g> katse enne, kui SIM-kaart püsivalt lukustatakse. Lisateavet küsige operaatorilt.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Kell on"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Kaksteist"</item> <item msgid="7389464214252023751">"Üks"</item> diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml index 3ebb536d0394..8b1284d7c535 100644 --- a/packages/SystemUI/res-keyguard/values-eu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. <xliff:g id="_NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIM txartela betiko erabilgaitz geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.</item> <item quantity="one">Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. <xliff:g id="_NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIM txartela betiko erabilgaitz geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Ordua:"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Hamabiak"</item> <item msgid="7389464214252023751">"Ordu bata"</item> diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml index 0c30d03cc14c..183152e37ff8 100644 --- a/packages/SystemUI/res-keyguard/values-fa/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">سیمکارت اکنون غیرفعال است. برای ادامه دادن کد PUK را وارد کنید. <xliff:g id="_NUMBER_1">%d</xliff:g> تلاش دیگر باقی مانده است و پس از آن سیمکارت برای همیشه غیرقابلاستفاده میشود. برای اطلاع از جزئیات با شرکت مخابراتی تماس بگیرید.</item> <item quantity="other">سیمکارت اکنون غیرفعال است. برای ادامه دادن کد PUK را وارد کنید. <xliff:g id="_NUMBER_1">%d</xliff:g> تلاش دیگر باقی مانده است و پس از آن سیمکارت برای همیشه غیرقابلاستفاده میشود. برای اطلاع از جزئیات با شرکت مخابراتی تماس بگیرید.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ساعت:"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"دوازده"</item> <item msgid="7389464214252023751">"یک"</item> diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml index 60923722fa56..ec3c596f31bf 100644 --- a/packages/SystemUI/res-keyguard/values-fi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM-kortti on nyt lukittu. Anna PUK-koodi, niin voit jatkaa. Sinulla on <xliff:g id="_NUMBER_1">%d</xliff:g> yritystä jäljellä, ennen kuin SIM-kortti poistuu pysyvästi käytöstä. Pyydä lisätietoja operaattoriltasi.</item> <item quantity="one">SIM-kortti on nyt lukittu. Anna PUK-koodi, niin voit jatkaa. Sinulla on <xliff:g id="_NUMBER_0">%d</xliff:g> yritys jäljellä, ennen kuin SIM-kortti poistuu pysyvästi käytöstä. Pyydä lisätietoja operaattoriltasi.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Kello on"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Kaksitoista"</item> <item msgid="7389464214252023751">"Yksi"</item> diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml index 8e92ffc91db6..73705c876091 100644 --- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM devienne définitivement inutilisable. Pour obtenir plus de détails, communiquez avec votre fournisseur de services.</item> <item quantity="other">La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM devienne définitivement inutilisable. Pour obtenir plus de détails, communiquez avec votre fournisseur de services.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Il est"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"douze h."</item> <item msgid="7389464214252023751">"Une h."</item> diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml index cde5e682224f..cf4f2d001d83 100644 --- a/packages/SystemUI/res-keyguard/values-fr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM ne devienne définitivement inutilisable. Pour de plus amples informations, veuillez contacter votre opérateur.</item> <item quantity="other">La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne devienne définitivement inutilisable. Pour de plus amples informations, veuillez contacter votre opérateur.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Il est"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"douze heures"</item> <item msgid="7389464214252023751">"une heure"</item> diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml index 6d85cdba5ce3..810a75ba034b 100644 --- a/packages/SystemUI/res-keyguard/values-gl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">A SIM está desactivada. Introduce o código PUK para continuar. Quédanche <xliff:g id="_NUMBER_1">%d</xliff:g> intentos antes de que a SIM quede inutilizable para sempre. Contacta co operador para obter información.</item> <item quantity="one">A SIM está desactivada. Introduce o código PUK para continuar. Quédache <xliff:g id="_NUMBER_0">%d</xliff:g> intento antes de que a SIM quede inutilizable para sempre. Contacta co operador para obter información.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Hora:"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Doce"</item> <item msgid="7389464214252023751">"Unha"</item> diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml index d9fdf03d4a17..538b10081a83 100644 --- a/packages/SystemUI/res-keyguard/values-gu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">સિમ હવે બંધ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાયમીરૂપે બિનઉપયોગી બની જાય એ પહેલાં તમારી પાસે <xliff:g id="_NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે. વિગતો માટે કૅરિઅરનો સંપર્ક કરો.</item> <item quantity="other">સિમ હવે બંધ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાયમીરૂપે બિનઉપયોગી બની જાય એ પહેલાં તમારી પાસે <xliff:g id="_NUMBER_1">%d</xliff:g> પ્રયાસો બાકી છે. વિગતો માટે કૅરિઅરનો સંપર્ક કરો.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"સમય છે"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"બાર"</item> <item msgid="7389464214252023751">"એક"</item> diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml index b004cdec4045..f03ddd44cb3b 100644 --- a/packages/SystemUI/res-keyguard/values-hi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास <xliff:g id="_NUMBER_1">%d</xliff:g> मौके बचे हैं, उसके बाद, सिम हमेशा के लिए काम करना बंद कर देगा. जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.</item> <item quantity="other">सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास <xliff:g id="_NUMBER_1">%d</xliff:g> मौके बचे हैं, उसके बाद, सिम हमेशा के लिए काम करना बंद कर देगा. जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"यह"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"बारह"</item> <item msgid="7389464214252023751">"एक"</item> diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml index c99b646b7682..28394538d8bb 100644 --- a/packages/SystemUI/res-keyguard/values-hr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml @@ -158,7 +158,7 @@ <item quantity="few">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.</item> <item quantity="other">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Sada je"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dvanaest"</item> <item msgid="7389464214252023751">"Jedan"</item> diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml index 4eb8bc886d0d..de22c02df0df 100644 --- a/packages/SystemUI/res-keyguard/values-hu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. Még <xliff:g id="_NUMBER_1">%d</xliff:g> próbálkozása van, mielőtt végleg használhatatlanná válik a SIM-kártya. További információért forduljon a szolgáltatóhoz.</item> <item quantity="one">A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. Még <xliff:g id="_NUMBER_0">%d</xliff:g> próbálkozása van, mielőtt végleg használhatatlanná válik a SIM-kártya. További információért forduljon a szolgáltatóhoz.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Az idő:"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Tizenkettő"</item> <item msgid="7389464214252023751">"Egy"</item> diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml index 5d9a2c0c3fcf..2c104371faa5 100644 --- a/packages/SystemUI/res-keyguard/values-hy/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">SIM քարտն անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մնացել է <xliff:g id="_NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել: Մանրամասների համար դիմեք օպերատորին:</item> <item quantity="other">SIM քարտն անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մնացել է <xliff:g id="_NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել: Մանրամասների համար դիմեք օպերատորին:</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Ժամն է՝"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"տասներկու"</item> <item msgid="7389464214252023751">"մեկ"</item> diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml index 603b4c25e9d0..0cd138250fad 100644 --- a/packages/SystemUI/res-keyguard/values-in/strings.xml +++ b/packages/SystemUI/res-keyguard/values-in/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa <xliff:g id="_NUMBER_1">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.</item> <item quantity="one">SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa <xliff:g id="_NUMBER_0">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Pukul"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dua Belas"</item> <item msgid="7389464214252023751">"Satu"</item> diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml index 71f2078a6010..dd9785d976a4 100644 --- a/packages/SystemUI/res-keyguard/values-is/strings.xml +++ b/packages/SystemUI/res-keyguard/values-is/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Það er <xliff:g id="_NUMBER_1">%d</xliff:g> tilraun eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.</item> <item quantity="other">SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Það eru <xliff:g id="_NUMBER_1">%d</xliff:g> tilraunir eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Hún er"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Tólf"</item> <item msgid="7389464214252023751">"Eitt"</item> diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml index e0b55b37fe23..ac2375fd8c34 100644 --- a/packages/SystemUI/res-keyguard/values-it/strings.xml +++ b/packages/SystemUI/res-keyguard/values-it/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">La scheda SIM è ora disattivata. Inserisci il codice PUK per continuare. Hai ancora <xliff:g id="_NUMBER_1">%d</xliff:g> tentativi a disposizione prima che la SIM diventi definitivamente inutilizzabile. Per informazioni dettagliate, contatta l\'operatore.</item> <item quantity="one">La scheda SIM è ora disattivata. Inserisci il codice PUK per continuare. Hai ancora <xliff:g id="_NUMBER_0">%d</xliff:g> tentativo a disposizione prima che la SIM diventi definitivamente inutilizzabile. Per informazioni dettagliate, contatta l\'operatore.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Ora"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dodici"</item> <item msgid="7389464214252023751">"Una"</item> diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml index 509c4637ab92..0fadaffa5c9e 100644 --- a/packages/SystemUI/res-keyguard/values-iw/strings.xml +++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml @@ -166,7 +166,7 @@ <item quantity="other">כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותרו לך <xliff:g id="_NUMBER_1">%d</xliff:g> ניסיונות נוספים לפני שכרטיס ה-SIM ינעל לצמיתות. למידע נוסף, ניתן לפנות לספק שלך.</item> <item quantity="one">כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותר לך <xliff:g id="_NUMBER_0">%d</xliff:g> ניסיון נוסף לפני שכרטיס ה-SIM ינעל לצמיתות. למידע נוסף, ניתן לפנות לספק שלך.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"השעה"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"שתים-עשרה"</item> <item msgid="7389464214252023751">"אחת"</item> diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml index 343d557e50c7..b0514ef4d741 100644 --- a/packages/SystemUI/res-keyguard/values-ja/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM が無効になりました。続行するには PUK コードを入力してください。入力できるのはあと <xliff:g id="_NUMBER_1">%d</xliff:g> 回です。この回数を超えると SIM は完全に使用できなくなります。詳しくは携帯通信会社にお問い合わせください。</item> <item quantity="one">SIM が無効になりました。続行するには PUK コードを入力してください。入力できるのはあと <xliff:g id="_NUMBER_0">%d</xliff:g> 回です。この回数を超えると SIM は完全に使用できなくなります。詳しくは携帯通信会社にお問い合わせください。</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"時刻:"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"12"</item> <item msgid="7389464214252023751">"1"</item> diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml index 9118e5666d5b..9290874557df 100644 --- a/packages/SystemUI/res-keyguard/values-ka/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. თქვენ დაგრჩათ <xliff:g id="_NUMBER_1">%d</xliff:g> მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდება. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს.</item> <item quantity="one">SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. თქვენ დაგრჩათ <xliff:g id="_NUMBER_0">%d</xliff:g> მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდება. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ახლაა"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"თორმეტი"</item> <item msgid="7389464214252023751">"ერთი"</item> diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml index 2270c92da0aa..f1d64499ac45 100644 --- a/packages/SystemUI/res-keyguard/values-kk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. <xliff:g id="_NUMBER_1">%d</xliff:g> мүмкіндік қалды, одан кейін SIM картасы біржола құлыпталады. Толығырақ мәліметті оператордан алыңыз.</item> <item quantity="one">SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. <xliff:g id="_NUMBER_0">%d</xliff:g> мүмкіндік қалды, одан кейін SIM картасы біржола құлыпталады. Толығырақ мәліметті оператордан алыңыз.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Қазір"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Он екі"</item> <item msgid="7389464214252023751">"Бір"</item> diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml index 80b124ad47de..f4795b6e79dd 100644 --- a/packages/SystemUI/res-keyguard/values-km/strings.xml +++ b/packages/SystemUI/res-keyguard/values-km/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">ឥឡូវនេះស៊ីមត្រូវបានបិទ។ សូមបញ្ចូលកូដ PUK ដើម្បីបន្ត។ អ្នកនៅសល់ការព្យាយាម <xliff:g id="_NUMBER_1">%d</xliff:g> ដងទៀតមុនពេលស៊ីមមិនអាចប្រើបានជាអចិន្ត្រៃយ៍។ ទាក់ទងទៅក្រុមហ៊ុនសេវាទូរសព្ទសម្រាប់ព័ត៌មានលម្អិត។</item> <item quantity="one">ឥឡូវនេះស៊ីមត្រូវបានបិទ។ សូមបញ្ចូលកូដ PUK ដើម្បីបន្ត។ អ្នកនៅសល់ការព្យាយាម <xliff:g id="_NUMBER_0">%d</xliff:g> ដងទៀតមុនពេលស៊ីមមិនអាចប្រើបានជាអចិន្ត្រៃយ៍។ ទាក់ទងទៅក្រុមហ៊ុនសេវាទូរសព្ទសម្រាប់ព័ត៌មានលម្អិត។</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"វាជា"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"ដប់ពីរ"</item> <item msgid="7389464214252023751">"មួយ"</item> diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml index f48d6060b2a6..6f83dde04176 100644 --- a/packages/SystemUI/res-keyguard/values-kn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">ಸಿಮ್ ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ <xliff:g id="_NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.</item> <item quantity="other">ಸಿಮ್ ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ <xliff:g id="_NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ಇದು"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"ಹನ್ನೆರಡು"</item> <item msgid="7389464214252023751">"ಒಂದು"</item> diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml index 046600911eae..1651be742a3d 100644 --- a/packages/SystemUI/res-keyguard/values-ko/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. <xliff:g id="_NUMBER_1">%d</xliff:g>번 더 실패하면 SIM을 완전히 사용할 수 없게 됩니다. 자세한 내용은 이동통신사에 문의하세요.</item> <item quantity="one">SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. <xliff:g id="_NUMBER_0">%d</xliff:g>번 더 실패하면 SIM을 완전히 사용할 수 없게 됩니다. 자세한 내용은 이동통신사에 문의하세요.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"현재 시각:"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"열두 시"</item> <item msgid="7389464214252023751">"한 시"</item> diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml index eca9b2214b96..6d0f2ff635dd 100644 --- a/packages/SystemUI/res-keyguard/values-ky/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгарына <xliff:g id="_NUMBER_1">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item> <item quantity="one">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгаарына <xliff:g id="_NUMBER_0">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Саат"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Он эки"</item> <item msgid="7389464214252023751">"Бир"</item> diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml index bd6e53df924b..23f179e049d4 100644 --- a/packages/SystemUI/res-keyguard/values-lo/strings.xml +++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">ຕອນນີ້ປິດການນຳໃຊ້ SIM ແລ້ວ. ໃສ່ລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="_NUMBER_1">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ. ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ.</item> <item quantity="one">ຕອນນີ້ປິດການນຳໃຊ້ SIM ແລ້ວ. ໃສ່ລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="_NUMBER_0">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ. ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ມັນແມ່ນ"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"ສິບສອງ"</item> <item msgid="7389464214252023751">"ໜຶ່ງ"</item> diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml index 6df93d8d4838..9e4d169129bc 100644 --- a/packages/SystemUI/res-keyguard/values-lt/strings.xml +++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml @@ -166,7 +166,7 @@ <item quantity="many">SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko <xliff:g id="_NUMBER_1">%d</xliff:g> bandymo. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.</item> <item quantity="other">SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko <xliff:g id="_NUMBER_1">%d</xliff:g> bandymų. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Dabar"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dvylika"</item> <item msgid="7389464214252023751">"Pirma"</item> diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml index d9061763e083..9ea4143f2e6e 100644 --- a/packages/SystemUI/res-keyguard/values-lv/strings.xml +++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml @@ -158,7 +158,7 @@ <item quantity="one">SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl <xliff:g id="_NUMBER_1">%d</xliff:g> reizi. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.</item> <item quantity="other">SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl <xliff:g id="_NUMBER_1">%d</xliff:g> reizes. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Laiks:"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Divpadsmit"</item> <item msgid="7389464214252023751">"Viens"</item> diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml index 221b99748291..e48b93d4fb46 100644 --- a/packages/SystemUI/res-keyguard/values-mk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостанува уште <xliff:g id="_NUMBER_1">%d</xliff:g> обид пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.</item> <item quantity="other">SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостануваат уште <xliff:g id="_NUMBER_1">%d</xliff:g> обиди пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Сега е"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Дванаесет"</item> <item msgid="7389464214252023751">"Еден"</item> diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml index e6642884b343..37ce00710b3f 100644 --- a/packages/SystemUI/res-keyguard/values-ml/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി <xliff:g id="_NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു. വിശദാംശങ്ങൾക്ക് കാരിയറുമായി ബന്ധപ്പെടുക.</item> <item quantity="one">സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി <xliff:g id="_NUMBER_0">%d</xliff:g> ശ്രമം കൂടി ശേഷിക്കുന്നു. വിശദാംശങ്ങൾക്ക് കാരിയറുമായി ബന്ധപ്പെടുക.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"സമയം"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"പന്ത്രണ്ട്"</item> <item msgid="7389464214252023751">"ഒന്ന്"</item> diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml index e4187316143a..86da6889249a 100644 --- a/packages/SystemUI/res-keyguard/values-mn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM-г идэвхгүй болголоо. Үргэлжлүүлэхийн тулд PUK кодыг оруулна уу. Таны SIM бүрмөсөн хүчингүй болох хүртэл <xliff:g id="_NUMBER_1">%d</xliff:g> оролдлого үлдлээ. Дэлгэрэнгүй мэдээлэл авахын тулд оператор компанитайгаа холбогдоно уу.</item> <item quantity="one">SIM-г идэвхгүй болголоо. Үргэлжлүүлэхийн тулд PUK кодыг оруулна уу. Таны SIM бүрмөсөн хүчингүй болох хүртэл <xliff:g id="_NUMBER_0">%d</xliff:g> оролдлого үлдлээ. Дэлгэрэнгүй мэдээлэл авахын тулд оператор компанитайгаа холбогдоно уу.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Одоо"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Арван хоёр"</item> <item msgid="7389464214252023751">"Нэг"</item> diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml index 9d83e93b5e68..ea0c0bb7737d 100644 --- a/packages/SystemUI/res-keyguard/values-mr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">सिम आता बंद केलेले आहे. सुरू ठेवण्यासाठी PUK कोड टाका. सिम कायमचे बंद होण्याआधी तुमच्याकडे <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहे. तपशीलांसाठी वाहकाशी संपर्क साधा.</item> <item quantity="other">सिम आता बंद केलेले आहे. सुरू ठेवण्यासाठी PUK कोड टाका. सिम कायमचे बंद होण्याआधी तुमच्याकडे <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत. तपशीलांसाठी वाहकाशी संपर्क साधा.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"हे आहे"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"बारा"</item> <item msgid="7389464214252023751">"एक"</item> diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml index 1c82f7c1bda6..03dca91c5d4e 100644 --- a/packages/SystemUI/res-keyguard/values-ms/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Tinggal <xliff:g id="_NUMBER_1">%d</xliff:g> percubaan sebelum SIM tidak boleh digunakan secara kekal. Hubungi pembawa untuk mendapatkan butiran.</item> <item quantity="one">Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Tinggal <xliff:g id="_NUMBER_0">%d</xliff:g> percubaan sebelum SIM tidak boleh digunakan secara kekal. Hubungi pembawa untuk mendapatkan butiran.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Pukul"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dua bls"</item> <item msgid="7389464214252023751">"Satu"</item> diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml index efdd779beae6..a468a852d787 100644 --- a/packages/SystemUI/res-keyguard/values-my/strings.xml +++ b/packages/SystemUI/res-keyguard/values-my/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">ဆင်းမ်ကဒ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ်ကဒ် အပြီးပိတ်မသွားမီ သင့်တွင် <xliff:g id="_NUMBER_1">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့် ကျန်ပါသေးသည်။ အသေးစိတ်အချက်များအတွက် ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ပါ။</item> <item quantity="one">ဆင်းမ်ကဒ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ်ကဒ် အပြီးပိတ်မသွားမီ သင့်တွင် <xliff:g id="_NUMBER_0">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့် ကျန်ပါသေးသည်။ အသေးစိတ်အချက်များအတွက် ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ပါ။</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ယခု"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"ဆယ့်နှစ်"</item> <item msgid="7389464214252023751">"တစ်"</item> diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml index 17704c4402d2..fcf06eb7b543 100644 --- a/packages/SystemUI/res-keyguard/values-nb/strings.xml +++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM-kortet er deaktivert nå. Skriv inn PUK-koden for å fortsette. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig. Kontakt operatøren for å få vite mer.</item> <item quantity="one">SIM-kortet er deaktivert nå. Skriv inn PUK-koden for å fortsette. Du har <xliff:g id="_NUMBER_0">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig. Kontakt operatøren for å få vite mer.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Klokken"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Tolv"</item> <item msgid="7389464214252023751">"Ett"</item> diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml index 77bc11337672..c3d92ab18a15 100644 --- a/packages/SystemUI/res-keyguard/values-ne/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयासहरू बाँकी छन्, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item> <item quantity="one">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"समय:"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"बाह्र"</item> <item msgid="7389464214252023751">"एक"</item> diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml index 3bbbb53e2a6b..b3d65bb7e9b4 100644 --- a/packages/SystemUI/res-keyguard/values-nl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item> <item quantity="one">De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_0">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Het is"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Twaalf"</item> <item msgid="7389464214252023751">"Eén"</item> diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml index 0db20aa6881a..94c42c4ccf79 100644 --- a/packages/SystemUI/res-keyguard/values-or/strings.xml +++ b/packages/SystemUI/res-keyguard/values-or/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM କାର୍ଡକୁ ବର୍ତ୍ତମାନ ଅକ୍ଷମ କରିଦିଆଯାଇଛି। ଜାରି ରଖିବାକୁ PUK କୋଡ୍ ଲେଖନ୍ତୁ। ଆଉ <xliff:g id="_NUMBER_1">%d</xliff:g> ଥର ଭୁଲ କୋଡ୍ ଲେଖିବା ପରେ SIM କାର୍ଡ ସ୍ଥାୟୀ ଭାବେ ଅନୁପଯୋଗୀ ହୋଇଯିବ। ବିବରଣୀ ପାଇଁ କେରିଅର୍ର ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।</item> <item quantity="one">SIM କାର୍ଡକୁ ବର୍ତ୍ତମାନ ଅକ୍ଷମ କରିଦିଆଯାଇଛି। ଜାରି ରଖିବାକୁ PUK କୋଡ୍ ଲେଖନ୍ତୁ। ଆଉ <xliff:g id="_NUMBER_0">%d</xliff:g> ଥର ଭୁଲ କୋଡ୍ ଲେଖିବା ପରେ SIM କାର୍ଡ ସ୍ଥାୟୀ ଭାବେ ଅନୁପଯୋଗୀ ହୋଇଯିବ। ବିବରଣୀ ପାଇଁ କେରିଅର୍ର ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ଏବେ"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"ବାର"</item> <item msgid="7389464214252023751">"ଏକ"</item> diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml index 9fd9b197c25e..9b4e28d36ecc 100644 --- a/packages/SystemUI/res-keyguard/values-pa/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item> <item quantity="other">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ਸਮਾਂ"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"ਬਾਰਾਂ"</item> <item msgid="7389464214252023751">"ਇੱਕ"</item> diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml index 106fab363270..229443089359 100644 --- a/packages/SystemUI/res-keyguard/values-pl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml @@ -166,7 +166,7 @@ <item quantity="other">Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Masz jeszcze <xliff:g id="_NUMBER_1">%d</xliff:g> próby, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.</item> <item quantity="one">Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Masz jeszcze <xliff:g id="_NUMBER_0">%d</xliff:g> próbę, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Jest"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dwanaście"</item> <item msgid="7389464214252023751">"Jeden"</item> diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml index 3c6a37252ba0..56815ca95d19 100644 --- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativa restante antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item> <item quantity="other">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas restantes antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"São"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Doze"</item> <item msgid="7389464214252023751">"Uma"</item> diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml index 4f601878e958..4e09dc79d237 100644 --- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">O SIM encontra-se desativado. Introduza o código PUK para continuar. Tem mais <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar permanentemente inutilizável. Contacte o operador para obter mais detalhes.</item> <item quantity="one">O SIM encontra-se desativado. Introduza o código PUK para continuar. Tem mais <xliff:g id="_NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar permanentemente inutilizável. Contacte o operador para obter mais detalhes.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"São"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Doze"</item> <item msgid="7389464214252023751">"Google One"</item> diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml index 3c6a37252ba0..56815ca95d19 100644 --- a/packages/SystemUI/res-keyguard/values-pt/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativa restante antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item> <item quantity="other">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas restantes antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"São"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Doze"</item> <item msgid="7389464214252023751">"Uma"</item> diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml index 9e4170ec3d6b..23be62ca44f1 100644 --- a/packages/SystemUI/res-keyguard/values-ro/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml @@ -158,7 +158,7 @@ <item quantity="other">Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-au mai rămas <xliff:g id="_NUMBER_1">%d</xliff:g> de încercări până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.</item> <item quantity="one">Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-a mai rămas <xliff:g id="_NUMBER_0">%d</xliff:g> încercare până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Este"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Douăsprezece"</item> <item msgid="7389464214252023751">"Unu"</item> diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml index dd9bc6a80e4d..f093748d852d 100644 --- a/packages/SystemUI/res-keyguard/values-ru/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml @@ -166,7 +166,7 @@ <item quantity="many">SIM-карта отключена. Чтобы продолжить, введите PUK-код. Осталось <xliff:g id="_NUMBER_1">%d</xliff:g> попыток. После этого SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.</item> <item quantity="other">SIM-карта отключена. Чтобы продолжить, введите PUK-код. Осталось <xliff:g id="_NUMBER_1">%d</xliff:g> попытки. После этого SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Сейчас"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"двенадцать"</item> <item msgid="7389464214252023751">"один"</item> diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml index 59d2a067bd40..17122a575612 100644 --- a/packages/SystemUI/res-keyguard/values-si/strings.xml +++ b/packages/SystemUI/res-keyguard/values-si/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">SIM දැන් අබල කර ඇත. දිගටම කරගෙන යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව උත්සාහයන් <xliff:g id="_NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත. විස්තර සඳහා වාහක සම්බන්ධ කර ගන්න.</item> <item quantity="other">SIM දැන් අබල කර ඇත. දිගටම කරගෙන යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව උත්සාහයන් <xliff:g id="_NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත. විස්තර සඳහා වාහක සම්බන්ධ කර ගන්න.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ඒ"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"දොළහ"</item> <item msgid="7389464214252023751">"එක"</item> diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml index 0cd5f78ece65..c9919033af61 100644 --- a/packages/SystemUI/res-keyguard/values-sk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml @@ -166,7 +166,7 @@ <item quantity="other">SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám <xliff:g id="_NUMBER_1">%d</xliff:g> pokusov, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.</item> <item quantity="one">SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám <xliff:g id="_NUMBER_0">%d</xliff:g> pokus, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Práve je"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dvanásť"</item> <item msgid="7389464214252023751">"Jedna"</item> diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml index 52b9d6020ddb..1aba2aae2c71 100644 --- a/packages/SystemUI/res-keyguard/values-sl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml @@ -166,7 +166,7 @@ <item quantity="few">Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še <xliff:g id="_NUMBER_1">%d</xliff:g> poskuse. Potem bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.</item> <item quantity="other">Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še <xliff:g id="_NUMBER_1">%d</xliff:g> poskusov. Potem bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Ura je"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dvanajst"</item> <item msgid="7389464214252023751">"Ena"</item> diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml index 1dfb8fd8b1db..29819e22df88 100644 --- a/packages/SystemUI/res-keyguard/values-sq/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">Karta SIM tani është çaktivizuar. Fut kodin PUK për të vazhduar. Të kanë mbetur edhe <xliff:g id="_NUMBER_1">%d</xliff:g> përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme. Kontakto me operatorin për detaje.</item> <item quantity="one">Karta SIM tani është çaktivizuar. Fut kodin PUK për të vazhduar. Të ka mbetur edhe <xliff:g id="_NUMBER_0">%d</xliff:g> përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme. Kontakto me operatorin për detaje.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Ora është"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Dymbëdhjetë"</item> <item msgid="7389464214252023751">"Një"</item> diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml index 7bb41e9767fb..d572f9692ac7 100644 --- a/packages/SystemUI/res-keyguard/values-sr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml @@ -158,7 +158,7 @@ <item quantity="few">SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још <xliff:g id="_NUMBER_1">%d</xliff:g> покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.</item> <item quantity="other">SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још <xliff:g id="_NUMBER_1">%d</xliff:g> покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Сада је"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"дванаест"</item> <item msgid="7389464214252023751">"један"</item> diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml index 2475dc1c72b8..6608addcfb19 100644 --- a/packages/SystemUI/res-keyguard/values-sv/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM-kortet är inaktiverat. Ange PUK-koden om du vill fortsätta. <xliff:g id="_NUMBER_1">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart. Kontakta operatören för mer information.</item> <item quantity="one">SIM-kortet är inaktiverat. Ange PUK-koden om du vill fortsätta. <xliff:g id="_NUMBER_0">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart. Kontakta operatören för mer information.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Hon är"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Tolv"</item> <item msgid="7389464214252023751">"En"</item> diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml index 0a1acf2f577b..102db535e5d4 100644 --- a/packages/SystemUI/res-keyguard/values-sw/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">Sasa SIM imefungwa. Weka msimbo wa PUK ili uendelee. Umesalia na majaribio <xliff:g id="_NUMBER_1">%d</xliff:g> kabla ya SIM kuacha kufanya kazi kabisa. Wasiliana na mtoa huduma kwa maelezo.</item> <item quantity="one">Sasa SIM imefungwa. Weka msimbo wa PUK ili uendelee. Umesalia na jaribio <xliff:g id="_NUMBER_0">%d</xliff:g> kabla ya SIM kuacha kufanya kazi kabisa. Wasiliana na mtoa huduma kwa maelezo.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Ni saa"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Sita"</item> <item msgid="7389464214252023751">"Saba"</item> diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml index 57a614a0cfa6..009fb2da2e98 100644 --- a/packages/SystemUI/res-keyguard/values-ta/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_1">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item> <item quantity="one">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_0">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"அதன்"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"பன்னிரண்டு"</item> <item msgid="7389464214252023751">"ஒன்று"</item> diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml index 58880c45cb76..8f4000f84615 100644 --- a/packages/SystemUI/res-keyguard/values-te/strings.xml +++ b/packages/SystemUI/res-keyguard/values-te/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి. వివరాల కోసం కారియర్ను సంప్రదించండి.</item> <item quantity="one">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది వివరాల కోసం కారియర్ను సంప్రదించండి.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"ఇప్పుడు"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"పన్నెండు"</item> <item msgid="7389464214252023751">"ఒకటి"</item> diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml index bb52a7f2bdef..bb58e2092721 100644 --- a/packages/SystemUI/res-keyguard/values-th/strings.xml +++ b/packages/SystemUI/res-keyguard/values-th/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">ซิมถูกปิดใช้งานในขณะนี้ โปรดป้อนรหัส PUK เพื่อทำต่อ คุณพยายามได้อีก <xliff:g id="_NUMBER_1">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร โปรดติดต่อสอบถามรายละเอียดจากผู้ให้บริการ</item> <item quantity="one">ซิมถูกปิดใช้งานในขณะนี้ โปรดป้อนรหัส PUK เพื่อทำต่อ คุณพยายามได้อีก <xliff:g id="_NUMBER_0">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร โปรดติดต่อสอบถามรายละเอียดจากผู้ให้บริการ</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"เวลา"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"สิบสอง"</item> <item msgid="7389464214252023751">"หนึ่ง"</item> diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml index 1f480f40379f..ec7b924969a3 100644 --- a/packages/SystemUI/res-keyguard/values-tl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">Naka-disable na ang SIM. Ilagay ang PUK code upang magpatuloy. Mayroon kang <xliff:g id="_NUMBER_1">%d</xliff:g> natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.</item> <item quantity="other">Naka-disable na ang SIM. Ilagay ang PUK code upang magpatuloy. Mayroon kang <xliff:g id="_NUMBER_1">%d</xliff:g> na natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Oras ay"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Twelve"</item> <item msgid="7389464214252023751">"One"</item> diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml index 8ff1d88ee83a..92b3fb37d6f7 100644 --- a/packages/SystemUI/res-keyguard/values-tr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM artık devre dışı. Devam etmek için PUK kodunu girin. SIM kalıcı olarak kullanım dışı kalmadan önce <xliff:g id="_NUMBER_1">%d</xliff:g> deneme hakkınız kaldı. Ayrıntılı bilgi için operatörünüzle iletişim kurun.</item> <item quantity="one">SIM artık devre dışı. Devam etmek için PUK kodunu girin. SIM kalıcı olarak kullanım dışı kalmadan önce <xliff:g id="_NUMBER_0">%d</xliff:g> deneme hakkınız kaldı. Ayrıntılı bilgi için operatörünüzle iletişim kurun.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Saat"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"On İki"</item> <item msgid="7389464214252023751">"Bir"</item> diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml index 3f0982fe5d47..2772d0738334 100644 --- a/packages/SystemUI/res-keyguard/values-uk/strings.xml +++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml @@ -166,7 +166,7 @@ <item quantity="many">SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. Залишилося <xliff:g id="_NUMBER_1">%d</xliff:g> спроб. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.</item> <item quantity="other">SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. Залишилося <xliff:g id="_NUMBER_1">%d</xliff:g> спроби. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Зараз"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"дванадцята"</item> <item msgid="7389464214252023751">"перша"</item> diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml index 3c520f955b93..e9e67097cfa8 100644 --- a/packages/SystemUI/res-keyguard/values-ur/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس <xliff:g id="_NUMBER_1">%d</xliff:g> کوششیں بچی ہیں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔</item> <item quantity="one">SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس <xliff:g id="_NUMBER_0">%d</xliff:g> کوشش بچی ہے۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"وقت/ابھی"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"بارہ"</item> <item msgid="7389464214252023751">"ایک"</item> diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml index 640a98760f2f..676f7bb97de6 100644 --- a/packages/SystemUI/res-keyguard/values-uz/strings.xml +++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml @@ -152,7 +152,7 @@ <item quantity="other">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_1">%d</xliff:g> marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item> <item quantity="one">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_0">%d</xliff:g> marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Hozir"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Oʻn ikki"</item> <item msgid="7389464214252023751">"Bir"</item> diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml index 2a62fb878231..f2cfb2a2a23e 100644 --- a/packages/SystemUI/res-keyguard/values-vi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM hiện đã bị tắt. Hãy nhập mã PUK để tiếp tục. Bạn còn <xliff:g id="_NUMBER_1">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ để biết chi tiết.</item> <item quantity="one">SIM hiện đã bị tắt. Hãy nhập mã PUK để tiếp tục. Bạn còn <xliff:g id="_NUMBER_0">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không thể sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ để biết chi tiết.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Hiện là"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Mười hai"</item> <item msgid="7389464214252023751">"Một"</item> diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml index 80fac9030fe0..efa5fc35ff1c 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM 卡现已停用,请输入 PUK 码继续使用。您还可以尝试 <xliff:g id="_NUMBER_1">%d</xliff:g> 次。如果仍不正确,该 SIM 卡将永远无法使用。有关详情,请联系您的运营商。</item> <item quantity="one">SIM 卡现已停用,请输入 PUK 码继续使用。您还可以尝试 <xliff:g id="_NUMBER_0">%d</xliff:g> 次。如果仍不正确,该 SIM 卡将永远无法使用。有关详情,请联系您的运营商。</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"时间是"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"十二"</item> <item msgid="7389464214252023751">"一"</item> diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml index 926d601ebb5a..eeff66acd9a8 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 <xliff:g id="_NUMBER_1">%d</xliff:g> 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請與流動網絡供應商聯絡。</item> <item quantity="one">SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 <xliff:g id="_NUMBER_0">%d</xliff:g> 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請與流動網絡供應商聯絡。</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"現在是"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"十二"</item> <item msgid="7389464214252023751">"一"</item> diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml index 728f1a97996f..961ef39f3809 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml @@ -150,7 +150,7 @@ <item quantity="other">SIM 卡現在已遭停用。請輸入 PUK 碼以繼續進行。你還可以再試 <xliff:g id="_NUMBER_1">%d</xliff:g> 次,如果仍然失敗,SIM 卡將永久無法使用。詳情請與電信業者聯絡。</item> <item quantity="one">SIM 卡現在已遭停用。請輸入 PUK 碼以繼續進行。你還可以再試 <xliff:g id="_NUMBER_0">%d</xliff:g> 次,如果仍然失敗,SIM 卡將永久無法使用。詳情請與電信業者聯絡。</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"時間是"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"十二"</item> <item msgid="7389464214252023751">"一"</item> diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml index 7e0a03c02c94..2e948b485276 100644 --- a/packages/SystemUI/res-keyguard/values-zu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml @@ -150,7 +150,7 @@ <item quantity="one">I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unemizamo engu-<xliff:g id="_NUMBER_1">%d</xliff:g> esele ngaphambi kokuthi i-SIM ingasebenziseki unaphakade. Xhumana nenkampani yenethiwekhi ngemininingwane.</item> <item quantity="other">I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unemizamo engu-<xliff:g id="_NUMBER_1">%d</xliff:g> esele ngaphambi kokuthi i-SIM ingasebenziseki unaphakade. Xhumana nenkampani yenethiwekhi ngemininingwane.</item> </plurals> - <string name="type_clock_header" msgid="4786545441902447636">"Kuyi-"</string> + <!-- no translation found for type_clock_header (6782840450655632763) --> <string-array name="type_clock_hours"> <item msgid="3543074812389379830">"Ishumi nambili"</item> <item msgid="7389464214252023751">"Kunye"</item> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 053371a0e527..9b765f824859 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> program gebruik jou <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Het dit"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privaatheidsinstellings"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Program wat jou <xliff:g id="TYPES_LIST">%s</xliff:g> gebruik"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Programme wat jou <xliff:g id="TYPES_LIST">%s</xliff:g> gebruik"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors is af"</string> <string name="device_services" msgid="1191212554435440592">"Toesteldienste"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Titelloos"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Maak <xliff:g id="APP_NAME">%1$s</xliff:g> oop"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Maak kennisgewinginstellings oop vir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 8acd1b832ed3..d12ba4ca08a4 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -879,8 +879,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> መተግበሪያዎች የእርስዎን <xliff:g id="TYPE_5">%2$s</xliff:g> እየተጠቀሙ ነው።</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"ገባኝ"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"የግላዊነት ቅንብሮች"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"የእርስዎን <xliff:g id="TYPES_LIST">%s</xliff:g> የሚጠቀሙ መተግበሪያዎች"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"የእርስዎን <xliff:g id="TYPES_LIST">%s</xliff:g> የሚጠቀሙ መተግበሪያዎች"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"፣ "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"ዳሳሾች ጠፍተዋል"</string> <string name="device_services" msgid="1191212554435440592">"የመሣሪያ አገልግሎቶች"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"ርዕስ የለም"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> ክፈት"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"የማስታወቂያ ቅንብሮች ለ <xliff:g id="APP_NAME">%1$s</xliff:g> ክፈት"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 0312adf36f23..7c08783e365d 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -907,8 +907,7 @@ <item quantity="one">هناك تطبيق واحد (<xliff:g id="NUM_APPS_0">%1$d</xliff:g>) يستخدِم <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"حسنًا"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"إعدادات الخصوصية"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"التطبيق الذي يستخدِم <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"التطبيقات التي تستخدِم <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"، "</string> @@ -927,8 +926,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"إيقاف أجهزة الاستشعار"</string> <string name="device_services" msgid="1191212554435440592">"خدمات الأجهزة"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"بلا عنوان"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"فتح <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"فتح إعدادات الإشعارات في <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index fbaad96d0454..c782d1be3da9 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 70608a17531d..896fe3408235 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> tətbiq <xliff:g id="TYPE_1">%2$s</xliff:g> tətbiqindən istifadə edir.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Anladım"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Məxfilik ayarları"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"<xliff:g id="TYPES_LIST">%s</xliff:g> tətbiqindən istifadə edən tətbiq"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"<xliff:g id="TYPES_LIST">%s</xliff:g> tətbiqindən istifadə edən tətbiqlər"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensorlar deaktivdir"</string> <string name="device_services" msgid="1191212554435440592">"Cihaz Xidmətləri"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Başlıq yoxdur"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqini açın"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün bildiriş ayarlarını açın"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 8a754f3425fc..14ab0a4422b0 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -886,8 +886,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplikacija koristi dozvolu <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Važi"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Podešav. privatnosti"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplikacija koja koristi dozvole <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplikacije koje koriste dozvole <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -903,8 +902,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzori su isključeni"</string> <string name="device_services" msgid="1191212554435440592">"Usluge za uređaje"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Bez naslova"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Otvorite <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Otvorite podešavanja obaveštenja za <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 3390fcbf8ad7..0e724fa02954 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -917,4 +917,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 00454ddda7e3..c44b3ad957ee 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> приложение използва <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Разбрах"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Поверит.: Настройки"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Приложение, което използва <xliff:g id="TYPES_LIST">%s</xliff:g> ви"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Приложения, които използват <xliff:g id="TYPES_LIST">%s</xliff:g> ви"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Сензорите са изключени"</string> <string name="device_services" msgid="1191212554435440592">"Услуги за устройството"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Няма заглавие"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Отваряне на „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Отваряне на настройките за известията за „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index b864206c6084..ec7ff6d7d110 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index d1528316b0ae..77069b2c4e2b 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -888,8 +888,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplikacija koristi <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Razumijem"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Postavke privatnosti"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplikacija koristi odobrenja <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplikacije koriste odobrenja <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -905,8 +904,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzori su isključeni"</string> <string name="device_services" msgid="1191212554435440592">"Usluge uređaja"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Bez naslova"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Otvorite aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Otvorite postavke obavijesti za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index f41ea3cd5b83..1c52610722cb 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 4bdc271df52b..735b476a4583 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -915,4 +915,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 0c3c253434da..615338dbcef3 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -879,8 +879,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> apps anvender din/dit <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privatlivsindstill."</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App, der anvender din/dit <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps, der anvender din/dit <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Deaktiver sensorer"</string> <string name="device_services" msgid="1191212554435440592">"Enhedstjenester"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Ingen titel"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Åbn <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Åbn notifikationsindstillingerne for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index c21288dbfadc..4e2e1e134905 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -441,7 +441,7 @@ <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduzierung der Leistung und Hintergrunddaten"</string> <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Energiesparmodus deaktivieren"</string> <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> nimmt alle auf deinem Bildschirm angezeigten Aktivitäten auf."</string> - <string name="media_projection_remember_text" msgid="3103510882172746752">"Nicht erneut anzeigen"</string> + <string name="media_projection_remember_text" msgid="3103510882172746752">"Nicht mehr anzeigen"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Alle löschen"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Verwalten"</string> <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Benachrichtigungen durch \"Bitte nicht stören\" pausiert"</string> @@ -883,8 +883,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> App verwendet gerade: <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Datenschutzeinst."</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App, die <xliff:g id="TYPES_LIST">%s</xliff:g> verwendet"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps, die <xliff:g id="TYPES_LIST">%s</xliff:g> verwenden"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -899,8 +898,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensoren aus"</string> <string name="device_services" msgid="1191212554435440592">"Gerätedienste"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Kein Titel"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> öffnen"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Benachrichtigungseinstellungen für <xliff:g id="APP_NAME">%1$s</xliff:g> öffnen"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 23818956b18e..1a0df6bcbda3 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> εφαρμογή χρησιμοποιεί το <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Κατάλαβα"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Ρυθμίσεις απορρήτου"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Εφαρμογή που χρησιμοποιεί τις λειτουργίες <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Εφαρμογές που χρησιμοποιούν τις λειτουργίες <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Αισθητήρες ανενεργοί"</string> <string name="device_services" msgid="1191212554435440592">"Υπηρεσίες συσκευής"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Χωρίς τίτλο"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Άνοιγμα <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Άνοιγμα ρυθμίσεων ειδοποιήσεων για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 63f677319abd..95c1349b76e4 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> application is using your <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Got it"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privacy settings"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> <string name="device_services" msgid="1191212554435440592">"Device Services"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"No title"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Open <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Open notification settings for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index d6539e7bcd20..6d55c5a6227a 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> application is using your <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Got it"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privacy settings"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> <string name="device_services" msgid="1191212554435440592">"Device Services"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"No title"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Open <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Open notification settings for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 63f677319abd..95c1349b76e4 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> application is using your <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Got it"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privacy settings"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> <string name="device_services" msgid="1191212554435440592">"Device Services"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"No title"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Open <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Open notification settings for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 63f677319abd..95c1349b76e4 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> application is using your <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Got it"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privacy settings"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> <string name="device_services" msgid="1191212554435440592">"Device Services"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"No title"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Open <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Open notification settings for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 36ef6479415e..266faa85f960 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> application is using your <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Got it"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privacy settings"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps using your <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensors off"</string> <string name="device_services" msgid="1191212554435440592">"Device Services"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"No title"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Open <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Open notification settings for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 81cd300fa200..b1f7068b5876 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplicación está usando tu <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Entendido"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Config. privacidad"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Una app está usando tu <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps que están usando tu <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Se desactivaron los sensores"</string> <string name="device_services" msgid="1191212554435440592">"Servicios del dispositivo"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sin título"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Abrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Abrir la configuración de notificaciones de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 16c182b97d18..b1947fdc46b7 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index b02e45746eb6..8085224caaee 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> rakendus kasutab üksust <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Selge"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privaatsusseaded"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Rakendus, mis kasutab üksusi <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Rakendused, mis kasutavad üksusi <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Andurid on välja lülitatud"</string> <string name="device_services" msgid="1191212554435440592">"Seadme teenused"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Pealkiri puudub"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Ava <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Ava rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> märguandeseaded"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index b2d29c12faaf..7f9bffa37c8d 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplikazio ari da <xliff:g id="TYPE_1">%2$s</xliff:g> erabiltzen.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Ados"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Pribatutasun-ezarpenak"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"<xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari den aplikazioa"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"<xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari diren aplikazioak"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sentsoreak desaktibatuta daude"</string> <string name="device_services" msgid="1191212554435440592">"Gailuetarako zerbitzuak"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Ez du izenik"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Ireki <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Ireki <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren jakinarazpen-ezarpenak"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 4fb889bc2501..018d6d1fd0da 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -879,8 +879,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> برنامه درحال استفاده از <xliff:g id="TYPE_5">%2$s</xliff:g> شما است.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"متوجه شدم"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"تنظیمات حریم خصوصی"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"برنامهای که از <xliff:g id="TYPES_LIST">%s</xliff:g> شما استفاده میکند"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"برنامههایی که از <xliff:g id="TYPES_LIST">%s</xliff:g> شما استفاده میکنند"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"، "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"حسگرها خاموش است"</string> <string name="device_services" msgid="1191212554435440592">"سرویسهای دستگاه"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"بدون عنوان"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"باز کردن <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"تنظیمات اعلان <xliff:g id="APP_NAME">%1$s</xliff:g> را باز کنید"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 1ab48a0855d5..0258ccbf9332 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="TYPE_1">%2$s</xliff:g> on <xliff:g id="NUM_APPS_0">%1$d</xliff:g> sovelluksen käytössä.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Selvä"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Tietosuoja-asetukset"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Sovellus, jolla on <xliff:g id="TYPES_LIST">%s</xliff:g> ‑käyttöoikeus"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Sovellukset, joilla on <xliff:g id="TYPES_LIST">%s</xliff:g> ‑käyttöoikeus"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Anturit pois päältä"</string> <string name="device_services" msgid="1191212554435440592">"Laitepalvelut"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Ei nimeä"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Avaa <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Avaa ilmoitusasetukset (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 554a22253d93..a3a31356fcfc 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 2e4700059fa3..d1ce32e3a193 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 90b9f87a12af..d76c34a64042 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplicación utiliza o teu dispositivo (<xliff:g id="TYPE_1">%2$s</xliff:g>).</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"De acordo"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Config. privacidade"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplicación que utiliza o seguinte: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplicacións que utilizan o seguinte: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Desactivar sensores"</string> <string name="device_services" msgid="1191212554435440592">"Servizos do dispositivo"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sen título"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Abre a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Abre a configuración de notificacións para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 5717616b706d..c84051cc51bb 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 20b9198e6e21..157f55c9bede 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 79f410a87929..77c3ce3b47b8 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -886,8 +886,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplikacija upotrebljava <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Shvaćam"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Postavke privatnosti"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplikacije koje upotrebljavaju <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplikacije koje upotrebljavaju <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -903,8 +902,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzori su isključeni"</string> <string name="device_services" msgid="1191212554435440592">"Usluge uređaja"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Bez naslova"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Otvorite aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Otvorite postavke obavijesti za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index d0cdfb4601d6..308295a20cc1 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> alkalmazás használja a következőt: <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Értem"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Adatvédelmi beállítások"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"A következőket használó alkalmazás: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"A következőt használó alkalmazások: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Érzékelők kikapcsolva"</string> <string name="device_services" msgid="1191212554435440592">"Eszközszolgáltatások"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Nincs cím"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> megnyitása"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> – az alkalmazás értesítési beállításainak megnyitása"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 41bd378e912e..a3e05ad1cc01 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 98e1c4b3d9a3..2bad55e03d62 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplikasi menggunakan <xliff:g id="TYPE_1">%2$s</xliff:g> Anda.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Oke"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Setelan privasi"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplikasi yang menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g> Anda"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplikasi yang menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g> Anda"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensor nonaktif"</string> <string name="device_services" msgid="1191212554435440592">"Layanan Perangkat"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Tanpa judul"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Buka <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Buka setelan notifikasi untuk <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index d1ea979f5a2e..35026134445e 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -879,8 +879,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> forrit eru að nota <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Ég skil"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Persónuvernd"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Forrit sem nota <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Forrit sem nota <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Slökkt á skynjurum"</string> <string name="device_services" msgid="1191212554435440592">"Tækjaþjónusta"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Enginn titill"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Opna <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Opna tilkynningastillingar fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index af22c6d19399..42ff72a59014 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> applicazione sta utilizzando <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Impostazioni privacy"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App che usa <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"App che utilizzano <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensori disattivati"</string> <string name="device_services" msgid="1191212554435440592">"Servizi del dispositivo"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Senza titolo"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Apri <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Apri le impostazioni di notifica dell\'app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index a7d5138cebb7..036b0dfa7f3b 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -519,9 +519,9 @@ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"כווץ"</string> <string name="accessibility_output_chooser" msgid="8185317493017988680">"החלפת מכשיר פלט"</string> <string name="screen_pinning_title" msgid="3273740381976175811">"המסך מוצמד"</string> - <string name="screen_pinning_description" msgid="8909878447196419623">"נשאר בתצוגה עד לביטול ההצמדה. גע בלחצנים \'הקודם\' ו\'סקירה\' והחזק כדי לבטל את ההצמדה."</string> + <string name="screen_pinning_description" msgid="8909878447196419623">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'סקירה\' כדי לבטל את ההצמדה."</string> <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'דף הבית\' כדי לבטל את ההצמדה."</string> - <string name="screen_pinning_description_accessible" msgid="426190689254018656">"נשאר בתצוגה עד לביטול ההצמדה. גע בלחצן \'סקירה\' והחזק כדי לבטל את ההצמדה."</string> + <string name="screen_pinning_description_accessible" msgid="426190689254018656">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצן \'סקירה\' כדי לבטל את ההצמדה."</string> <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצן \'דף הבית\' כדי לבטל את ההצמדה."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"כדי לבטל את ההצמדה של מסך זה, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'סקירה\'"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"כדי לבטל את ההצמדה של מסך זה, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'דף הבית\'"</string> @@ -915,4 +915,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 9095fd1a8cdd..7aa7fbf39661 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> 個のアプリが <xliff:g id="TYPE_1">%2$s</xliff:g> を使用しています。</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"プライバシー設定"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"<xliff:g id="TYPES_LIST">%s</xliff:g>を使用しているアプリ"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"<xliff:g id="TYPES_LIST">%s</xliff:g>を使用しているアプリ"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"、 "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"センサー OFF"</string> <string name="device_services" msgid="1191212554435440592">"デバイス サービス"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"タイトルなし"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> を開く"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> の通知設定を開く"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 92368300422a..4fec28473a7f 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -879,8 +879,7 @@ <item quantity="one">თქვენი <xliff:g id="TYPE_1">%2$s</xliff:g> გამოიყენება <xliff:g id="NUM_APPS_0">%1$d</xliff:g> აპლიკაციის მიერ.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"გასაგებია"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"კონფიდ. პარამეტრები"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"აპი, რომლის მიერაც გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"აპები, რომელთა მიერაც გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"სენსორების გამორთვა"</string> <string name="device_services" msgid="1191212554435440592">"მოწყობილობის სერვისები"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"უსათაურო"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის გახსნა"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის შეტყობინების პარამეტრების გახსნა"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 3b46364d8faf..c5022b55cacd 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 6811072ef0ff..c03dddd43ba6 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 273470ada54e..aa0e63f855be 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ca45e4ddedc6..eb949037461e 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 82d709b52359..14d93e498e8f 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index ed0540780031..467a2dc77b67 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index a136772baad4..c79743ffdbd0 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -893,8 +893,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> programų naudoja jūsų <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Supratau"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privatumo nustatymai"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Programa, kuri naudoja: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Programos, kurios naudoja: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -911,8 +910,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Jutikliai išjungti"</string> <string name="device_services" msgid="1191212554435440592">"Įrenginio paslaugos"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Nėra pavadinimo"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Atidaryti „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Atidaryti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ pranešimų nustatymus"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index fec4fe8ca672..d6dc8f34c6dc 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -886,8 +886,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> lietojumprogrammās tiek izmantots: <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Labi"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Konfidencialitāte"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Lietotne, kurā tiek izmantots: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Lietotnes, kurās tiek izmantots: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -903,8 +902,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensori izslēgti"</string> <string name="device_services" msgid="1191212554435440592">"Ierīces pakalpojumi"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Nav nosaukuma"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Atvērt lietotni <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Atvērt paziņojumu iestatījumus lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 6b3e8cc111e5..03e31f745794 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 37d4b8c85f96..f25ae1d0e1d8 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 42cb765369b1..0e5dbb71d39a 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -879,8 +879,7 @@ <item quantity="one">Таны <xliff:g id="TYPE_1">%2$s</xliff:g>-г <xliff:g id="NUM_APPS_0">%1$d</xliff:g> апп ашиглаж байна.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Ойлголоо"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Нууцлалын тохиргоо"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Апп таны <xliff:g id="TYPES_LIST">%s</xliff:g>-г ашиглаж байна"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Аппууд таны <xliff:g id="TYPES_LIST">%s</xliff:g>-г ашиглаж байна"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Мэдрэгчийг унтраах"</string> <string name="device_services" msgid="1191212554435440592">"Төхөөрөмжийн үйлчилгээ"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Гарчиггүй"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нээх"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н мэдэгдлийн тохиргоог нээх"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 44d8c4e8f3ff..1b81062cc247 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index eee6b25bcddf..df10b2ffa438 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index b341bea7d19b..f8278059919d 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -684,7 +684,7 @@ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"ဂဏန်းကွက်<xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"စနစ်"</string> <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ပင်မ"</string> - <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"မကြာသေးခင်က"</string> + <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"လတ်တလော"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"နောက်သို့"</string> <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"အကြောင်းကြားချက်များ"</string> <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"ကီးဘုတ် ဖြတ်လမ်းများ"</string> @@ -879,8 +879,7 @@ <item quantity="one">အပလီကေးရှင်း <xliff:g id="NUM_APPS_0">%1$d</xliff:g> ခုက သင်၏ <xliff:g id="TYPE_1">%2$s</xliff:g> ကို အသုံးပြုနေသည်။</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"ရပါပြီ"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"ကန့်သတ်ဆက်တင်များ"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"သင့် <xliff:g id="TYPES_LIST">%s</xliff:g> ကို အသုံးပြုနေသော အက်ပ်"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"သင့် <xliff:g id="TYPES_LIST">%s</xliff:g> ကို အသုံးပြုနေသော အက်ပ်များ"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"၊ "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"အာရုံခံကိရိယာများ ပိတ်ထားသည်"</string> <string name="device_services" msgid="1191212554435440592">"စက်ပစ္စည်းဝန်ဆောင်မှုများ"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"ခေါင်းစဉ် မရှိပါ"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကိုဖွင့်ရန်"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် အကြောင်းကြားချက်ဆက်တင်များကို ဖွင့်ရန်"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index a27addba20de..1370468c32e5 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 1bb366481b25..08f3cef84582 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 8075ef4cd6af..7cb4b5a359c0 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -792,7 +792,7 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g>-instellingen openen."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Volgorde van instellingen bewerken."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string> - <string name="tuner_lock_screen" msgid="5755818559638850294">"Scherm vergrendelen"</string> + <string name="tuner_lock_screen" msgid="5755818559638850294">"Vergrendelingsscherm"</string> <string name="pip_phone_expand" msgid="5889780005575693909">"Uitvouwen"</string> <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimaliseren"</string> <string name="pip_phone_close" msgid="8416647892889710330">"Sluiten"</string> @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> app gebruikt je <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Privacyinstellingen"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App die je <xliff:g id="TYPES_LIST">%s</xliff:g> gebruikt"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps die je <xliff:g id="TYPES_LIST">%s</xliff:g> gebruiken"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensoren uit"</string> <string name="device_services" msgid="1191212554435440592">"Apparaatservices"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Geen titel"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> openen"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Instellingen voor meldingen voor <xliff:g id="APP_NAME">%1$s</xliff:g> openen"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 337b15d219f7..b9b4ea8f8360 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 4d8e3f11ceab..5432975a7320 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index d955236c3b09..b69204593082 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -893,8 +893,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplikacja używa: <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Ustawienia prywatności"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplikacje, które używają: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplikacje, które używają: <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -911,8 +910,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Wyłącz czujniki"</string> <string name="device_services" msgid="1191212554435440592">"Usługi urządzenia"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Bez tytułu"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Otwórz: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Otwórz ustawienia powiadomień z aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index d2219d259522..fcd7f85cf6f4 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -879,8 +879,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplicativos estão usando <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Ok"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Config. de privacidade"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App usando <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps usando <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensores desativados"</string> <string name="device_services" msgid="1191212554435440592">"Serviços do dispositivo"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sem título"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Abrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Abra as configurações de notificação do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 0866ffc7acea..6579645c83b9 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplicação está a utilizar o(a) <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Compreendi"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Def. de privacidade"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplicações que utilizam o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplicações que utilizam o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensores desativados"</string> <string name="device_services" msgid="1191212554435440592">"Serviços do dispositivo"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sem título"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Abrir a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Abrir as definições de notificação da aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index d2219d259522..fcd7f85cf6f4 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -879,8 +879,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> aplicativos estão usando <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Ok"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Config. de privacidade"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App usando <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Apps usando <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensores desativados"</string> <string name="device_services" msgid="1191212554435440592">"Serviços do dispositivo"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Sem título"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Abrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Abra as configurações de notificação do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index e04048458ea6..144bfc38f677 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -886,8 +886,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplicație folosește <xliff:g id="TYPE_1">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Setări de confidențialitate"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplicație care folosește <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplicații care folosesc <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -903,8 +902,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzori dezactivați"</string> <string name="device_services" msgid="1191212554435440592">"Servicii pentru dispozitiv"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Fără titlu"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Accesați <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Deschideți setările pentru notificări pentru aplicația <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 338ce14764a0..6d65592ad549 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -893,8 +893,7 @@ <item quantity="other">Функцию \"<xliff:g id="TYPE_5">%2$s</xliff:g>\" используют <xliff:g id="NUM_APPS_4">%1$d</xliff:g> приложения.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"ОК"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Конфиденциальность"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Приложение, в котором используются операции <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Приложения, в которых используются операции <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -911,8 +910,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Датчики отключены"</string> <string name="device_services" msgid="1191212554435440592">"Сервисы устройства"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Без названия"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Открыть приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Настройки уведомлений приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 3a0b3a4200ba..2529f19370c0 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -879,8 +879,7 @@ <item quantity="other">යෙදුම් <xliff:g id="NUM_APPS_4">%1$d</xliff:g>ක් ඔබේ <xliff:g id="TYPE_5">%2$s</xliff:g> භාවිත කරමින් සිටිති.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"තේරුණා"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"පෞද්ගලිකත්ව සැකසීම්"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"ඔබගේ <xliff:g id="TYPES_LIST">%s</xliff:g> භාවිත කරන යෙදුම්"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"ඔබගේ <xliff:g id="TYPES_LIST">%s</xliff:g> භාවිත කරන යෙදුම්"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"සංවේදක ක්රියාවිරහිතයි"</string> <string name="device_services" msgid="1191212554435440592">"උපාංග සේවා"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"මාතෘකාවක් නැත"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> විවෘත කරන්න"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා දැනුම්දීම් සැකසීම් විවෘත කරන්න"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 883243e65496..923384f93511 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -893,8 +893,7 @@ <item quantity="one"><xliff:g id="TYPE_1">%2$s</xliff:g> používa <xliff:g id="NUM_APPS_0">%1$d</xliff:g> aplikácia.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Dobre"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Nastavenia ochrany súkromia"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Aplikácia používajúca <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Aplikácie používajúce <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -911,8 +910,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Senzory sú vypnuté"</string> <string name="device_services" msgid="1191212554435440592">"Služby zariadenia"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Bez názvu"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Otvoriť <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Otvoriť nastavenia upozornení pre <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index db40b44c4d17..d497f26926de 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -915,4 +915,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index ad6113e74c2b..db905cebb30d 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 768ae7fa2a2d..264698a779b7 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -886,8 +886,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> апликација користи дозволу <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Важи"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Подешав. приватности"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Апликација која користи дозволе <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Апликације које користе дозволе <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -903,8 +902,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Сензори су искључени"</string> <string name="device_services" msgid="1191212554435440592">"Услуге за уређаје"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Без наслова"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Отворите <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Отворите подешавања обавештења за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 0f36517ccce0..7e8446e1a427 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index a11e4d44e1c0..eb658ff17cfb 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index a8587c121815..5bcc6fec7d39 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index a512c0c0adc4..cb9b70d6bbdf 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index b8a840eedaad..6a126ff00684 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -879,8 +879,7 @@ <item quantity="one">มี <xliff:g id="NUM_APPS_0">%1$d</xliff:g> แอปพลิเคชันกำลังใช้<xliff:g id="TYPE_1">%2$s</xliff:g></item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"รับทราบ"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"การตั้งค่าความเป็นส่วนตัว"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"มีแอปกำลังใช้<xliff:g id="TYPES_LIST">%s</xliff:g>ของคุณ"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"มีหลายแอปกำลังใช้<xliff:g id="TYPES_LIST">%s</xliff:g>ของคุณ"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"เซ็นเซอร์ปิดอยู่"</string> <string name="device_services" msgid="1191212554435440592">"บริการของอุปกรณ์"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"ไม่มีชื่อ"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"เปิด <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"เปิดการตั้งค่าการแจ้งเตือนสำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 72c5eacf806c..1550787b4b27 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -879,8 +879,7 @@ <item quantity="other">Ginagamit ng <xliff:g id="NUM_APPS_4">%1$d</xliff:g> na application ang iyong <xliff:g id="TYPE_5">%2$s</xliff:g>.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Mga setting ng privacy"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"App na gumagamit ng iyong <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Mga app na gumagamit ng iyong <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Naka-off ang mga sensor"</string> <string name="device_services" msgid="1191212554435440592">"Mga Serbisyo ng Device"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Walang pamagat"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Buksan ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Buksan ang mga setting ng notification para sa <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 5cd4e4c5f39f..93671558e3ef 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index b231c581b212..a850f213ca94 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -915,4 +915,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 90447d777794..c7bf3b0e4e0a 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> ایپلیکیشن آپ کی <xliff:g id="TYPE_1">%2$s</xliff:g> کا استعمال کر رہی ہے۔</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"سمجھ آ گئی"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"رازداری کی ترتیبات"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"ایپ آپ کی <xliff:g id="TYPES_LIST">%s</xliff:g> کا استعمال کر رہی ہیں"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"ایپس آپ کی <xliff:g id="TYPES_LIST">%s</xliff:g> کا استعمال کر رہی ہیں"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"، "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"سینسرز آف ہیں"</string> <string name="device_services" msgid="1191212554435440592">"آلہ کی سروس"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"کوئی عنوان نہیں ہے"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"<xliff:g id="APP_NAME">%1$s</xliff:g> کھولیں"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لئے اطلاع کی ترتیبات کھولیں"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 4a7af622bc64..48532fad0c1d 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> ta ilova <xliff:g id="TYPE_1">%2$s</xliff:g> ishlatmoqda.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Maxfiylik sozlama-ri"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"<xliff:g id="TYPES_LIST">%s</xliff:g> ishlatayotgan ilova"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Ilovalar <xliff:g id="TYPES_LIST">%s</xliff:g> ishlatmoqda"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensorlar nofaol"</string> <string name="device_services" msgid="1191212554435440592">"Qurilma xizmatlari"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Nomsiz"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Ochish: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"<xliff:g id="APP_NAME">%1$s</xliff:g> bildirishnoma sozlamalarini ochish"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index ad8d17cc23c1..b796503bbf3d 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -879,8 +879,7 @@ <item quantity="one"><xliff:g id="NUM_APPS_0">%1$d</xliff:g> ứng dụng đang dùng <xliff:g id="TYPE_1">%2$s</xliff:g> của bạn.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"OK"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Cài đặt quyền riêng tư"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Ứng dụng đang sử dụng <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Các ứng dụng đang sử dụng <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Tắt cảm biến"</string> <string name="device_services" msgid="1191212554435440592">"Dịch vụ cho thiết bị"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Không có tiêu đề"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Mở <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"Mở mục cài đặt thông báo dành cho <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 0330edf023e0..3a5dd5cda55d 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -899,4 +899,10 @@ <skip /> <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> <skip /> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> + <skip /> + <!-- no translation found for yes_bubbles (668809525728633841) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 01797fb83fd2..8d67f5c7a5dc 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -879,8 +879,7 @@ <item quantity="one">有 <xliff:g id="NUM_APPS_0">%1$d</xliff:g> 個應用程式正在使用您的<xliff:g id="TYPE_1">%2$s</xliff:g>。</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"知道了"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"隱私權設定"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"使用<xliff:g id="TYPES_LIST">%s</xliff:g>的應用程式"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"使用<xliff:g id="TYPES_LIST">%s</xliff:g>的應用程式"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"、 "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"感應器已關閉"</string> <string name="device_services" msgid="1191212554435440592">"裝置服務"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"無標題"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"開啟「<xliff:g id="APP_NAME">%1$s</xliff:g>」"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"開啟「<xliff:g id="APP_NAME">%1$s</xliff:g>」的通知設定"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 62b7cb667937..d8d0c07bcbc0 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -879,8 +879,7 @@ <item quantity="one">有 <xliff:g id="NUM_APPS_0">%1$d</xliff:g> 個應用程式正在使用你的<xliff:g id="TYPE_1">%2$s</xliff:g>。</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"我知道了"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"隱私權設定"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"使用<xliff:g id="TYPES_LIST">%s</xliff:g>的應用程式"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"使用<xliff:g id="TYPES_LIST">%s</xliff:g>的應用程式"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">"、 "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"已關閉感應器"</string> <string name="device_services" msgid="1191212554435440592">"裝置服務"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"無標題"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"開啟「<xliff:g id="APP_NAME">%1$s</xliff:g>」"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"開啟「<xliff:g id="APP_NAME">%1$s</xliff:g>」的通知設定"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index f8bf2e39d748..2e0efcc863c7 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -879,8 +879,7 @@ <item quantity="other"><xliff:g id="NUM_APPS_4">%1$d</xliff:g> izinhlelo zokusebenza zisebenzisa i-<xliff:g id="TYPE_5">%2$s</xliff:g> yakho.</item> </plurals> <string name="ongoing_privacy_dialog_ok" msgid="3273300106348958308">"Ngiyezwa"</string> - <!-- no translation found for ongoing_privacy_dialog_open_settings (6773015940472748876) --> - <skip /> + <string name="ongoing_privacy_dialog_open_settings" msgid="6773015940472748876">"Izilungiselelo zobumfihlo"</string> <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"Uhlelo lokusebenza olusebenzisa i-<xliff:g id="TYPES_LIST">%s</xliff:g> yakho"</string> <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"Izinhlelo zokusebenza ezisebenzisa i-<xliff:g id="TYPES_LIST">%s</xliff:g> yakho"</string> <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string> @@ -895,8 +894,12 @@ <string name="sensor_privacy_mode" msgid="8982771253020769598">"Izinzwa zivaliwe"</string> <string name="device_services" msgid="1191212554435440592">"Amasevisi edivayisi"</string> <string name="music_controls_no_title" msgid="5236895307087002011">"Asikho isihloko"</string> - <!-- no translation found for bubbles_deep_link_button_description (8895837143057564517) --> + <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Vula i-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <string name="bubbles_settings_button_description" msgid="1940331766151865776">"VUla izilungiselelo zesaziso ze-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string> + <!-- no translation found for bubbles_prompt (2684301469286150276) --> + <skip /> + <!-- no translation found for no_bubbles (7173621233904687258) --> <skip /> - <!-- no translation found for bubbles_settings_button_description (1940331766151865776) --> + <!-- no translation found for yes_bubbles (668809525728633841) --> <skip /> </resources> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java new file mode 100644 index 000000000000..f7ccb816b675 --- /dev/null +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java @@ -0,0 +1,113 @@ +/** + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shared.system; + +import android.os.Looper; +import android.util.Pair; +import android.view.BatchedInputEventReceiver; +import android.view.Choreographer; +import android.view.InputChannel; +import android.view.InputEvent; +import android.view.InputEventSender; + +/** + * @see android.view.InputChannel + */ +public class InputChannelCompat { + + /** + * Callback for receiving event callbacks + */ + public interface InputEventListener { + /** + * @param ev event to be handled + */ + void onInputEvent(InputEvent ev); + } + + /** + * Creates a dispatcher and receiver pair to better handle events across threads. + */ + public static Pair<InputEventDispatcher, InputEventReceiver> createPair(String name, + Looper looper, Choreographer choreographer, InputEventListener listener) { + InputChannel[] channels = InputChannel.openInputChannelPair(name); + + InputEventDispatcher dispatcher = new InputEventDispatcher(channels[0], looper); + InputEventReceiver receiver = new InputEventReceiver(channels[1], looper, choreographer, + listener); + return Pair.create(dispatcher, receiver); + } + + /** + * @see BatchedInputEventReceiver + */ + public static class InputEventReceiver { + + private final BatchedInputEventReceiver mReceiver; + private final InputChannel mInputChannel; + + public InputEventReceiver(InputChannel inputChannel, Looper looper, + Choreographer choreographer, final InputEventListener listener) { + mInputChannel = inputChannel; + mReceiver = new BatchedInputEventReceiver(inputChannel, looper, choreographer) { + + @Override + public void onInputEvent(InputEvent event) { + listener.onInputEvent(event); + finishInputEvent(event, true /* handled */); + } + }; + } + + /** + * @see BatchedInputEventReceiver#dispose() + */ + public void dispose() { + mReceiver.dispose(); + mInputChannel.dispose(); + } + } + + /** + * @see InputEventSender + */ + public static class InputEventDispatcher { + + private final InputChannel mInputChannel; + private final InputEventSender mSender; + + private InputEventDispatcher(InputChannel inputChannel, Looper looper) { + mInputChannel = inputChannel; + mSender = new InputEventSender(inputChannel, looper) { }; + } + + /** + * @see InputEventSender#sendInputEvent(int, InputEvent) + */ + public void dispatch(InputEvent ev) { + mSender.sendInputEvent(ev.getSequenceNumber(), ev); + } + + /** + * @see InputEventSender#dispose() + */ + public void dispose() { + mSender.dispose(); + mInputChannel.dispose(); + } + } +} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java index 2bdbf0bf3c22..221782e950d0 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java @@ -20,6 +20,7 @@ import android.app.WindowConfiguration; import android.graphics.Point; import android.graphics.Rect; import android.view.RemoteAnimationTarget; +import android.view.SurfaceControl; /** * @see RemoteAnimationTarget @@ -47,6 +48,8 @@ public class RemoteAnimationTargetCompat { public final boolean isNotInRecents; public final Rect contentInsets; + private final SurfaceControl mStartLeash; + public RemoteAnimationTargetCompat(RemoteAnimationTarget app) { taskId = app.taskId; mode = app.mode; @@ -59,6 +62,8 @@ public class RemoteAnimationTargetCompat { isNotInRecents = app.isNotInRecents; contentInsets = app.contentInsets; activityType = app.windowConfiguration.getActivityType(); + + mStartLeash = app.startLeash; } public static RemoteAnimationTargetCompat[] wrap(RemoteAnimationTarget[] apps) { @@ -69,4 +74,14 @@ public class RemoteAnimationTargetCompat { } return appsCompat; } + + /** + * @see SurfaceControl#release() + */ + public void release() { + leash.mSurfaceControl.release(); + if (mStartLeash != null) { + mStartLeash.release(); + } + } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java index d5bd2b202803..1539582ef18b 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java @@ -299,8 +299,9 @@ public class CarrierTextController { displayText.toString().split(mSeparator.toString()), anySimReadyAndInService && !missingSimsWithSubs, subsIds); - if (mCarrierTextCallback != null) { - handler.post(() -> mCarrierTextCallback.updateCarrierInfo(info)); + final CarrierTextCallback callback = mCarrierTextCallback; + if (callback != null) { + handler.post(() -> callback.updateCarrierInfo(info)); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java index 7218acf614d4..fc1843ba982a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java @@ -1,5 +1,6 @@ package com.android.keyguard; +import android.app.WallpaperManager; import android.content.Context; import android.graphics.Paint; import android.graphics.Paint.Style; @@ -12,11 +13,13 @@ import android.widget.TextClock; import androidx.annotation.VisibleForTesting; +import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.clock.ClockManager; import com.android.systemui.Dependency; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import java.util.TimeZone; @@ -50,6 +53,8 @@ public class KeyguardClockSwitch extends RelativeLayout { * Maintain state so that a newly connected plugin can be initialized. */ private float mDarkAmount; + private boolean mSupportsDarkText; + private int[] mColorPalette; private final StatusBarStateController.StateListener mStateListener = new StatusBarStateController.StateListener() { @@ -72,6 +77,21 @@ public class KeyguardClockSwitch extends RelativeLayout { private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin; + /** + * Listener for changes to the color palette. + * + * The color palette changes when the wallpaper is changed. + */ + private SysuiColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> { + if ((which & WallpaperManager.FLAG_LOCK) != 0) { + if (extractor instanceof SysuiColorExtractor) { + updateColors((SysuiColorExtractor) extractor); + } else { + updateColors(Dependency.get(SysuiColorExtractor.class)); + } + } + }; + public KeyguardClockSwitch(Context context) { this(context, null); } @@ -100,6 +120,9 @@ public class KeyguardClockSwitch extends RelativeLayout { super.onAttachedToWindow(); Dependency.get(ClockManager.class).addOnClockChangedListener(mClockChangedListener); Dependency.get(StatusBarStateController.class).addCallback(mStateListener); + SysuiColorExtractor colorExtractor = Dependency.get(SysuiColorExtractor.class); + colorExtractor.addOnColorsChangedListener(mColorsListener); + updateColors(colorExtractor); } @Override @@ -107,6 +130,8 @@ public class KeyguardClockSwitch extends RelativeLayout { super.onDetachedFromWindow(); Dependency.get(ClockManager.class).removeOnClockChangedListener(mClockChangedListener); Dependency.get(StatusBarStateController.class).removeCallback(mStateListener); + Dependency.get(SysuiColorExtractor.class) + .removeOnColorsChangedListener(mColorsListener); } private void setClockPlugin(ClockPlugin plugin) { @@ -149,6 +174,9 @@ public class KeyguardClockSwitch extends RelativeLayout { mClockPlugin.setStyle(getPaint().getStyle()); mClockPlugin.setTextColor(getCurrentTextColor()); mClockPlugin.setDarkAmount(mDarkAmount); + if (mColorPalette != null) { + mClockPlugin.setColorPalette(mSupportsDarkText, mColorPalette); + } } /** @@ -246,6 +274,16 @@ public class KeyguardClockSwitch extends RelativeLayout { } } + private void updateColors(SysuiColorExtractor colorExtractor) { + ColorExtractor.GradientColors colors = colorExtractor.getColors(WallpaperManager.FLAG_LOCK, + true); + mSupportsDarkText = colors.supportsDarkText(); + mColorPalette = colors.getColorPalette(); + if (mClockPlugin != null) { + mClockPlugin.setColorPalette(mSupportsDarkText, mColorPalette); + } + } + @VisibleForTesting (otherwise = VisibleForTesting.NONE) ClockManager.ClockChangedListener getClockChangedListener() { return mClockChangedListener; diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java index db6127f1d573..3114708de038 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java @@ -89,7 +89,17 @@ public class BubbleClockController implements ClockPlugin { @Override public void setTextColor(int color) { mLockClock.setTextColor(color); - mDigitalClock.setTextColor(color); + } + + @Override + public void setColorPalette(boolean supportsDarkText, int[] colorPalette) { + if (colorPalette == null || colorPalette.length == 0) { + return; + } + final int length = colorPalette.length; + mDigitalClock.setTextColor(colorPalette[Math.max(0, length - 6)]); + mAnalogClock.setClockColors(colorPalette[Math.max(0, length - 6)], + colorPalette[Math.max(0, length - 3)]); } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java b/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java index 2c709e0393bd..e35cf113c111 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java @@ -78,6 +78,16 @@ public class ImageClock extends FrameLayout { mTime.setTimeZone(timeZone); } + /** + * Sets the colors to use on the clock face. + * @param dark Darker color obtained from color palette. + * @param light Lighter color obtained from color palette. + */ + public void setClockColors(int dark, int light) { + mHourHand.setColorFilter(dark); + mMinuteHand.setColorFilter(light); + } + @Override protected void onFinishInflate() { super.onFinishInflate(); diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClock.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClock.java index 8734754541a6..3c9a4f821c62 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClock.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClock.java @@ -76,10 +76,12 @@ public class StretchAnalogClock extends View { } /** - * Set the color of the minute hand. + * Set the colors to use on the clock face. + * @param dark Darker color obtained from color palette. + * @param light Lighter color obtained from color palette. */ - public void setMinuteHandColor(int color) { - mMinutePaint.setColor(color); + public void setClockColor(int dark, int light) { + mHourPaint.setColor(dark); invalidate(); } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java index 0a39158cd4be..c4651149521c 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java @@ -89,8 +89,17 @@ public class StretchAnalogClockController implements ClockPlugin { @Override public void setTextColor(int color) { mLockClock.setTextColor(color); - mDigitalClock.setTextColor(color); - mAnalogClock.setMinuteHandColor(color); + } + + @Override + public void setColorPalette(boolean supportsDarkText, int[] colorPalette) { + if (colorPalette == null || colorPalette.length == 0) { + return; + } + final int length = colorPalette.length; + mDigitalClock.setTextColor(colorPalette[Math.max(0, length - 5)]); + mAnalogClock.setClockColor(colorPalette[Math.max(0, length - 5)], + colorPalette[Math.max(0, length - 2)]); } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java index 17d929dc8a3b..2ea39c40bee2 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java @@ -87,6 +87,15 @@ public class TypeClockController implements ClockPlugin { } @Override + public void setColorPalette(boolean supportsDarkText, int[] colorPalette) { + if (colorPalette == null || colorPalette.length == 0) { + return; + } + final int length = colorPalette.length; + mTypeClock.setClockColor(colorPalette[Math.max(0, length - 5)]); + } + + @Override public void dozeTimeTick() { mTypeClock.onTimeChanged(); } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java index 8feae53159ac..6f1b59c69865 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java @@ -43,7 +43,7 @@ public class TypographicClock extends TextView { private final Resources mResources; private final String[] mHours; private final String[] mMinutes; - private final int mAccentColor; + private int mAccentColor; private Calendar mTime; private String mDescFormat; private TimeZone mTimeZone; @@ -106,6 +106,13 @@ public class TypographicClock extends TextView { mTime.setTimeZone(timeZone); } + /** + * Sets the accent color used on the clock face. + */ + public void setClockColor(int color) { + mAccentColor = color; + } + @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index c3f61eee4930..567207376996 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -42,6 +42,7 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.VolumeDialogController; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.PowerUI; import com.android.systemui.privacy.PrivacyItemController; @@ -55,7 +56,6 @@ import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.SmartReplyController; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationEntryManager; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 9b3d7ed8f045..755d6fcffb43 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -33,6 +33,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.classifier.FalsingManager; import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.DismissCallbackRegistry; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.EnhancedEstimatesImpl; import com.android.systemui.statusbar.KeyguardIndicationController; @@ -40,7 +41,7 @@ import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.ScrimView; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; import com.android.systemui.statusbar.notification.collection.NotificationData; @@ -152,6 +153,15 @@ public class SystemUIFactory { return new VolumeDialogComponent(systemUi, context); } + /** + * Provides status bar state controller implementation + */ + @Singleton + @Provides + public StatusBarStateController provideStatusBarStateController(Context context) { + return new StatusBarStateControllerImpl(); + } + @Singleton @Provides public NotificationData.KeyguardEnvironment provideKeyguardEnvironment(Context context) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 6877f5ed6b26..41bc1b29075c 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -28,6 +28,9 @@ import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.android.systemui.statusbar.notification.NotificationAlertingManager.alertAgain; import android.annotation.Nullable; +import android.app.ActivityManager; +import android.app.ActivityTaskManager; +import android.app.IActivityTaskManager; import android.app.INotificationManager; import android.app.Notification; import android.app.PendingIntent; @@ -35,11 +38,13 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.Rect; +import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import android.service.notification.StatusBarNotification; import android.util.Log; import android.util.StatsLog; +import android.view.Display; import android.view.LayoutInflater; import android.view.ViewGroup; import android.view.WindowManager; @@ -51,7 +56,9 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; @@ -60,6 +67,7 @@ import com.android.systemui.statusbar.notification.row.NotificationInflater; import com.android.systemui.statusbar.phone.StatusBarWindowController; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -93,6 +101,8 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe private final Context mContext; private final NotificationEntryManager mNotificationEntryManager; + private final IActivityTaskManager mActivityTaskManager; + private final BubbleTaskStackListener mTaskStackListener; private BubbleStateChangeListener mStateChangeListener; private BubbleExpandListener mExpandListener; private LayoutInflater mInflater; @@ -176,6 +186,10 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe mStatusBarWindowController = statusBarWindowController; mStatusBarStateListener = new StatusBarStateListener(); Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener); + + mActivityTaskManager = ActivityTaskManager.getService(); + mTaskStackListener = new BubbleTaskStackListener(); + ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); } /** @@ -533,6 +547,64 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe || autoBubbleAll; } + /** + * This task stack listener is responsible for responding to tasks moved to the front + * which are on the default (main) display. When this happens, expanded bubbles must be + * collapsed so the user may interact with the app which was just moved to the front. + * <p> + * This listener is registered with SystemUI's ActivityManagerWrapper which dispatches + * these calls via a main thread Handler. + */ + @MainThread + private class BubbleTaskStackListener extends TaskStackChangeListener { + + @Nullable + private ActivityManager.StackInfo findStackInfo(int taskId) throws RemoteException { + final List<ActivityManager.StackInfo> stackInfoList = + mActivityTaskManager.getAllStackInfos(); + // Iterate through stacks from top to bottom. + final int stackCount = stackInfoList.size(); + for (int stackIndex = 0; stackIndex < stackCount; stackIndex++) { + final ActivityManager.StackInfo stackInfo = stackInfoList.get(stackIndex); + // Iterate through tasks from top to bottom. + for (int taskIndex = stackInfo.taskIds.length - 1; taskIndex >= 0; taskIndex--) { + if (stackInfo.taskIds[taskIndex] == taskId) { + return stackInfo; + } + } + } + return null; + } + + @Override + public void onTaskMovedToFront(int taskId) { + ActivityManager.StackInfo stackInfo = null; + try { + stackInfo = findStackInfo(taskId); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + if (stackInfo != null && stackInfo.displayId == Display.DEFAULT_DISPLAY + && mStackView != null) { + mStackView.collapseStack(); + } + } + + /** + * This is a workaround for the case when the activity had to be created in a new task. + * Existing code in ActivityStackSupervisor checks the display where the activity + * ultimately ended up, displays an error message toast, and calls this method instead of + * onTaskMovedToFront. + */ + // TODO(b/124058588): add requestedDisplayId to this callback, ignore unless matches + @Override + public void onActivityLaunchOnSecondaryDisplayFailed() { + if (mStackView != null) { + mStackView.collapseStack(); + } + } + } + private static boolean shouldAutoBubbleMessages(Context context) { return Settings.Secure.getInt(context.getContentResolver(), ENABLE_AUTO_BUBBLE_MESSAGES, 0) != 0; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 305f86655fcd..f6f3fa646232 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -41,6 +41,7 @@ import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.LinearLayout; +import androidx.annotation.MainThread; import androidx.annotation.Nullable; import androidx.dynamicanimation.animation.DynamicAnimation; import androidx.dynamicanimation.animation.SpringAnimation; @@ -384,7 +385,10 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F /** * Collapses the stack of bubbles. + * <p> + * Must be called from the main thread. */ + @MainThread public void collapseStack() { if (mIsExpanded) { // TODO: Save opened bubble & move it to top of stack @@ -402,7 +406,10 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F /** * Expands the stack fo bubbles. + * <p> + * Must be called from the main thread. */ + @MainThread public void expandStack() { if (!mIsExpanded) { mExpandedBubble = getTopBubble(); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java index 2c23c0ccf614..74ddc8f6b8fc 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java @@ -22,6 +22,8 @@ import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.graphics.Color; +import android.graphics.Insets; +import android.graphics.Point; import android.graphics.PointF; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -32,6 +34,7 @@ import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; +import android.view.WindowInsets; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; @@ -266,6 +269,24 @@ public class BubbleView extends FrameLayout implements BubbleTouchHandler.Floati } } }); + mActivityView.setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> { + ActivityView activityView = (ActivityView) view; + // Here we assume that the position of the ActivityView on the screen + // remains regardless of IME status. When we move ActivityView, the + // forwardedInsets should be computed not against the current location + // and size, but against the post-moved location and size. + Point displaySize = new Point(); + view.getContext().getDisplay().getSize(displaySize); + int[] windowLocation = view.getLocationOnScreen(); + final int windowBottom = windowLocation[1] + view.getHeight(); + final int keyboardHeight = insets.getSystemWindowInsetBottom() + - insets.getStableInsetBottom(); + final int insetsBottom = Math.max(0, + windowBottom + keyboardHeight - displaySize.y); + activityView.setForwardedInsets(Insets.of(0, 0, 0, insetsBottom)); + return view.onApplyWindowInsets(insets); + }); + } return mActivityView; } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java index 4ff27b1b64f0..8f215ff47855 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java @@ -35,9 +35,9 @@ import android.view.accessibility.AccessibilityManager; import com.android.systemui.Dependency; import com.android.systemui.UiOffloadThread; import com.android.systemui.analytics.DataCollector; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.util.AsyncSensorManager; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java index fdf18ce24f50..900ea72d856c 100644 --- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java @@ -48,6 +48,7 @@ import javax.inject.Singleton; @Singleton public class SysuiColorExtractor extends ColorExtractor implements Dumpable { private static final String TAG = "SysuiColorExtractor"; + private final Tonal mTonal; private boolean mWallpaperVisible; private boolean mHasBackdrop; // Colors to return when the wallpaper isn't visible @@ -61,6 +62,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { @VisibleForTesting public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) { super(context, type); + mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context); mWpHiddenColors = new GradientColors(); WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); @@ -94,7 +96,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { } private void updateDefaultGradients(WallpaperColors colors) { - Tonal.applyFallback(colors, mWpHiddenColors); + mTonal.applyFallback(colors, mWpHiddenColors); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java index c4c8bc703802..684175cf4212 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java @@ -51,8 +51,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.R; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationMediaManager; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.NextAlarmControllerImpl; import com.android.systemui.statusbar.policy.ZenModeController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index e1a43785b5c4..e275690f70aa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -58,10 +58,10 @@ import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.State; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.PagedTileLayout.TilePage; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QuickStatusBarHeader; -import com.android.systemui.statusbar.StatusBarStateController; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 2811505d738c..be749aef7f25 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -47,7 +47,8 @@ import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; import com.android.systemui.statusbar.phone.LockIcon; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index 4f9d4282dae8..6a49b804f5ba 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -44,8 +44,9 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.recents.OverviewProxyService; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 98a3a547ed2c..490317b188c2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -47,6 +47,7 @@ import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.Interpolators; import com.android.systemui.colorextraction.SysuiColorExtractor; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 546b2e9df7b5..01b0bb14c7ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -26,7 +26,6 @@ import android.graphics.Rect; import android.os.SystemProperties; import android.util.AttributeSet; import android.util.Log; -import android.util.MathUtils; import android.view.DisplayCutout; import android.view.View; import android.view.ViewGroup; @@ -38,7 +37,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -118,8 +118,8 @@ public class NotificationShelf extends ActivatableNotificationView implements @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - Dependency.get(StatusBarStateController.class) - .addCallback(this, StatusBarStateController.RANK_SHELF); + ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class)) + .addCallback(this, SysuiStatusBarStateController.RANK_SHELF); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index f2ff85bb226c..662cf514b977 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -61,7 +61,7 @@ public class NotificationViewHierarchyManager { protected final NotificationLockscreenUserManager mLockscreenUserManager; protected final NotificationGroupManager mGroupManager; protected final VisualStabilityManager mVisualStabilityManager; - private final StatusBarStateController mStatusBarStateController; + private final StatusBarStateControllerImpl mStatusBarStateController; private final NotificationEntryManager mEntryManager; // Lazy @@ -82,7 +82,7 @@ public class NotificationViewHierarchyManager { NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationGroupManager groupManager, VisualStabilityManager visualStabilityManager, - StatusBarStateController statusBarStateController, + StatusBarStateControllerImpl statusBarStateController, NotificationEntryManager notificationEntryManager, Lazy<ShadeController> shadeController) { mLockscreenUserManager = notificationLockscreenUserManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java index 54bce1c00354..ad5aa57f12ea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,27 +11,22 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ package com.android.systemui.statusbar; -import static java.lang.annotation.RetentionPolicy.SOURCE; - import android.animation.ObjectAnimator; import android.animation.ValueAnimator; -import android.annotation.IntDef; import android.util.FloatProperty; import android.view.animation.Interpolator; import com.android.internal.annotations.GuardedBy; import com.android.systemui.Interpolators; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; -import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.CallbackController; -import java.lang.annotation.Retention; import java.util.ArrayList; import java.util.Comparator; @@ -42,24 +37,25 @@ import javax.inject.Singleton; * Tracks and reports on {@link StatusBarState}. */ @Singleton -public class StatusBarStateController implements CallbackController<StateListener> { +public class StatusBarStateControllerImpl implements SysuiStatusBarStateController, + CallbackController<StateListener> { private static final String TAG = "SbStateController"; private static final int MAX_STATE = StatusBarState.FULLSCREEN_USER_SWITCHER; private static final int MIN_STATE = StatusBarState.SHADE; - private static final Comparator <RankedListener> mComparator - = (o1, o2) -> Integer.compare(o1.rank, o2.rank); - private static final FloatProperty<StatusBarStateController> SET_DARK_AMOUNT_PROPERTY = - new FloatProperty<StatusBarStateController>("mDozeAmount") { + private static final Comparator<RankedListener> sComparator = + Comparator.comparingInt(o -> o.mRank); + private static final FloatProperty<StatusBarStateControllerImpl> SET_DARK_AMOUNT_PROPERTY = + new FloatProperty<StatusBarStateControllerImpl>("mDozeAmount") { @Override - public void setValue(StatusBarStateController object, float value) { + public void setValue(StatusBarStateControllerImpl object, float value) { object.setDozeAmountInternal(value); } @Override - public Float get(StatusBarStateController object) { + public Float get(StatusBarStateControllerImpl object) { return object.mDozeAmount; } }; @@ -95,29 +91,16 @@ public class StatusBarStateController implements CallbackController<StateListene */ private Interpolator mDozeInterpolator = Interpolators.FAST_OUT_SLOW_IN; - // TODO: b/115739177 (remove this explicit ordering if we can) - @Retention(SOURCE) - @IntDef({RANK_STATUS_BAR, RANK_STATUS_BAR_WINDOW_CONTROLLER, RANK_STACK_SCROLLER, RANK_SHELF}) - public @interface SbStateListenerRank {} - // This is the set of known dependencies when updating StatusBarState - public static final int RANK_STATUS_BAR = 0; - public static final int RANK_STATUS_BAR_WINDOW_CONTROLLER = 1; - public static final int RANK_STACK_SCROLLER = 2; - public static final int RANK_SHELF = 3; - @Inject - public StatusBarStateController() { + public StatusBarStateControllerImpl() { } + @Override public int getState() { return mState; } - /** - * Update the status bar state - * @param state see {@link StatusBarState} for valid options - * @return {@code true} if the state changed, else {@code false} - */ + @Override public boolean setState(int state) { if (state > MAX_STATE || state < MIN_STATE) { throw new IllegalArgumentException("Invalid state " + state); @@ -127,40 +110,38 @@ public class StatusBarStateController implements CallbackController<StateListene } synchronized (mListeners) { for (RankedListener rl : new ArrayList<>(mListeners)) { - rl.listener.onStatePreChange(mState, state); + rl.mListener.onStatePreChange(mState, state); } mLastState = mState; mState = state; for (RankedListener rl : new ArrayList<>(mListeners)) { - rl.listener.onStateChanged(mState); + rl.mListener.onStateChanged(mState); } for (RankedListener rl : new ArrayList<>(mListeners)) { - rl.listener.onStatePostChange(); + rl.mListener.onStatePostChange(); } } return true; } + @Override public boolean isDozing() { return mIsDozing; } + @Override public float getDozeAmount() { return mDozeAmount; } + @Override public float getInterpolatedDozeAmount() { return mDozeInterpolator.getInterpolation(mDozeAmount); } - /** - * Update the dozing state from {@link StatusBar}'s perspective - * @param isDozing well, are we dozing? - * @return {@code true} if the state changed, else {@code false} - */ - @SuppressWarnings("UnusedReturnValue") + @Override public boolean setIsDozing(boolean isDozing) { if (mIsDozing == isDozing) { return false; @@ -170,19 +151,14 @@ public class StatusBarStateController implements CallbackController<StateListene synchronized (mListeners) { for (RankedListener rl : new ArrayList<>(mListeners)) { - rl.listener.onDozingChanged(isDozing); + rl.mListener.onDozingChanged(isDozing); } } return true; } - /** - * Changes the current doze amount. - * - * @param dozeAmount New doze/dark amount. - * @param animated If change should be animated or not. This will cancel current animations. - */ + @Override public void setDozeAmount(float dozeAmount, boolean animated) { if (mDarkAnimator != null && mDarkAnimator.isRunning()) { if (animated && mDozeAmountTarget == dozeAmount) { @@ -217,27 +193,32 @@ public class StatusBarStateController implements CallbackController<StateListene float interpolatedAmount = mDozeInterpolator.getInterpolation(dozeAmount); synchronized (mListeners) { for (RankedListener rl : new ArrayList<>(mListeners)) { - rl.listener.onDozeAmountChanged(mDozeAmount, interpolatedAmount); + rl.mListener.onDozeAmountChanged(mDozeAmount, interpolatedAmount); } } } + @Override public boolean goingToFullShade() { return mState == StatusBarState.SHADE && mLeaveOpenOnKeyguardHide; } + @Override public void setLeaveOpenOnKeyguardHide(boolean leaveOpen) { mLeaveOpenOnKeyguardHide = leaveOpen; } + @Override public boolean leaveOpenOnKeyguardHide() { return mLeaveOpenOnKeyguardHide; } + @Override public boolean fromShadeLocked() { return mLastState == StatusBarState.SHADE_LOCKED; } + @Override public void addCallback(StateListener listener) { synchronized (mListeners) { addListenerInternalLocked(listener, Integer.MAX_VALUE); @@ -254,6 +235,8 @@ public class StatusBarStateController implements CallbackController<StateListene * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking * (i.e., they are non-dependent on the order of operations of StatusBarState listeners). */ + @Deprecated + @Override public void addCallback(StateListener listener, @SbStateListenerRank int rank) { synchronized (mListeners) { addListenerInternalLocked(listener, rank); @@ -264,91 +247,38 @@ public class StatusBarStateController implements CallbackController<StateListene private void addListenerInternalLocked(StateListener listener, int rank) { // Protect against double-subscribe for (RankedListener rl : mListeners) { - if (rl.listener.equals(listener)) { + if (rl.mListener.equals(listener)) { return; } } - RankedListener rl = new RankedListener(listener, rank); + RankedListener rl = new SysuiStatusBarStateController.RankedListener(listener, rank); mListeners.add(rl); - mListeners.sort(mComparator); + mListeners.sort(sComparator); } + + @Override public void removeCallback(StateListener listener) { synchronized (mListeners) { - mListeners.removeIf((it) -> it.listener.equals(listener)); + mListeners.removeIf((it) -> it.mListener.equals(listener)); } } + @Override public void setKeyguardRequested(boolean keyguardRequested) { mKeyguardRequested = keyguardRequested; } + @Override public boolean isKeyguardRequested() { return mKeyguardRequested; } - public static String describe(int state) { - return StatusBarState.toShortString(state); - } - - private class RankedListener { - private final StateListener listener; - private final int rank; - - private RankedListener(StateListener l, int r) { - listener = l; - rank = r; - } - } - /** - * Listener for StatusBarState updates + * Returns String readable state of status bar from {@link StatusBarState} */ - public interface StateListener { - - /** - * Callback before the new state is applied, for those who need to preempt the change. - * - * @param oldState state before the change - * @param newState new state to be applied in {@link #onStateChanged} - */ - public default void onStatePreChange(int oldState, int newState) { - } - - /** - * Callback after all listeners have had a chance to update based on the state change - */ - public default void onStatePostChange() { - } - - /** - * Required callback. Get the new state and do what you will with it. Keep in mind that - * other listeners are typically unordered and don't rely on your work being done before - * other peers. - * - * Only called if the state is actually different. - * - * @param newState the new {@link StatusBarState} - */ - default void onStateChanged(int newState) { - } - - /** - * Callback to be notified when Dozing changes. Dozing is stored separately from state. - * - * @param isDozing {@code true} if dozing according to {@link StatusBar} - */ - public default void onDozingChanged(boolean isDozing) {} - - /** - * Callback to be notified when the doze amount changes. Useful for animations. - * Note: this will be called for each animation frame. Please be careful to avoid - * performance regressions. - * - * @param linear A number from 0 to 1, where 1 means that the device is dozing. - * @param eased Same as {@code linear} but transformed by an interpolator. - */ - default void onDozeAmountChanged(float linear, float eased) {} + public static String describe(int state) { + return StatusBarState.toShortString(state); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java new file mode 100644 index 000000000000..dc5e1e913b4c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar; + +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import android.annotation.IntDef; + +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.phone.StatusBar; + +import java.lang.annotation.Retention; + +/** + * Sends updates to {@link StateListener}s about changes to the status bar state and dozing state + */ +public interface SysuiStatusBarStateController extends StatusBarStateController { + + // TODO: b/115739177 (remove this explicit ordering if we can) + @Retention(SOURCE) + @IntDef({RANK_STATUS_BAR, RANK_STATUS_BAR_WINDOW_CONTROLLER, RANK_STACK_SCROLLER, RANK_SHELF}) + @interface SbStateListenerRank {} + // This is the set of known dependencies when updating StatusBarState + int RANK_STATUS_BAR = 0; + int RANK_STATUS_BAR_WINDOW_CONTROLLER = 1; + int RANK_STACK_SCROLLER = 2; + int RANK_SHELF = 3; + + /** + * Add a listener and a rank based on the priority of this message + * @param listener the listener + * @param rank the order in which you'd like to be called. Ranked listeners will be + * notified before unranked, and we will sort ranked listeners from low to high + * + * @deprecated This method exists only to solve latent inter-dependencies from refactoring + * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking + * (i.e., they are non-dependent on the order of operations of StatusBarState listeners). + */ + @Deprecated + void addCallback(StateListener listener, int rank); + + /** + * Update the status bar state + * @param state see {@link StatusBarState} for valid options + * @return {@code true} if the state changed, else {@code false} + */ + boolean setState(int state); + + /** + * Update the dozing state from {@link StatusBar}'s perspective + * @param isDozing well, are we dozing? + * @return {@code true} if the state changed, else {@code false} + */ + boolean setIsDozing(boolean isDozing); + + /** + * Changes the current doze amount. + * + * @param dozeAmount New doze/dark amount. + * @param animated If change should be animated or not. This will cancel current animations. + */ + void setDozeAmount(float dozeAmount, boolean animated); + + /** + * Sets whether to leave status bar open when hiding keyguard + */ + void setLeaveOpenOnKeyguardHide(boolean leaveOpen); + + /** + * Whether to leave status bar open when hiding keyguard + */ + boolean leaveOpenOnKeyguardHide(); + + /** + * Interpolated doze amount + */ + float getInterpolatedDozeAmount(); + + /** + * Whether status bar is going to full shade + */ + boolean goingToFullShade(); + + /** + * Whether the previous state of the status bar was the shade locked + */ + boolean fromShadeLocked(); + + /** + * Set keyguard requested + */ + void setKeyguardRequested(boolean keyguardRequested); + + /** + * Is keyguard requested + */ + boolean isKeyguardRequested(); + + /** + * Listener with rankings SbStateListenerRank that have dependencies so must be updated + * in a certain order + */ + class RankedListener { + final StateListener mListener; + final int mRank; + + RankedListener(StateListener l, int r) { + mListener = l; + mRank = r; + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java index c50f10b55a71..7cbe1a3e279e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java @@ -35,8 +35,8 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationPresenter; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.policy.HeadsUpManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java index 54ed0d9cd8ce..8b522a2033f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java @@ -16,8 +16,10 @@ package com.android.systemui.statusbar.notification.collection; +import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; +import android.app.Person; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.SnoozeCriterion; @@ -235,8 +237,11 @@ public class NotificationData { if (mRankingMap != null) { getRanking(statusBarNotification.getKey(), mTmpRanking); if (mTmpRanking.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT - || statusBarNotification.getNotification().isForegroundService() - || statusBarNotification.getNotification().hasMediaSession()) { + || isImportantOngoing(statusBarNotification.getNotification()) + || statusBarNotification.getNotification().hasMediaSession() + || hasPerson(statusBarNotification.getNotification()) + || hasStyle(statusBarNotification.getNotification(), + Notification.MessagingStyle.class)) { return true; } if (mGroupManager.isSummaryOfGroup(statusBarNotification)) { @@ -252,6 +257,24 @@ public class NotificationData { return false; } + private boolean isImportantOngoing(Notification notification) { + return notification.isForegroundService() + && mTmpRanking.getImportance() >= NotificationManager.IMPORTANCE_LOW; + } + + private boolean hasStyle(Notification notification, Class targetStyle) { + Class<? extends Notification.Style> style = notification.getNotificationStyle(); + return targetStyle.equals(style); + } + + private boolean hasPerson(Notification notification) { + // TODO: cache favorite and recent contacts to check contact affinity + ArrayList<Person> people = notification.extras != null + ? notification.extras.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST) + : new ArrayList<>(); + return people != null && !people.isEmpty(); + } + public boolean isAmbient(String key) { if (mRankingMap != null) { getRanking(key, mTmpRanking); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java index 5e5241910e7f..c4ecb8259a4f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java @@ -33,9 +33,9 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.UiOffloadThread; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.NotificationListener; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index aa221993cd82..fea01ef61df9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -42,11 +42,11 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java index 4bdc1705c5ff..4c9c2f95b35c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java @@ -17,12 +17,7 @@ package com.android.systemui.statusbar.notification.row.wrapper; import android.content.Context; -import android.content.res.Configuration; import android.graphics.Color; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.Paint; -import android.os.Build; import android.view.View; import com.android.internal.graphics.ColorUtils; @@ -49,43 +44,22 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper { } @Override - public void onReinflated() { - super.onReinflated(); - - Configuration configuration = mView.getResources().getConfiguration(); - boolean nightMode = (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK) - == Configuration.UI_MODE_NIGHT_YES; - - float[] hsl = new float[] {0f, 0f, 0f}; - ColorUtils.colorToHSL(mBackgroundColor, hsl); - boolean backgroundIsDark = Color.alpha(mBackgroundColor) == 0 - || hsl[1] == 0 && hsl[2] < 0.5; - boolean backgroundHasColor = hsl[1] > 0; + public void onContentUpdated(ExpandableNotificationRow row) { + super.onContentUpdated(row); // Let's invert the notification colors when we're in night mode and // the notification background isn't colorized. - if (!backgroundIsDark && !backgroundHasColor && nightMode - && mRow.getEntry().targetSdk < Build.VERSION_CODES.Q) { - Paint paint = new Paint(); - ColorMatrix matrix = new ColorMatrix(); - ColorMatrix tmp = new ColorMatrix(); - // Inversion should happen on Y'UV space to conseve the colors and - // only affect the luminosity. - matrix.setRGB2YUV(); - tmp.set(new float[]{ - -1f, 0f, 0f, 0f, 255f, - 0f, 1f, 0f, 0f, 0f, - 0f, 0f, 1f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - }); - matrix.postConcat(tmp); - tmp.setYUV2RGB(); - matrix.postConcat(tmp); - paint.setColorFilter(new ColorMatrixColorFilter(matrix)); - mView.setLayerType(View.LAYER_TYPE_HARDWARE, paint); - - hsl[2] = 1f - hsl[2]; - mBackgroundColor = ColorUtils.HSLToColor(hsl); + if (needsInversion(mBackgroundColor, mView)) { + invertViewLuminosity(mView); + + // Also invert background color if necessary + // (Otherwise we'd end-up with white on white.) + float[] hsl = new float[] {0f, 0f, 0f}; + ColorUtils.colorToHSL(mBackgroundColor, hsl); + if (mBackgroundColor != Color.TRANSPARENT && hsl[2] > 0.5) { + hsl[2] = 1f - hsl[2]; + mBackgroundColor = ColorUtils.HSLToColor(hsl); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationDecoratedCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationDecoratedCustomViewWrapper.java new file mode 100644 index 000000000000..49a8d56e1e65 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationDecoratedCustomViewWrapper.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row.wrapper; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; + +/** + * Wraps a notification containing a decorated custom view. + */ +public class NotificationDecoratedCustomViewWrapper extends NotificationTemplateViewWrapper { + + private View mWrappedView = null; + + protected NotificationDecoratedCustomViewWrapper(Context ctx, View view, + ExpandableNotificationRow row) { + super(ctx, view, row); + } + + @Override + public void onContentUpdated(ExpandableNotificationRow row) { + ViewGroup container = mView.findViewById( + com.android.internal.R.id.notification_main_column); + Integer childIndex = (Integer) container.getTag( + com.android.internal.R.id.notification_custom_view_index_tag); + if (childIndex != null && childIndex != -1) { + mWrappedView = container.getChildAt(childIndex); + } + if (needsInversion(resolveBackgroundColor(), mWrappedView)) { + invertViewLuminosity(mWrappedView); + } + super.onContentUpdated(row); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java index 9258c9971451..4c06ff6f5e49 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java @@ -16,13 +16,22 @@ package com.android.systemui.statusbar.notification.row.wrapper; +import android.annotation.ColorInt; +import android.app.Notification; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Color; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Paint; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.view.NotificationHeaderView; import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import com.android.internal.graphics.ColorUtils; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.notification.TransformState; @@ -50,6 +59,11 @@ public abstract class NotificationViewWrapper implements TransformableView { } else if ("messaging".equals(v.getTag())) { return new NotificationMessagingTemplateViewWrapper(ctx, v, row); } + Class<? extends Notification.Style> style = + row.getEntry().notification.getNotification().getNotificationStyle(); + if (Notification.DecoratedCustomViewStyle.class.equals(style)) { + return new NotificationDecoratedCustomViewWrapper(ctx, v, row); + } return new NotificationTemplateViewWrapper(ctx, v, row); } else if (v instanceof NotificationHeaderView) { return new NotificationHeaderViewWrapper(ctx, v, row); @@ -75,14 +89,110 @@ public abstract class NotificationViewWrapper implements TransformableView { if (shouldClearBackgroundOnReapply()) { mBackgroundColor = 0; } - Drawable background = mView.getBackground(); - if (background instanceof ColorDrawable) { - int backgroundColor = ((ColorDrawable) background).getColor(); - if (backgroundColor != Color.TRANSPARENT) { - mBackgroundColor = backgroundColor; - mView.setBackground(new ColorDrawable(Color.TRANSPARENT)); + int backgroundColor = getBackgroundColor(mView); + if (backgroundColor != Color.TRANSPARENT) { + mBackgroundColor = backgroundColor; + mView.setBackground(new ColorDrawable(Color.TRANSPARENT)); + } + } + + protected boolean needsInversion(int defaultBackgroundColor, View view) { + if (view == null) { + return false; + } + + Configuration configuration = mView.getResources().getConfiguration(); + boolean nightMode = (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK) + == Configuration.UI_MODE_NIGHT_YES; + if (!nightMode) { + return false; + } + + int background = getBackgroundColor(view); + if (background == Color.TRANSPARENT) { + background = defaultBackgroundColor; + } + if (background == Color.TRANSPARENT) { + background = resolveBackgroundColor(); + } + + float[] hsl = new float[] {0f, 0f, 0f}; + ColorUtils.colorToHSL(background, hsl); + + // Notifications with colored backgrounds should not be inverted + if (hsl[1] != 0) { + return false; + } + + // Invert white or light gray backgrounds. + boolean isLightGrayOrWhite = hsl[1] == 0 && hsl[2] > 0.5; + if (isLightGrayOrWhite) { + return true; + } + + // Now let's check if there's unprotected text somewhere, and invert if we find it. + if (view instanceof ViewGroup) { + return childrenNeedInversion(background, (ViewGroup) view); + } else { + return false; + } + } + + private boolean childrenNeedInversion(@ColorInt int parentBackground, ViewGroup viewGroup) { + if (viewGroup == null) { + return false; + } + + for (int i = 0; i < viewGroup.getChildCount(); i++) { + View child = viewGroup.getChildAt(i); + int backgroundColor = getBackgroundColor(viewGroup); + if (backgroundColor == Color.TRANSPARENT) { + backgroundColor = parentBackground; } + if (child instanceof TextView) { + int foreground = ((TextView) child).getCurrentTextColor(); + if (ColorUtils.calculateContrast(foreground, backgroundColor) < 3) { + return true; + } + } else if (child instanceof ViewGroup) { + if (childrenNeedInversion(backgroundColor, (ViewGroup) child)) { + return true; + } + } + } + + return false; + } + + protected int getBackgroundColor(View view) { + if (view == null) { + return Color.TRANSPARENT; } + Drawable background = view.getBackground(); + if (background instanceof ColorDrawable) { + return ((ColorDrawable) background).getColor(); + } + return Color.TRANSPARENT; + } + + protected void invertViewLuminosity(View view) { + Paint paint = new Paint(); + ColorMatrix matrix = new ColorMatrix(); + ColorMatrix tmp = new ColorMatrix(); + // Inversion should happen on Y'UV space to conserve the colors and + // only affect the luminosity. + matrix.setRGB2YUV(); + tmp.set(new float[]{ + -1f, 0f, 0f, 0f, 255f, + 0f, 1f, 0f, 0f, 0f, + 0f, 0f, 1f, 0f, 0f, + 0f, 0f, 0f, 1f, 0f + }); + matrix.postConcat(tmp); + tmp.setYUV2RGB(); + matrix.postConcat(tmp); + paint.setColorFilter(new ColorMatrixColorFilter(matrix)); + view.setLayerType(View.LAYER_TYPE_HARDWARE, paint); } protected boolean shouldClearBackgroundOnReapply() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 855cfd9ef7cf..7105876907bf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -86,6 +86,8 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DragDownHelper.DragDownCallback; import com.android.systemui.statusbar.EmptyShadeView; @@ -94,8 +96,7 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; @@ -664,8 +665,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) protected void onAttachedToWindow() { super.onAttachedToWindow(); - Dependency.get(StatusBarStateController.class) - .addCallback(mStateListener, StatusBarStateController.RANK_STACK_SCROLLER); + ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class)) + .addCallback(mStateListener, SysuiStatusBarStateController.RANK_STACK_SCROLLER); Dependency.get(ConfigurationController.class).addCallback(this); } @@ -5430,7 +5431,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mHeadsUpAppearanceController.setPublicMode(publicMode); } - StatusBarStateController state = Dependency.get(StatusBarStateController.class); + SysuiStatusBarStateController state = (SysuiStatusBarStateController) + Dependency.get(StatusBarStateController.class); setHideSensitive(publicMode, state.goingToFullShade() /* animate */); setDimmed(onKeyguard, state.fromShadeLocked() /* animate */); setExpandingEnabled(!onKeyguard); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java index 35763dce5529..6410860a852d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java @@ -33,8 +33,8 @@ import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager; import com.android.systemui.statusbar.policy.EncryptionHelper; import com.android.systemui.statusbar.policy.KeyguardMonitor; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java index 280dda0cd1dc..d9d74b9d17a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java @@ -24,8 +24,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; /** * Controller which handles all the doze animations of the scrims. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index 035ccf1d6b81..4c1c0a4b4e58 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -38,9 +38,9 @@ import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.ScreenDecorations; import com.android.systemui.bubbles.BubbleController; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java index 1944c3f21444..5ccb9b294718 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java @@ -33,9 +33,9 @@ import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.Interpolators; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.policy.KeyguardMonitor; import java.io.FileDescriptor; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index ee047e41ec78..538d79717293 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -85,6 +85,7 @@ import com.android.systemui.SysUiServiceProvider; import com.android.systemui.assist.AssistManager; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -92,7 +93,6 @@ import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.ContextualButton.ContextButtonListener; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java index d364356b19fe..b613e8efa8ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java @@ -25,12 +25,12 @@ import android.util.ArrayMap; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.AmbientPulseManager.OnAmbientChangedListener; import com.android.systemui.statusbar.InflationTask; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java index bb9e4183ba76..cc8af3ba64fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java @@ -22,11 +22,11 @@ import android.util.ArraySet; import android.util.Log; import com.android.systemui.Dependency; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.AmbientPulseManager.OnAmbientChangedListener; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.policy.HeadsUpManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index 9e99fe9dac36..62f85fe8a00e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -11,6 +11,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import androidx.annotation.NonNull; +import androidx.collection.ArrayMap; + import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.ContrastColorUtil; @@ -19,10 +22,10 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarIconView; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -31,9 +34,6 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import java.util.ArrayList; import java.util.function.Function; -import androidx.annotation.NonNull; -import androidx.collection.ArrayMap; - /** * A controller for the space in the status bar to the left of the system icons. This area is * normally reserved for notifications. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index a9727c953afe..069703e9dd81 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -17,8 +17,7 @@ package com.android.systemui.statusbar.phone; import static com.android.systemui.SysUiServiceProvider.getComponent; -import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator - .ExpandAnimationParameters; +import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -63,6 +62,8 @@ import com.android.systemui.classifier.FalsingManager; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.plugins.qs.QS; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.qs.QSFragment; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.FlingAnimationUtils; @@ -73,8 +74,6 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.NotificationEntryManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index f17145d72be1..4d0c8c3a7fb6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -44,9 +44,10 @@ import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.classifier.FalsingManager; import com.android.systemui.doze.DozeLog; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.policy.KeyguardMonitor; @@ -142,8 +143,8 @@ public abstract class PanelView extends FrameLayout { private boolean mIgnoreXTouchSlop; private boolean mExpandLatencyTracking; protected final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); - protected final StatusBarStateController mStatusBarStateController = - Dependency.get(StatusBarStateController.class); + protected final SysuiStatusBarStateController mStatusBarStateController = + (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class); protected void onExpandingFinished() { mBar.onExpandingFinished(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 37a0610d4de5..9f3bec60cb6d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -163,6 +163,7 @@ import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSFragment; import com.android.systemui.qs.QSPanel; import com.android.systemui.recents.Recents; @@ -188,7 +189,8 @@ import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.StatusBarStateControllerImpl; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; import com.android.systemui.statusbar.notification.NotificationActivityStarter; @@ -558,8 +560,8 @@ public class StatusBar extends SystemUI implements DemoMode, }; private boolean mNoAnimationOnNextBarModeChange; protected FalsingManager mFalsingManager; - private final StatusBarStateController - mStatusBarStateController = Dependency.get(StatusBarStateController.class); + private final SysuiStatusBarStateController mStatusBarStateController = + (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class); private final KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { @@ -650,7 +652,8 @@ public class StatusBar extends SystemUI implements DemoMode, } mColorExtractor.addOnColorsChangedListener(this); - mStatusBarStateController.addCallback(this, StatusBarStateController.RANK_STATUS_BAR); + mStatusBarStateController.addCallback(this, + StatusBarStateControllerImpl.RANK_STATUS_BAR); mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); mDreamManager = IDreamManager.Stub.asInterface( @@ -804,15 +807,17 @@ public class StatusBar extends SystemUI implements DemoMode, mNotificationLogger.setUpWithContainer(notifListContainer); mNotificationIconAreaController = SystemUIFactory.getInstance() - .createNotificationIconAreaController( - context, this, mStatusBarStateController, mNotificationListener); + .createNotificationIconAreaController(context, this, + mStatusBarStateController, mNotificationListener); inflateShelf(); mNotificationIconAreaController.setupShelf(mNotificationShelf); Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController); - // Allow plugins to reference DarkIconDispatcher + // Allow plugins to reference DarkIconDispatcher and StatusBarStateController Dependency.get(PluginDependencyProvider.class) .allowPluginDependency(DarkIconDispatcher.class); + Dependency.get(PluginDependencyProvider.class) + .allowPluginDependency(StatusBarStateController.class); FragmentHostManager.get(mStatusBarWindow) .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> { CollapsedStatusBarFragment statusBarFragment = @@ -3370,7 +3375,8 @@ public class StatusBar extends SystemUI implements DemoMode, // ringing. // Other transitions are covered in handleVisibleToUserChanged(). if (mVisible && (newState == StatusBarState.SHADE_LOCKED - || (Dependency.get(StatusBarStateController.class).goingToFullShade()))) { + || (((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class)) + .goingToFullShade()))) { clearNotificationEffects(); } if (newState == StatusBarState.KEYGUARD) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index bb23608799f0..5014783c43b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -42,10 +42,11 @@ import com.android.systemui.DejankUtils; import com.android.systemui.Dependency; import com.android.systemui.SystemUIFactory; import com.android.systemui.keyguard.DismissCallbackRegistry; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.RemoteInputController; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.phone.KeyguardBouncer.BouncerExpansionCallback; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.KeyguardMonitorImpl; @@ -701,7 +702,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } public boolean isGoingToNotificationShade() { - return Dependency.get(StatusBarStateController.class).leaveOpenOnKeyguardHide(); + return ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class)) + .leaveOpenOnKeyguardHide(); } public boolean isSecure(int userId) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index 86326beb8b00..b0e006d75f81 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -51,13 +51,13 @@ import com.android.systemui.EventLogTags; import com.android.systemui.UiOffloadThread; import com.android.systemui.assist.AssistManager; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationEntryListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index df7f53b3b63a..e9705ff35a4d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -48,6 +48,7 @@ import com.android.systemui.InitController; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -56,7 +57,7 @@ import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.AboveShelfObserver; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; import com.android.systemui.statusbar.notification.NotificationAlertingManager; @@ -92,8 +93,8 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, Dependency.get(NotificationViewHierarchyManager.class); private final NotificationLockscreenUserManager mLockscreenUserManager = Dependency.get(NotificationLockscreenUserManager.class); - private final StatusBarStateController mStatusBarStateController = - Dependency.get(StatusBarStateController.class); + private final SysuiStatusBarStateController mStatusBarStateController = + (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class); private final NotificationEntryManager mEntryManager = Dependency.get(NotificationEntryManager.class); private final NotificationRowBinder mNotificationRowBinder = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java index 8d5841088591..21d9dcc6897d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java @@ -35,13 +35,14 @@ import android.view.ViewParent; import com.android.systemui.Dependency; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationRemoteInputManager.Callback; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.KeyguardMonitor; @@ -57,10 +58,10 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, StatusBarStateController.StateListener { private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); - private final StatusBarStateController mStatusBarStateController - = Dependency.get(StatusBarStateController.class); - private final NotificationLockscreenUserManager mLockscreenUserManager - = Dependency.get(NotificationLockscreenUserManager.class); + private final SysuiStatusBarStateController mStatusBarStateController = + (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class); + private final NotificationLockscreenUserManager mLockscreenUserManager = + Dependency.get(NotificationLockscreenUserManager.class); private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class); private final Context mContext; private View mPendingWorkRemoteInputView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java index 86e17f33fc77..e1a77b00f3ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java @@ -43,10 +43,11 @@ import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.RemoteInputController.Callback; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; @@ -98,8 +99,9 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat mDozeParameters = dozeParameters; mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze(); mLpChanged = new WindowManager.LayoutParams(); - Dependency.get(StatusBarStateController.class).addCallback( - mStateListener, StatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER); + ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class)) + .addCallback(mStateListener, + SysuiStatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER); Dependency.get(ConfigurationController.class).addCallback(this); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index c39e17266b56..ad4ba75d6569 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -59,15 +59,14 @@ import com.android.systemui.Dependency; import com.android.systemui.ExpandHelper; import com.android.systemui.R; import com.android.systemui.classifier.FalsingManager; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.DragDownHelper; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import java.io.FileDescriptor; import java.io.PrintWriter; - public class StatusBarWindowView extends FrameLayout { public static final String TAG = "StatusBarWindowView"; public static final boolean DEBUG = StatusBar.DEBUG; diff --git a/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java b/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java index 52cabe278e2d..6ee341dd974c 100644 --- a/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java +++ b/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java @@ -34,7 +34,7 @@ import android.widget.ImageView; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; import com.android.systemui.statusbar.notification.stack.AnimationProperties; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java index d80b444ad64b..5d03f19f4655 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java @@ -42,8 +42,8 @@ import android.widget.TextClock; import com.android.keyguard.clock.ClockManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ClockPlugin; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import org.junit.Before; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java index cfc19ef28c92..01d7b8b21b0c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java @@ -44,8 +44,8 @@ import androidx.slice.core.SliceQuery; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationMediaManager; -import com.android.systemui.statusbar.StatusBarStateController; import org.junit.Assert; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java index e5464e0343f4..86f6cd331fc9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java @@ -47,10 +47,10 @@ import com.android.internal.logging.MetricsLogger; import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.qs.QSTile; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QSTileHost; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import org.junit.Before; import org.junit.Ignore; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java index 56e1fc6b70de..62700c0b3b4c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java @@ -95,7 +95,7 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { mViewHierarchyManager = new NotificationViewHierarchyManager(mContext, mLockscreenUserManager, mGroupManager, mVisualStabilityManager, - mock(StatusBarStateController.class), mEntryManager, + mock(StatusBarStateControllerImpl.class), mEntryManager, () -> mShadeController); Dependency.get(InitController.class).executePostInitTasks(); mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java index ba2aec0dd3e1..9f36a1eb9943 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java @@ -23,12 +23,19 @@ import static android.app.Notification.CATEGORY_CALL; import static android.app.Notification.CATEGORY_EVENT; import static android.app.Notification.CATEGORY_MESSAGE; import static android.app.Notification.CATEGORY_REMINDER; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.NotificationManager.IMPORTANCE_MIN; + +import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_CHANNEL; +import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_IMPORTANCE; +import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_VIS_EFFECTS; import static junit.framework.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -36,6 +43,7 @@ import static org.mockito.Mockito.when; import android.Manifest; import android.app.Notification; import android.app.NotificationChannel; +import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Person; import android.content.Intent; @@ -84,8 +92,6 @@ public class NotificationDataTest extends SysuiTestCase { private static final int UID_NORMAL = 123; private static final int UID_ALLOW_DURING_SETUP = 456; - private static final String TEST_HIDDEN_NOTIFICATION_KEY = "testHiddenNotificationKey"; - private static final String TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY = "exempt"; private static final NotificationChannel NOTIFICATION_CHANNEL = new NotificationChannel("id", "name", NotificationChannel.USER_LOCKED_IMPORTANCE); @@ -97,7 +103,7 @@ public class NotificationDataTest extends SysuiTestCase { NotificationData.KeyguardEnvironment mEnvironment; private final IPackageManager mMockPackageManager = mock(IPackageManager.class); - private NotificationData mNotificationData; + private TestableNotificationData mNotificationData; private ExpandableNotificationRow mRow; @Before @@ -131,6 +137,7 @@ public class NotificationDataTest extends SysuiTestCase { @Test public void testChannelSetWhenAdded() { + mNotificationData.rankingOverrides.putParcelable(OVERRIDE_CHANNEL, NOTIFICATION_CHANNEL); mNotificationData.add(mRow.getEntry()); assertEquals(NOTIFICATION_CHANNEL, mRow.getEntry().channel); } @@ -217,12 +224,12 @@ public class NotificationDataTest extends SysuiTestCase { @Test public void testIsExemptFromDndVisualSuppression_foreground() { initStatusBarNotification(false); - when(mMockStatusBarNotification.getKey()).thenReturn( - TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY); + Notification n = mMockStatusBarNotification.getNotification(); n.flags = Notification.FLAG_FOREGROUND_SERVICE; NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification); mNotificationData.add(entry); + mNotificationData.rankingOverrides.putInt(OVERRIDE_VIS_EFFECTS, 255); assertTrue(entry.isExemptFromDndVisualSuppression()); assertFalse(entry.shouldSuppressAmbient()); @@ -231,8 +238,6 @@ public class NotificationDataTest extends SysuiTestCase { @Test public void testIsExemptFromDndVisualSuppression_media() { initStatusBarNotification(false); - when(mMockStatusBarNotification.getKey()).thenReturn( - TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY); Notification n = mMockStatusBarNotification.getNotification(); Notification.Builder nb = Notification.Builder.recoverBuilder(mContext, n); nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class))); @@ -240,6 +245,7 @@ public class NotificationDataTest extends SysuiTestCase { when(mMockStatusBarNotification.getNotification()).thenReturn(n); NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification); mNotificationData.add(entry); + mNotificationData.rankingOverrides.putInt(OVERRIDE_VIS_EFFECTS, 255); assertTrue(entry.isExemptFromDndVisualSuppression()); assertFalse(entry.shouldSuppressAmbient()); @@ -248,11 +254,10 @@ public class NotificationDataTest extends SysuiTestCase { @Test public void testIsExemptFromDndVisualSuppression_system() { initStatusBarNotification(false); - when(mMockStatusBarNotification.getKey()).thenReturn( - TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY); NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification); entry.mIsSystemNotification = true; mNotificationData.add(entry); + mNotificationData.rankingOverrides.putInt(OVERRIDE_VIS_EFFECTS, 255); assertTrue(entry.isExemptFromDndVisualSuppression()); assertFalse(entry.shouldSuppressAmbient()); @@ -261,10 +266,10 @@ public class NotificationDataTest extends SysuiTestCase { @Test public void testIsNotExemptFromDndVisualSuppression_hiddenCategories() { initStatusBarNotification(false); - when(mMockStatusBarNotification.getKey()).thenReturn( - TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY); NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification); entry.mIsSystemNotification = true; + mNotificationData.rankingOverrides.putInt(OVERRIDE_VIS_EFFECTS, + NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT); mNotificationData.add(entry); when(mMockStatusBarNotification.getNotification()).thenReturn( @@ -353,6 +358,64 @@ public class NotificationDataTest extends SysuiTestCase { assertTrue(entry.isLastMessageFromReply()); } + @Test + public void personHighPriority() { + Person person = new Person.Builder() + .setName("name") + .setKey("abc") + .setUri("uri") + .setBot(true) + .build(); + + Notification notification = new Notification.Builder(mContext, "test") + .addPerson(person) + .build(); + + StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, + notification, mContext.getUser(), "", 0); + + assertTrue(mNotificationData.isHighPriority(sbn)); + } + + @Test + public void messagingStyleHighPriority() { + + Notification notification = new Notification.Builder(mContext, "test") + .setStyle(new Notification.MessagingStyle("")) + .build(); + + StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, + notification, mContext.getUser(), "", 0); + + assertTrue(mNotificationData.isHighPriority(sbn)); + } + + @Test + public void minForegroundNotHighPriority() { + Notification notification = mock(Notification.class); + when(notification.isForegroundService()).thenReturn(true); + + mNotificationData.rankingOverrides.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_MIN); + + StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, + notification, mContext.getUser(), "", 0); + + assertFalse(mNotificationData.isHighPriority(sbn)); + } + + @Test + public void lowForegroundHighPriority() { + Notification notification = mock(Notification.class); + when(notification.isForegroundService()).thenReturn(true); + + mNotificationData.rankingOverrides.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_LOW); + + StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0, + notification, mContext.getUser(), "", 0); + + assertTrue(mNotificationData.isHighPriority(sbn)); + } + private void initStatusBarNotification(boolean allowDuringSetup) { Bundle bundle = new Bundle(); bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup); @@ -362,39 +425,90 @@ public class NotificationDataTest extends SysuiTestCase { when(mMockStatusBarNotification.getNotification()).thenReturn(notification); } - private class TestableNotificationData extends NotificationData { + public static class TestableNotificationData extends NotificationData { public TestableNotificationData() { super(); } + public static final String OVERRIDE_RANK = "r"; + public static final String OVERRIDE_DND = "dnd"; + public static final String OVERRIDE_VIS_OVERRIDE = "vo"; + public static final String OVERRIDE_VIS_EFFECTS = "ve"; + public static final String OVERRIDE_IMPORTANCE = "i"; + public static final String OVERRIDE_IMP_EXP = "ie"; + public static final String OVERRIDE_GROUP = "g"; + public static final String OVERRIDE_CHANNEL = "c"; + public static final String OVERRIDE_PEOPLE = "p"; + public static final String OVERRIDE_SNOOZE_CRITERIA = "sc"; + public static final String OVERRIDE_BADGE = "b"; + public static final String OVERRIDE_USER_SENTIMENT = "us"; + public static final String OVERRIDE_HIDDEN = "h"; + public static final String OVERRIDE_LAST_ALERTED = "la"; + public static final String OVERRIDE_NOISY = "n"; + public static final String OVERRIDE_SMART_ACTIONS = "sa"; + public static final String OVERRIDE_SMART_REPLIES = "sr"; + public static final String OVERRIDE_BUBBLE = "cb"; + + public Bundle rankingOverrides = new Bundle(); + @Override protected boolean getRanking(String key, Ranking outRanking) { super.getRanking(key, outRanking); - if (key.equals(TEST_HIDDEN_NOTIFICATION_KEY)) { - outRanking.populate(key, outRanking.getRank(), - outRanking.matchesInterruptionFilter(), - outRanking.getVisibilityOverride(), outRanking.getSuppressedVisualEffects(), - outRanking.getImportance(), outRanking.getImportanceExplanation(), - outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null, - outRanking.canShowBadge(), outRanking.getUserSentiment(), true, - -1, false, null, null, outRanking.canBubble()); - } else if (key.equals(TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY)) { - outRanking.populate(key, outRanking.getRank(), - outRanking.matchesInterruptionFilter(), - outRanking.getVisibilityOverride(), 255, - outRanking.getImportance(), outRanking.getImportanceExplanation(), - outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null, - outRanking.canShowBadge(), outRanking.getUserSentiment(), true, -1, - false, null, null, outRanking.canBubble()); - } else { - outRanking.populate(key, outRanking.getRank(), - outRanking.matchesInterruptionFilter(), - outRanking.getVisibilityOverride(), outRanking.getSuppressedVisualEffects(), - outRanking.getImportance(), outRanking.getImportanceExplanation(), - outRanking.getOverrideGroupKey(), NOTIFICATION_CHANNEL, null, null, - outRanking.canShowBadge(), outRanking.getUserSentiment(), false, -1, - false, null, null, outRanking.canBubble()); + + ArrayList<String> currentAdditionalPeople = new ArrayList<>(); + if (outRanking.getAdditionalPeople() != null) { + currentAdditionalPeople.addAll(outRanking.getAdditionalPeople()); + } + + ArrayList<SnoozeCriterion> currentSnooze = new ArrayList<>(); + if (outRanking.getSnoozeCriteria() != null) { + currentSnooze.addAll(outRanking.getSnoozeCriteria()); + } + + ArrayList<Notification.Action> currentActions = new ArrayList<>(); + if (outRanking.getSmartActions() != null) { + currentActions.addAll(outRanking.getSmartActions()); } + + ArrayList<CharSequence> currentReplies = new ArrayList<>(); + if (outRanking.getSmartReplies() != null) { + currentReplies.addAll(outRanking.getSmartReplies()); + } + + outRanking.populate(key, + rankingOverrides.getInt(OVERRIDE_RANK, outRanking.getRank()), + rankingOverrides.getBoolean(OVERRIDE_DND, + outRanking.matchesInterruptionFilter()), + rankingOverrides.getInt(OVERRIDE_VIS_OVERRIDE, + outRanking.getVisibilityOverride()), + rankingOverrides.getInt(OVERRIDE_VIS_EFFECTS, + outRanking.getSuppressedVisualEffects()), + rankingOverrides.getInt(OVERRIDE_IMPORTANCE, outRanking.getImportance()), + rankingOverrides.getCharSequence(OVERRIDE_IMP_EXP, + outRanking.getImportanceExplanation()), + rankingOverrides.getString(OVERRIDE_GROUP, outRanking.getOverrideGroupKey()), + rankingOverrides.containsKey(OVERRIDE_CHANNEL) + ? (NotificationChannel) rankingOverrides.getParcelable(OVERRIDE_CHANNEL) + : outRanking.getChannel(), + rankingOverrides.containsKey(OVERRIDE_PEOPLE) + ? rankingOverrides.getStringArrayList(OVERRIDE_PEOPLE) + : currentAdditionalPeople, + rankingOverrides.containsKey(OVERRIDE_SNOOZE_CRITERIA) + ? rankingOverrides.getParcelableArrayList(OVERRIDE_SNOOZE_CRITERIA) + : currentSnooze, + rankingOverrides.getBoolean(OVERRIDE_BADGE, outRanking.canShowBadge()), + rankingOverrides.getInt(OVERRIDE_USER_SENTIMENT, outRanking.getUserSentiment()), + rankingOverrides.getBoolean(OVERRIDE_HIDDEN, outRanking.isSuspended()), + rankingOverrides.getLong(OVERRIDE_LAST_ALERTED, + outRanking.getLastAudiblyAlertedMillis()), + rankingOverrides.getBoolean(OVERRIDE_NOISY, outRanking.isNoisy()), + rankingOverrides.containsKey(OVERRIDE_SMART_ACTIONS) + ? rankingOverrides.getParcelableArrayList(OVERRIDE_SMART_ACTIONS) + : currentActions, + rankingOverrides.containsKey(OVERRIDE_SMART_REPLIES) + ? rankingOverrides.getCharSequenceArrayList(OVERRIDE_SMART_REPLIES) + : currentReplies, + rankingOverrides.getBoolean(OVERRIDE_BUBBLE, outRanking.canBubble())); return true; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java index db2706bee3c9..d47700b6f3e0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java @@ -40,7 +40,7 @@ import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.UiOffloadThread; import com.android.systemui.statusbar.NotificationListener; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationData; @@ -99,7 +99,7 @@ public class NotificationLoggerTest extends SysuiTestCase { mEntry.setRow(mRow); mLogger = new TestableNotificationLogger(mListener, Dependency.get(UiOffloadThread.class), - mEntryManager, mock(StatusBarStateController.class), mBarService, + mEntryManager, mock(StatusBarStateControllerImpl.class), mBarService, mExpansionStateLogger); mLogger.setUpWithContainer(mListContainer); verify(mEntryManager).addNotificationEntryListener(mEntryListenerCaptor.capture()); @@ -167,7 +167,7 @@ public class NotificationLoggerTest extends SysuiTestCase { TestableNotificationLogger(NotificationListener notificationListener, UiOffloadThread uiOffloadThread, NotificationEntryManager entryManager, - StatusBarStateController statusBarStateController, + StatusBarStateControllerImpl statusBarStateController, IStatusBarService barService, ExpansionStateLogger expansionStateLogger) { super(notificationListener, uiOffloadThread, entryManager, statusBarStateController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index ae70b01cd35c..d83508201529 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -51,13 +51,13 @@ import com.android.systemui.InitController; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationData; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java index a72be7af8cd8..3c5425ce7d6f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java @@ -32,8 +32,8 @@ import android.view.ViewPropertyAnimator; import com.android.systemui.R; import com.android.systemui.SysuiBaseFragmentTest; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.tuner.TunerService; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java index 13145b830178..608dd8b0d281 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java @@ -20,23 +20,15 @@ import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MOD import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import android.content.Context; import android.provider.Settings; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import com.android.systemui.SysuiTestCase; -import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationListener; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.phone.LightBarTransitionsController.DarkIntensityApplier; import org.junit.Before; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 3b98f0ca8ce2..a97fa1ff1629 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -27,8 +27,9 @@ import android.testing.TestableLooper; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; @@ -46,7 +47,7 @@ import org.mockito.MockitoAnnotations; public class NotificationPanelViewTest extends SysuiTestCase { @Mock - private StatusBarStateController mStatusBarStateController; + private SysuiStatusBarStateController mStatusBarStateController; @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout; @Mock diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index 036e57acb7e4..a95361f9e046 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -82,6 +82,7 @@ import com.android.systemui.doze.DozeLog; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.NavigationBarController; @@ -94,7 +95,7 @@ import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.notification.NotificationAlertingManager; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; @@ -153,7 +154,7 @@ public class StatusBarTest extends SysuiTestCase { @Mock private NotificationLockscreenUserManager mLockscreenUserManager; @Mock private NotificationRemoteInputManager mRemoteInputManager; @Mock private RemoteInputController mRemoteInputController; - @Mock private StatusBarStateController mStatusBarStateController; + @Mock private StatusBarStateControllerImpl mStatusBarStateController; @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private NotificationPresenter mNotificationPresenter; @Mock diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java index 46335dc3b5ec..11284d6ce261 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java @@ -28,9 +28,9 @@ import android.view.MotionEvent; import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.DragDownHelper; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import org.junit.Before; diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto index 2b45b49ff322..82359c547a88 100644 --- a/proto/src/wifi.proto +++ b/proto/src/wifi.proto @@ -515,6 +515,9 @@ message WifiLog { // Total number of scan results for WPA3-Enterprise networks optional int32 num_wpa3_enterprise_network_scan_results = 136; + + // WifiConfigStore read/write metrics. + optional WifiConfigStoreIO wifi_config_store_io = 137; } // Information that gets logged for every WiFi connection. @@ -668,6 +671,9 @@ message ConnectionEvent { // Has bug report been taken. optional bool automatic_bug_report_taken = 9; + + // Connection is using locally generated random MAC address. + optional bool use_randomized_mac = 10 [default = false]; } // Number of occurrences of a specific RSSI poll rssi value @@ -1874,6 +1880,13 @@ message WifiUsabilityStatsEntry { // Rx link speed at the sample time in Mbps optional int32 rx_link_speed_mbps = 27; + + // Sequence number generated by framework + optional int32 seq_num_inside_framework = 28; + + // Whether current entry is for the same BSSID on the same frequency compared + // to last entry + optional bool is_same_bssid_and_freq = 29; } message WifiUsabilityStats { @@ -2170,3 +2183,25 @@ message WifiDppLog { EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = 9; } } + +// WifiConfigStore read/write metrics. +message WifiConfigStoreIO { + // Histogram of config store read durations. + repeated DurationBucket read_durations = 1; + + // Histogram of config store write durations. + repeated DurationBucket write_durations = 2; + + // Total Number of instances of write/read duration in this duration bucket. + message DurationBucket { + // Bucket covers duration : [range_start_ms, range_end_ms) + // The (inclusive) lower bound of read/write duration represented by this bucket + optional int32 range_start_ms = 1; + + // The (exclusive) upper bound of read/write duration represented by this bucket + optional int32 range_end_ms = 2; + + // Number of read/write durations that fit into this bucket + optional int32 count = 3; + } +} diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index 9249c9cc023a..4afbc641ea6c 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; +import android.app.ActivityThread; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -39,6 +40,7 @@ import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.UserHandle; import android.os.UserManager; +import android.provider.DeviceConfig; import android.provider.Settings; import android.util.LocalLog; import android.util.Slog; @@ -89,19 +91,38 @@ public final class ContentCaptureManagerService extends @Nullable private SparseBooleanArray mDisabledUsers; + /** + * Global kill-switch based on value defined by + * {@link ContentCaptureManager#DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED}. + */ + @GuardedBy("mLock") + @Nullable + private boolean mDisabledByDeviceConfig; public ContentCaptureManagerService(@NonNull Context context) { super(context, new FrameworkResourcesServiceNameResolver(context, com.android.internal.R.string.config_defaultContentCaptureService), UserManager.DISALLOW_CONTENT_CAPTURE); - // Sets which serviecs are disabled + DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_CONTENT_CAPTURE, + ActivityThread.currentApplication().getMainExecutor(), + (namespace, key, value) -> { + if (!ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED + .equals(key)) { + Slog.i(mTag, "Ignoring change on " + key); + return; + } + setDisabledByDeviceConfig(value); + }); + setDisabledByDeviceConfig(); + + // Sets which services are disabled final UserManager um = getContext().getSystemService(UserManager.class); final List<UserInfo> users = um.getUsers(); for (int i = 0; i < users.size(); i++) { final int userId = users.get(i).id; - final boolean disabled = isDisabledBySettings(userId); + final boolean disabled = mDisabledByDeviceConfig || isDisabledBySettings(userId); if (disabled) { - Slog.i(mTag, "user " + userId + " disabled by settings"); + Slog.i(mTag, "user " + userId + " disabled by settings or device config"); if (mDisabledUsers == null) { mDisabledUsers = new SparseBooleanArray(1); } @@ -160,7 +181,8 @@ public final class ContentCaptureManagerService extends @Override // from AbstractMasterSystemService protected boolean isDisabledLocked(@UserIdInt int userId) { - return isDisabledBySettingsLocked(userId) || super.isDisabledLocked(userId); + return mDisabledByDeviceConfig || isDisabledBySettingsLocked(userId) + || super.isDisabledLocked(userId); } private boolean isDisabledBySettingsLocked(@UserIdInt int userId) { @@ -191,6 +213,45 @@ public final class ContentCaptureManagerService extends return false; } + private void setDisabledByDeviceConfig() { + final String value = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_CONTENT_CAPTURE, + ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED); + setDisabledByDeviceConfig(value); + } + + private void setDisabledByDeviceConfig(@Nullable String value) { + if (verbose) Slog.v(mTag, "setDisabledByDeviceConfig(): value=" + value); + final UserManager um = getContext().getSystemService(UserManager.class); + final List<UserInfo> users = um.getUsers(); + + final boolean newDisabledValue; + + if (value != null && value.equalsIgnoreCase("false")) { + newDisabledValue = true; + } else { + newDisabledValue = false; + } + + synchronized (mLock) { + if (mDisabledByDeviceConfig == newDisabledValue) { + if (verbose) { + Slog.v(mTag, "setDisabledByDeviceConfig(): already " + newDisabledValue); + } + return; + } + mDisabledByDeviceConfig = newDisabledValue; + + Slog.i(mTag, "setDisabledByDeviceConfig(): set to " + mDisabledByDeviceConfig); + for (int i = 0; i < users.size(); i++) { + final int userId = users.get(i).id; + boolean disabled = mDisabledByDeviceConfig || isDisabledBySettingsLocked(userId); + Slog.i(mTag, "setDisabledByDeviceConfig(): updating service for user " + + userId + " to " + (disabled ? "'disabled'" : "'enabled'")); + updateCachedServiceLocked(userId, disabled); + } + } + } + private void setContentCaptureFeatureEnabledForUser(@UserIdInt int userId, boolean enabled) { synchronized (mLock) { if (mDisabledUsers == null) { @@ -338,6 +399,8 @@ public final class ContentCaptureManagerService extends super.dumpLocked(prefix, pw); pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers); + pw.print(prefix); pw.print("Disabled by DeviceConfig: "); + pw.println(mDisabledByDeviceConfig); } final class ContentCaptureManagerServiceStub extends IContentCaptureManager.Stub { @@ -406,7 +469,7 @@ public final class ContentCaptureManagerService extends "isContentCaptureFeatureEnabled()", userId, Binder.getCallingUid(), result); if (!isService) return; - enabled = !isDisabledBySettingsLocked(userId); + enabled = !mDisabledByDeviceConfig && !isDisabledBySettingsLocked(userId); } try { result.send(enabled ? ContentCaptureManager.RESULT_CODE_TRUE diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index f2329d3ebf8e..e7d7434b5dc8 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -4013,7 +4013,7 @@ class StorageManagerService extends IStorageManager.Stub return; } userPackages.add(packageName); - sandboxId = getSandboxId(packageName, sharedUserId); + sandboxId = StorageManagerService.this.getSandboxId(packageName, sharedUserId); } try { @@ -4028,7 +4028,8 @@ class StorageManagerService extends IStorageManager.Stub if (!ENABLE_ISOLATED_STORAGE) { return; } - final String sandboxId = getSandboxId(packageName, sharedUserId); + final String sandboxId = StorageManagerService.this.getSandboxId( + packageName, sharedUserId); synchronized (mPackagesLock) { final ArraySet<String> userPackages = mPackages.get(userId); // If the userPackages is null, it means the user is not started but we still @@ -4056,6 +4057,12 @@ class StorageManagerService extends IStorageManager.Stub return visibleVolsForUser.toArray(new String[visibleVolsForUser.size()]); } + @Override + public String getSandboxId(String packageName) { + return StorageManagerService.this.getSandboxId(packageName, + mPmInternal.getSharedUserIdForPackage(packageName)); + } + private String getVolumeLabel(VolumeInfo vol) { // STOPSHIP: Label needs to part of VolumeInfo and need to be passed on from vold switch (vol.getType()) { diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index c7b9a3cb7847..eaf790bb05c4 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -82,6 +82,9 @@ public class AdbDebuggingManager { private static final String ADB_DIRECTORY = "misc/adb"; // This file contains keys that will always be allowed to connect to the device via adb. private static final String ADB_KEYS_FILE = "adb_keys"; + // This file contains keys that will be allowed to connect without user interaction as long + // as a subsequent connection occurs within the allowed duration. + private static final String ADB_TEMP_KEYS_FILE = "adb_temp_keys.xml"; private static final int BUFFER_SIZE = 4096; private final Context mContext; @@ -263,7 +266,6 @@ public class AdbDebuggingManager { AdbDebuggingHandler(Looper looper) { super(looper); - mAdbKeyStore = new AdbKeyStore(); } /** @@ -289,6 +291,7 @@ public class AdbDebuggingManager { mThread = new AdbDebuggingThread(); mThread.start(); + mAdbKeyStore = new AdbKeyStore(); break; case MESSAGE_ADB_DISABLED: @@ -303,6 +306,9 @@ public class AdbDebuggingManager { mThread = null; } + cancelJobToUpdateAdbKeyStore(); + mAdbKeyStore = null; + mConnectedKey = null; break; case MESSAGE_ADB_ALLOW: { @@ -532,7 +538,11 @@ public class AdbDebuggingManager { return new File(adbDir, fileName); } - private File getUserKeyFile() { + File getAdbTempKeysFile() { + return getAdbFile(ADB_TEMP_KEYS_FILE); + } + + File getUserKeyFile() { return getAdbFile(ADB_KEYS_FILE); } @@ -668,9 +678,6 @@ public class AdbDebuggingManager { private Map<String, Long> mKeyMap; private File mKeyFile; private AtomicFile mAtomicKeyFile; - // This file contains keys that will be allowed to connect without user interaction as long - // as a subsequent connection occurs within the allowed duration. - private static final String ADB_TEMP_KEYS_FILE = "adb_temp_keys.xml"; private static final String XML_TAG_ADB_KEY = "adbKey"; private static final String XML_ATTRIBUTE_KEY = "key"; private static final String XML_ATTRIBUTE_LAST_CONNECTION = "lastConnection"; @@ -704,9 +711,9 @@ public class AdbDebuggingManager { */ private void initKeyFile() { if (mKeyFile == null) { - mKeyFile = getAdbFile(ADB_TEMP_KEYS_FILE); + mKeyFile = getAdbTempKeysFile(); } - // getAdbFile can return null if the adb file cannot be obtained + // getAdbTempKeysFile can return null if the adb file cannot be obtained if (mKeyFile != null) { mAtomicKeyFile = new AtomicFile(mKeyFile); } @@ -767,7 +774,8 @@ public class AdbDebuggingManager { public void persistKeyStore() { // if there is nothing in the key map then ensure any keys left in the key store files // are deleted as well. - if (mKeyMap.size() == 0) { + filterOutOldKeys(); + if (mKeyMap.isEmpty()) { deleteKeyStore(); return; } @@ -784,22 +792,15 @@ public class AdbDebuggingManager { keyStream = mAtomicKeyFile.startWrite(); serializer.setOutput(keyStream, StandardCharsets.UTF_8.name()); serializer.startDocument(null, true); - long allowedTime = getAllowedConnectionTime(); - long systemTime = System.currentTimeMillis(); - Iterator keyMapIterator = mKeyMap.entrySet().iterator(); - while (keyMapIterator.hasNext()) { - Map.Entry<String, Long> keyEntry = (Map.Entry) keyMapIterator.next(); - long connectionTime = keyEntry.getValue(); - if (systemTime < (connectionTime + allowedTime)) { - serializer.startTag(null, XML_TAG_ADB_KEY); - serializer.attribute(null, XML_ATTRIBUTE_KEY, keyEntry.getKey()); - serializer.attribute(null, XML_ATTRIBUTE_LAST_CONNECTION, - String.valueOf(keyEntry.getValue())); - serializer.endTag(null, XML_TAG_ADB_KEY); - } else { - keyMapIterator.remove(); - } + + for (Map.Entry<String, Long> keyEntry : mKeyMap.entrySet()) { + serializer.startTag(null, XML_TAG_ADB_KEY); + serializer.attribute(null, XML_ATTRIBUTE_KEY, keyEntry.getKey()); + serializer.attribute(null, XML_ATTRIBUTE_LAST_CONNECTION, + String.valueOf(keyEntry.getValue())); + serializer.endTag(null, XML_TAG_ADB_KEY); } + serializer.endDocument(); mAtomicKeyFile.finishWrite(keyStream); } catch (IOException e) { @@ -808,6 +809,19 @@ public class AdbDebuggingManager { } } + private void filterOutOldKeys() { + long allowedTime = getAllowedConnectionTime(); + long systemTime = System.currentTimeMillis(); + Iterator<Map.Entry<String, Long>> keyMapIterator = mKeyMap.entrySet().iterator(); + while (keyMapIterator.hasNext()) { + Map.Entry<String, Long> keyEntry = keyMapIterator.next(); + long connectionTime = keyEntry.getValue(); + if (allowedTime != 0 && systemTime > (connectionTime + allowedTime)) { + keyMapIterator.remove(); + } + } + } + /** * Removes all of the entries in the key map and deletes the key file. */ diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java index c31691551269..7fd98e0043c9 100644 --- a/services/core/java/com/android/server/adb/AdbService.java +++ b/services/core/java/com/android/server/adb/AdbService.java @@ -45,6 +45,7 @@ import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemService; +import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collections; @@ -95,6 +96,16 @@ public class AdbService extends IAdbManager.Stub { public boolean isAdbEnabled() { return mAdbEnabled; } + + @Override + public File getAdbKeysFile() { + return mDebuggingManager.getUserKeyFile(); + } + + @Override + public File getAdbTempKeysFile() { + return mDebuggingManager.getAdbTempKeysFile(); + } } private final class AdbHandler extends Handler { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 5932f99b562b..60a45bfe04bb 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2226,7 +2226,7 @@ public class ActivityManagerService extends IActivityManager.Stub mConstants = hasHandlerThread ? new ActivityManagerConstants(this, mHandler) : null; final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */); mProcessList.init(this, activeUids); - mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids, new Object()); + mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids); mIntentFirewall = hasHandlerThread ? new IntentFirewall(new IntentFirewallInterface(), mHandler) : null; @@ -2274,7 +2274,7 @@ public class ActivityManagerService extends IActivityManager.Stub mConstants = new ActivityManagerConstants(this, mHandler); final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */); mProcessList.init(this, activeUids); - mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids, atm.getGlobalLock()); + mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids); // Broadcast policy parameters final BroadcastConstants foreConstants = new BroadcastConstants( @@ -6549,7 +6549,7 @@ public class ActivityManagerService extends IActivityManager.Stub conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag, stable); if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { - if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { + if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { // If this is a perceptible app accessing the provider, // make sure to count it as being accessed and thus // back up on the LRU list. This is good because @@ -10828,6 +10828,7 @@ public class ActivityManagerService extends IActivityManager.Stub printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); + printOomLevel(pw, "PERCEPTIBLE_LOW_APP_ADJ", ProcessList.PERCEPTIBLE_LOW_APP_ADJ); printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); @@ -10878,16 +10879,17 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" Total number of kills: " + cnt); return reportLmkKillAtOrBelow(pw, ProcessList.CACHED_APP_MAX_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.CACHED_APP_MIN_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.SERVICE_B_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.PREVIOUS_APP_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.HOME_APP_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.SERVICE_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.HEAVY_WEIGHT_APP_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.BACKUP_APP_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.PERCEPTIBLE_APP_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.VISIBLE_APP_ADJ) && - reportLmkKillAtOrBelow(pw, ProcessList.FOREGROUND_APP_ADJ); + reportLmkKillAtOrBelow(pw, ProcessList.CACHED_APP_MIN_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.SERVICE_B_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.PREVIOUS_APP_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.HOME_APP_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.SERVICE_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.HEAVY_WEIGHT_APP_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.BACKUP_APP_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.PERCEPTIBLE_LOW_APP_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.PERCEPTIBLE_APP_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.VISIBLE_APP_ADJ) && + reportLmkKillAtOrBelow(pw, ProcessList.FOREGROUND_APP_ADJ); } /** @@ -11760,7 +11762,8 @@ public class ActivityManagerService extends IActivityManager.Stub ProcessList.NATIVE_ADJ, ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, - ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, + ProcessList.VISIBLE_APP_ADJ, + ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_LOW_APP_ADJ, ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ @@ -11768,7 +11771,7 @@ public class ActivityManagerService extends IActivityManager.Stub static final String[] DUMP_MEM_OOM_LABEL = new String[] { "Native", "System", "Persistent", "Persistent Service", "Foreground", - "Visible", "Perceptible", + "Visible", "Perceptible", "Perceptible Low", "Heavy Weight", "Backup", "A Services", "Home", "Previous", "B Services", "Cached" @@ -11776,7 +11779,7 @@ public class ActivityManagerService extends IActivityManager.Stub static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { "native", "sys", "pers", "persvc", "fore", - "vis", "percept", + "vis", "percept", "perceptl", "heavy", "backup", "servicea", "home", "prev", "serviceb", "cached" diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/AppCompactor.java index 502f078b532e..c7e4fc78c013 100644 --- a/services/core/java/com/android/server/am/AppCompactor.java +++ b/services/core/java/com/android/server/am/AppCompactor.java @@ -55,6 +55,8 @@ public final class AppCompactor { private static final int COMPACT_ACTION_FILE_FLAG = 1; private static final int COMPACT_ACTION_ANON_FLAG = 2; private static final int COMPACT_ACTION_FULL_FLAG = 3; + private static final int COMPACT_ACTION_NONE_FLAG = 4; + private static final String COMPACT_ACTION_NONE = ""; private static final String COMPACT_ACTION_FILE = "file"; private static final String COMPACT_ACTION_ANON = "anon"; private static final String COMPACT_ACTION_FULL = "all"; @@ -320,6 +322,8 @@ public final class AppCompactor { @VisibleForTesting static String compactActionIntToString(int action) { switch(action) { + case COMPACT_ACTION_NONE_FLAG: + return COMPACT_ACTION_NONE; case COMPACT_ACTION_FILE_FLAG: return COMPACT_ACTION_FILE; case COMPACT_ACTION_ANON_FLAG: @@ -327,7 +331,7 @@ public final class AppCompactor { case COMPACT_ACTION_FULL_FLAG: return COMPACT_ACTION_FULL; default: - return COMPACT_ACTION_FILE; + return COMPACT_ACTION_NONE; } } @@ -398,6 +402,10 @@ public final class AppCompactor { action = mCompactActionFull; } + if (action.equals(COMPACT_ACTION_NONE)) { + return; + } + try { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Compact " + ((pendingAction == COMPACT_PROCESS_SOME) ? "some" : "full") diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 7035698d5ee0..93a71e5a2ed4 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -127,18 +127,8 @@ public final class OomAdjuster { private final ActivityManagerService mService; private final ProcessList mProcessList; - /** - * Used to lock {@link #updateOomAdjImpl} for state consistency. It also reduces frequency lock - * and unlock when getting and setting value to {@link ProcessRecord#mWindowProcessController}. - * Note it is declared as Object type so the locked-region-code-injection won't wrap the - * unnecessary priority booster. - */ - private final Object mAtmGlobalLock; - - OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, - Object atmGlobalLock) { + OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids) { mService = service; - mAtmGlobalLock = atmGlobalLock; mProcessList = processList; mActiveUids = activeUids; @@ -196,13 +186,6 @@ public final class OomAdjuster { @GuardedBy("mService") final void updateOomAdjLocked() { - synchronized (mAtmGlobalLock) { - updateOomAdjImpl(); - } - } - - @GuardedBy({"mService", "mAtmGlobalLock"}) - private void updateOomAdjImpl() { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "updateOomAdj"); mService.mOomAdjProfiler.oomAdjStarted(); final ProcessRecord TOP_APP = mService.getTopAppLocked(); @@ -1224,8 +1207,8 @@ public final class OomAdjuster { } } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ - && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) { - newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1; + && adj > ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { + newAdj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ; } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { @@ -1610,7 +1593,7 @@ public final class OomAdjuster { // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); if (adj > app.maxAdj) { adj = app.maxAdj; - if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { + if (app.maxAdj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; } } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 69cf54b5528a..f01305eab761 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -183,6 +183,10 @@ public final class ProcessList { // is not entirely fatal but is generally a bad idea. static final int BACKUP_APP_ADJ = 300; + // This is a process bound by the system that's more important than services but not so + // perceptible that it affects the user immediately if killed. + static final int PERCEPTIBLE_LOW_APP_ADJ = 250; + // This is a process only hosting components that are perceptible to the // user, and we really want to avoid killing them, but they are not // immediately visible. An example is background music playback. @@ -717,6 +721,9 @@ public final class ProcessList { } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) { return buildOomTag("bkup ", "bkup", null, setAdj, ProcessList.BACKUP_APP_ADJ, compact); + } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { + return buildOomTag("prcl ", "prcl", null, setAdj, + ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact); } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { return buildOomTag("prcp ", "prcp", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ, compact); @@ -1740,8 +1747,11 @@ public final class ProcessList { try { final String[] packageNames = mService.mContext.getPackageManager() .getPackagesForUid(uid); - final String[] visibleVolIds = LocalServices.getService(StorageManagerInternal.class) + final StorageManagerInternal storageManagerInternal = + LocalServices.getService(StorageManagerInternal.class); + final String[] visibleVolIds = storageManagerInternal .getVisibleVolumesForUser(UserHandle.getUserId(uid)); + final String sandboxId = storageManagerInternal.getSandboxId(app.info.packageName); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + app.processName); checkSlow(startTime, "startProcess: asking zygote to start proc"); @@ -1751,7 +1761,7 @@ public final class ProcessList { app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, app.info.packageName, - packageNames, visibleVolIds, + packageNames, visibleVolIds, sandboxId, new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } else if (hostingType.equals("app_zygote")) { final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); @@ -1760,14 +1770,14 @@ public final class ProcessList { app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, app.info.packageName, - packageNames, visibleVolIds, /*useBlastulaPool=*/ false, + packageNames, visibleVolIds, sandboxId, /*useBlastulaPool=*/ false, new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } else { startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, app.info.packageName, - packageNames, visibleVolIds, + packageNames, visibleVolIds, sandboxId, new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } checkSlow(startTime, "startProcess: returned from zygote!"); diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 5dccaf14e1f1..fcc857b7a75d 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -713,6 +713,8 @@ final class ProcessRecord implements WindowProcessListener { adj = ProcessList.VISIBLE_APP_ADJ; } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { adj = ProcessList.PERCEPTIBLE_APP_ADJ; + } else if (adj < ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { + adj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ; } else if (adj < ProcessList.CACHED_APP_MIN_ADJ) { adj = ProcessList.CACHED_APP_MIN_ADJ; } else if (adj < ProcessList.CACHED_APP_MAX_ADJ) { diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 0dc73d9278a2..6df60d6bdd3a 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -21,6 +21,8 @@ import static com.android.server.audio.AudioService.CONNECTION_STATE_DISCONNECTE import android.annotation.NonNull; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHeadset; +import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.content.ContentResolver; import android.content.Context; @@ -424,11 +426,28 @@ import java.util.ArrayList; } /*package*/ void postDisconnectHearingAid() { - sendMsgNoDelay(MSG_DISCONNECT_HEARING_AID, SENDMSG_QUEUE); + sendMsgNoDelay(MSG_DISCONNECT_BT_HEARING_AID, SENDMSG_QUEUE); } /*package*/ void postDisconnectHeadset() { - sendMsgNoDelay(MSG_DISCONNECT_HEADSET, SENDMSG_QUEUE); + sendMsgNoDelay(MSG_DISCONNECT_BT_HEADSET, SENDMSG_QUEUE); + } + + /*package*/ void postBtA2dpProfileConnected(BluetoothA2dp a2dpProfile) { + sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP, SENDMSG_QUEUE, a2dpProfile); + } + + /*package*/ void postBtA2dpSinkProfileConnected(BluetoothProfile profile) { + sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP_SINK, SENDMSG_QUEUE, profile); + } + + /*package*/ void postBtHeasetProfileConnected(BluetoothHeadset headsetProfile) { + sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET, SENDMSG_QUEUE, headsetProfile); + } + + /*package*/ void postBtHearingAidProfileConnected(BluetoothHearingAid hearingAidProfile) { + sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEARING_AID, SENDMSG_QUEUE, + hearingAidProfile); } //--------------------------------------------------------------------- @@ -460,16 +479,14 @@ import java.util.ArrayList; } } + @GuardedBy("mDeviceStateLock") /*package*/ void handleSetA2dpSinkConnectionState(@BluetoothProfile.BtProfileState int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) { final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED; - final int delay; - synchronized (mDeviceStateLock) { - delay = mDeviceInventory.checkSendBecomingNoisyIntent( + final int delay = mDeviceInventory.checkSendBecomingNoisyIntent( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, intState, AudioSystem.DEVICE_NONE); - } final String addr = btDeviceInfo == null ? "null" : btDeviceInfo.getBtDevice().getAddress(); if (AudioService.DEBUG_DEVICES) { @@ -719,16 +736,36 @@ import java.util.ArrayList; mDeviceInventory.disconnectA2dpSink(); } break; - case MSG_DISCONNECT_HEARING_AID: + case MSG_DISCONNECT_BT_HEARING_AID: synchronized (mDeviceStateLock) { mDeviceInventory.disconnectHearingAid(); } break; - case MSG_DISCONNECT_HEADSET: + case MSG_DISCONNECT_BT_HEADSET: synchronized (mDeviceStateLock) { mBtHelper.disconnectHeadset(); } break; + case MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP: + synchronized (mDeviceStateLock) { + mBtHelper.onA2dpProfileConnected((BluetoothA2dp) msg.obj); + } + break; + case MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP_SINK: + synchronized (mDeviceStateLock) { + mBtHelper.onA2dpSinkProfileConnected((BluetoothProfile) msg.obj); + } + break; + case MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEARING_AID: + synchronized (mDeviceStateLock) { + mBtHelper.onHearingAidProfileConnected((BluetoothHearingAid) msg.obj); + } + break; + case MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET: + synchronized (mDeviceStateLock) { + mBtHelper.onHeadsetProfileConnected((BluetoothHeadset) msg.obj); + } + break; default: Log.wtf(TAG, "Invalid message " + msg.what); } @@ -766,8 +803,12 @@ import java.util.ArrayList; private static final int MSG_L_A2DP_ACTIVE_DEVICE_CHANGE = 18; private static final int MSG_DISCONNECT_A2DP = 19; private static final int MSG_DISCONNECT_A2DP_SINK = 20; - private static final int MSG_DISCONNECT_HEARING_AID = 21; - private static final int MSG_DISCONNECT_HEADSET = 22; + private static final int MSG_DISCONNECT_BT_HEARING_AID = 21; + private static final int MSG_DISCONNECT_BT_HEADSET = 22; + private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP = 23; + private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP_SINK = 24; + private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEARING_AID = 25; + private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET = 26; private static boolean isMessageHandledUnderWakelock(int msgId) { diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index e9189974e988..58c1882abf6f 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -393,6 +393,84 @@ public class BtHelper { mBluetoothHeadset = null; } + /*package*/ synchronized void onA2dpProfileConnected(BluetoothA2dp a2dp) { + mA2dp = a2dp; + final List<BluetoothDevice> deviceList = mA2dp.getConnectedDevices(); + if (deviceList.isEmpty()) { + return; + } + final BluetoothDevice btDevice = deviceList.get(0); + final @BluetoothProfile.BtProfileState int state = mA2dp.getConnectionState(btDevice); + mDeviceBroker.handleSetA2dpSinkConnectionState( + state, new BluetoothA2dpDeviceInfo(btDevice)); + } + + /*package*/ synchronized void onA2dpSinkProfileConnected(BluetoothProfile profile) { + final List<BluetoothDevice> deviceList = profile.getConnectedDevices(); + if (deviceList.isEmpty()) { + return; + } + final BluetoothDevice btDevice = deviceList.get(0); + final @BluetoothProfile.BtProfileState int state = + profile.getConnectionState(btDevice); + mDeviceBroker.postSetA2dpSourceConnectionState( + state, new BluetoothA2dpDeviceInfo(btDevice)); + } + + /*package*/ synchronized void onHearingAidProfileConnected(BluetoothHearingAid hearingAid) { + mHearingAid = hearingAid; + final List<BluetoothDevice> deviceList = mHearingAid.getConnectedDevices(); + if (deviceList.isEmpty()) { + return; + } + final BluetoothDevice btDevice = deviceList.get(0); + final @BluetoothProfile.BtProfileState int state = + mHearingAid.getConnectionState(btDevice); + mDeviceBroker.setBluetoothHearingAidDeviceConnectionState( + btDevice, state, + /*suppressNoisyIntent*/ false, + /*musicDevice*/ android.media.AudioSystem.DEVICE_NONE, + /*eventSource*/ "mBluetoothProfileServiceListener"); + } + + /*package*/ synchronized void onHeadsetProfileConnected(BluetoothHeadset headset) { + // Discard timeout message + mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService(); + mBluetoothHeadset = headset; + setBtScoActiveDevice(mBluetoothHeadset.getActiveDevice()); + // Refresh SCO audio state + checkScoAudioState(); + if (mScoAudioState != SCO_STATE_ACTIVATE_REQ + && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) { + return; + } + boolean status = false; + if (mBluetoothHeadsetDevice != null) { + switch (mScoAudioState) { + case SCO_STATE_ACTIVATE_REQ: + status = connectBluetoothScoAudioHelper( + mBluetoothHeadset, + mBluetoothHeadsetDevice, mScoAudioMode); + if (status) { + mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; + } + break; + case SCO_STATE_DEACTIVATE_REQ: + status = disconnectBluetoothScoAudioHelper( + mBluetoothHeadset, + mBluetoothHeadsetDevice, mScoAudioMode); + if (status) { + mScoAudioState = SCO_STATE_DEACTIVATING; + } + break; + } + } + if (!status) { + mScoAudioState = SCO_STATE_INACTIVE; + broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); + } + } + //---------------------------------------------------------------------- private void broadcastScoConnectionState(int state) { mDeviceBroker.postBroadcastScoConnectionState(state); @@ -462,99 +540,36 @@ public class BtHelper { } } + // NOTE this listener is NOT called from AudioDeviceBroker event thread, only call async + // methods inside listener. private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { - final BluetoothDevice btDevice; - List<BluetoothDevice> deviceList; switch(profile) { case BluetoothProfile.A2DP: - synchronized (BtHelper.this) { - mA2dp = (BluetoothA2dp) proxy; - deviceList = mA2dp.getConnectedDevices(); - if (deviceList.size() > 0) { - btDevice = deviceList.get(0); - if (btDevice == null) { - Log.e(TAG, "Invalid null device in BT profile listener"); - return; - } - final @BluetoothProfile.BtProfileState int state = - mA2dp.getConnectionState(btDevice); - mDeviceBroker.handleSetA2dpSinkConnectionState( - state, new BluetoothA2dpDeviceInfo(btDevice)); - } - } + AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( + "BT profile service: connecting A2DP profile")); + mDeviceBroker.postBtA2dpProfileConnected((BluetoothA2dp) proxy); break; case BluetoothProfile.A2DP_SINK: - deviceList = proxy.getConnectedDevices(); - if (deviceList.size() > 0) { - btDevice = deviceList.get(0); - final @BluetoothProfile.BtProfileState int state = - proxy.getConnectionState(btDevice); - mDeviceBroker.postSetA2dpSourceConnectionState( - state, new BluetoothA2dpDeviceInfo(btDevice)); - } + AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( + "BT profile service: connecting A2DP_SINK profile")); + mDeviceBroker.postBtA2dpSinkProfileConnected(proxy); break; case BluetoothProfile.HEADSET: - synchronized (BtHelper.this) { - // Discard timeout message - mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService(); - mBluetoothHeadset = (BluetoothHeadset) proxy; - setBtScoActiveDevice(mBluetoothHeadset.getActiveDevice()); - // Refresh SCO audio state - checkScoAudioState(); - // Continue pending action if any - if (mScoAudioState == SCO_STATE_ACTIVATE_REQ - || mScoAudioState == SCO_STATE_DEACTIVATE_REQ) { - boolean status = false; - if (mBluetoothHeadsetDevice != null) { - switch (mScoAudioState) { - case SCO_STATE_ACTIVATE_REQ: - status = connectBluetoothScoAudioHelper( - mBluetoothHeadset, - mBluetoothHeadsetDevice, mScoAudioMode); - if (status) { - mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; - } - break; - case SCO_STATE_DEACTIVATE_REQ: - status = disconnectBluetoothScoAudioHelper( - mBluetoothHeadset, - mBluetoothHeadsetDevice, mScoAudioMode); - if (status) { - mScoAudioState = SCO_STATE_DEACTIVATING; - } - break; - } - } - if (!status) { - mScoAudioState = SCO_STATE_INACTIVE; - broadcastScoConnectionState( - AudioManager.SCO_AUDIO_STATE_DISCONNECTED); - } - } - } + AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( + "BT profile service: connecting HEADSET profile")); + mDeviceBroker.postBtHeasetProfileConnected((BluetoothHeadset) proxy); break; case BluetoothProfile.HEARING_AID: - synchronized (BtHelper.this) { - mHearingAid = (BluetoothHearingAid) proxy; - deviceList = mHearingAid.getConnectedDevices(); - if (deviceList.size() > 0) { - btDevice = deviceList.get(0); - final @BluetoothProfile.BtProfileState int state = - mHearingAid.getConnectionState(btDevice); - mDeviceBroker.setBluetoothHearingAidDeviceConnectionState( - btDevice, state, - /*suppressNoisyIntent*/ false, - /*musicDevice*/ android.media.AudioSystem.DEVICE_NONE, - /*eventSource*/ "mBluetoothProfileServiceListener"); - } - } + AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( + "BT profile service: connecting HEARING_AID profile")); + mDeviceBroker.postBtHearingAidProfileConnected( + (BluetoothHearingAid) proxy); break; - default: break; } diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index b50b800f0e20..bca84f7b7217 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -391,10 +391,11 @@ public class BiometricService extends SystemService { private final Random mRandom = new Random(); // TODO(b/123378871): Remove when moved. - // When BiometricPrompt#setEnableFallback is set to true, we need to store the client (app) - // receiver. BiometricService internally launches CDCA which invokes BiometricService to - // start authentication (normal path). When auth is success/rejected, CDCA will use an aidl - // method to poke BiometricService - the result will then be forwarded to this receiver. + // When BiometricPrompt#setAllowDeviceCredentials is set to true, we need to store the + // client (app) receiver. BiometricService internally launches CDCA which invokes + // BiometricService to start authentication (normal path). When auth is success/rejected, + // CDCA will use an aidl method to poke BiometricService - the result will then be forwarded + // to this receiver. private IBiometricServiceReceiver mConfirmDeviceCredentialReceiver; // The current authentication session, null if idle/done. We need to track both the current @@ -803,11 +804,21 @@ public class BiometricService extends SystemService { // we can't get activity results. Store the receiver somewhere so we can forward the // result back to the client. // TODO(b/123378871): Remove when moved. - if (bundle.getBoolean(BiometricPrompt.KEY_ENABLE_FALLBACK)) { + if (bundle.getBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL)) { mHandler.post(() -> { - mConfirmDeviceCredentialReceiver = receiver; final KeyguardManager kgm = getContext().getSystemService( KeyguardManager.class); + if (!kgm.isDeviceSecure()) { + try { + receiver.onError(BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL, + getContext().getString( + R.string.biometric_error_device_not_secured)); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + return; + } + mConfirmDeviceCredentialReceiver = receiver; // Use this so we don't need to duplicate logic.. final Intent intent = kgm.createConfirmDeviceCredentialIntent(null /* title */, null /* description */); diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index b65535af52b1..9e0f2fcaa29f 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -624,7 +624,8 @@ public abstract class BiometricServiceBase extends SystemService handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE, 0 /*vendorCode */); - StatsLog.write(StatsLog.BIOMETRIC_HAL_DEATH_REPORTED, statsModality()); + StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, statsModality(), + BiometricsProtoEnums.ISSUE_HAL_DEATH); } protected ClientMonitor getCurrentClient() { diff --git a/services/core/java/com/android/server/biometrics/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/LoggableMonitor.java index 91c924de27a2..3b75b95fb0b9 100644 --- a/services/core/java/com/android/server/biometrics/LoggableMonitor.java +++ b/services/core/java/com/android/server/biometrics/LoggableMonitor.java @@ -28,7 +28,7 @@ import android.util.StatsLog; public abstract class LoggableMonitor { public static final String TAG = "BiometricStats"; - public static final boolean DEBUG = true; + public static final boolean DEBUG = false; private long mFirstAcquireTimeMs; @@ -137,6 +137,8 @@ public abstract class LoggableMonitor { + ", RequireConfirmation: " + requireConfirmation + ", State: " + authState + ", Latency: " + latency); + } else { + Slog.v(TAG, "Authentication latency: " + latency); } StatsLog.write(StatsLog.BIOMETRIC_AUTHENTICATED, diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index 017503a03816..8995068ef504 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -705,6 +705,8 @@ public class FaceService extends BiometricServiceBase { public void serviceDied(long cookie) { super.serviceDied(cookie); mDaemon = null; + + mCurrentUserId = UserHandle.USER_NULL; // Force updateActiveGroup() to re-evaluate } @Override diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java index 9e0a1c0c2ef2..d8544e324618 100644 --- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java @@ -49,6 +49,7 @@ import android.os.SELinux; import android.os.UserHandle; import android.os.UserManager; import android.util.Slog; +import android.util.StatsLog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; @@ -554,6 +555,8 @@ public class FingerprintService extends BiometricServiceBase { + " " + f.getDeviceId()); FingerprintUtils.getInstance().removeBiometricForUser(getContext(), getTargetUserId(), f.getBiometricId()); + StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, + BiometricsProtoEnums.ISSUE_UNKNOWN_TEMPLATE_ENROLLED_FRAMEWORK); } mEnrolledList.clear(); } @@ -1003,6 +1006,8 @@ public class FingerprintService extends BiometricServiceBase { mHalDeviceId, mToken, new ServiceListenerImpl(null), uf.f.getBiometricId(), uf.f.getGroupId(), uf.userId, restricted, getContext().getOpPackageName()); removeInternal(client); + StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, statsModality(), + BiometricsProtoEnums.ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL); } else { clearEnumerateState(); } diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index 19d10ecfb34d..cefe583fc5d1 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -509,7 +509,7 @@ public class JobSchedulerService extends com.android.server.SystemService private static final float DEFAULT_CONN_CONGESTION_DELAY_FRAC = 0.5f; private static final float DEFAULT_CONN_PREFETCH_RELAX_FRAC = 0.5f; private static final boolean DEFAULT_USE_HEARTBEATS = false; - private static final boolean DEFAULT_TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false; + private static final boolean DEFAULT_TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true; private static final long DEFAULT_QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS = 10 * 60 * 1000L; // 10 minutes private static final long DEFAULT_QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS = diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java index 97c3bac4ddbb..74628fb9b502 100644 --- a/services/core/java/com/android/server/job/controllers/StateController.java +++ b/services/core/java/com/android/server/job/controllers/StateController.java @@ -110,6 +110,7 @@ public abstract class StateController { final boolean jobWouldBeReady = jobStatus.wouldBeReadyWithConstraint(constraint); if (DEBUG) { Slog.v(TAG, "wouldBeReadyWithConstraintLocked: " + jobStatus.toShortString() + + " constraint=" + constraint + " readyWithConstraint=" + jobWouldBeReady); } if (!jobWouldBeReady) { diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java index 26f3caf2e487..70deb38080b4 100644 --- a/services/core/java/com/android/server/job/controllers/TimeController.java +++ b/services/core/java/com/android/server/job/controllers/TimeController.java @@ -149,8 +149,8 @@ public final class TimeController extends StateController { @Override public void onConstantsUpdatedLocked() { - checkExpiredDelaysAndResetAlarm(); checkExpiredDeadlinesAndResetAlarm(); + checkExpiredDelaysAndResetAlarm(); } @Override @@ -159,20 +159,47 @@ public final class TimeController extends StateController { return; } - if (job.hasTimingDelayConstraint() - && job.getEarliestRunTime() <= mNextDelayExpiredElapsedMillis) { - checkExpiredDelaysAndResetAlarm(); - } + final long nowElapsedMillis = sElapsedRealtimeClock.millis(); + + // Check deadline constraint first because if it's satisfied, we avoid a little bit of + // unnecessary processing of the timing delay. if (job.hasDeadlineConstraint() + && !job.isConstraintSatisfied(JobStatus.CONSTRAINT_DEADLINE) && job.getLatestRunTimeElapsed() <= mNextJobExpiredElapsedMillis) { - checkExpiredDeadlinesAndResetAlarm(); + if (evaluateDeadlineConstraint(job, nowElapsedMillis)) { + checkExpiredDeadlinesAndResetAlarm(); + checkExpiredDelaysAndResetAlarm(); + } else { + final boolean isAlarmForJob = + job.getLatestRunTimeElapsed() == mNextJobExpiredElapsedMillis; + final boolean wouldBeReady = wouldBeReadyWithConstraintLocked( + job, JobStatus.CONSTRAINT_DEADLINE); + if ((isAlarmForJob && !wouldBeReady) || (!isAlarmForJob && wouldBeReady)) { + checkExpiredDeadlinesAndResetAlarm(); + } + } + } + if (job.hasTimingDelayConstraint() + && !job.isConstraintSatisfied(JobStatus.CONSTRAINT_TIMING_DELAY) + && job.getEarliestRunTime() <= mNextDelayExpiredElapsedMillis) { + if (evaluateTimingDelayConstraint(job, nowElapsedMillis)) { + checkExpiredDelaysAndResetAlarm(); + } else { + final boolean isAlarmForJob = + job.getEarliestRunTime() == mNextDelayExpiredElapsedMillis; + final boolean wouldBeReady = wouldBeReadyWithConstraintLocked( + job, JobStatus.CONSTRAINT_TIMING_DELAY); + if ((isAlarmForJob && !wouldBeReady) || (!isAlarmForJob && wouldBeReady)) { + checkExpiredDelaysAndResetAlarm(); + } + } } } @Override public void reevaluateStateLocked(int uid) { - checkExpiredDelaysAndResetAlarm(); checkExpiredDeadlinesAndResetAlarm(); + checkExpiredDelaysAndResetAlarm(); } /** @@ -182,10 +209,10 @@ public final class TimeController extends StateController { * back and forth. */ private boolean canStopTrackingJobLocked(JobStatus job) { - return (!job.hasTimingDelayConstraint() || - (job.satisfiedConstraints&JobStatus.CONSTRAINT_TIMING_DELAY) != 0) && - (!job.hasDeadlineConstraint() || - (job.satisfiedConstraints&JobStatus.CONSTRAINT_DEADLINE) != 0); + return (!job.hasTimingDelayConstraint() + || job.isConstraintSatisfied(JobStatus.CONSTRAINT_TIMING_DELAY)) + && (!job.hasDeadlineConstraint() + || job.isConstraintSatisfied(JobStatus.CONSTRAINT_DEADLINE)); } private void ensureAlarmServiceLocked() { @@ -241,6 +268,7 @@ public final class TimeController extends StateController { } } + /** @return true if the job's deadline constraint is satisfied */ private boolean evaluateDeadlineConstraint(JobStatus job, long nowElapsedMillis) { final long jobDeadline = job.getLatestRunTimeElapsed(); @@ -279,7 +307,7 @@ public final class TimeController extends StateController { if (job.isReady()) { ready = true; } - } else if (!job.isConstraintSatisfied(JobStatus.CONSTRAINT_TIMING_DELAY)) { + } else { if (mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS && !wouldBeReadyWithConstraintLocked( job, JobStatus.CONSTRAINT_TIMING_DELAY)) { @@ -319,6 +347,7 @@ public final class TimeController extends StateController { } } + /** @return true if the job's delay constraint is satisfied */ private boolean evaluateTimingDelayConstraint(JobStatus job, long nowElapsedMillis) { final long jobDelayTime = job.getEarliestRunTime(); if (jobDelayTime <= nowElapsedMillis) { @@ -347,6 +376,9 @@ public final class TimeController extends StateController { */ private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis, WorkSource ws) { alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis); + if (mNextDelayExpiredElapsedMillis == alarmTimeElapsedMillis) { + return; + } mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis; updateAlarmWithListenerLocked(DELAY_TAG, mNextDelayExpiredListener, mNextDelayExpiredElapsedMillis, ws); @@ -359,6 +391,9 @@ public final class TimeController extends StateController { */ private void setDeadlineExpiredAlarmLocked(long alarmTimeElapsedMillis, WorkSource ws) { alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis); + if (mNextJobExpiredElapsedMillis == alarmTimeElapsedMillis) { + return; + } mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis; updateAlarmWithListenerLocked(DEADLINE_TAG, mDeadlineExpiredListener, mNextJobExpiredElapsedMillis, ws); diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java index 72259268aa81..91b5234e02e5 100644 --- a/services/core/java/com/android/server/location/GnssConfiguration.java +++ b/services/core/java/com/android/server/location/GnssConfiguration.java @@ -367,7 +367,7 @@ class GnssConfiguration { return defaultValue; } try { - return Integer.parseInt(valueString); + return Integer.decode(valueString); } catch (NumberFormatException e) { Log.e(TAG, "Unable to parse config parameter " + configParameter + " value: " + valueString + ". Using default value: " + defaultValue); diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index f368e7b8494e..2f0b388b9a7d 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -302,7 +302,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements MAX_RETRY_INTERVAL); // true if we are enabled, protected by this - private boolean mEnabled = true; + private boolean mEnabled; private boolean mShutdown; diff --git a/services/core/java/com/android/server/location/LocationBasedCountryDetector.java b/services/core/java/com/android/server/location/LocationBasedCountryDetector.java index 6527899f2979..8ee1285b41f2 100644 --- a/services/core/java/com/android/server/location/LocationBasedCountryDetector.java +++ b/services/core/java/com/android/server/location/LocationBasedCountryDetector.java @@ -235,18 +235,15 @@ public class LocationBasedCountryDetector extends CountryDetectorBase { * Start a new thread to query the country from Geocoder. */ private synchronized void queryCountryCode(final Location location) { - if (location == null) { - notifyListener(null); - return; - } if (mQueryThread != null) return; mQueryThread = new Thread(new Runnable() { @Override public void run() { - String countryIso = null; - if (location != null) { - countryIso = getCountryFromLocation(location); + if (location == null) { + notifyListener(null); + return; } + String countryIso = getCountryFromLocation(location); if (countryIso != null) { mDetectedCountry = new Country(countryIso, Country.COUNTRY_SOURCE_LOCATION); } else { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index eaedec597359..874d1a719ee6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -16321,7 +16321,6 @@ public class PackageManagerService extends IPackageManager.Stub final boolean onExternal = args.volumeUuid != null; final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); - final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); final boolean virtualPreload = ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0); @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; @@ -16353,8 +16352,7 @@ public class PackageManagerService extends IPackageManager.Stub // Retrieve PackageSettings and parse package @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | PackageParser.PARSE_ENFORCE_CODE - | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) - | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); + | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); PackageParser pp = new PackageParser(); pp.setSeparateProcesses(mSeparateProcesses); @@ -16775,19 +16773,6 @@ public class PackageManagerService extends IPackageManager.Stub "replacePackageLI: new=" + pkg + ", old=" + oldPackage); } - // don't allow upgrade to target a release SDK from a pre-release SDK - final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion - == Build.VERSION_CODES.CUR_DEVELOPMENT; - final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion - == Build.VERSION_CODES.CUR_DEVELOPMENT; - if (oldTargetsPreRelease - && !newTargetsPreRelease - && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { - Slog.w(TAG, "Can't install package targeting released sdk"); - throw new PrepareFailure( - PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); - } - ps = mSettings.mPackages.get(pkgName11); disabledPs = mSettings.getDisabledSystemPkgLPr(ps); diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index dc18dfcf8613..2eb762b59be4 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -2383,8 +2383,7 @@ class PackageManagerShellCommand extends ShellCommand { sessionParams.volumeUuid = null; } break; - case "--force-sdk": - sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK; + case "--force-sdk": // ignore break; case "--apex": sessionParams.setInstallAsApex(); @@ -2961,8 +2960,6 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" 0=unknown, 1=admin policy, 2=device restore,"); pw.println(" 3=device setup, 4=user request"); pw.println(" --force-uuid: force install on to disk volume with given UUID"); - pw.println(" --force-sdk: allow install even when existing app targets platform"); - pw.println(" codename but new one targets a final API level"); pw.println(" --apex: install an .apex file, not an .apk"); pw.println(""); pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]"); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 89aea36429d2..fa8360b1e5ba 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -220,6 +220,7 @@ public class StagingManager { session.setStagedSessionFailed( SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, "APEX staging failed, check logcat messages from apexd for more details."); + return; } if (apexInfoList.apexInfos != null && apexInfoList.apexInfos.length > 0) { diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java index 8d64b810b407..18e292feba30 100644 --- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java +++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java @@ -743,6 +743,9 @@ public class UserRestrictionsUtils { case android.provider.Settings.Global.PRIVATE_DNS_MODE: case android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER: + if (callingUid == Process.SYSTEM_UID) { + return false; + } restriction = UserManager.DISALLOW_CONFIG_PRIVATE_DNS; break; default: diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index 23705db884f5..9948a3ad47da 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -480,10 +480,13 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { final String apkPath = pkg.baseCodePath; final ApplicationInfo appInfo = pkg.applicationInfo; final String outDexFile = appInfo.dataDir + "/code_cache/compiled_view.dex"; - if (appInfo.isPrivilegedApp() || appInfo.isEmbeddedDexUsed()) { + if (appInfo.isPrivilegedApp() || appInfo.isEmbeddedDexUsed() + || appInfo.isDefaultToDeviceProtectedStorage()) { // Privileged apps prefer to load trusted code so they don't use compiled views. // If the app is not privileged but prefers code integrity, also avoid compiling // views. + // Also disable the view compiler for protected storage apps since there are + // selinux permissions required for writing to user_de. return false; } Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath + diff --git a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java index e7de8ddf87d1..3534cf30e2bf 100644 --- a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java +++ b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java @@ -67,8 +67,8 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder mContext.getContentResolver(), Settings.Secure.SMS_DEFAULT_APPLICATION, userId); - // TODO: STOPSHIP: Remove the following code once we remove default_sms_application - // and use the new config_defaultRoleHolders. + // TODO: STOPSHIP: Remove the following code once we read the value of + // config_defaultSms in RoleControllerService. if (result == null) { Collection<SmsApplication.SmsApplicationData> applications = SmsApplication.getApplicationCollectionAsUser(mContext, userId); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index af3bff0c96ba..1782b6a8aa78 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -197,7 +197,8 @@ public final class PowerManagerService extends SystemService // System Property indicating that retail demo mode is currently enabled. private static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled"; - // Possible reasons for shutting down for use in data/misc/reboot/last_shutdown_reason + // Possible reasons for shutting down or reboot for use in REBOOT_PROPERTY(sys.boot.reason) + // which is set by bootstat private static final String REASON_SHUTDOWN = "shutdown"; private static final String REASON_REBOOT = "reboot"; private static final String REASON_USERREQUESTED = "shutdown,userrequested"; diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java index 3c6a54af4bd7..3a2b69f8a6e1 100644 --- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -16,8 +16,11 @@ package com.android.server.rollback; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; import android.content.rollback.PackageRollbackInfo; @@ -25,6 +28,7 @@ import android.content.rollback.RollbackInfo; import android.content.rollback.RollbackManager; import android.os.Handler; import android.os.HandlerThread; +import android.os.PowerManager; import android.text.TextUtils; import android.util.Pair; import android.util.Slog; @@ -91,6 +95,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve + failedPackage.getVersionCode() + "]"); return false; } + RollbackInfo rollback = rollbackPair.first; // We only log mainline package rollbacks, so check if rollback contains the // module metadata provider, if it does, the rollback is a mainline rollback @@ -111,6 +116,12 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS, moduleMetadataPackage.getPackageName(), moduleMetadataPackage.getVersionCode()); + if (rollback.isStaged()) { + int rollbackId = rollback.getRollbackId(); + BroadcastReceiver listener = + listenForStagedSessionReady(rollbackManager, rollbackId); + handleStagedSessionChange(rollbackManager, rollbackId, listener); + } } else { StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE, @@ -178,4 +189,42 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve return null; } } + + private BroadcastReceiver listenForStagedSessionReady(RollbackManager rollbackManager, + int rollbackId) { + BroadcastReceiver sessionUpdatedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + handleStagedSessionChange(rollbackManager, + rollbackId, this /* BroadcastReceiver */); + } + }; + IntentFilter sessionUpdatedFilter = + new IntentFilter(PackageInstaller.ACTION_SESSION_UPDATED); + mContext.registerReceiver(sessionUpdatedReceiver, sessionUpdatedFilter); + return sessionUpdatedReceiver; + } + + private void handleStagedSessionChange(RollbackManager rollbackManager, int rollbackId, + BroadcastReceiver listener) { + PackageInstaller packageInstaller = + mContext.getPackageManager().getPackageInstaller(); + List<RollbackInfo> recentRollbacks = + rollbackManager.getRecentlyCommittedRollbacks(); + for (int i = 0; i < recentRollbacks.size(); i++) { + RollbackInfo recentRollback = recentRollbacks.get(i); + int sessionId = recentRollback.getCommittedSessionId(); + if ((rollbackId == recentRollback.getRollbackId()) + && (sessionId != PackageInstaller.SessionInfo.INVALID_ID)) { + PackageInstaller.SessionInfo sessionInfo = + packageInstaller.getSessionInfo(sessionId); + if (sessionInfo.isSessionReady()) { + mContext.unregisterReceiver(listener); + mContext.getSystemService(PowerManager.class).reboot("Rollback staged install"); + } else if (sessionInfo.isSessionFailed()) { + mContext.unregisterReceiver(listener); + } + } + } + } } diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 35867728f2c9..dd2cda20e0f1 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -45,6 +45,8 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PermissionInfo; import android.content.pm.UserInfo; +import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.net.ConnectivityManager; import android.net.INetworkStatsService; @@ -1419,23 +1421,35 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - private void pullNumFingerprints(int tagId, long elapsedNanos, long wallClockNanos, - List<StatsLogEventWrapper> pulledData) { + private void pullNumBiometricsEnrolled(int modality, int tagId, long elapsedNanos, + long wallClockNanos, List<StatsLogEventWrapper> pulledData) { FingerprintManager fingerprintManager = mContext.getSystemService(FingerprintManager.class); - if (fingerprintManager == null) { + FaceManager faceManager = mContext.getSystemService(FaceManager.class); + if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) { + return; + } + if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) { return; } UserManager userManager = mContext.getSystemService(UserManager.class); if (userManager == null) { return; } + final long token = Binder.clearCallingIdentity(); for (UserInfo user : userManager.getUsers()) { final int userId = user.getUserHandle().getIdentifier(); - final int numFingerprints = fingerprintManager.getEnrolledFingerprints(userId).size(); + int numEnrolled = 0; + if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) { + numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size(); + } else if (modality == BiometricsProtoEnums.MODALITY_FACE) { + numEnrolled = faceManager.getEnrolledFaces(userId).size(); + } else { + return; + } StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(userId); - e.writeInt(numFingerprints); + e.writeInt(numEnrolled); pulledData.add(e); } Binder.restoreCallingIdentity(token); @@ -2027,7 +2041,13 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { break; } case StatsLog.NUM_FINGERPRINTS_ENROLLED: { - pullNumFingerprints(tagId, elapsedNanos, wallClockNanos, ret); + pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FINGERPRINT, tagId, + elapsedNanos, wallClockNanos, ret); + break; + } + case StatsLog.NUM_FACES_ENROLLED: { + pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FACE, tagId, elapsedNanos, + wallClockNanos, ret); break; } case StatsLog.PROC_STATS: { diff --git a/services/core/java/com/android/server/testharness/TestHarnessModeService.java b/services/core/java/com/android/server/testharness/TestHarnessModeService.java index 4adce586e9a5..ec62ec76b32f 100644 --- a/services/core/java/com/android/server/testharness/TestHarnessModeService.java +++ b/services/core/java/com/android/server/testharness/TestHarnessModeService.java @@ -22,6 +22,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; +import android.debug.AdbManagerInternal; import android.os.BatteryManager; import android.os.Binder; import android.os.IBinder; @@ -42,6 +43,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; @@ -49,7 +51,6 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermission; import java.util.Set; @@ -85,6 +86,7 @@ public class TestHarnessModeService extends SystemService { break; case PHASE_BOOT_COMPLETED: disableAutoSync(); + configureSettings(); break; } super.onBootPhase(phase); @@ -98,47 +100,60 @@ public class TestHarnessModeService extends SystemService { return; } mShouldSetUpTestHarnessMode = true; + setUpAdb(testHarnessModeData); + setDeviceProvisioned(); + } + + private void setUpAdb(byte[] testHarnessModeData) { + ContentResolver cr = getContext().getContentResolver(); + // Disable the TTL for ADB keys before enabling ADB + Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0); + PersistentData persistentData = PersistentData.fromBytes(testHarnessModeData); SystemProperties.set(TEST_HARNESS_MODE_PROPERTY, persistentData.mEnabled ? "1" : "0"); writeAdbKeysFile(persistentData); - // Clear out the data block so that we don't revert the ADB keys on every boot. - getPersistentDataBlock().clearTestHarnessModeData(); + } - ContentResolver cr = getContext().getContentResolver(); - if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) { - // Enable ADB - Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1); - } else { - // ADB is already enabled, we should restart the service so it picks up the new keys - android.os.SystemService.restart("adbd"); + private void disableAutoSync() { + if (!mShouldSetUpTestHarnessMode) { + return; } + UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser(); + ContentResolver + .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier()); + } + + private void configureSettings() { + if (!mShouldSetUpTestHarnessMode) { + return; + } + ContentResolver cr = getContext().getContentResolver(); + Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1); + Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); Settings.Global.putInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0); Settings.Global.putInt( cr, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_ANY); Settings.Global.putInt(cr, Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE, 1); - Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); - - setDeviceProvisioned(); } - private void disableAutoSync() { - if (!mShouldSetUpTestHarnessMode) { - return; - } - UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser(); - ContentResolver - .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier()); + private void writeAdbKeysFile(PersistentData persistentData) { + AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class); + + writeBytesToFile(persistentData.mAdbKeys, adbManager.getAdbKeysFile().toPath()); + writeBytesToFile(persistentData.mAdbTempKeys, adbManager.getAdbTempKeysFile().toPath()); + + // Clear out the data block so that we don't revert the ADB keys on every boot. + getPersistentDataBlock().clearTestHarnessModeData(); } - private void writeAdbKeysFile(PersistentData persistentData) { - Path adbKeys = Paths.get("/data/misc/adb/adb_keys"); + private void writeBytesToFile(byte[] keys, Path adbKeys) { try { OutputStream fileOutputStream = Files.newOutputStream(adbKeys); - fileOutputStream.write(persistentData.mAdbKeys); + fileOutputStream.write(keys); fileOutputStream.close(); Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(adbKeys); @@ -219,23 +234,22 @@ public class TestHarnessModeService extends SystemService { } private int handleEnable() { - Path adbKeys = Paths.get("/data/misc/adb/adb_keys"); - if (!Files.exists(adbKeys)) { + AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class); + File adbKeys = adbManager.getAdbKeysFile(); + File adbTempKeys = adbManager.getAdbTempKeysFile(); + if (adbKeys == null && adbTempKeys == null) { // This should only be accessible on eng builds that haven't yet set up ADB keys getErrPrintWriter() .println("No ADB keys stored; not enabling test harness mode"); return 1; } - try (InputStream inputStream = Files.newInputStream(adbKeys)) { - long size = Files.size(adbKeys); - byte[] adbKeysBytes = new byte[(int) size]; - int numBytes = inputStream.read(adbKeysBytes); - if (numBytes != size) { - getErrPrintWriter().println("Failed to read all bytes of adb_keys"); - return 1; - } - PersistentData persistentData = new PersistentData(true, adbKeysBytes); + try { + byte[] adbKeysBytes = getBytesFromFile(adbKeys); + byte[] adbTempKeysBytes = getBytesFromFile(adbTempKeys); + + PersistentData persistentData = + new PersistentData(true, adbKeysBytes, adbTempKeysBytes); getPersistentDataBlock().setTestHarnessModeData(persistentData.toBytes()); } catch (IOException e) { Slog.e(TAG, "Failed to store ADB keys.", e); @@ -252,6 +266,22 @@ public class TestHarnessModeService extends SystemService { return 0; } + private byte[] getBytesFromFile(File file) throws IOException { + if (file == null || !file.exists()) { + return new byte[0]; + } + Path path = file.toPath(); + try (InputStream inputStream = Files.newInputStream(path)) { + int size = (int) Files.size(path); + byte[] bytes = new byte[size]; + int numBytes = inputStream.read(bytes); + if (numBytes != size) { + throw new IOException("Failed to read the whole file"); + } + return bytes; + } + } + @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); @@ -290,15 +320,17 @@ public class TestHarnessModeService extends SystemService { final int mVersion; final boolean mEnabled; final byte[] mAdbKeys; + final byte[] mAdbTempKeys; - PersistentData(boolean enabled, byte[] adbKeys) { - this(VERSION_1, enabled, adbKeys); + PersistentData(boolean enabled, byte[] adbKeys, byte[] adbTempKeys) { + this(VERSION_1, enabled, adbKeys, adbTempKeys); } - PersistentData(int version, boolean enabled, byte[] adbKeys) { + PersistentData(int version, boolean enabled, byte[] adbKeys, byte[] adbTempKeys) { this.mVersion = version; this.mEnabled = enabled; this.mAdbKeys = adbKeys; + this.mAdbTempKeys = adbTempKeys; } static PersistentData fromBytes(byte[] bytes) { @@ -309,7 +341,10 @@ public class TestHarnessModeService extends SystemService { int adbKeysLength = is.readInt(); byte[] adbKeys = new byte[adbKeysLength]; is.readFully(adbKeys); - return new PersistentData(version, enabled, adbKeys); + int adbTempKeysLength = is.readInt(); + byte[] adbTempKeys = new byte[adbTempKeysLength]; + is.readFully(adbTempKeys); + return new PersistentData(version, enabled, adbKeys, adbTempKeys); } catch (IOException e) { throw new RuntimeException(e); } @@ -323,6 +358,8 @@ public class TestHarnessModeService extends SystemService { dos.writeBoolean(mEnabled); dos.writeInt(mAdbKeys.length); dos.write(mAdbKeys); + dos.writeInt(mAdbTempKeys.length); + dos.write(mAdbTempKeys); dos.close(); return os.toByteArray(); } catch (IOException e) { diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java index 62421ac4fc76..f882fdee8c1f 100644 --- a/services/core/java/com/android/server/wm/ActivityDisplay.java +++ b/services/core/java/com/android/server/wm/ActivityDisplay.java @@ -40,6 +40,7 @@ import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY; import static com.android.server.am.ActivityDisplayProto.SINGLE_TASK_INSTANCE; import static com.android.server.am.ActivityDisplayProto.STACKS; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; +import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; @@ -575,7 +576,8 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> final ActivityStack stack = mStacks.get(stackNdx); final ActivityRecord resumedActivity = stack.getResumedActivity(); if (resumedActivity != null - && (!stack.shouldBeVisible(resuming) || !stack.isFocusable())) { + && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE + || !stack.isFocusable())) { if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack + " mResumedActivity=" + resumedActivity); someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming, diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index ef4064846381..4faf910f52ea 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -109,6 +109,7 @@ import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; import static com.android.server.wm.ActivityStack.LAUNCH_TICK; import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG; import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG; +import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS; @@ -2054,8 +2055,10 @@ final class ActivityRecord extends ConfigurationContainer { * @param activeActivity the activity that is active or just completed pause action. We won't * resume if this activity is active. */ - private boolean shouldResumeActivity(ActivityRecord activeActivity) { - return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED); + @VisibleForTesting + boolean shouldResumeActivity(ActivityRecord activeActivity) { + return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED) + && getActivityStack().getVisibility(activeActivity) == STACK_VISIBILITY_VISIBLE; } /** diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 6f07be82d267..cc78588eeb84 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -108,6 +108,7 @@ import static com.android.server.wm.RootActivityContainer.FindTaskResult; import static java.lang.Integer.MAX_VALUE; +import android.annotation.IntDef; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerInternal; @@ -223,6 +224,22 @@ class ActivityStack extends ConfigurationContainer { // How many activities have to be scheduled to stop to force a stop pass. private static final int MAX_STOPPING_TO_FORCE = 3; + @IntDef(prefix = {"STACK_VISIBILITY"}, value = { + STACK_VISIBILITY_VISIBLE, + STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + STACK_VISIBILITY_INVISIBLE, + }) + @interface StackVisibility {} + + /** Stack is visible. No other stacks on top that fully or partially occlude it. */ + static final int STACK_VISIBILITY_VISIBLE = 0; + + /** Stack is partially occluded by other translucent stack(s) on top of it. */ + static final int STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT = 1; + + /** Stack is completely invisible. */ + static final int STACK_VISIBILITY_INVISIBLE = 2; + @Override protected int getChildCount() { return mTaskHistory.size(); @@ -1959,14 +1976,28 @@ class ActivityStack extends ConfigurationContainer { * @param starting The currently starting activity or null if there is none. */ boolean shouldBeVisible(ActivityRecord starting) { + return getVisibility(starting) != STACK_VISIBILITY_INVISIBLE; + } + + /** + * Returns true if the stack should be visible. + * + * @param starting The currently starting activity or null if there is none. + */ + @StackVisibility + int getVisibility(ActivityRecord starting) { if (!isAttached() || mForceHidden) { - return false; + return STACK_VISIBILITY_INVISIBLE; } final ActivityDisplay display = getDisplay(); boolean gotSplitScreenStack = false; boolean gotOpaqueSplitScreenPrimary = false; boolean gotOpaqueSplitScreenSecondary = false; + boolean gotTranslucentFullscreen = false; + boolean gotTranslucentSplitScreenPrimary = false; + boolean gotTranslucentSplitScreenSecondary = false; + boolean shouldBeVisible = true; final int windowingMode = getWindowingMode(); final boolean isAssistantType = isActivityTypeAssistant(); for (int i = display.getChildCount() - 1; i >= 0; --i) { @@ -1975,8 +2006,9 @@ class ActivityStack extends ConfigurationContainer { if (other == this) { // Should be visible if there is no other stack occluding it, unless it doesn't // have any running activities, not starting one and not home stack. - return hasRunningActivities || isInStackLocked(starting) != null + shouldBeVisible = hasRunningActivities || isInStackLocked(starting) != null || isActivityTypeHome(); + break; } if (!hasRunningActivities) { @@ -1996,51 +2028,79 @@ class ActivityStack extends ConfigurationContainer { if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { if (activityType == ACTIVITY_TYPE_HOME || (activityType == ACTIVITY_TYPE_ASSISTANT - && mWindowManager.getRecentsAnimationController() != null)) { - return true; + && mWindowManager.getRecentsAnimationController() != null)) { + break; } } if (other.isStackTranslucent(starting)) { // Can be visible behind a translucent fullscreen stack. + gotTranslucentFullscreen = true; continue; } - return false; + return STACK_VISIBILITY_INVISIBLE; } else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !gotOpaqueSplitScreenPrimary) { gotSplitScreenStack = true; - gotOpaqueSplitScreenPrimary = - !other.isStackTranslucent(starting); + gotTranslucentSplitScreenPrimary = other.isStackTranslucent(starting); + gotOpaqueSplitScreenPrimary = !gotTranslucentSplitScreenPrimary; if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && gotOpaqueSplitScreenPrimary) { // Can not be visible behind another opaque stack in split-screen-primary mode. - return false; + return STACK_VISIBILITY_INVISIBLE; } } else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY && !gotOpaqueSplitScreenSecondary) { gotSplitScreenStack = true; - gotOpaqueSplitScreenSecondary = - !other.isStackTranslucent(starting); + gotTranslucentSplitScreenSecondary = other.isStackTranslucent(starting); + gotOpaqueSplitScreenSecondary = !gotTranslucentSplitScreenSecondary; if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY && gotOpaqueSplitScreenSecondary) { // Can not be visible behind another opaque stack in split-screen-secondary mode. - return false; + return STACK_VISIBILITY_INVISIBLE; } } if (gotOpaqueSplitScreenPrimary && gotOpaqueSplitScreenSecondary) { // Can not be visible if we are in split-screen windowing mode and both halves of // the screen are opaque. - return false; + return STACK_VISIBILITY_INVISIBLE; } if (isAssistantType && gotSplitScreenStack) { // Assistant stack can't be visible behind split-screen. In addition to this not // making sense, it also works around an issue here we boost the z-order of the // assistant window surfaces in window manager whenever it is visible. - return false; + return STACK_VISIBILITY_INVISIBLE; } } - // Well, nothing is stopping you from being visible... - return true; + if (!shouldBeVisible) { + return STACK_VISIBILITY_INVISIBLE; + } + + // Handle cases when there can be a translucent split-screen stack on top. + switch (windowingMode) { + case WINDOWING_MODE_FULLSCREEN: + if (gotTranslucentSplitScreenPrimary || gotTranslucentSplitScreenSecondary) { + // At least one of the split-screen stacks that covers this one is translucent. + return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; + } + break; + case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: + if (gotTranslucentSplitScreenPrimary) { + // Covered by translucent primary split-screen on top. + return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; + } + break; + case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: + if (gotTranslucentSplitScreenSecondary) { + // Covered by translucent secondary split-screen on top. + return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; + } + break; + } + + // Lastly - check if there is a translucent fullscreen stack on top. + return gotTranslucentFullscreen ? STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT + : STACK_VISIBILITY_VISIBLE; } final int rankTaskLayers(int baseLayer) { diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 7aa34819692b..875fc4eab273 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -1383,6 +1383,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setMayWait(userId) + .setAllowBackgroundActivityStart(true) .execute(); } @@ -1398,6 +1399,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { .setResolvedType(resolvedType) .setActivityOptions(bOptions) .setMayWait(userId) + .setAllowBackgroundActivityStart(true) .execute(); } diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java index 0e14e46e77de..5519729c17f5 100644 --- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java +++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java @@ -143,7 +143,7 @@ class AppWindowThumbnail implements Animatable { void destroy() { mSurfaceAnimator.cancelAnimation(); - mSurfaceControl.remove(); + getPendingTransaction().remove(mSurfaceControl); } /** diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 2cc85e2076e0..bcf6abaac5da 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1275,7 +1275,19 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree void onDisplayChanged(DisplayContent dc) { DisplayContent prevDc = mDisplayContent; super.onDisplayChanged(dc); - if (prevDc != null && prevDc.mFocusedApp == this) { + if (prevDc == null) { + return; + } + if (prevDc.mChangingApps.contains(this)) { + // This gets called *after* the AppWindowToken has been reparented to the new display. + // That reparenting resulted in this window changing modes (eg. FREEFORM -> FULLSCREEN), + // so this token is now "frozen" while waiting for the animation to start on prevDc + // (which will be cancelled since the window is no-longer a child). However, since this + // is no longer a child of prevDc, this won't be notified of the cancelled animation, + // so we need to cancel the change transition here. + clearChangeLeash(getPendingTransaction(), true /* cancel */); + } + if (prevDc.mFocusedApp == this) { prevDc.setFocusedApp(null); final TaskStack stack = dc.getTopStack(); if (stack != null) { @@ -1584,7 +1596,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } private boolean shouldStartChangeTransition(int prevWinMode, int newWinMode) { - if (!isVisible() || getDisplayContent().mAppTransition.isTransitionSet()) { + if (mWmService.mDisableTransitionAnimation + || !isVisible() + || getDisplayContent().mAppTransition.isTransitionSet() + || getSurfaceControl() == null) { return false; } // Only do an animation into and out-of freeform mode for now. Other mode @@ -2561,9 +2576,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return; } else if (mTransitChangeLeash != null) { // unparent mTransitChangeLeash for clean-up - t.hide(mTransitChangeLeash); - t.reparent(mTransitChangeLeash, null); - mTransitChangeLeash = null; + clearChangeLeash(t, false /* cancel */); } if (mAnimatingAppWindowTokenRegistry != null) { @@ -2659,15 +2672,36 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return super.isSelfAnimating(); } + /** + * @param cancel {@code true} if clearing the leash due to cancelling instead of transferring + * to another leash. + */ + private void clearChangeLeash(Transaction t, boolean cancel) { + if (mTransitChangeLeash == null) { + return; + } + if (cancel) { + clearThumbnail(); + SurfaceControl sc = getSurfaceControl(); + SurfaceControl parentSc = getParentSurfaceControl(); + // Don't reparent if surface is getting destroyed + if (parentSc != null && sc != null) { + t.reparent(sc, getParentSurfaceControl()); + } + } + t.hide(mTransitChangeLeash); + t.reparent(mTransitChangeLeash, null); + mTransitChangeLeash = null; + if (cancel) { + onAnimationLeashDestroyed(t); + } + } + @Override void cancelAnimation() { cancelAnimationOnly(); clearThumbnail(); - if (mTransitChangeLeash != null) { - getPendingTransaction().hide(mTransitChangeLeash); - getPendingTransaction().reparent(mTransitChangeLeash, null); - mTransitChangeLeash = null; - } + clearChangeLeash(getPendingTransaction(), true /* cancel */); } /** @@ -3003,7 +3037,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree void removeFromPendingTransition() { if (isWaitingForTransitionStart() && mDisplayContent != null) { mDisplayContent.mOpeningApps.remove(this); - mDisplayContent.mChangingApps.remove(this); + if (mDisplayContent.mChangingApps.remove(this)) { + clearChangeLeash(getPendingTransaction(), true /* cancel */); + } mDisplayContent.mClosingApps.remove(this); } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 928b57cf050b..5cfc20b6339f 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; -import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -38,6 +37,7 @@ import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.view.View.GONE; +import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; import static android.view.WindowManager.DOCKED_BOTTOM; import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_TOP; @@ -138,6 +138,7 @@ import android.content.pm.PackageManager; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; @@ -172,6 +173,7 @@ import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import android.view.View; +import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.WindowManagerPolicyConstants.PointerEventListener; @@ -3251,6 +3253,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mInputMethodTargetWaitingAnim = targetWaitingAnim; assignWindowLayers(false /* setLayoutNeeded */); mInsetsStateController.onImeTargetChanged(target); + updateImeParent(); + } + + private void updateImeParent() { + if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE) { + return; + } + final SurfaceControl newParent = computeImeParent(); + if (newParent != null) { + mPendingTransaction.reparent(mImeWindowsContainers.mSurfaceControl, newParent); + scheduleAnimation(); + } + } + + /** + * Computes the window the IME should be attached to. + */ + @VisibleForTesting + SurfaceControl computeImeParent() { + + // Attach it to app if the target is part of an app and such app is covering the entire + // screen. If it's not covering the entire screen the IME might extend beyond the apps + // bounds. + if (mInputMethodTarget != null && mInputMethodTarget.mAppToken != null && + mInputMethodTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) { + return mInputMethodTarget.mAppToken.getSurfaceControl(); + } + + // Otherwise, we just attach it to the display. + return mWindowingLayer; } boolean getNeedsMenu(WindowState top, WindowManagerPolicy.WindowState bottom) { @@ -4885,6 +4917,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo .reparent(mWindowingLayer, sc).reparent(mOverlayLayer, sc); } + @VisibleForTesting + SurfaceControl getWindowingLayer() { + return mWindowingLayer; + } + /** * Create a portal window handle for input. This window transports any touch to the display * indicated by {@link InputWindowHandle#portalToDisplayId} if the touch hits this window. @@ -4909,4 +4946,19 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo portalWindowHandle.portalToDisplayId = mDisplayId; return portalWindowHandle; } + + /** + * @see IWindowManager#setForwardedInsets + */ + public void setForwardedInsets(Insets insets) { + if (insets == null) { + insets = Insets.NONE; + } + if (mDisplayPolicy.getForwardedInsets().equals(insets)) { + return; + } + mDisplayPolicy.setForwardedInsets(insets); + setLayoutNeeded(); + mWmService.mWindowPlacerLocked.requestTraversal(); + } } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index bbf115f17969..2ee30ac5c8ff 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -27,6 +27,7 @@ import static android.content.res.Configuration.UI_MODE_TYPE_CAR; import static android.content.res.Configuration.UI_MODE_TYPE_MASK; import static android.view.InsetsState.TYPE_TOP_BAR; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; @@ -103,6 +104,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.localLOGV; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityThread; @@ -110,6 +112,7 @@ import android.app.StatusBarManager; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.graphics.Insets; import android.graphics.Rect; import android.hardware.input.InputManager; import android.hardware.power.V1_0.PowerHint; @@ -134,6 +137,7 @@ import android.view.MotionEvent; import android.view.PointerIcon; import android.view.Surface; import android.view.View; +import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.WindowManagerGlobal; @@ -339,6 +343,16 @@ public class DisplayPolicy { private InputConsumer mInputConsumer = null; + /** + * The area covered by system windows which belong to another display. Forwarded insets is set + * in case this is a virtual display, this is displayed on another display that has insets, and + * the bounds of this display is overlapping with the insets of the host display (e.g. IME is + * displayed on the host display, and it covers a part of this virtual display.) + * The forwarded insets is used to compute display frames of this virtual display, which will + * be then used to layout windows in the virtual display. + */ + @NonNull private Insets mForwardedInsets = Insets.NONE; + // -------- PolicyHandler -------- private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 1; private static final int MSG_REQUEST_TRANSIENT_BARS = 2; @@ -1362,6 +1376,15 @@ public class DisplayPolicy { displayFrames.mDisplayCutoutSafe.top = Math.max(displayFrames.mDisplayCutoutSafe.top, displayFrames.mStable.top); } + + // In case this is a virtual display, and the host display has insets that overlap this + // virtual display, apply the insets of the overlapped area onto the current and content + // frame of this virtual display. This let us layout windows in the virtual display as + // expected when the window needs to avoid overlap with the system windows. + // TODO: Generalize the forwarded insets, so that we can handle system windows other than + // IME. + displayFrames.mCurrent.inset(mForwardedInsets); + displayFrames.mContent.inset(mForwardedInsets); } private void layoutScreenDecorWindows(DisplayFrames displayFrames) { @@ -1900,7 +1923,10 @@ public class DisplayPolicy { if (win.isVoiceInteraction()) { cf.set(displayFrames.mVoiceContent); } else { - if (adjust != SOFT_INPUT_ADJUST_RESIZE) { + // IME Insets are handled on the client for ADJUST_RESIZE in the new + // insets world + if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_NONE + || adjust != SOFT_INPUT_ADJUST_RESIZE) { cf.set(displayFrames.mDock); } else { cf.set(displayFrames.mContent); @@ -1991,7 +2017,11 @@ public class DisplayPolicy { of.set(displayFrames.mRestricted); df.set(displayFrames.mRestricted); pf.set(displayFrames.mRestricted); - if (adjust != SOFT_INPUT_ADJUST_RESIZE) { + + // IME Insets are handled on the client for ADJUST_RESIZE in the new insets + // world + if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_NONE + || adjust != SOFT_INPUT_ADJUST_RESIZE) { cf.set(displayFrames.mDock); } else { cf.set(displayFrames.mContent); @@ -2718,6 +2748,18 @@ public class DisplayPolicy { } } + /** + * @see IWindowManager#setForwardedInsets + */ + public void setForwardedInsets(@NonNull Insets forwardedInsets) { + mForwardedInsets = forwardedInsets; + } + + @NonNull + public Insets getForwardedInsets() { + return mForwardedInsets; + } + @NavigationBarPosition int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) { if (navigationBarCanMove() && displayWidth > displayHeight) { diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index afae9c4ac228..a1b52f424fee 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -112,6 +112,7 @@ class InsetsStateController { * Called when a layout pass has occurred. */ void onPostLayout() { + mState.setDisplayFrame(mDisplayContent.getBounds()); for (int i = mControllers.size() - 1; i>= 0; i--) { mControllers.valueAt(i).onPostLayout(); } diff --git a/services/core/java/com/android/server/wm/TEST_MAPPING b/services/core/java/com/android/server/wm/TEST_MAPPING index bbe542458b87..b2e8bbe3b885 100644 --- a/services/core/java/com/android/server/wm/TEST_MAPPING +++ b/services/core/java/com/android/server/wm/TEST_MAPPING @@ -1,34 +1,4 @@ { - "presubmit": [ - { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.wm." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] - }, - { - "name": "WmTests", - "options": [ - { - "include-filter": "com.android.server.wm." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] - } - ], "postsubmit": [ { "name": "CtsWindowManagerDeviceTestCases" diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 3bb660825843..6c3e1f4ce1c2 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -134,6 +134,7 @@ import android.content.pm.PackageManagerInternal; import android.content.res.Configuration; import android.database.ContentObserver; import android.graphics.Bitmap; +import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; @@ -6438,6 +6439,23 @@ public class WindowManagerService extends IWindowManager.Stub } } + @Override + public void setForwardedInsets(int displayId, Insets insets) throws RemoteException { + synchronized (mGlobalLock) { + final DisplayContent dc = mRoot.getDisplayContent(displayId); + if (dc == null) { + return; + } + final int callingUid = Binder.getCallingUid(); + final int displayOwnerUid = dc.getDisplay().getOwnerUid(); + if (callingUid != displayOwnerUid) { + throw new SecurityException( + "Only owner of the display can set ForwardedInsets to it."); + } + dc.setForwardedInsets(insets); + } + } + void intersectDisplayInsetBounds(Rect display, Rect insets, Rect inOutBounds) { mTmpRect3.set(display); mTmpRect3.inset(insets); diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 33317b554988..c18e98bab9c4 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -373,6 +373,9 @@ void NativeInputManager::dump(std::string& dump) { mInputManager->getReader()->dump(dump); dump += "\n"; + mInputManager->getClassifier()->dump(dump); + dump += "\n"; + mInputManager->getDispatcher()->dump(dump); dump += "\n"; } diff --git a/services/core/jni/com_android_server_security_VerityUtils.cpp b/services/core/jni/com_android_server_security_VerityUtils.cpp index bf96f9a3b71b..6cd9f2c718ee 100644 --- a/services/core/jni/com_android_server_security_VerityUtils.cpp +++ b/services/core/jni/com_android_server_security_VerityUtils.cpp @@ -122,7 +122,7 @@ class JavaByteArrayHolder { } ~JavaByteArrayHolder() { - LOG_ALWAYS_FATAL_IF(mElements == nullptr, "Elements are not released"); + LOG_ALWAYS_FATAL_IF(mElements != nullptr, "Elements are not released"); } private: diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 1155f499d619..e30acf71d328 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -12790,10 +12790,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - // TODO(b/22388012): When backup is available for secondary users and profiles, consider - // whether there are any privacy/security implications of enabling the backup service here - // if there are other users or profiles unmanaged or managed by a different entity (i.e. not - // affiliated). @Override public void setBackupServiceEnabled(ComponentName admin, boolean enabled) { if (!mHasFeature) { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index ab30cda271f0..a6017f2c1e86 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -64,6 +64,7 @@ import android.util.EventLog; import android.util.Slog; import android.util.TimingsTraceLog; import android.view.WindowManager; +import android.view.contentcapture.ContentCaptureManager; import android.view.inputmethod.InputMethodSystemProperty; import com.android.internal.R; @@ -2214,33 +2215,30 @@ public final class SystemServer { } private void startContentCaptureService(@NonNull Context context) { - // Check if it was explicitly enabled by DeviceConfig - final String settings = DeviceConfig.getProperty(DeviceConfig.ContentCapture.NAMESPACE, - DeviceConfig.ContentCapture.PROPERTY_CONTENTCAPTURE_ENABLED); - if (settings == null) { - // Better be safe than sorry... - Slog.d(TAG, "ContentCaptureService disabled because its not set by OEM"); - return; - } - switch (settings) { - case "always": - // Should be used only during development + // First check if it was explicitly enabled by DeviceConfig + boolean explicitlySupported = false; + String settings = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_CONTENT_CAPTURE, + ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED); + if (settings != null && !settings.equalsIgnoreCase("default")) { + explicitlySupported = Boolean.parseBoolean(settings); + if (explicitlySupported) { Slog.d(TAG, "ContentCaptureService explicitly enabled by DeviceConfig"); - break; - case "default": - // Default case: check if OEM overlaid the resource that defines the service. - final String serviceName = context.getString( - com.android.internal.R.string.config_defaultContentCaptureService); - if (TextUtils.isEmpty(serviceName)) { - Slog.d(TAG, "ContentCaptureService disabled because resource is not overlaid"); - return; - } - break; - default: - // Kill switch for OEMs - Slog.d(TAG, "ContentCaptureService disabled because its set to: " + settings); + } else { + Slog.d(TAG, "ContentCaptureService explicitly disabled by DeviceConfig"); return; + } } + + // Then check if OEM overlaid the resource that defines the service. + if (!explicitlySupported) { + final String serviceName = context + .getString(com.android.internal.R.string.config_defaultContentCaptureService); + if (TextUtils.isEmpty(serviceName)) { + Slog.d(TAG, "ContentCaptureService disabled because resource is not overlaid"); + return; + } + } + traceBeginAndSlog("StartContentCaptureService"); mSystemServiceManager.startService(CONTENT_CAPTURE_MANAGER_SERVICE_CLASS); traceEnd(); diff --git a/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java b/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java index 2f8e5456a695..63015be6ef3f 100644 --- a/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java +++ b/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java @@ -147,10 +147,10 @@ public final class AppCompactorTest { KEY_USE_COMPACTION, "true", false); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_ACTION_1, - Integer.toString((AppCompactor.DEFAULT_COMPACT_ACTION_1 + 1 % 3) + 1), false); + Integer.toString((AppCompactor.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1), false); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_ACTION_2, - Integer.toString((AppCompactor.DEFAULT_COMPACT_ACTION_2 + 1 % 3) + 1), false); + Integer.toString((AppCompactor.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1), false); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_THROTTLE_1, Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1), false); @@ -173,9 +173,9 @@ public final class AppCompactorTest { assertThat(mCompactorUnderTest.mCompactionThread.isAlive(), is(true)); assertThat(mCompactorUnderTest.mCompactActionSome, - is(compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_1 + 1 % 3) + 1))); + is(compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1))); assertThat(mCompactorUnderTest.mCompactActionFull, - is(compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_2 + 1 % 3) + 1))); + is(compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1))); assertThat(mCompactorUnderTest.mCompactThrottleSomeSome, is(AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1)); assertThat(mCompactorUnderTest.mCompactThrottleSomeFull, @@ -233,13 +233,13 @@ public final class AppCompactorTest { // When we override new values for the compaction action with reasonable values... - // There are three possible values for compactAction[Some|Full]. - for (int i = 1; i < 4; i++) { + // There are four possible values for compactAction[Some|Full]. + for (int i = 1; i < 5; i++) { mCountDown = new CountDownLatch(2); - int expectedSome = (mCompactorUnderTest.DEFAULT_COMPACT_ACTION_1 + i) % 3 + 1; + int expectedSome = (mCompactorUnderTest.DEFAULT_COMPACT_ACTION_1 + i) % 4 + 1; DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_ACTION_1, Integer.toString(expectedSome), false); - int expectedFull = (mCompactorUnderTest.DEFAULT_COMPACT_ACTION_2 + i) % 3 + 1; + int expectedFull = (mCompactorUnderTest.DEFAULT_COMPACT_ACTION_2 + i) % 4 + 1; DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_ACTION_2, Integer.toString(expectedFull), false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 192915fe903c..4073ff106592 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -24,6 +24,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM; @@ -34,6 +35,9 @@ import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING; +import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE; +import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; +import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -381,6 +385,21 @@ public class ActivityRecordTests extends ActivityTestsBase { } @Test + public void testShouldResume_stackVisibility() { + mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); + spyOn(mStack); + + doReturn(STACK_VISIBILITY_VISIBLE).when(mStack).getVisibility(null); + assertEquals(true, mActivity.shouldResumeActivity(null /* activeActivity */)); + + doReturn(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT).when(mStack).getVisibility(null); + assertEquals(false, mActivity.shouldResumeActivity(null /* activeActivity */)); + + doReturn(STACK_VISIBILITY_INVISIBLE).when(mStack).getVisibility(null); + assertEquals(false, mActivity.shouldResumeActivity(null /* activeActivity */)); + } + + @Test public void testPushConfigurationWhenLaunchTaskBehind() throws Exception { mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index 986943aaf146..822700f48dd5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -37,6 +37,9 @@ import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING; +import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE; +import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; +import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE; @@ -321,12 +324,23 @@ public class ActivityStackTests extends ActivityTestsBase { assertFalse(homeStack.shouldBeVisible(null /* starting */)); assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenPrimary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenSecondary.getVisibility(null /* starting */)); // Home stack should be visible if one of the halves of split-screen is translucent. splitScreenPrimary.setIsTranslucent(true); assertTrue(homeStack.shouldBeVisible(null /* starting */)); assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + homeStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenPrimary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenSecondary.getVisibility(null /* starting */)); final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultDisplay, @@ -336,12 +350,20 @@ public class ActivityStackTests extends ActivityTestsBase { splitScreenSecondary2.setIsTranslucent(false); assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenSecondary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenSecondary2.getVisibility(null /* starting */)); // First split-screen secondary should be visible behind another translucent split-screen // secondary. splitScreenSecondary2.setIsTranslucent(true); assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + splitScreenSecondary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenSecondary2.getVisibility(null /* starting */)); final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); @@ -352,6 +374,14 @@ public class ActivityStackTests extends ActivityTestsBase { assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */)); assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */)); assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + assistantStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenPrimary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenSecondary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenSecondary2.getVisibility(null /* starting */)); // Split-screen stacks should be visible behind a translucent fullscreen stack. assistantStack.setIsTranslucent(true); @@ -359,6 +389,14 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + assistantStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + splitScreenPrimary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + splitScreenSecondary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + splitScreenSecondary2.getVisibility(null /* starting */)); // Assistant stack shouldn't be visible behind translucent split-screen stack assistantStack.setIsTranslucent(false); @@ -369,6 +407,113 @@ public class ActivityStackTests extends ActivityTestsBase { assertFalse(assistantStack.shouldBeVisible(null /* starting */)); assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + assistantStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenPrimary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenSecondary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenSecondary2.getVisibility(null /* starting */)); + } + + @Test + public void testGetVisibility_FullscreenBehindTranslucent() { + final TestActivityStack bottomStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + false /* translucent */); + final TestActivityStack translucentStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + true /* translucent */); + + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + bottomStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + translucentStack.getVisibility(null /* starting */)); + } + + @Test + public void testGetVisibility_FullscreenBehindTranslucentAndOpaque() { + final TestActivityStack bottomStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + false /* translucent */); + final TestActivityStack translucentStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + true /* translucent */); + final TestActivityStack opaqueStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + false /* translucent */); + + assertEquals(STACK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + translucentStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */)); + } + + @Test + public void testGetVisibility_FullscreenBehindOpaqueAndTranslucent() { + final TestActivityStack bottomStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + false /* translucent */); + final TestActivityStack opaqueStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + false /* translucent */); + final TestActivityStack translucentStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + true /* translucent */); + + assertEquals(STACK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + opaqueStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + translucentStack.getVisibility(null /* starting */)); + } + + @Test + public void testGetVisibility_FullscreenTranslucentBehindTranslucent() { + final TestActivityStack bottomTranslucentStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + true /* translucent */); + final TestActivityStack translucentStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + true /* translucent */); + + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + bottomTranslucentStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + translucentStack.getVisibility(null /* starting */)); + } + + @Test + public void testGetVisibility_FullscreenTranslucentBehindOpaque() { + final TestActivityStack bottomTranslucentStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + true /* translucent */); + final TestActivityStack opaqueStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + false /* translucent */); + + assertEquals(STACK_VISIBILITY_INVISIBLE, + bottomTranslucentStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */)); + } + + @Test + public void testGetVisibility_FullscreenBehindTranslucentAndPip() { + final TestActivityStack bottomStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + false /* translucent */); + final TestActivityStack translucentStack = + createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN, + true /* translucent */); + final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay, + WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); + + assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, + bottomStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + translucentStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, pinnedStack.getVisibility(null /* starting */)); } @Test @@ -628,6 +773,14 @@ public class ActivityStackTests extends ActivityTestsBase { assertFalse(assistantStack.shouldBeVisible(null /* starting */)); } + private TestActivityStack createStandardStackForVisibilityTest(int windowingMode, + boolean translucent) { + final TestActivityStack stack = createStackForShouldBeVisibleTest(mDefaultDisplay, + windowingMode, ACTIVITY_TYPE_STANDARD, true /* onTop */); + stack.setIsTranslucent(translucent); + return stack; + } + @SuppressWarnings("TypeParameterUnusedInFormals") private <T extends ActivityStack> T createStackForShouldBeVisibleTest( ActivityDisplay display, int windowingMode, int activityType, boolean onTop) { diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java index defe9811ebcf..a7520dcbcff9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java @@ -16,24 +16,29 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import android.graphics.Rect; import android.os.IBinder; +import android.view.Display; import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationRunner; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; -import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; -import org.junit.Before; import org.junit.Test; /** @@ -49,14 +54,20 @@ public class AppChangeTransitionTests extends WindowTestsBase { private Task mTask; private WindowTestUtils.TestAppWindowToken mToken; - @Before - public void setUp() throws Exception { - mStack = createTaskStackOnDisplay(mDisplayContent); + public void setUpOnDisplay(DisplayContent dc) { + mStack = createTaskStackOnDisplay(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, dc); mTask = createTaskInStack(mStack, 0 /* userId */); - mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent); + mToken = WindowTestUtils.createTestAppWindowToken(dc); mToken.mSkipOnParentChanged = false; mTask.addChild(mToken, 0); + + // Set a remote animator with snapshot disabled. Snapshots don't work in wmtests. + RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); + RemoteAnimationAdapter adapter = + new RemoteAnimationAdapter(new TestRemoteAnimationRunner(), 10, 1, false); + definition.addRemoteAnimation(TRANSIT_TASK_CHANGE_WINDOWING_MODE, adapter); + dc.registerRemoteAnimations(definition); } class TestRemoteAnimationRunner implements IRemoteAnimationRunner { @@ -85,14 +96,58 @@ public class AppChangeTransitionTests extends WindowTestsBase { @Test public void testModeChangeRemoteAnimatorNoSnapshot() { - RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); - RemoteAnimationAdapter adapter = - new RemoteAnimationAdapter(new TestRemoteAnimationRunner(), 10, 1, false); - definition.addRemoteAnimation(TRANSIT_TASK_CHANGE_WINDOWING_MODE, adapter); - mDisplayContent.registerRemoteAnimations(definition); + // setup currently defaults to no snapshot. + setUpOnDisplay(mDisplayContent); mTask.setWindowingMode(WINDOWING_MODE_FREEFORM); assertEquals(1, mDisplayContent.mChangingApps.size()); + + // Verify we are in a change transition, but without a snapshot. + // Though, the test will actually have crashed by now if a snapshot is attempted. + assertNull(mToken.getThumbnail()); + assertTrue(mToken.isInChangeTransition()); + + waitUntilHandlersIdle(); + mToken.removeImmediately(); + } + + @Test + public void testCancelPendingChangeOnRemove() { + // setup currently defaults to no snapshot. + setUpOnDisplay(mDisplayContent); + + mTask.setWindowingMode(WINDOWING_MODE_FREEFORM); + assertEquals(1, mDisplayContent.mChangingApps.size()); + assertTrue(mToken.isInChangeTransition()); + + // Removing the app-token from the display should clean-up the + // the change leash. + mDisplayContent.removeAppToken(mToken.token); + assertEquals(0, mDisplayContent.mChangingApps.size()); + assertFalse(mToken.isInChangeTransition()); + + waitUntilHandlersIdle(); + mToken.removeImmediately(); + } + + @Test + public void testNoChangeWhenMoveDisplay() { + mDisplayContent.setWindowingMode(WINDOWING_MODE_FULLSCREEN); + final DisplayContent dc1 = createNewDisplay(Display.STATE_ON); + dc1.setWindowingMode(WINDOWING_MODE_FREEFORM); + setUpOnDisplay(dc1); + + assertEquals(WINDOWING_MODE_FREEFORM, mTask.getWindowingMode()); + + // Reparenting to a display with different windowing mode may trigger + // a change transition internally, but it should be cleaned-up once + // the display change is complete. + mStack.reparent(mDisplayContent.getDisplayId(), new Rect(), true); + + assertEquals(WINDOWING_MODE_FULLSCREEN, mTask.getWindowingMode()); + + // Make sure we're not waiting for a change animation (no leash) + assertFalse(mToken.isInChangeTransition()); assertNull(mToken.getThumbnail()); waitUntilHandlersIdle(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 3826fac22b05..a62bc713db40 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -51,17 +51,22 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; import android.annotation.SuppressLint; +import android.app.WindowConfiguration; import android.content.res.Configuration; import android.graphics.Rect; import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.view.DisplayCutout; +import android.view.DisplayInfo; import android.view.Gravity; import android.view.MotionEvent; import android.view.Surface; +import android.view.ViewRootImpl; +import android.view.test.InsetsModeSession; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; @@ -628,6 +633,39 @@ public class DisplayContentTests extends WindowTestsBase { eq(activityRecord), anyBoolean(), eq(dc.getDisplayId())); } + @Test + public void testComputeImeParent_app() throws Exception { + try (final InsetsModeSession session = + new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) { + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app"); + assertEquals(dc.mInputMethodTarget.mAppToken.getSurfaceControl(), + dc.computeImeParent()); + } + } + + @Test + public void testComputeImeParent_app_notFullscreen() throws Exception { + try (final InsetsModeSession session = + new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) { + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app"); + dc.mInputMethodTarget.setWindowingMode( + WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + assertEquals(dc.getWindowingLayer(), dc.computeImeParent()); + } + } + + @Test + public void testComputeImeParent_noApp() throws Exception { + try (final InsetsModeSession session = + new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) { + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar"); + assertEquals(dc.getWindowingLayer(), dc.computeImeParent()); + } + } + private boolean isOptionsPanelAtRight(int displayId) { return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 845a09f44b82..4279c4152836 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -28,6 +28,8 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; @@ -37,6 +39,7 @@ import static org.junit.Assert.assertThat; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.spy; +import android.graphics.Insets; import android.graphics.PixelFormat; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; @@ -350,6 +353,48 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { } @Test + public void layoutWindowLw_withForwardInset_SoftInputAdjustResize() { + synchronized (mWm.mGlobalLock) { + mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE; + addWindow(mWindow); + + final int forwardedInsetBottom = 50; + mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom)); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), + STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom); + assertInsetByTopBottom(mWindow.getVisibleFrameLw(), + STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom); + assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); + assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); + } + } + + @Test + public void layoutWindowLw_withForwardInset_SoftInputAdjustNothing() { + synchronized (mWm.mGlobalLock) { + mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING; + addWindow(mWindow); + + final int forwardedInsetBottom = 50; + mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom)); + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); + assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0); + assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); + } + } + + @Test public void layoutHint_appWindow() { synchronized (mWm.mGlobalLock) { // Initialize DisplayFrames diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 8876214b9636..3eb9085b68f6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -39,6 +39,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static org.hamcrest.Matchers.is; @@ -53,6 +54,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; import android.graphics.Insets; import android.graphics.Matrix; @@ -65,11 +67,13 @@ import android.view.SurfaceControl; import android.view.ViewRootImpl; import android.view.WindowManager; +import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import com.android.server.wm.utils.WmDisplayCutout; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -88,6 +92,7 @@ public class WindowStateTests extends WindowTestsBase { @BeforeClass public static void setUpOnce() { + // TODO: Make use of SettingsSession when it becomes feasible for this. sPreviousNewInsetsMode = ViewRootImpl.sNewInsetsMode; // To let the insets provider control the insets visibility, the insets mode has to be // NEW_INSETS_MODE_FULL. @@ -99,6 +104,15 @@ public class WindowStateTests extends WindowTestsBase { ViewRootImpl.sNewInsetsMode = sPreviousNewInsetsMode; } + @Before + public void setUp() { + // TODO: Let the insets source with new mode keep the visibility control, and remove this + // setup code. Now mTopFullscreenOpaqueWindowState will take back the control of insets + // visibility. + spyOn(mDisplayContent); + doNothing().when(mDisplayContent).layoutAndAssignWindowLayersIfNeeded(); + } + @Test public void testIsParentWindowHidden() { final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow"); @@ -345,6 +359,7 @@ public class WindowStateTests extends WindowTestsBase { assertFalse(app.canAffectSystemUiFlags()); } + @FlakyTest(detail = "Promote to presubmit when shown to be stable.") @Test public void testVisibleWithInsetsProvider() throws Exception { final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar"); @@ -356,6 +371,7 @@ public class WindowStateTests extends WindowTestsBase { mDisplayContent.getInsetsStateController().onBarControllingWindowChanged(app); mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR) .onInsetsModified(app, new InsetsSource(TYPE_TOP_BAR)); + waitUntilHandlersIdle(); assertFalse(topBar.isVisible()); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 7cab43233f35..93f758c2a9ad 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -1307,13 +1307,15 @@ public class VoiceInteractionManagerService extends SystemService { List<String> roleHolders = mRm.getRoleHoldersAsUser(roleName, user); + int userId = user.getIdentifier(); if (roleHolders.isEmpty()) { - Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.ASSISTANT, ""); - Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.VOICE_INTERACTION_SERVICE, ""); - Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.VOICE_RECOGNITION_SERVICE, getDefaultRecognizer(user)); + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.ASSISTANT, "", userId); + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.VOICE_INTERACTION_SERVICE, "", userId); + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.VOICE_RECOGNITION_SERVICE, getDefaultRecognizer(user), + userId); } else { // Assistant is singleton role String pkg = roleHolders.get(0); @@ -1321,7 +1323,7 @@ public class VoiceInteractionManagerService extends SystemService { // Try to set role holder as VoiceInteractionService List<ResolveInfo> services = mPm.queryIntentServicesAsUser( new Intent(VoiceInteractionService.SERVICE_INTERFACE).setPackage(pkg), - PackageManager.GET_META_DATA, user.getIdentifier()); + PackageManager.GET_META_DATA, userId); for (ResolveInfo resolveInfo : services) { ServiceInfo serviceInfo = resolveInfo.serviceInfo; @@ -1339,12 +1341,14 @@ public class VoiceInteractionManagerService extends SystemService { voiceInteractionServiceInfo.getRecognitionService()) .flattenToShortString(); - Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.ASSISTANT, serviceComponentName); - Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.VOICE_INTERACTION_SERVICE, serviceComponentName); - Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.VOICE_RECOGNITION_SERVICE, serviceRecognizerName); + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.ASSISTANT, serviceComponentName, userId); + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.VOICE_INTERACTION_SERVICE, serviceComponentName, + userId); + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.VOICE_RECOGNITION_SERVICE, serviceRecognizerName, + userId); return; } @@ -1352,19 +1356,19 @@ public class VoiceInteractionManagerService extends SystemService { // If no service could be found try to set assist activity final List<ResolveInfo> activities = mPm.queryIntentActivitiesAsUser( new Intent(Intent.ACTION_ASSIST).setPackage(pkg), - PackageManager.MATCH_DEFAULT_ONLY, user.getIdentifier()); + PackageManager.MATCH_DEFAULT_ONLY, userId); for (ResolveInfo resolveInfo : activities) { ActivityInfo activityInfo = resolveInfo.activityInfo; - Settings.Secure.putString(getContext().getContentResolver(), + Settings.Secure.putStringForUser(getContext().getContentResolver(), Settings.Secure.ASSISTANT, - activityInfo.getComponentName().flattenToShortString()); - Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.VOICE_INTERACTION_SERVICE, ""); - Settings.Secure.putString(getContext().getContentResolver(), + activityInfo.getComponentName().flattenToShortString(), userId); + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.VOICE_INTERACTION_SERVICE, "", userId); + Settings.Secure.putStringForUser(getContext().getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE, - getDefaultRecognizer(user)); + getDefaultRecognizer(user), userId); } } } diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java index 818ebd998f50..2fa388fa037e 100644 --- a/telecomm/java/android/telecom/CallScreeningService.java +++ b/telecomm/java/android/telecom/CallScreeningService.java @@ -75,7 +75,7 @@ import java.lang.annotation.RetentionPolicy; * * public void requestRole() { * RoleManager roleManager = (RoleManager) getSystemService(ROLE_SERVICE); - * Intent intent = roleManager.createRequestRoleIntent("android.app.role.CALL_SCREENING_APP"); + * Intent intent = roleManager.createRequestRoleIntent("android.app.role.CALL_SCREENING"); * startActivityForResult(intent, REQUEST_ID); * } * diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index 7d1f8ce75919..6382acf0511d 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -19,6 +19,7 @@ package android.telecom; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; @@ -571,6 +572,7 @@ public abstract class Conference extends Conferenceable { * @return The primary connection. * @hide */ + @TestApi @SystemApi public Connection getPrimaryConnection() { if (mUnmodifiableChildConnections == null || mUnmodifiableChildConnections.isEmpty()) { diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java index f5f0af7e4666..cbcd40f15583 100644 --- a/telecomm/java/android/telecom/InCallService.java +++ b/telecomm/java/android/telecom/InCallService.java @@ -35,7 +35,6 @@ import com.android.internal.os.SomeArgs; import com.android.internal.telecom.IInCallAdapter; import com.android.internal.telecom.IInCallService; -import java.lang.String; import java.util.Collections; import java.util.List; @@ -212,7 +211,7 @@ import java.util.List; * {@link android.Manifest.permission.CALL_COMPANION_APP}.</li> * </ul> * <p> - * Your app should request to fill the role {@code android.app.role.CAR_MODE_DIALER_APP} in order to + * Your app should request to fill the role {@code android.app.role.CAR_MODE_DIALER} in order to * become the default (see <a href="#requestRole">above</a> for how to request your app fills this * role). * @@ -232,7 +231,7 @@ import java.util.List; * {@link android.Manifest.permission.CALL_COMPANION_APP}.</li> * </ul> * <p> - * Your app should request to fill the role {@code android.app.role.CALL_COMPANION_APP} in order to + * Your app should request to fill the role {@code android.app.role.CALL_COMPANION} in order to * become a call companion app (see <a href="#requestRole">above</a> for how to request your app * fills this role). */ diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 0e17a3373a65..e99a289729a4 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -22,6 +22,7 @@ import android.annotation.SuppressAutoDoc; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.role.RoleManagerCallback; import android.content.ComponentName; @@ -552,6 +553,7 @@ public class TelecomManager { * * @hide */ + @TestApi @SystemApi public static final int TTY_MODE_OFF = 0; @@ -561,6 +563,7 @@ public class TelecomManager { * * @hide */ + @TestApi @SystemApi public static final int TTY_MODE_FULL = 1; @@ -571,6 +574,7 @@ public class TelecomManager { * * @hide */ + @TestApi @SystemApi public static final int TTY_MODE_HCO = 2; @@ -581,6 +585,7 @@ public class TelecomManager { * * @hide */ + @TestApi @SystemApi public static final int TTY_MODE_VCO = 3; @@ -819,6 +824,7 @@ public class TelecomManager { * @hide */ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @TestApi @SystemApi public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) { try { @@ -1521,6 +1527,7 @@ public class TelecomManager { * @hide */ @SystemApi + @TestApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public @TtyMode int getCurrentTtyMode() { try { @@ -1969,6 +1976,7 @@ public class TelecomManager { * @hide */ @SystemApi + @TestApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall() { try { diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java index 9c64cf6ddd8f..75165afe097e 100644 --- a/telephony/java/android/telephony/AccessNetworkConstants.java +++ b/telephony/java/android/telephony/AccessNetworkConstants.java @@ -54,8 +54,15 @@ public final class AccessNetworkConstants { */ @SystemApi public static final class TransportType { + /** + * Invalid transport type. + * @hide + */ + public static final int INVALID = -1; + /** Wireless Wide Area Networks (i.e. Cellular) */ public static final int WWAN = 1; + /** Wireless Local Area Networks (i.e. Wifi) */ public static final int WLAN = 2; @@ -65,6 +72,7 @@ public final class AccessNetworkConstants { /** @hide */ public static String toString(int type) { switch (type) { + case INVALID: return "INVALID"; case WWAN: return "WWAN"; case WLAN: return "WLAN"; default: return Integer.toString(type); diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java index 30e641d61143..a4207c99ce4d 100644 --- a/telephony/java/android/telephony/CellSignalStrengthGsm.java +++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java @@ -63,6 +63,10 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P public CellSignalStrengthGsm(android.hardware.radio.V1_0.GsmSignalStrength gsm) { // Convert from HAL values as part of construction. this(getRssiDbmFromAsu(gsm.signalStrength), gsm.bitErrorRate, gsm.timingAdvance); + + if (mRssi == CellInfo.UNAVAILABLE) { + setDefaultValues(); + } } /** @hide */ diff --git a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java index 6f52b853d23b..5ae89b0f8b3d 100644 --- a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java @@ -72,6 +72,10 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen // Convert from HAL values as part of construction. this(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, tdscdma.rscp != CellInfo.UNAVAILABLE ? -tdscdma.rscp : tdscdma.rscp); + + if (mRssi == CellInfo.UNAVAILABLE && mRscp == CellInfo.UNAVAILABLE) { + setDefaultValues(); + } } /** @hide */ @@ -79,6 +83,10 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen // Convert from HAL values as part of construction. this(getRssiDbmFromAsu(tdscdma.signalStrength), tdscdma.bitErrorRate, getRscpDbmFromAsu(tdscdma.rscp)); + + if (mRssi == CellInfo.UNAVAILABLE && mRscp == CellInfo.UNAVAILABLE) { + setDefaultValues(); + } } /** @hide */ diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java index 0760407171ae..efa3647f0e9b 100644 --- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java @@ -92,8 +92,12 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements /** @hide */ public CellSignalStrengthWcdma(android.hardware.radio.V1_0.WcdmaSignalStrength wcdma) { // Convert from HAL values as part of construction. - this(getRssiDbmFromAsu(wcdma.signalStrength), - wcdma.bitErrorRate, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE); + this(getRssiDbmFromAsu(wcdma.signalStrength), wcdma.bitErrorRate, + CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE); + + if (mRssi == CellInfo.UNAVAILABLE && mRscp == CellInfo.UNAVAILABLE) { + setDefaultValues(); + } } /** @hide */ @@ -103,6 +107,10 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements wcdma.base.bitErrorRate, getRscpDbmFromAsu(wcdma.rscp), getEcNoDbFromAsu(wcdma.ecno)); + + if (mRssi == CellInfo.UNAVAILABLE && mRscp == CellInfo.UNAVAILABLE) { + setDefaultValues(); + } } /** @hide */ diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index e40bae18d4f0..099015fd3d0e 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -187,15 +187,7 @@ public class SmsMessage { int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); String format = (PHONE_TYPE_CDMA == activePhone) ? SmsConstants.FORMAT_3GPP2 : SmsConstants.FORMAT_3GPP; - message = createFromPdu(pdu, format); - - if (null == message || null == message.mWrappedSmsMessage) { - // decoding pdu failed based on activePhone type, must be other format - format = (PHONE_TYPE_CDMA == activePhone) ? - SmsConstants.FORMAT_3GPP : SmsConstants.FORMAT_3GPP2; - message = createFromPdu(pdu, format); - } - return message; + return createFromPdu(pdu, format); } /** @@ -211,11 +203,18 @@ public class SmsMessage { * {@link android.provider.Telephony.Sms.Intents#SMS_RECEIVED_ACTION} intent */ public static SmsMessage createFromPdu(byte[] pdu, String format) { - SmsMessageBase wrappedMessage; + return createFromPdu(pdu, format, true); + } + + private static SmsMessage createFromPdu(byte[] pdu, String format, + boolean fallbackToOtherFormat) { if (pdu == null) { Rlog.i(LOG_TAG, "createFromPdu(): pdu is null"); return null; } + SmsMessageBase wrappedMessage; + String otherFormat = SmsConstants.FORMAT_3GPP2.equals(format) ? SmsConstants.FORMAT_3GPP : + SmsConstants.FORMAT_3GPP2; if (SmsConstants.FORMAT_3GPP2.equals(format)) { wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu); } else if (SmsConstants.FORMAT_3GPP.equals(format)) { @@ -228,8 +227,12 @@ public class SmsMessage { if (wrappedMessage != null) { return new SmsMessage(wrappedMessage); } else { - Rlog.e(LOG_TAG, "createFromPdu(): wrappedMessage is null"); - return null; + if (fallbackToOtherFormat) { + return createFromPdu(pdu, otherFormat, false); + } else { + Rlog.e(LOG_TAG, "createFromPdu(): wrappedMessage is null"); + return null; + } } } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index dfe36efcd5d1..313146d5538b 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -2047,6 +2047,8 @@ public class SubscriptionManager { putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]); } else { logd("putPhoneIdAndSubIdExtra: no valid subs"); + intent.putExtra(PhoneConstants.PHONE_KEY, phoneId); + intent.putExtra(PhoneConstants.SLOT_KEY, phoneId); } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index eab536f94290..f5d452e9721d 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -4920,12 +4920,13 @@ public class TelephonyManager { * * <p>Apps targeting {@link android.os.Build.VERSION_CODES#Q Android Q} or higher will no * longer trigger a refresh of the cached CellInfo by invoking this API. Instead, those apps - * will receive the latest cached results. Apps targeting + * will receive the latest cached results, which may not be current. Apps targeting * {@link android.os.Build.VERSION_CODES#Q Android Q} or higher that wish to request updated * CellInfo should call - * {android.telephony.TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()} and - * listen for responses via {@link android.telephony.PhoneStateListener#onCellInfoChanged - * onCellInfoChanged()}. + * {@link android.telephony.TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()}; + * however, in all cases, updates will be rate-limited and are not guaranteed. To determine the + * recency of CellInfo data, callers should check + * {@link android.telephony.CellInfo#getTimeStamp CellInfo#getTimeStamp()}. * * <p>This method returns valid data for devices with * {@link android.content.pm.PackageManager#FEATURE_TELEPHONY FEATURE_TELEPHONY}. In cases diff --git a/telephony/java/android/telephony/ims/Rcs1To1Thread.java b/telephony/java/android/telephony/ims/Rcs1To1Thread.java index cc28ee0758c2..3255f8d0786d 100644 --- a/telephony/java/android/telephony/ims/Rcs1To1Thread.java +++ b/telephony/java/android/telephony/ims/Rcs1To1Thread.java @@ -23,7 +23,7 @@ import android.annotation.WorkerThread; * {@link RcsParticipant}s. Please see Section 5 (1-to-1 Messaging) - GSMA RCC.71 (RCS Universal * Profile Service Definition Document) * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public class Rcs1To1Thread extends RcsThread { private int mThreadId; diff --git a/telephony/java/android/telephony/ims/RcsEvent.java b/telephony/java/android/telephony/ims/RcsEvent.java index 744ac76a7828..ef359a124d47 100644 --- a/telephony/java/android/telephony/ims/RcsEvent.java +++ b/telephony/java/android/telephony/ims/RcsEvent.java @@ -16,14 +16,17 @@ package android.telephony.ims; import android.os.Parcel; -import android.os.Parcelable; /** * The base class for events that can happen on {@link RcsParticipant}s and {@link RcsThread}s. - * @hide - TODO(109759350) make this public + * + * @hide - TODO: make public */ -public abstract class RcsEvent implements Parcelable { - protected long mTimestamp; +public abstract class RcsEvent { + /** + * @hide + */ + protected final long mTimestamp; protected RcsEvent(long timestamp) { mTimestamp = timestamp; @@ -44,17 +47,17 @@ public abstract class RcsEvent implements Parcelable { */ abstract void persist() throws RcsMessageStoreException; + /** + * @hide + */ RcsEvent(Parcel in) { mTimestamp = in.readLong(); } - @Override + /** + * @hide + */ public void writeToParcel(Parcel dest, int flags) { dest.writeLong(mTimestamp); } - - @Override - public int describeContents() { - return 0; - } } diff --git a/telephony/java/android/telephony/ims/RcsEventQueryParameters.aidl b/telephony/java/android/telephony/ims/RcsEventQueryParams.aidl index 9a3600bbae90..f18c4dfd2dcd 100644 --- a/telephony/java/android/telephony/ims/RcsEventQueryParameters.aidl +++ b/telephony/java/android/telephony/ims/RcsEventQueryParams.aidl @@ -17,4 +17,4 @@ package android.telephony.ims; -parcelable RcsEventQueryParameters; +parcelable RcsEventQueryParams; diff --git a/telephony/java/android/telephony/ims/RcsEventQueryParameters.java b/telephony/java/android/telephony/ims/RcsEventQueryParams.java index 6aee56f56f45..5249becd476e 100644 --- a/telephony/java/android/telephony/ims/RcsEventQueryParameters.java +++ b/telephony/java/android/telephony/ims/RcsEventQueryParams.java @@ -35,29 +35,29 @@ import java.security.InvalidParameterException; /** * The parameters to pass into - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} in order to select a + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} in order to select a * subset of {@link RcsEvent}s present in the message store. * - * @hide TODO - make the Builder and builder() public. The rest should stay internal only. + * @hide - TODO: make public */ -public class RcsEventQueryParameters implements Parcelable { +public final class RcsEventQueryParams implements Parcelable { /** * Flag to be used with {@link Builder#setEventType(int)} to make - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return all types of + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} return all types of * {@link RcsEvent}s */ public static final int ALL_EVENTS = -1; /** * Flag to be used with {@link Builder#setEventType(int)} to make - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return sub-types of + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} return sub-types of * {@link RcsGroupThreadEvent}s */ public static final int ALL_GROUP_THREAD_EVENTS = 0; /** * Flag to be used with {@link Builder#setEventType(int)} to make - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} return only * {@link RcsParticipantAliasChangedEvent}s */ public static final int PARTICIPANT_ALIAS_CHANGED_EVENT = @@ -65,7 +65,7 @@ public class RcsEventQueryParameters implements Parcelable { /** * Flag to be used with {@link Builder#setEventType(int)} to make - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} return only * {@link RcsGroupThreadParticipantJoinedEvent}s */ public static final int GROUP_THREAD_PARTICIPANT_JOINED_EVENT = @@ -73,7 +73,7 @@ public class RcsEventQueryParameters implements Parcelable { /** * Flag to be used with {@link Builder#setEventType(int)} to make - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} return only * {@link RcsGroupThreadParticipantLeftEvent}s */ public static final int GROUP_THREAD_PARTICIPANT_LEFT_EVENT = @@ -81,14 +81,14 @@ public class RcsEventQueryParameters implements Parcelable { /** * Flag to be used with {@link Builder#setEventType(int)} to make - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} return only * {@link RcsGroupThreadNameChangedEvent}s */ public static final int GROUP_THREAD_NAME_CHANGED_EVENT = NAME_CHANGED_EVENT_TYPE; /** * Flag to be used with {@link Builder#setEventType(int)} to make - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} return only * {@link RcsGroupThreadIconChangedEvent}s */ public static final int GROUP_THREAD_ICON_CHANGED_EVENT = ICON_CHANGED_EVENT_TYPE; @@ -134,7 +134,7 @@ public class RcsEventQueryParameters implements Parcelable { // The thread that the results are limited to private int mThreadId; - RcsEventQueryParameters(@EventType int eventType, int threadId, + RcsEventQueryParams(@EventType int eventType, int threadId, @SortingProperty int sortingProperty, boolean isAscending, int limit) { mEventType = eventType; mSortingProperty = sortingProperty; @@ -144,7 +144,7 @@ public class RcsEventQueryParameters implements Parcelable { } /** - * @return Returns the type of {@link RcsEvent}s that this {@link RcsEventQueryParameters} is + * @return Returns the type of {@link RcsEvent}s that this {@link RcsEventQueryParams} is * set to query for. */ public @EventType int getEventType() { @@ -152,7 +152,7 @@ public class RcsEventQueryParameters implements Parcelable { } /** - * @return Returns the type of {@link RcsEvent}s that this {@link RcsEventQueryParameters} is + * @return Returns the type of {@link RcsEvent}s that this {@link RcsEventQueryParams} is * set to query for. */ public int getLimit() { @@ -186,7 +186,7 @@ public class RcsEventQueryParameters implements Parcelable { } /** - * A helper class to build the {@link RcsEventQueryParameters}. + * A helper class to build the {@link RcsEventQueryParams}. */ public static class Builder { private @EventType int mEventType; @@ -196,8 +196,8 @@ public class RcsEventQueryParameters implements Parcelable { private int mThreadId; /** - * Creates a new builder for {@link RcsEventQueryParameters} to be used in - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} + * Creates a new builder for {@link RcsEventQueryParams} to be used in + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} */ public Builder() { // empty implementation @@ -236,7 +236,7 @@ public class RcsEventQueryParameters implements Parcelable { /** * Sets the property where the results should be sorted against. Defaults to - * {@link RcsEventQueryParameters.SortingProperty#SORT_BY_CREATION_ORDER} + * {@link RcsEventQueryParams.SortingProperty#SORT_BY_CREATION_ORDER} * * @param sortingProperty against which property the results should be sorted * @return The same instance of the builder to chain parameters. @@ -273,18 +273,18 @@ public class RcsEventQueryParameters implements Parcelable { } /** - * Builds the {@link RcsEventQueryParameters} to use in - * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} + * Builds the {@link RcsEventQueryParams} to use in + * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} * - * @return An instance of {@link RcsEventQueryParameters} to use with the event query. + * @return An instance of {@link RcsEventQueryParams} to use with the event query. */ - public RcsEventQueryParameters build() { - return new RcsEventQueryParameters(mEventType, mThreadId, mSortingProperty, + public RcsEventQueryParams build() { + return new RcsEventQueryParams(mEventType, mThreadId, mSortingProperty, mIsAscending, mLimit); } } - protected RcsEventQueryParameters(Parcel in) { + private RcsEventQueryParams(Parcel in) { mEventType = in.readInt(); mThreadId = in.readInt(); mSortingProperty = in.readInt(); @@ -292,20 +292,19 @@ public class RcsEventQueryParameters implements Parcelable { mLimit = in.readInt(); } - public static final Creator<RcsEventQueryParameters> CREATOR = - new Creator<RcsEventQueryParameters>() { + public static final Creator<RcsEventQueryParams> CREATOR = + new Creator<RcsEventQueryParams>() { @Override - public RcsEventQueryParameters createFromParcel(Parcel in) { - return new RcsEventQueryParameters(in); + public RcsEventQueryParams createFromParcel(Parcel in) { + return new RcsEventQueryParams(in); } @Override - public RcsEventQueryParameters[] newArray(int size) { - return new RcsEventQueryParameters[size]; + public RcsEventQueryParams[] newArray(int size) { + return new RcsEventQueryParams[size]; } }; - @Override public int describeContents() { return 0; diff --git a/telephony/java/android/telephony/ims/RcsEventQueryResult.java b/telephony/java/android/telephony/ims/RcsEventQueryResult.java index 27898ab0d9a2..f8d57fa5c09d 100644 --- a/telephony/java/android/telephony/ims/RcsEventQueryResult.java +++ b/telephony/java/android/telephony/ims/RcsEventQueryResult.java @@ -22,13 +22,13 @@ import android.os.Parcelable; import java.util.List; /** - * The result of a {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} + * The result of a {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} * call. This class allows getting the token for querying the next batch of events in order to * prevent handling large amounts of data at once. * - * @hide + * @hide - TODO: make public */ -public class RcsEventQueryResult implements Parcelable { +public final class RcsEventQueryResult implements Parcelable { private RcsQueryContinuationToken mContinuationToken; private List<RcsEvent> mEvents; @@ -63,7 +63,8 @@ public class RcsEventQueryResult implements Parcelable { return mEvents; } - protected RcsEventQueryResult(Parcel in) { + private RcsEventQueryResult(Parcel in) { + mContinuationToken = in.readParcelable(RcsQueryContinuationToken.class.getClassLoader()); } public static final Creator<RcsEventQueryResult> CREATOR = new Creator<RcsEventQueryResult>() { diff --git a/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.aidl b/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.aidl deleted file mode 100644 index 5fec021525af..000000000000 --- a/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * - * Copyright 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony.ims; - -parcelable RcsFileTransferCreationParameters; diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.aidl b/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.aidl index ea8288cd9f6a..155219038d7b 100644 --- a/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.aidl +++ b/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.aidl @@ -17,4 +17,4 @@ package android.telephony.ims; -parcelable RcsParticipantQueryParameters; +parcelable RcsFileTransferCreationParams; diff --git a/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.java b/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java index bd7cb4bc90bc..663def5df50f 100644 --- a/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.java +++ b/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java @@ -22,12 +22,12 @@ import android.os.Parcelable; /** * Pass an instance of this class to - * {@link RcsMessage#insertFileTransfer(RcsFileTransferCreationParameters)} create an + * {@link RcsMessage#insertFileTransfer(RcsFileTransferCreationParams)} create an * {@link RcsFileTransferPart} and save it into storage. * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ -public class RcsFileTransferCreationParameters implements Parcelable { +public final class RcsFileTransferCreationParams implements Parcelable { private String mRcsFileTransferSessionId; private Uri mContentUri; private String mContentMimeType; @@ -128,7 +128,7 @@ public class RcsFileTransferCreationParameters implements Parcelable { /** * @hide */ - RcsFileTransferCreationParameters(Builder builder) { + RcsFileTransferCreationParams(Builder builder) { mRcsFileTransferSessionId = builder.mRcsFileTransferSessionId; mContentUri = builder.mContentUri; mContentMimeType = builder.mContentMimeType; @@ -143,7 +143,7 @@ public class RcsFileTransferCreationParameters implements Parcelable { } /** - * A builder to create instances of {@link RcsFileTransferCreationParameters} + * A builder to create instances of {@link RcsFileTransferCreationParams} */ public class Builder { private String mRcsFileTransferSessionId; @@ -300,18 +300,18 @@ public class RcsFileTransferCreationParameters implements Parcelable { } /** - * Creates an instance of {@link RcsFileTransferCreationParameters} with the given + * Creates an instance of {@link RcsFileTransferCreationParams} with the given * parameters. * * @return The same instance of {@link Builder} to chain methods - * @see RcsMessage#insertFileTransfer(RcsFileTransferCreationParameters) + * @see RcsMessage#insertFileTransfer(RcsFileTransferCreationParams) */ - public RcsFileTransferCreationParameters build() { - return new RcsFileTransferCreationParameters(this); + public RcsFileTransferCreationParams build() { + return new RcsFileTransferCreationParams(this); } } - protected RcsFileTransferCreationParameters(Parcel in) { + private RcsFileTransferCreationParams(Parcel in) { mRcsFileTransferSessionId = in.readString(); mContentUri = in.readParcelable(Uri.class.getClassLoader()); mContentMimeType = in.readString(); @@ -325,16 +325,16 @@ public class RcsFileTransferCreationParameters implements Parcelable { mFileTransferStatus = in.readInt(); } - public static final Creator<RcsFileTransferCreationParameters> CREATOR = - new Creator<RcsFileTransferCreationParameters>() { + public static final Creator<RcsFileTransferCreationParams> CREATOR = + new Creator<RcsFileTransferCreationParams>() { @Override - public RcsFileTransferCreationParameters createFromParcel(Parcel in) { - return new RcsFileTransferCreationParameters(in); + public RcsFileTransferCreationParams createFromParcel(Parcel in) { + return new RcsFileTransferCreationParams(in); } @Override - public RcsFileTransferCreationParameters[] newArray(int size) { - return new RcsFileTransferCreationParameters[size]; + public RcsFileTransferCreationParams[] newArray(int size) { + return new RcsFileTransferCreationParams[size]; } }; diff --git a/telephony/java/android/telephony/ims/RcsFileTransferPart.java b/telephony/java/android/telephony/ims/RcsFileTransferPart.java index 2eadc4a1724e..1ce799919e09 100644 --- a/telephony/java/android/telephony/ims/RcsFileTransferPart.java +++ b/telephony/java/android/telephony/ims/RcsFileTransferPart.java @@ -27,7 +27,7 @@ import java.lang.annotation.RetentionPolicy; * A part of a composite {@link RcsMessage} that holds a file transfer. Please see Section 7 * (File Transfer) - GSMA RCC.71 (RCS Universal Profile Service Definition Document) * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public class RcsFileTransferPart { /** diff --git a/telephony/java/android/telephony/ims/RcsGroupThread.java b/telephony/java/android/telephony/ims/RcsGroupThread.java index 6f6258e3d894..2c42494ee924 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThread.java +++ b/telephony/java/android/telephony/ims/RcsGroupThread.java @@ -30,7 +30,7 @@ import java.util.Set; * or leave. Please see Section 6 (Group Chat) - GSMA RCC.71 (RCS Universal Profile Service * Definition Document) * - * @hide - TODO(sahinc) make this public + * @hide - TODO: make public */ public class RcsGroupThread extends RcsThread { /** @@ -166,8 +166,8 @@ public class RcsGroupThread extends RcsThread { @WorkerThread @NonNull public Set<RcsParticipant> getParticipants() throws RcsMessageStoreException { - RcsParticipantQueryParameters queryParameters = - new RcsParticipantQueryParameters.Builder().setThread(this).build(); + RcsParticipantQueryParams queryParameters = + new RcsParticipantQueryParams.Builder().setThread(this).build(); RcsParticipantQueryResult queryResult = RcsControllerCall.call( iRcs -> iRcs.getParticipants(queryParameters)); diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java index a18437b8366e..bc61877a81d6 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java @@ -21,7 +21,7 @@ import android.os.Parcel; /** * An event that happened on an {@link RcsGroupThread}. * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public abstract class RcsGroupThreadEvent extends RcsEvent { private final int mRcsGroupThreadId; @@ -50,13 +50,18 @@ public abstract class RcsGroupThreadEvent extends RcsEvent { return new RcsParticipant(mOriginatingParticipantId); } + /** + * @hide + */ RcsGroupThreadEvent(Parcel in) { super(in); mRcsGroupThreadId = in.readInt(); mOriginatingParticipantId = in.readInt(); } - @Override + /** + * @hide + */ public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(mRcsGroupThreadId); diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java index 7beed3ba7ec2..74af9738e976 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java @@ -19,14 +19,16 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.os.Parcel; +import android.os.Parcelable; /** * An event that indicates an {@link RcsGroupThread}'s icon was changed. Please see R6-2-5 - GSMA * RCC.71 (RCS Universal Profile Service Definition Document) * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ -public class RcsGroupThreadIconChangedEvent extends RcsGroupThreadEvent { +public final class RcsGroupThreadIconChangedEvent extends RcsGroupThreadEvent implements + Parcelable { private final Uri mNewIcon; /** @@ -91,7 +93,7 @@ public class RcsGroupThreadIconChangedEvent extends RcsGroupThreadEvent { } }; - protected RcsGroupThreadIconChangedEvent(Parcel in) { + private RcsGroupThreadIconChangedEvent(Parcel in) { super(in); mNewIcon = in.readParcelable(Uri.class.getClassLoader()); } diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java index 0d2ea4febfbc..06f4d5b10bb4 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java @@ -18,15 +18,17 @@ package android.telephony.ims; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; +import android.os.Parcelable; /** * An event that indicates an {@link RcsGroupThread}'s name was changed. Please see R6-2-5 - GSMA * RCC.71 (RCS Universal Profile Service Definition Document) * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ -public class RcsGroupThreadNameChangedEvent extends RcsGroupThreadEvent { - private String mNewName; +public final class RcsGroupThreadNameChangedEvent extends RcsGroupThreadEvent implements + Parcelable { + private final String mNewName; /** * Creates a new {@link RcsGroupThreadNameChangedEvent}. This event is not persisted into @@ -89,7 +91,7 @@ public class RcsGroupThreadNameChangedEvent extends RcsGroupThreadEvent { } }; - protected RcsGroupThreadNameChangedEvent(Parcel in) { + private RcsGroupThreadNameChangedEvent(Parcel in) { super(in); mNewName = in.readString(); } diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java index 2adafc7e1bb1..493270795e01 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java @@ -17,15 +17,17 @@ package android.telephony.ims; import android.annotation.NonNull; import android.os.Parcel; +import android.os.Parcelable; /** * An event that indicates an RCS participant has joined an {@link RcsThread}. Please see US6-3 - * GSMA RCC.71 (RCS Universal Profile Service Definition Document) * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ -public class RcsGroupThreadParticipantJoinedEvent extends RcsGroupThreadEvent { - private int mJoinedParticipantId; +public final class RcsGroupThreadParticipantJoinedEvent extends RcsGroupThreadEvent implements + Parcelable { + private final int mJoinedParticipantId; /** * Creates a new {@link RcsGroupThreadParticipantJoinedEvent}. This event is not persisted into @@ -89,7 +91,7 @@ public class RcsGroupThreadParticipantJoinedEvent extends RcsGroupThreadEvent { } }; - protected RcsGroupThreadParticipantJoinedEvent(Parcel in) { + private RcsGroupThreadParticipantJoinedEvent(Parcel in) { super(in); mJoinedParticipantId = in.readInt(); } diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java index 87c1852964ee..970a046e1105 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java +++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java @@ -17,15 +17,17 @@ package android.telephony.ims; import android.annotation.NonNull; import android.os.Parcel; +import android.os.Parcelable; /** * An event that indicates an RCS participant has left an {@link RcsThread}. Please see US6-23 - * GSMA RCC.71 (RCS Universal Profile Service Definition Document) * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ -public class RcsGroupThreadParticipantLeftEvent extends RcsGroupThreadEvent { - private int mLeavingParticipantId; +public final class RcsGroupThreadParticipantLeftEvent extends RcsGroupThreadEvent implements + Parcelable { + private final int mLeavingParticipantId; /** * Creates a new {@link RcsGroupThreadParticipantLeftEvent}. his event is not persisted into @@ -88,7 +90,7 @@ public class RcsGroupThreadParticipantLeftEvent extends RcsGroupThreadEvent { } }; - protected RcsGroupThreadParticipantLeftEvent(Parcel in) { + private RcsGroupThreadParticipantLeftEvent(Parcel in) { super(in); mLeavingParticipantId = in.readInt(); } diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessage.java b/telephony/java/android/telephony/ims/RcsIncomingMessage.java index 2ea115bd675b..f3b7815c2453 100644 --- a/telephony/java/android/telephony/ims/RcsIncomingMessage.java +++ b/telephony/java/android/telephony/ims/RcsIncomingMessage.java @@ -20,7 +20,7 @@ import android.annotation.WorkerThread; /** * This is a single instance of a message received over RCS. * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public class RcsIncomingMessage extends RcsMessage { /** diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.aidl b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.aidl deleted file mode 100644 index 76073c22af0c..000000000000 --- a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * - * Copyright 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony.ims; - -parcelable RcsIncomingMessageCreationParameters; diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.aidl b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.aidl new file mode 100644 index 000000000000..1f1d4f68213a --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.aidl @@ -0,0 +1,20 @@ +/* + * + * Copyright 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +parcelable RcsIncomingMessageCreationParams; diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.java b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java index acde8af0d295..64b2339905eb 100644 --- a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.java +++ b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java @@ -21,13 +21,13 @@ import android.os.Parcel; import android.os.Parcelable; /** - * {@link RcsIncomingMessageCreationParameters} is a collection of parameters that should be passed - * into {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParameters)} to generate an + * {@link RcsIncomingMessageCreationParams} is a collection of parameters that should be passed + * into {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParams)} to generate an * {@link RcsIncomingMessage} on that {@link RcsThread} * - * @hide TODO:make public + * @hide - TODO: make public */ -public class RcsIncomingMessageCreationParameters extends RcsMessageCreationParameters implements +public final class RcsIncomingMessageCreationParams extends RcsMessageCreationParams implements Parcelable { // The arrival timestamp for the RcsIncomingMessage to be created private final long mArrivalTimestamp; @@ -37,18 +37,18 @@ public class RcsIncomingMessageCreationParameters extends RcsMessageCreationPara private final int mSenderParticipantId; /** - * Builder to help create an {@link RcsIncomingMessageCreationParameters} + * Builder to help create an {@link RcsIncomingMessageCreationParams} * - * @see RcsThread#addIncomingMessage(RcsIncomingMessageCreationParameters) + * @see RcsThread#addIncomingMessage(RcsIncomingMessageCreationParams) */ - public static class Builder extends RcsMessageCreationParameters.Builder { + public static class Builder extends RcsMessageCreationParams.Builder { private RcsParticipant mSenderParticipant; private long mArrivalTimestamp; private long mSeenTimestamp; /** * Creates a {@link Builder} to create an instance of - * {@link RcsIncomingMessageCreationParameters} + * {@link RcsIncomingMessageCreationParams} * * @param originationTimestamp The timestamp of {@link RcsMessage} creation. The origination * timestamp value in milliseconds passed after midnight, @@ -103,22 +103,22 @@ public class RcsIncomingMessageCreationParameters extends RcsMessageCreationPara /** * Creates parameters for creating a new incoming message. - * @return A new instance of {@link RcsIncomingMessageCreationParameters} to create a new + * @return A new instance of {@link RcsIncomingMessageCreationParams} to create a new * {@link RcsIncomingMessage} */ - public RcsIncomingMessageCreationParameters build() { - return new RcsIncomingMessageCreationParameters(this); + public RcsIncomingMessageCreationParams build() { + return new RcsIncomingMessageCreationParams(this); } } - private RcsIncomingMessageCreationParameters(Builder builder) { + private RcsIncomingMessageCreationParams(Builder builder) { super(builder); mArrivalTimestamp = builder.mArrivalTimestamp; mSeenTimestamp = builder.mSeenTimestamp; mSenderParticipantId = builder.mSenderParticipant.getId(); } - protected RcsIncomingMessageCreationParameters(Parcel in) { + private RcsIncomingMessageCreationParams(Parcel in) { super(in); mArrivalTimestamp = in.readLong(); mSeenTimestamp = in.readLong(); @@ -152,16 +152,16 @@ public class RcsIncomingMessageCreationParameters extends RcsMessageCreationPara return mSenderParticipantId; } - public static final Creator<RcsIncomingMessageCreationParameters> CREATOR = - new Creator<RcsIncomingMessageCreationParameters>() { + public static final Creator<RcsIncomingMessageCreationParams> CREATOR = + new Creator<RcsIncomingMessageCreationParams>() { @Override - public RcsIncomingMessageCreationParameters createFromParcel(Parcel in) { - return new RcsIncomingMessageCreationParameters(in); + public RcsIncomingMessageCreationParams createFromParcel(Parcel in) { + return new RcsIncomingMessageCreationParams(in); } @Override - public RcsIncomingMessageCreationParameters[] newArray(int size) { - return new RcsIncomingMessageCreationParameters[size]; + public RcsIncomingMessageCreationParams[] newArray(int size) { + return new RcsIncomingMessageCreationParams[size]; } }; @@ -172,7 +172,7 @@ public class RcsIncomingMessageCreationParameters extends RcsMessageCreationPara @Override public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); + super.writeToParcel(dest); dest.writeLong(mArrivalTimestamp); dest.writeLong(mSeenTimestamp); dest.writeInt(mSenderParticipantId); diff --git a/telephony/java/android/telephony/ims/RcsManager.java b/telephony/java/android/telephony/ims/RcsManager.java index e84d4ed9e7be..90bd0446d6f3 100644 --- a/telephony/java/android/telephony/ims/RcsManager.java +++ b/telephony/java/android/telephony/ims/RcsManager.java @@ -20,11 +20,19 @@ import android.content.Context; /** * The manager class for RCS related utilities. - * @hide + * + * @hide - TODO: make public */ @SystemService(Context.TELEPHONY_RCS_SERVICE) public class RcsManager { + /** + * @hide + */ + public RcsManager() { + // empty constructor + } + private static final RcsMessageStore sRcsMessageStoreInstance = new RcsMessageStore(); /** diff --git a/telephony/java/android/telephony/ims/RcsMessage.java b/telephony/java/android/telephony/ims/RcsMessage.java index b70a9a7973f5..1700941b94ed 100644 --- a/telephony/java/android/telephony/ims/RcsMessage.java +++ b/telephony/java/android/telephony/ims/RcsMessage.java @@ -28,7 +28,7 @@ import java.util.Set; /** * This is a single instance of a message sent or received over RCS. * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public abstract class RcsMessage { /** @@ -83,7 +83,10 @@ public abstract class RcsMessage { */ public static final int SEEN = 9; - protected int mId; + /** + * @hide + */ + protected final int mId; @IntDef({ DRAFT, QUEUED, SENDING, SENT, RETRYING, FAILED, RECEIVED, SEEN @@ -277,7 +280,7 @@ public abstract class RcsMessage { @NonNull @WorkerThread public RcsFileTransferPart insertFileTransfer( - RcsFileTransferCreationParameters fileTransferCreationParameters) + RcsFileTransferCreationParams fileTransferCreationParameters) throws RcsMessageStoreException { return new RcsFileTransferPart(RcsControllerCall.call( iRcs -> iRcs.storeFileTransfer(mId, isIncoming(), fileTransferCreationParameters))); diff --git a/telephony/java/android/telephony/ims/RcsMessageCreationParameters.java b/telephony/java/android/telephony/ims/RcsMessageCreationParams.java index ff3f33ed2e1b..9ac4dcdf2d74 100644 --- a/telephony/java/android/telephony/ims/RcsMessageCreationParameters.java +++ b/telephony/java/android/telephony/ims/RcsMessageCreationParams.java @@ -21,18 +21,16 @@ import static android.telephony.ims.RcsMessage.LOCATION_NOT_SET; import android.annotation.CheckResult; import android.annotation.Nullable; import android.os.Parcel; -import android.os.Parcelable; -import android.telephony.SubscriptionInfo; /** * The collection of parameters to be passed into - * {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParameters)} and - * {@link RcsThread#addOutgoingMessage(RcsMessageCreationParameters)} to create and persist + * {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParams)} and + * {@link RcsThread#addOutgoingMessage(RcsOutgoingMessageCreationParams)} to create and persist * {@link RcsMessage}s on an {@link RcsThread} * - * @hide TODO - make public + * @hide - TODO: make public */ -public class RcsMessageCreationParameters implements Parcelable { +public class RcsMessageCreationParams { // The globally unique id of the RcsMessage to be created. private final String mRcsMessageGlobalId; @@ -110,7 +108,7 @@ public class RcsMessageCreationParameters implements Parcelable { /** * The base builder for creating {@link RcsMessage}s on {@link RcsThread}s. * - * @see RcsIncomingMessageCreationParameters + * @see RcsIncomingMessageCreationParams */ public static class Builder { private String mRcsMessageGlobalId; @@ -122,15 +120,7 @@ public class RcsMessageCreationParameters implements Parcelable { private double mLongitude = LOCATION_NOT_SET; /** - * Creates a new {@link Builder} to create an instance of - * {@link RcsMessageCreationParameters}. - * - * @param originationTimestamp The timestamp of {@link RcsMessage} creation. The origination - * timestamp value in milliseconds passed after midnight, - * January 1, 1970 UTC - * @param subscriptionId The subscription ID that was used to send or receive this - * {@link RcsMessage} - * @see SubscriptionInfo#getSubscriptionId() + * @hide */ public Builder(long originationTimestamp, int subscriptionId) { mOriginationTimestamp = originationTimestamp; @@ -207,14 +197,14 @@ public class RcsMessageCreationParameters implements Parcelable { } /** - * @hide + * @return Builds and returns a newly created {@link RcsMessageCreationParams} */ - public RcsMessageCreationParameters build() { - return new RcsMessageCreationParameters(this); + public RcsMessageCreationParams build() { + return new RcsMessageCreationParams(this); } } - protected RcsMessageCreationParameters(Builder builder) { + protected RcsMessageCreationParams(Builder builder) { mRcsMessageGlobalId = builder.mRcsMessageGlobalId; mSubId = builder.mSubId; mMessageStatus = builder.mMessageStatus; @@ -224,7 +214,10 @@ public class RcsMessageCreationParameters implements Parcelable { mLongitude = builder.mLongitude; } - protected RcsMessageCreationParameters(Parcel in) { + /** + * @hide + */ + RcsMessageCreationParams(Parcel in) { mRcsMessageGlobalId = in.readString(); mSubId = in.readInt(); mMessageStatus = in.readInt(); @@ -234,26 +227,10 @@ public class RcsMessageCreationParameters implements Parcelable { mLongitude = in.readDouble(); } - public static final Creator<RcsMessageCreationParameters> CREATOR = - new Creator<RcsMessageCreationParameters>() { - @Override - public RcsMessageCreationParameters createFromParcel(Parcel in) { - return new RcsMessageCreationParameters(in); - } - - @Override - public RcsMessageCreationParameters[] newArray(int size) { - return new RcsMessageCreationParameters[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { + /** + * @hide + */ + public void writeToParcel(Parcel dest) { dest.writeString(mRcsMessageGlobalId); dest.writeInt(mSubId); dest.writeInt(mMessageStatus); diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl b/telephony/java/android/telephony/ims/RcsMessageQueryParams.aidl index 52e73ce02407..e9cbd9cc4ebe 100644 --- a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl +++ b/telephony/java/android/telephony/ims/RcsMessageQueryParams.aidl @@ -17,4 +17,4 @@ package android.telephony.ims; -parcelable RcsThreadQueryParameters; +parcelable RcsMessageQueryParams; diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryParameters.java b/telephony/java/android/telephony/ims/RcsMessageQueryParams.java index c964cf9af7c5..fae0d97cd722 100644 --- a/telephony/java/android/telephony/ims/RcsMessageQueryParameters.java +++ b/telephony/java/android/telephony/ims/RcsMessageQueryParams.java @@ -29,12 +29,12 @@ import java.security.InvalidParameterException; /** * The parameters to pass into - * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} in order to select a + * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} in order to select a * subset of {@link RcsMessage}s present in the message store. * - * @hide TODO - make the Builder and builder() public. The rest should stay internal only. + * @hide - TODO: make public */ -public class RcsMessageQueryParameters implements Parcelable { +public final class RcsMessageQueryParams implements Parcelable { /** * @hide - not meant for public use */ @@ -60,28 +60,28 @@ public class RcsMessageQueryParameters implements Parcelable { /** * Bitmask flag to be used with {@link Builder#setMessageType(int)} to make - * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} return + * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} return * {@link RcsIncomingMessage}s. */ public static final int MESSAGE_TYPE_INCOMING = 0x0001; /** * Bitmask flag to be used with {@link Builder#setMessageType(int)} to make - * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} return + * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} return * {@link RcsOutgoingMessage}s. */ public static final int MESSAGE_TYPE_OUTGOING = 0x0002; /** * Bitmask flag to be used with {@link Builder#setFileTransferPresence(int)} to make - * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} return {@link RcsMessage}s + * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} return {@link RcsMessage}s * that have an {@link RcsFileTransferPart} attached. */ public static final int MESSAGES_WITH_FILE_TRANSFERS = 0x0004; /** * Bitmask flag to be used with {@link Builder#setFileTransferPresence(int)} to make - * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} return {@link RcsMessage}s + * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} return {@link RcsMessage}s * that don't have an {@link RcsFileTransferPart} attached. */ public static final int MESSAGES_WITHOUT_FILE_TRANSFERS = 0x0008; @@ -106,7 +106,7 @@ public class RcsMessageQueryParameters implements Parcelable { // The thread that the results should be limited to private int mThreadId; - RcsMessageQueryParameters(int messageType, int fileTransferPresence, String messageLike, + RcsMessageQueryParams(int messageType, int fileTransferPresence, String messageLike, int threadId, @SortingProperty int sortingProperty, boolean isAscending, int limit) { mMessageType = messageType; mFileTransferPresence = fileTransferPresence; @@ -118,7 +118,7 @@ public class RcsMessageQueryParameters implements Parcelable { } /** - * @return Returns the type of {@link RcsMessage}s that this {@link RcsMessageQueryParameters} + * @return Returns the type of {@link RcsMessage}s that this {@link RcsMessageQueryParams} * is set to query for. */ public int getMessageType() { @@ -177,7 +177,7 @@ public class RcsMessageQueryParameters implements Parcelable { } /** - * A helper class to build the {@link RcsMessageQueryParameters}. + * A helper class to build the {@link RcsMessageQueryParams}. */ public static class Builder { private @SortingProperty int mSortingProperty; @@ -189,8 +189,8 @@ public class RcsMessageQueryParameters implements Parcelable { private int mThreadId = THREAD_ID_NOT_SET; /** - * Creates a new builder for {@link RcsMessageQueryParameters} to be used in - * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} + * Creates a new builder for {@link RcsMessageQueryParams} to be used in + * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} * */ public Builder() { @@ -221,8 +221,8 @@ public class RcsMessageQueryParameters implements Parcelable { * * @param messageType The type of message to be returned. * @return The same instance of the builder to chain parameters. - * @see RcsMessageQueryParameters#MESSAGE_TYPE_INCOMING - * @see RcsMessageQueryParameters#MESSAGE_TYPE_OUTGOING + * @see RcsMessageQueryParams#MESSAGE_TYPE_INCOMING + * @see RcsMessageQueryParams#MESSAGE_TYPE_OUTGOING */ @CheckResult public Builder setMessageType(int messageType) { @@ -235,8 +235,8 @@ public class RcsMessageQueryParameters implements Parcelable { * * @param fileTransferPresence Whether file transfers should be included in the result * @return The same instance of the builder to chain parameters. - * @see RcsMessageQueryParameters#MESSAGES_WITH_FILE_TRANSFERS - * @see RcsMessageQueryParameters#MESSAGES_WITHOUT_FILE_TRANSFERS + * @see RcsMessageQueryParams#MESSAGES_WITH_FILE_TRANSFERS + * @see RcsMessageQueryParams#MESSAGES_WITHOUT_FILE_TRANSFERS */ @CheckResult public Builder setFileTransferPresence(int fileTransferPresence) { @@ -264,7 +264,7 @@ public class RcsMessageQueryParameters implements Parcelable { /** * Sets the property where the results should be sorted against. Defaults to - * {@link RcsMessageQueryParameters.SortingProperty#SORT_BY_CREATION_ORDER} + * {@link RcsMessageQueryParams.SortingProperty#SORT_BY_CREATION_ORDER} * * @param sortingProperty against which property the results should be sorted * @return The same instance of the builder to chain parameters. @@ -305,14 +305,14 @@ public class RcsMessageQueryParameters implements Parcelable { } /** - * Builds the {@link RcsMessageQueryParameters} to use in - * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} + * Builds the {@link RcsMessageQueryParams} to use in + * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} * - * @return An instance of {@link RcsMessageQueryParameters} to use with the message + * @return An instance of {@link RcsMessageQueryParams} to use with the message * query. */ - public RcsMessageQueryParameters build() { - return new RcsMessageQueryParameters(mMessageType, mFileTransferPresence, mMessageLike, + public RcsMessageQueryParams build() { + return new RcsMessageQueryParams(mMessageType, mFileTransferPresence, mMessageLike, mThreadId, mSortingProperty, mIsAscending, mLimit); } } @@ -320,7 +320,7 @@ public class RcsMessageQueryParameters implements Parcelable { /** * Parcelable boilerplate below. */ - protected RcsMessageQueryParameters(Parcel in) { + private RcsMessageQueryParams(Parcel in) { mMessageType = in.readInt(); mFileTransferPresence = in.readInt(); mMessageLike = in.readString(); @@ -330,16 +330,16 @@ public class RcsMessageQueryParameters implements Parcelable { mThreadId = in.readInt(); } - public static final Creator<RcsMessageQueryParameters> CREATOR = - new Creator<RcsMessageQueryParameters>() { + public static final Creator<RcsMessageQueryParams> CREATOR = + new Creator<RcsMessageQueryParams>() { @Override - public RcsMessageQueryParameters createFromParcel(Parcel in) { - return new RcsMessageQueryParameters(in); + public RcsMessageQueryParams createFromParcel(Parcel in) { + return new RcsMessageQueryParams(in); } @Override - public RcsMessageQueryParameters[] newArray(int size) { - return new RcsMessageQueryParameters[size]; + public RcsMessageQueryParams[] newArray(int size) { + return new RcsMessageQueryParams[size]; } }; diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java index c3846fdebf2e..5adab760d594 100644 --- a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java +++ b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java @@ -29,13 +29,13 @@ import java.util.ArrayList; import java.util.List; /** - * The result of a {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} + * The result of a {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} * call. This class allows getting the token for querying the next batch of messages in order to * prevent handling large amounts of data at once. * - * @hide + * @hide - TODO: make public */ -public class RcsMessageQueryResult implements Parcelable { +public final class RcsMessageQueryResult implements Parcelable { // The token to continue the query to get the next batch of results private RcsQueryContinuationToken mContinuationToken; // The message type and message ID pairs for all the messages in this query result @@ -83,7 +83,7 @@ public class RcsMessageQueryResult implements Parcelable { return messages; } - protected RcsMessageQueryResult(Parcel in) { + private RcsMessageQueryResult(Parcel in) { mContinuationToken = in.readParcelable( RcsQueryContinuationToken.class.getClassLoader()); in.readTypedList(mMessageTypeIdPairs, RcsTypeIdPair.CREATOR); diff --git a/telephony/java/android/telephony/ims/RcsMessageSnippet.java b/telephony/java/android/telephony/ims/RcsMessageSnippet.java index 9399c2003827..565bb99de89a 100644 --- a/telephony/java/android/telephony/ims/RcsMessageSnippet.java +++ b/telephony/java/android/telephony/ims/RcsMessageSnippet.java @@ -24,9 +24,9 @@ import android.telephony.ims.RcsMessage.RcsMessageStatus; /** * An immutable summary of the latest {@link RcsMessage} on an {@link RcsThread} * - * @hide TODO: make public + * @hide - TODO: make public */ -public class RcsMessageSnippet implements Parcelable { +public final class RcsMessageSnippet implements Parcelable { private final String mText; private final @RcsMessageStatus int mStatus; private final long mTimestamp; @@ -65,7 +65,7 @@ public class RcsMessageSnippet implements Parcelable { return mTimestamp; } - protected RcsMessageSnippet(Parcel in) { + private RcsMessageSnippet(Parcel in) { mText = in.readString(); mStatus = in.readInt(); mTimestamp = in.readLong(); diff --git a/telephony/java/android/telephony/ims/RcsMessageStore.java b/telephony/java/android/telephony/ims/RcsMessageStore.java index c8c36a8e479b..eca5ed518521 100644 --- a/telephony/java/android/telephony/ims/RcsMessageStore.java +++ b/telephony/java/android/telephony/ims/RcsMessageStore.java @@ -27,7 +27,7 @@ import java.util.List; * RcsMessageStore is the application interface to RcsProvider and provides access methods to * RCS related database tables. * - * @hide - TODO make this public + * @hide - TODO: make public */ public class RcsMessageStore { /** @@ -39,7 +39,7 @@ public class RcsMessageStore { */ @WorkerThread @NonNull - public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParameters queryParameters) + public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParams queryParameters) throws RcsMessageStoreException { return RcsControllerCall.call(iRcs -> iRcs.getRcsThreads(queryParameters)); } @@ -68,7 +68,7 @@ public class RcsMessageStore { @WorkerThread @NonNull public RcsParticipantQueryResult getRcsParticipants( - @Nullable RcsParticipantQueryParameters queryParameters) + @Nullable RcsParticipantQueryParams queryParameters) throws RcsMessageStoreException { return RcsControllerCall.call(iRcs -> iRcs.getParticipants(queryParameters)); } @@ -99,7 +99,7 @@ public class RcsMessageStore { @WorkerThread @NonNull public RcsMessageQueryResult getRcsMessages( - @Nullable RcsMessageQueryParameters queryParameters) throws RcsMessageStoreException { + @Nullable RcsMessageQueryParams queryParameters) throws RcsMessageStoreException { return RcsControllerCall.call(iRcs -> iRcs.getMessages(queryParameters)); } @@ -127,7 +127,7 @@ public class RcsMessageStore { @WorkerThread @NonNull public RcsEventQueryResult getRcsEvents( - @Nullable RcsEventQueryParameters queryParameters) throws RcsMessageStoreException { + @Nullable RcsEventQueryParams queryParameters) throws RcsMessageStoreException { return RcsControllerCall.call(iRcs -> iRcs.getEvents(queryParameters)); } diff --git a/telephony/java/android/telephony/ims/RcsMessageStoreException.java b/telephony/java/android/telephony/ims/RcsMessageStoreException.java index e158f1a55aec..7c00749b1690 100644 --- a/telephony/java/android/telephony/ims/RcsMessageStoreException.java +++ b/telephony/java/android/telephony/ims/RcsMessageStoreException.java @@ -20,7 +20,7 @@ package android.telephony.ims; * An exception that happened on {@link RcsMessageStore} or one of the derived storage classes in * {@link android.telephony.ims} * - * @hide TODO: make public + * @hide - TODO: make public */ public class RcsMessageStoreException extends Exception { diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java index 0bd55ec2d25a..dfcdee4a803d 100644 --- a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java +++ b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java @@ -24,7 +24,7 @@ import java.util.List; /** * This is a single instance of a message sent over RCS. * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public class RcsOutgoingMessage extends RcsMessage { RcsOutgoingMessage(int id) { diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.aidl b/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.aidl new file mode 100644 index 000000000000..0c38d9f5766b --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.aidl @@ -0,0 +1,20 @@ +/* + * + * Copyright 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +parcelable RcsOutgoingMessageCreationParams; diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java b/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java new file mode 100644 index 000000000000..ca466e8c9d3e --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * {@link RcsOutgoingMessageCreationParams} is a collection of parameters that should be passed + * into {@link RcsThread#addOutgoingMessage(RcsOutgoingMessageCreationParams)} to generate an + * {@link RcsOutgoingMessage} on that {@link RcsThread} + * + * @hide - TODO: make public + */ +public final class RcsOutgoingMessageCreationParams extends RcsMessageCreationParams + implements Parcelable { + /** + * A builder to instantiate and persist an {@link RcsOutgoingMessage} + */ + public static class Builder extends RcsMessageCreationParams.Builder { + + /** + * Creates a new {@link Builder} to create an instance of + * {@link RcsOutgoingMessageCreationParams}. + * + * @param originationTimestamp The timestamp of {@link RcsMessage} creation. The origination + * timestamp value in milliseconds passed after midnight, + * January 1, 1970 UTC + * @param subscriptionId The subscription ID that was used to send or receive this + * {@link RcsMessage} + * @see android.telephony.SubscriptionInfo#getSubscriptionId() + */ + public Builder(long originationTimestamp, int subscriptionId) { + super(originationTimestamp, subscriptionId); + } + + /** + * Creates configuration parameters for a new message. + */ + public RcsOutgoingMessageCreationParams build() { + return new RcsOutgoingMessageCreationParams(this); + } + } + + private RcsOutgoingMessageCreationParams(Builder builder) { + super(builder); + } + + private RcsOutgoingMessageCreationParams(Parcel in) { + super(in); + } + + public static final Creator<RcsOutgoingMessageCreationParams> CREATOR = + new Creator<RcsOutgoingMessageCreationParams>() { + @Override + public RcsOutgoingMessageCreationParams createFromParcel(Parcel in) { + return new RcsOutgoingMessageCreationParams(in); + } + + @Override + public RcsOutgoingMessageCreationParams[] newArray(int size) { + return new RcsOutgoingMessageCreationParams[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest); + } +} diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java index b93f892df295..5a3062a69e3f 100644 --- a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java +++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java @@ -22,7 +22,7 @@ import android.annotation.WorkerThread; * This class holds the delivery information of an {@link RcsOutgoingMessage} for each * {@link RcsParticipant} that the message was intended for. * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public class RcsOutgoingMessageDelivery { // The participant that this delivery is intended for diff --git a/telephony/java/android/telephony/ims/RcsParticipant.java b/telephony/java/android/telephony/ims/RcsParticipant.java index ce0ad2c4749b..37b827b8e83c 100644 --- a/telephony/java/android/telephony/ims/RcsParticipant.java +++ b/telephony/java/android/telephony/ims/RcsParticipant.java @@ -21,7 +21,7 @@ import android.annotation.WorkerThread; /** * RcsParticipant is an RCS capable contact that can participate in {@link RcsThread}s. * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public class RcsParticipant { // The row ID of this participant in the database diff --git a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java index 04cdf86df9c0..aa278b38cf81 100644 --- a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java +++ b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java @@ -18,18 +18,19 @@ package android.telephony.ims; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; +import android.os.Parcelable; /** * An event that indicates an {@link RcsParticipant}'s alias was changed. Please see US18-2 - GSMA * RCC.71 (RCS Universal Profile Service Definition Document) * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ -public class RcsParticipantAliasChangedEvent extends RcsEvent { +public final class RcsParticipantAliasChangedEvent extends RcsEvent implements Parcelable { // The ID of the participant that changed their alias - private int mParticipantId; + private final int mParticipantId; // The new alias of the above participant - private String mNewAlias; + private final String mNewAlias; /** * Creates a new {@link RcsParticipantAliasChangedEvent}. This event is not persisted into @@ -98,7 +99,7 @@ public class RcsParticipantAliasChangedEvent extends RcsEvent { } }; - protected RcsParticipantAliasChangedEvent(Parcel in) { + private RcsParticipantAliasChangedEvent(Parcel in) { super(in); mNewAlias = in.readString(); mParticipantId = in.readInt(); diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryParameters.aidl b/telephony/java/android/telephony/ims/RcsParticipantQueryParams.aidl index c325c23ba9bd..b7c0f93c8c5f 100644 --- a/telephony/java/android/telephony/ims/RcsMessageQueryParameters.aidl +++ b/telephony/java/android/telephony/ims/RcsParticipantQueryParams.aidl @@ -17,4 +17,4 @@ package android.telephony.ims; -parcelable RcsMessageQueryParameters; +parcelable RcsParticipantQueryParams; diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.java b/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java index 3611fc187fc4..57c67fa7aa03 100644 --- a/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.java +++ b/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java @@ -28,12 +28,12 @@ import java.security.InvalidParameterException; /** * The parameters to pass into - * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParameters)} in order to select a + * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParams)} in order to select a * subset of {@link RcsThread}s present in the message store. * - * @hide TODO - make the Builder and builder() public. The rest should stay internal only. + * @hide - TODO: make public */ -public class RcsParticipantQueryParameters implements Parcelable { +public final class RcsParticipantQueryParams implements Parcelable { /** * Flag to set with {@link Builder#setSortProperty(int)} to sort the results in the order of * creation time for faster query results @@ -75,7 +75,7 @@ public class RcsParticipantQueryParameters implements Parcelable { */ public static final String PARTICIPANT_QUERY_PARAMETERS_KEY = "participant_query_parameters"; - RcsParticipantQueryParameters(int rcsThreadId, String aliasLike, String canonicalAddressLike, + RcsParticipantQueryParams(int rcsThreadId, String aliasLike, String canonicalAddressLike, @SortingProperty int sortingProperty, boolean isAscending, int limit) { mThreadId = rcsThreadId; @@ -143,7 +143,7 @@ public class RcsParticipantQueryParameters implements Parcelable { } /** - * A helper class to build the {@link RcsParticipantQueryParameters}. + * A helper class to build the {@link RcsParticipantQueryParams}. */ public static class Builder { private String mAliasLike; @@ -154,8 +154,8 @@ public class RcsParticipantQueryParameters implements Parcelable { private int mThreadId; /** - * Creates a new builder for {@link RcsParticipantQueryParameters} to be used in - * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParameters)} + * Creates a new builder for {@link RcsParticipantQueryParams} to be used in + * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParams)} */ public Builder() { // empty implementation @@ -231,7 +231,7 @@ public class RcsParticipantQueryParameters implements Parcelable { /** * Sets the property where the results should be sorted against. Defaults to - * {@link RcsParticipantQueryParameters.SortingProperty#SORT_BY_CREATION_ORDER} + * {@link RcsParticipantQueryParams.SortingProperty#SORT_BY_CREATION_ORDER} * * @param sortingProperty against which property the results should be sorted * @return The same instance of the builder to chain parameters. @@ -255,14 +255,14 @@ public class RcsParticipantQueryParameters implements Parcelable { } /** - * Builds the {@link RcsParticipantQueryParameters} to use in - * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParameters)} + * Builds the {@link RcsParticipantQueryParams} to use in + * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParams)} * - * @return An instance of {@link RcsParticipantQueryParameters} to use with the participant + * @return An instance of {@link RcsParticipantQueryParams} to use with the participant * query. */ - public RcsParticipantQueryParameters build() { - return new RcsParticipantQueryParameters(mThreadId, mAliasLike, mCanonicalAddressLike, + public RcsParticipantQueryParams build() { + return new RcsParticipantQueryParams(mThreadId, mAliasLike, mCanonicalAddressLike, mSortingProperty, mIsAscending, mLimit); } } @@ -270,7 +270,7 @@ public class RcsParticipantQueryParameters implements Parcelable { /** * Parcelable boilerplate below. */ - protected RcsParticipantQueryParameters(Parcel in) { + private RcsParticipantQueryParams(Parcel in) { mAliasLike = in.readString(); mCanonicalAddressLike = in.readString(); mSortingProperty = in.readInt(); @@ -279,16 +279,16 @@ public class RcsParticipantQueryParameters implements Parcelable { mThreadId = in.readInt(); } - public static final Creator<RcsParticipantQueryParameters> CREATOR = - new Creator<RcsParticipantQueryParameters>() { + public static final Creator<RcsParticipantQueryParams> CREATOR = + new Creator<RcsParticipantQueryParams>() { @Override - public RcsParticipantQueryParameters createFromParcel(Parcel in) { - return new RcsParticipantQueryParameters(in); + public RcsParticipantQueryParams createFromParcel(Parcel in) { + return new RcsParticipantQueryParams(in); } @Override - public RcsParticipantQueryParameters[] newArray(int size) { - return new RcsParticipantQueryParameters[size]; + public RcsParticipantQueryParams[] newArray(int size) { + return new RcsParticipantQueryParams[size]; } }; diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java index 2f4ab465a6cf..4eae39d1a2c6 100644 --- a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java +++ b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java @@ -25,13 +25,13 @@ import java.util.ArrayList; import java.util.List; /** - * The result of a {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParameters)} + * The result of a {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParams)} * call. This class allows getting the token for querying the next batch of participants in order to * prevent handling large amounts of data at once. * - * @hide + * @hide - TODO: make public */ -public class RcsParticipantQueryResult implements Parcelable { +public final class RcsParticipantQueryResult implements Parcelable { // A token for the caller to continue their query for the next batch of results private RcsQueryContinuationToken mContinuationToken; // The list of participant IDs returned with this query @@ -75,7 +75,7 @@ public class RcsParticipantQueryResult implements Parcelable { return participantList; } - protected RcsParticipantQueryResult(Parcel in) { + private RcsParticipantQueryResult(Parcel in) { mContinuationToken = in.readParcelable( RcsQueryContinuationToken.class.getClassLoader()); } diff --git a/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java index e880651d6cdb..c1ff39652397 100644 --- a/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java +++ b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java @@ -24,11 +24,17 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * This interface allows using the same implementation for continuation token usage in - * {@link com.android.providers.telephony.RcsProvider} - * @hide - TODO make getQueryType() and types public - the rest should stay internal + * A token for enabling continuation queries. Instances are acquired through + * {@code getContinuationToken} on result objects after initial query is done. + * + * @see RcsEventQueryResult#getContinuationToken() + * @see RcsMessageQueryResult#getContinuationToken() + * @see RcsParticipantQueryResult#getContinuationToken() + * @see RcsThreadQueryResult#getContinuationToken() + * + * @hide - TODO: make public */ -public class RcsQueryContinuationToken implements Parcelable { +public final class RcsQueryContinuationToken implements Parcelable { /** * Denotes that this {@link RcsQueryContinuationToken} token is meant to allow continuing * {@link RcsEvent} queries @@ -116,7 +122,7 @@ public class RcsQueryContinuationToken implements Parcelable { return mQueryType; } - protected RcsQueryContinuationToken(Parcel in) { + private RcsQueryContinuationToken(Parcel in) { mQueryType = in.readInt(); mRawQuery = in.readString(); mLimit = in.readInt(); diff --git a/telephony/java/android/telephony/ims/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java index 238f5e7ce625..88655865f47b 100644 --- a/telephony/java/android/telephony/ims/RcsThread.java +++ b/telephony/java/android/telephony/ims/RcsThread.java @@ -28,10 +28,13 @@ import com.android.internal.annotations.VisibleForTesting; * RcsThread represents a single RCS conversation thread. It holds messages that were sent and * received and events that occurred on that thread. * - * @hide - TODO(109759350) make this public + * @hide - TODO: make public */ public abstract class RcsThread { - // The rcs_participant_thread_id that represents this thread in the database + /** + * The rcs_participant_thread_id that represents this thread in the database + * @hide + */ protected int mThreadId; /** @@ -59,10 +62,10 @@ public abstract class RcsThread { @WorkerThread @NonNull public RcsIncomingMessage addIncomingMessage( - @NonNull RcsIncomingMessageCreationParameters rcsIncomingMessageCreationParameters) + @NonNull RcsIncomingMessageCreationParams rcsIncomingMessageCreationParams) throws RcsMessageStoreException { return new RcsIncomingMessage(RcsControllerCall.call(iRcs -> iRcs.addIncomingMessage( - mThreadId, rcsIncomingMessageCreationParameters))); + mThreadId, rcsIncomingMessageCreationParams))); } /** @@ -73,10 +76,10 @@ public abstract class RcsThread { @WorkerThread @NonNull public RcsOutgoingMessage addOutgoingMessage( - @NonNull RcsMessageCreationParameters rcsMessageCreationParameters) + @NonNull RcsOutgoingMessageCreationParams rcsOutgoingMessageCreationParams) throws RcsMessageStoreException { int messageId = RcsControllerCall.call(iRcs -> iRcs.addOutgoingMessage( - mThreadId, rcsMessageCreationParameters)); + mThreadId, rcsOutgoingMessageCreationParams)); return new RcsOutgoingMessage(messageId); } @@ -97,7 +100,7 @@ public abstract class RcsThread { /** * Convenience function for loading all the {@link RcsMessage}s in this {@link RcsThread}. For * a more detailed and paginated query, please use - * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} + * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} * * @return Loads the {@link RcsMessage}s in this thread and returns them in an immutable list. * @throws RcsMessageStoreException if the messages could not be read from the storage @@ -105,8 +108,8 @@ public abstract class RcsThread { @WorkerThread @NonNull public RcsMessageQueryResult getMessages() throws RcsMessageStoreException { - RcsMessageQueryParameters queryParameters = - new RcsMessageQueryParameters.Builder().setThread(this).build(); + RcsMessageQueryParams queryParameters = + new RcsMessageQueryParams.Builder().setThread(this).build(); return RcsControllerCall.call(iRcs -> iRcs.getMessages(queryParameters)); } diff --git a/telephony/java/android/telephony/ims/RcsMessageCreationParameters.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryParams.aidl index 5774d00ca934..3f351dc5efee 100644 --- a/telephony/java/android/telephony/ims/RcsMessageCreationParameters.aidl +++ b/telephony/java/android/telephony/ims/RcsThreadQueryParams.aidl @@ -17,4 +17,4 @@ package android.telephony.ims; -parcelable RcsMessageCreationParameters; +parcelable RcsThreadQueryParams; diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java b/telephony/java/android/telephony/ims/RcsThreadQueryParams.java index 4aa42073b8f8..ba32e320c95b 100644 --- a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java +++ b/telephony/java/android/telephony/ims/RcsThreadQueryParams.java @@ -33,22 +33,22 @@ import java.util.List; import java.util.Set; /** - * The parameters to pass into {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} in + * The parameters to pass into {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParams)} in * order to select a subset of {@link RcsThread}s present in the message store. * - * @hide TODO - make the Builder and builder() public. The rest should stay internal only. + * @hide - TODO: make public */ -public class RcsThreadQueryParameters implements Parcelable { +public final class RcsThreadQueryParams implements Parcelable { /** * Bitmask flag to be used with {@link Builder#setThreadType(int)} to make - * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} return + * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParams)} return * {@link RcsGroupThread}s. */ public static final int THREAD_TYPE_GROUP = 0x0001; /** * Bitmask flag to be used with {@link Builder#setThreadType(int)} to make - * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} return + * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParams)} return * {@link Rcs1To1Thread}s. */ public static final int THREAD_TYPE_1_TO_1 = 0x0002; @@ -86,7 +86,7 @@ public class RcsThreadQueryParameters implements Parcelable { */ public static final String THREAD_QUERY_PARAMETERS_KEY = "thread_query_parameters"; - RcsThreadQueryParameters(int threadType, Set<RcsParticipant> participants, + RcsThreadQueryParams(int threadType, Set<RcsParticipant> participants, int limit, int sortingProperty, boolean isAscending) { mThreadType = threadType; mRcsParticipantIds = convertParticipantSetToIdList(participants); @@ -148,7 +148,7 @@ public class RcsThreadQueryParameters implements Parcelable { } /** - * A helper class to build the {@link RcsThreadQueryParameters}. + * A helper class to build the {@link RcsThreadQueryParams}. */ public static class Builder { private int mThreadType; @@ -158,8 +158,8 @@ public class RcsThreadQueryParameters implements Parcelable { private boolean mIsAscending; /** - * Constructs a {@link RcsThreadQueryParameters.Builder} to help build an - * {@link RcsThreadQueryParameters} + * Constructs a {@link RcsThreadQueryParams.Builder} to help build an + * {@link RcsThreadQueryParams} */ public Builder() { mParticipants = new HashSet<>(); @@ -170,8 +170,8 @@ public class RcsThreadQueryParameters implements Parcelable { * * @param threadType Whether to limit the query result to group threads. * @return The same instance of the builder to chain parameters. - * @see RcsThreadQueryParameters#THREAD_TYPE_GROUP - * @see RcsThreadQueryParameters#THREAD_TYPE_1_TO_1 + * @see RcsThreadQueryParams#THREAD_TYPE_GROUP + * @see RcsThreadQueryParams#THREAD_TYPE_1_TO_1 */ @CheckResult public Builder setThreadType(int threadType) { @@ -253,13 +253,13 @@ public class RcsThreadQueryParameters implements Parcelable { } /** - * Builds the {@link RcsThreadQueryParameters} to use in - * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} + * Builds the {@link RcsThreadQueryParams} to use in + * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParams)} * - * @return An instance of {@link RcsThreadQueryParameters} to use with the thread query. + * @return An instance of {@link RcsThreadQueryParams} to use with the thread query. */ - public RcsThreadQueryParameters build() { - return new RcsThreadQueryParameters(mThreadType, mParticipants, mLimit, + public RcsThreadQueryParams build() { + return new RcsThreadQueryParams(mThreadType, mParticipants, mLimit, mSortingProperty, mIsAscending); } } @@ -267,7 +267,7 @@ public class RcsThreadQueryParameters implements Parcelable { /** * Parcelable boilerplate below. */ - protected RcsThreadQueryParameters(Parcel in) { + private RcsThreadQueryParams(Parcel in) { mThreadType = in.readInt(); mRcsParticipantIds = new ArrayList<>(); in.readList(mRcsParticipantIds, Integer.class.getClassLoader()); @@ -276,16 +276,16 @@ public class RcsThreadQueryParameters implements Parcelable { mIsAscending = in.readByte() == 1; } - public static final Creator<RcsThreadQueryParameters> CREATOR = - new Creator<RcsThreadQueryParameters>() { + public static final Creator<RcsThreadQueryParams> CREATOR = + new Creator<RcsThreadQueryParams>() { @Override - public RcsThreadQueryParameters createFromParcel(Parcel in) { - return new RcsThreadQueryParameters(in); + public RcsThreadQueryParams createFromParcel(Parcel in) { + return new RcsThreadQueryParams(in); } @Override - public RcsThreadQueryParameters[] newArray(int size) { - return new RcsThreadQueryParameters[size]; + public RcsThreadQueryParams[] newArray(int size) { + return new RcsThreadQueryParams[size]; } }; diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java index 6515933fff0e..a91126b89cce 100644 --- a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java +++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java @@ -29,13 +29,13 @@ import java.util.ArrayList; import java.util.List; /** - * The result of a {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} + * The result of a {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParams)} * call. This class allows getting the token for querying the next batch of threads in order to * prevent handling large amounts of data at once. * - * @hide + * @hide - TODO: make public */ -public class RcsThreadQueryResult implements Parcelable { +public final class RcsThreadQueryResult implements Parcelable { // A token for the caller to continue their query for the next batch of results private RcsQueryContinuationToken mContinuationToken; // The list of thread IDs returned with this query @@ -84,7 +84,7 @@ public class RcsThreadQueryResult implements Parcelable { return rcsThreads; } - protected RcsThreadQueryResult(Parcel in) { + private RcsThreadQueryResult(Parcel in) { mContinuationToken = in.readParcelable( RcsQueryContinuationToken.class.getClassLoader()); mRcsThreadIds = new ArrayList<>(); diff --git a/telephony/java/android/telephony/ims/aidl/IRcs.aidl b/telephony/java/android/telephony/ims/aidl/IRcs.aidl index a399786dec54..2478f8cff6b7 100644 --- a/telephony/java/android/telephony/ims/aidl/IRcs.aidl +++ b/telephony/java/android/telephony/ims/aidl/IRcs.aidl @@ -17,18 +17,18 @@ package android.telephony.ims.aidl; import android.net.Uri; -import android.telephony.ims.RcsEventQueryParameters; +import android.telephony.ims.RcsEventQueryParams; import android.telephony.ims.RcsEventQueryResult; -import android.telephony.ims.RcsFileTransferCreationParameters; -import android.telephony.ims.RcsIncomingMessageCreationParameters; -import android.telephony.ims.RcsMessageCreationParameters; +import android.telephony.ims.RcsFileTransferCreationParams; +import android.telephony.ims.RcsIncomingMessageCreationParams; import android.telephony.ims.RcsMessageSnippet; -import android.telephony.ims.RcsMessageQueryParameters; +import android.telephony.ims.RcsMessageQueryParams; import android.telephony.ims.RcsMessageQueryResult; -import android.telephony.ims.RcsParticipantQueryParameters; +import android.telephony.ims.RcsOutgoingMessageCreationParams; +import android.telephony.ims.RcsParticipantQueryParams; import android.telephony.ims.RcsParticipantQueryResult; import android.telephony.ims.RcsQueryContinuationToken; -import android.telephony.ims.RcsThreadQueryParameters; +import android.telephony.ims.RcsThreadQueryParams; import android.telephony.ims.RcsThreadQueryResult; /** @@ -39,22 +39,22 @@ interface IRcs { ///////////////////////// // RcsMessageStore APIs ///////////////////////// - RcsThreadQueryResult getRcsThreads(in RcsThreadQueryParameters queryParameters); + RcsThreadQueryResult getRcsThreads(in RcsThreadQueryParams queryParams); RcsThreadQueryResult getRcsThreadsWithToken( in RcsQueryContinuationToken continuationToken); - RcsParticipantQueryResult getParticipants(in RcsParticipantQueryParameters queryParameters); + RcsParticipantQueryResult getParticipants(in RcsParticipantQueryParams queryParams); RcsParticipantQueryResult getParticipantsWithToken( in RcsQueryContinuationToken continuationToken); - RcsMessageQueryResult getMessages(in RcsMessageQueryParameters queryParameters); + RcsMessageQueryResult getMessages(in RcsMessageQueryParams queryParams); RcsMessageQueryResult getMessagesWithToken( in RcsQueryContinuationToken continuationToken); - RcsEventQueryResult getEvents(in RcsEventQueryParameters queryParameters); + RcsEventQueryResult getEvents(in RcsEventQueryParams queryParams); RcsEventQueryResult getEventsWithToken( in RcsQueryContinuationToken continuationToken); @@ -74,11 +74,11 @@ interface IRcs { // Creates a new RcsIncomingMessage on the given thread and returns its row ID int addIncomingMessage(int rcsThreadId, - in RcsIncomingMessageCreationParameters rcsIncomingMessageCreationParameters); + in RcsIncomingMessageCreationParams rcsIncomingMessageCreationParams); // Creates a new RcsOutgoingMessage on the given thread and returns its row ID int addOutgoingMessage(int rcsThreadId, - in RcsMessageCreationParameters rcsMessageCreationParameters); + in RcsOutgoingMessageCreationParams rcsOutgoingMessageCreationParams); // TODO: modify RcsProvider URI's to allow deleting a message without specifying its thread void deleteMessage(int rcsMessageId, boolean isIncoming, int rcsThreadId, boolean isGroup); @@ -203,7 +203,7 @@ interface IRcs { // Performs the initial write to storage and returns the row ID. int storeFileTransfer(int messageId, boolean isIncoming, - in RcsFileTransferCreationParameters fileTransferCreationParameters); + in RcsFileTransferCreationParams fileTransferCreationParams); void deleteFileTransfer(int partId); diff --git a/test-base/api/TEST_MAPPING b/test-base/api/TEST_MAPPING new file mode 100644 index 000000000000..3535954bc019 --- /dev/null +++ b/test-base/api/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "CtsAndroidTestBase27ApiSignatureTestCases" + } + ] +} diff --git a/test-mock/api/TEST_MAPPING b/test-mock/api/TEST_MAPPING new file mode 100644 index 000000000000..d1bd9afaf287 --- /dev/null +++ b/test-mock/api/TEST_MAPPING @@ -0,0 +1,10 @@ +{ + "presubmit": [ + { + "name": "CtsAndroidTestMockCurrentApiSignatureTestCases" + }, + { + "name": "CtsCurrentApiSignatureTestCases" + } + ] +} diff --git a/test-runner/api/TEST_MAPPING b/test-runner/api/TEST_MAPPING new file mode 100644 index 000000000000..76ade3c1e647 --- /dev/null +++ b/test-runner/api/TEST_MAPPING @@ -0,0 +1,10 @@ +{ + "presubmit": [ + { + "name": "CtsAndroidTestRunnerCurrentApiSignatureTestCases" + }, + { + "name": "CtsCurrentApiSignatureTestCases" + } + ] +} diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParametersTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParamsTest.java index b4bcb5d12e0d..6361a393187e 100644 --- a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParametersTest.java +++ b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParamsTest.java @@ -19,39 +19,39 @@ import static com.google.common.truth.Truth.assertThat; import android.os.Parcel; import android.support.test.runner.AndroidJUnit4; -import android.telephony.ims.RcsParticipantQueryParameters; +import android.telephony.ims.RcsParticipantQueryParams; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -public class RcsParticipantQueryParametersTest { +public class RcsParticipantQueryParamsTest { @Test public void testCanUnparcel() { - RcsParticipantQueryParameters rcsParticipantQueryParameters = - new RcsParticipantQueryParameters.Builder() + RcsParticipantQueryParams rcsParticipantQueryParams = + new RcsParticipantQueryParams.Builder() .setAliasLike("%alias_") .setCanonicalAddressLike("_canonical%") - .setSortProperty(RcsParticipantQueryParameters.SORT_BY_CANONICAL_ADDRESS) + .setSortProperty(RcsParticipantQueryParams.SORT_BY_CANONICAL_ADDRESS) .setSortDirection(true) .setResultLimit(432) .build(); Parcel parcel = Parcel.obtain(); - rcsParticipantQueryParameters.writeToParcel(parcel, - rcsParticipantQueryParameters.describeContents()); + rcsParticipantQueryParams.writeToParcel(parcel, + rcsParticipantQueryParams.describeContents()); parcel.setDataPosition(0); - rcsParticipantQueryParameters = RcsParticipantQueryParameters.CREATOR.createFromParcel( + rcsParticipantQueryParams = RcsParticipantQueryParams.CREATOR.createFromParcel( parcel); - assertThat(rcsParticipantQueryParameters.getAliasLike()).isEqualTo("%alias_"); - assertThat(rcsParticipantQueryParameters.getCanonicalAddressLike()).contains("_canonical%"); - assertThat(rcsParticipantQueryParameters.getLimit()).isEqualTo(432); - assertThat(rcsParticipantQueryParameters.getSortingProperty()).isEqualTo( - RcsParticipantQueryParameters.SORT_BY_CANONICAL_ADDRESS); - assertThat(rcsParticipantQueryParameters.getSortDirection()).isTrue(); + assertThat(rcsParticipantQueryParams.getAliasLike()).isEqualTo("%alias_"); + assertThat(rcsParticipantQueryParams.getCanonicalAddressLike()).contains("_canonical%"); + assertThat(rcsParticipantQueryParams.getLimit()).isEqualTo(432); + assertThat(rcsParticipantQueryParams.getSortingProperty()).isEqualTo( + RcsParticipantQueryParams.SORT_BY_CANONICAL_ADDRESS); + assertThat(rcsParticipantQueryParams.getSortDirection()).isTrue(); } } diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java index 0a70eeccb0fa..beb4f8ad28e2 100644 --- a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java +++ b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java @@ -15,26 +15,26 @@ */ package com.android.tests.ims; -import static android.telephony.ims.RcsThreadQueryParameters.SORT_BY_TIMESTAMP; -import static android.telephony.ims.RcsThreadQueryParameters.THREAD_TYPE_GROUP; +import static android.telephony.ims.RcsThreadQueryParams.SORT_BY_TIMESTAMP; +import static android.telephony.ims.RcsThreadQueryParams.THREAD_TYPE_GROUP; import static com.google.common.truth.Truth.assertThat; import android.os.Parcel; import android.support.test.runner.AndroidJUnit4; import android.telephony.ims.RcsParticipant; -import android.telephony.ims.RcsThreadQueryParameters; +import android.telephony.ims.RcsThreadQueryParams; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -public class RcsThreadQueryParametersTest { +public class RcsThreadQueryParamsTest { @Test public void testCanUnparcel() { RcsParticipant rcsParticipant = new RcsParticipant(1); - RcsThreadQueryParameters rcsThreadQueryParameters = new RcsThreadQueryParameters.Builder() + RcsThreadQueryParams rcsThreadQueryParams = new RcsThreadQueryParams.Builder() .setThreadType(THREAD_TYPE_GROUP) .setParticipant(rcsParticipant) .setResultLimit(50) @@ -43,16 +43,16 @@ public class RcsThreadQueryParametersTest { .build(); Parcel parcel = Parcel.obtain(); - rcsThreadQueryParameters.writeToParcel(parcel, rcsThreadQueryParameters.describeContents()); + rcsThreadQueryParams.writeToParcel(parcel, rcsThreadQueryParams.describeContents()); parcel.setDataPosition(0); - rcsThreadQueryParameters = RcsThreadQueryParameters.CREATOR.createFromParcel(parcel); + rcsThreadQueryParams = RcsThreadQueryParams.CREATOR.createFromParcel(parcel); - assertThat(rcsThreadQueryParameters.getThreadType()).isEqualTo(THREAD_TYPE_GROUP); - assertThat(rcsThreadQueryParameters.getRcsParticipantsIds()) + assertThat(rcsThreadQueryParams.getThreadType()).isEqualTo(THREAD_TYPE_GROUP); + assertThat(rcsThreadQueryParams.getRcsParticipantsIds()) .contains(rcsParticipant.getId()); - assertThat(rcsThreadQueryParameters.getLimit()).isEqualTo(50); - assertThat(rcsThreadQueryParameters.getSortingProperty()).isEqualTo(SORT_BY_TIMESTAMP); - assertThat(rcsThreadQueryParameters.getSortDirection()).isTrue(); + assertThat(rcsThreadQueryParams.getLimit()).isEqualTo(50); + assertThat(rcsThreadQueryParams.getSortingProperty()).isEqualTo(SORT_BY_TIMESTAMP); + assertThat(rcsThreadQueryParams.getSortDirection()).isTrue(); } } diff --git a/tests/utils/testutils/java/android/view/test/InsetsModeSession.java b/tests/utils/testutils/java/android/view/test/InsetsModeSession.java new file mode 100644 index 000000000000..c83dfa41d260 --- /dev/null +++ b/tests/utils/testutils/java/android/view/test/InsetsModeSession.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view.test; + +import android.view.ViewRootImpl; + +/** + * Session to set insets mode for {@link ViewRootImpl#sNewInsetsMode}. + */ +public class InsetsModeSession implements AutoCloseable { + + private int mOldMode; + + public InsetsModeSession(int flag) { + mOldMode = ViewRootImpl.sNewInsetsMode; + ViewRootImpl.sNewInsetsMode = flag; + } + + @Override + public void close() throws Exception { + ViewRootImpl.sNewInsetsMode = mOldMode; + } +} diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp index 55440d2261d3..0270c72ff240 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -688,7 +688,7 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map); size_t i = 0; - // Print constants + // Print atom constants for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { string constant = make_constant_name(atom->name); @@ -714,6 +714,30 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, "};\n"); fprintf(out, "\n"); + // Print constants for the enum values. + fprintf(out, "//\n"); + fprintf(out, "// Constants for enum values\n"); + fprintf(out, "//\n\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + for (vector<AtomField>::const_iterator field = atom->fields.begin(); + field != atom->fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ENUM) { + fprintf(out, "// Values for %s.%s\n", atom->message.c_str(), + field->name.c_str()); + for (map<int, string>::const_iterator value = field->enumValues.begin(); + value != field->enumValues.end(); value++) { + fprintf(out, "const int32_t %s__%s__%s = %d;\n", + make_constant_name(atom->message).c_str(), + make_constant_name(field->name).c_str(), + make_constant_name(value->second).c_str(), + value->first); + } + fprintf(out, "\n"); + } + } + } + fprintf(out, "struct BytesField {\n"); fprintf(out, " BytesField(char const* array, size_t len) : arg(array), " diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index c5b9cf137dd8..3881e9e68eca 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -969,7 +969,8 @@ public class WifiConfiguration implements Parcelable { /** * Returns MAC address set to be the local randomized MAC address. - * Does not guarantee that the returned address is valid for use. + * Depending on user preference, the device may or may not use the returned MAC address for + * connections to this network. * <p> * Information is restricted to Device Owner, Profile Owner, and Carrier apps * (which will only obtain addresses for configurations which they create). Other callers diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 289f99dc9339..2cc1d8313225 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -981,7 +981,7 @@ public class WifiManager { * @deprecated This API is non-functional and will have no impact. */ @Deprecated - public static final int WIFI_MODE_FULL = 1; + public static final int WIFI_MODE_FULL = WifiProtoEnums.WIFI_MODE_FULL; // 1 /** * In this Wi-Fi lock mode, Wi-Fi will be kept active, @@ -995,7 +995,7 @@ public class WifiManager { * @deprecated This API is non-functional and will have no impact. */ @Deprecated - public static final int WIFI_MODE_SCAN_ONLY = 2; + public static final int WIFI_MODE_SCAN_ONLY = WifiProtoEnums.WIFI_MODE_SCAN_ONLY; // 2 /** * In this Wi-Fi lock mode, Wi-Fi will not go to power save. @@ -1013,7 +1013,7 @@ public class WifiManager { * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_HIGH_PERF} * lock will have no impact. */ - public static final int WIFI_MODE_FULL_HIGH_PERF = 3; + public static final int WIFI_MODE_FULL_HIGH_PERF = WifiProtoEnums.WIFI_MODE_FULL_HIGH_PERF; // 3 /** * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency. @@ -1037,15 +1037,13 @@ public class WifiManager { * Example use cases are real time gaming or virtual reality applications where * low latency is a key factor for user experience. * <p> - * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_LOW_LATENCY} - * lock will cause the device not to go power save. - * <p> * Note: For an app which acquires both {@link #WIFI_MODE_FULL_LOW_LATENCY} and * {@link #WIFI_MODE_FULL_HIGH_PERF} locks, {@link #WIFI_MODE_FULL_LOW_LATENCY} * lock will be effective when app is running in foreground and screen is on, * while the {@link #WIFI_MODE_FULL_HIGH_PERF} lock will take effect otherwise. */ - public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; + public static final int WIFI_MODE_FULL_LOW_LATENCY = + WifiProtoEnums.WIFI_MODE_FULL_LOW_LATENCY; // 4 /** Anything worse than or equal to this will show 0 bars. */ @UnsupportedAppUsage @@ -4876,4 +4874,4 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } -}
\ No newline at end of file +} diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index a69c7a501452..333b82ccd146 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -421,7 +421,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc * .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX)) * .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), * MacAddress.fromString("ff:ff:ff:00:00:00")) - * .buildNetworkSpecifier() + * .build() * final NetworkRequest request = * new NetworkRequest.Builder() * .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 460c633e16bd..233fa2cb4fff 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -413,17 +413,17 @@ public final class WifiNetworkSuggestion implements Parcelable { * final WifiNetworkSuggestion suggestion1 = * new Builder() * .setSsid("test111111") - * .buildNetworkSuggestion() + * .build() * final WifiNetworkSuggestion suggestion2 = * new Builder() * .setSsid("test222222") * .setWpa2Passphrase("test123456") - * .buildNetworkSuggestion() + * .build() * final WifiNetworkSuggestion suggestion3 = * new Builder() * .setSsid("test333333") * .setWpa3Passphrase("test6789") - * .buildNetworkSuggestion() + * .build() * final List<WifiNetworkSuggestion> suggestionsList = * new ArrayList<WifiNetworkSuggestion> {{ * add(suggestion1); |