summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rw-r--r--Android.mk3
-rw-r--r--api/current.txt495
-rw-r--r--api/system-current.txt10
-rw-r--r--api/test-current.txt10
-rw-r--r--cmds/statsd/Android.bp1
-rw-r--r--cmds/statsd/src/StatsService.cpp18
-rw-r--r--cmds/statsd/src/StatsService.h13
-rw-r--r--cmds/statsd/src/atoms.proto19
-rw-r--r--cmds/statsd/src/external/StatsCallbackPuller.cpp61
-rw-r--r--cmds/statsd/src/external/StatsCallbackPuller.h38
-rw-r--r--cmds/statsd/src/external/StatsPuller.cpp2
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp28
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.h8
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.cpp17
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.h13
-rw-r--r--cmds/statsd/src/stats_log.proto2
-rw-r--r--cmds/statsd/src/stats_log_util.cpp6
-rw-r--r--cmds/statsd/tests/guardrail/StatsdStats_test.cpp6
-rw-r--r--core/java/android/accessibilityservice/OWNERS3
-rw-r--r--core/java/android/app/StatsManager.java34
-rw-r--r--core/java/android/app/TaskInfo.java9
-rw-r--r--core/java/android/app/usage/UsageStatsManager.java17
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java13
-rw-r--r--core/java/android/content/pm/PackageParser.java7
-rw-r--r--core/java/android/hardware/display/ColorDisplayManager.java19
-rw-r--r--core/java/android/hardware/display/IColorDisplayManager.aidl1
-rw-r--r--core/java/android/os/FileUtils.java6
-rw-r--r--core/java/android/os/IStatsManager.aidl18
-rw-r--r--core/java/android/os/IStatsPullerCallback.aidl35
-rw-r--r--core/java/android/os/StatsLogEventWrapper.java78
-rw-r--r--core/java/android/provider/DeviceConfig.java23
-rw-r--r--core/java/android/provider/Settings.java21
-rw-r--r--core/java/android/service/textclassifier/TEST_MAPPING7
-rw-r--r--core/java/android/view/LayoutInflater.java7
-rw-r--r--core/java/android/view/View.java30
-rw-r--r--core/java/android/view/ViewGroup.java4
-rw-r--r--core/java/android/view/ViewStub.java3
-rw-r--r--core/java/android/view/accessibility/OWNERS3
-rw-r--r--core/java/android/view/autofill/AutofillManager.java32
-rw-r--r--core/java/android/view/textclassifier/TEST_MAPPING23
-rw-r--r--core/java/android/widget/AbsListView.java4
-rw-r--r--core/java/android/widget/AbsSeekBar.java2
-rw-r--r--core/java/android/widget/AbsSpinner.java2
-rw-r--r--core/java/android/widget/ActivityChooserView.java2
-rw-r--r--core/java/android/widget/AdapterViewAnimator.java3
-rw-r--r--core/java/android/widget/AdapterViewFlipper.java2
-rw-r--r--core/java/android/widget/AnalogClock.java2
-rw-r--r--core/java/android/widget/AutoCompleteTextView.java4
-rw-r--r--core/java/android/widget/CalendarView.java2
-rw-r--r--core/java/android/widget/CheckedTextView.java2
-rw-r--r--core/java/android/widget/Chronometer.java2
-rw-r--r--core/java/android/widget/CompoundButton.java2
-rw-r--r--core/java/android/widget/DatePicker.java2
-rw-r--r--core/java/android/widget/DayPickerView.java2
-rw-r--r--core/java/android/widget/ExpandableListView.java2
-rw-r--r--core/java/android/widget/FrameLayout.java2
-rw-r--r--core/java/android/widget/Gallery.java2
-rw-r--r--core/java/android/widget/GridLayout.java2
-rw-r--r--core/java/android/widget/GridView.java2
-rw-r--r--core/java/android/widget/HorizontalScrollView.java116
-rw-r--r--core/java/android/widget/ImageView.java2
-rw-r--r--core/java/android/widget/LinearLayout.java2
-rw-r--r--core/java/android/widget/ListView.java2
-rw-r--r--core/java/android/widget/NumberPicker.java2
-rw-r--r--core/java/android/widget/ProgressBar.java4
-rw-r--r--core/java/android/widget/RadialTimePickerView.java2
-rw-r--r--core/java/android/widget/RadioGroup.java2
-rw-r--r--core/java/android/widget/RatingBar.java2
-rw-r--r--core/java/android/widget/RelativeLayout.java2
-rw-r--r--core/java/android/widget/ScrollView.java119
-rw-r--r--core/java/android/widget/SearchView.java2
-rw-r--r--core/java/android/widget/SlidingDrawer.java2
-rw-r--r--core/java/android/widget/Spinner.java2
-rw-r--r--core/java/android/widget/StackView.java2
-rw-r--r--core/java/android/widget/Switch.java2
-rw-r--r--core/java/android/widget/TabHost.java2
-rw-r--r--core/java/android/widget/TabWidget.java2
-rw-r--r--core/java/android/widget/TextClock.java2
-rw-r--r--core/java/android/widget/TimePicker.java2
-rw-r--r--core/java/android/widget/ToggleButton.java2
-rw-r--r--core/java/android/widget/Toolbar.java2
-rw-r--r--core/java/android/widget/TwoLineListItem.java2
-rw-r--r--core/java/com/android/internal/os/BinderCallsStats.java37
-rw-r--r--core/java/com/android/internal/os/LooperStats.java10
-rw-r--r--core/jni/android_opengl_EGL14.cpp14
-rw-r--r--core/res/res/values/attrs_manifest.xml9
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--core/res/res/values/styles_device_defaults.xml4
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--core/tests/coretests/src/android/view/contentcapture/ViewNodeTest.java3
-rw-r--r--core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java3
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java67
-rw-r--r--core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java28
-rw-r--r--graphics/java/android/graphics/Typeface.java7
-rw-r--r--media/java/android/media/IRingtonePlayer.aidl3
-rw-r--r--media/java/android/media/Ringtone.java3
-rw-r--r--media/java/android/media/VolumeShaper.aidl19
-rw-r--r--media/jni/soundpool/SoundPool.cpp9
-rw-r--r--native/android/libandroid.map.txt1
-rw-r--r--native/android/surface_control.cpp14
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java2
-rw-r--r--packages/SystemUI/res-keyguard/layout/bubble_clock.xml16
-rw-r--r--packages/SystemUI/res-keyguard/layout/stretchanalog_clock.xml16
-rw-r--r--packages/SystemUI/res/layout/notification_info.xml119
-rw-r--r--packages/SystemUI/res/values/strings.xml6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java51
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java73
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java39
-rw-r--r--sax/tests/saxtests/Android.bp11
-rw-r--r--sax/tests/saxtests/Android.mk16
-rw-r--r--services/accessibility/OWNERS3
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java38
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java3
-rw-r--r--services/core/java/com/android/server/AlarmManagerInternal.java2
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java11
-rw-r--r--services/core/java/com/android/server/BinderCallsStatsService.java8
-rw-r--r--services/core/java/com/android/server/DeviceIdleController.java185
-rw-r--r--services/core/java/com/android/server/LooperStatsService.java13
-rw-r--r--services/core/java/com/android/server/adb/AdbDebuggingManager.java20
-rw-r--r--services/core/java/com/android/server/display/ColorDisplayService.java113
-rw-r--r--services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java2
-rw-r--r--services/core/java/com/android/server/pm/UserRestrictionsUtils.java1
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimator.java8
-rw-r--r--services/core/java/com/android/server/wm/TaskRecord.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java230
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java24
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestSystemServices.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/utils/MockTracker.java94
-rw-r--r--services/usage/java/com/android/server/usage/AppTimeLimitController.java5
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java2
-rw-r--r--telecomm/java/android/telecom/DefaultDialerManager.java34
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java14
-rw-r--r--telephony/java/android/telephony/CarrierRestrictionRules.java122
-rw-r--r--telephony/java/android/telephony/PhoneStateListener.java3
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java7
-rw-r--r--telephony/java/android/telephony/ims/Rcs1To1Thread.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsEvent.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsEventQueryParams.java6
-rw-r--r--telephony/java/android/telephony/ims/RcsEventQueryResult.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsFileTransferPart.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThread.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadEvent.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsIncomingMessage.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsManager.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsMessage.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageCreationParams.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageQueryParams.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageQueryResult.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageSnippet.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageStore.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsMessageStoreException.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsOutgoingMessage.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsParticipant.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsParticipantQueryParams.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsParticipantQueryResult.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsQueryContinuationToken.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsThread.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsThreadQueryParams.java2
-rw-r--r--telephony/java/android/telephony/ims/RcsThreadQueryResult.java2
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl3
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyPermissions.java3
-rw-r--r--test-runner/Android.mk20
-rw-r--r--test-runner/tests/Android.bp40
-rw-r--r--test-runner/tests/Android.mk39
-rw-r--r--tools/preload/Android.bp17
-rw-r--r--tools/preload/Android.mk23
-rw-r--r--tools/preload/loadclass/Android.bp4
-rw-r--r--tools/preload/loadclass/Android.mk9
-rw-r--r--wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java59
-rw-r--r--wifi/java/android/net/wifi/aware/PeerHandle.java31
-rw-r--r--wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java20
189 files changed, 2763 insertions, 636 deletions
diff --git a/Android.bp b/Android.bp
index 7bdedc79943d..0848d2b7668e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -804,6 +804,7 @@ filegroup {
srcs: [
"core/java/android/os/IStatsCompanionService.aidl",
"core/java/android/os/IStatsManager.aidl",
+ "core/java/android/os/IStatsPullerCallback.aidl",
],
}
diff --git a/Android.mk b/Android.mk
index 9c65948f4838..9a91dd1c491a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -72,6 +72,9 @@ $(OUT_DOCS)/offline-sdk-timestamp: $(OUT_DOCS)/offline-sdk-docs-docs.zip
$(hide) mkdir -p $(OUT_DOCS)/offline-sdk
( unzip -qo $< -d $(OUT_DOCS)/offline-sdk && touch -f $@ ) || exit 1
+.PHONY: docs offline-sdk-docs
+docs offline-sdk-docs: $(OUT_DOCS)/offline-sdk-timestamp
+
# Run this for checkbuild
checkbuild: doc-comment-check-docs
# Check comment when you are updating the API
diff --git a/api/current.txt b/api/current.txt
index b793470bdb66..c5cd57378a9d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30111,10 +30111,14 @@ package android.net.wifi.aware {
method public void onIdentityChanged(byte[]);
}
- public final class PeerHandle implements android.os.Parcelable {
+ public final class ParcelablePeerHandle extends android.net.wifi.aware.PeerHandle implements android.os.Parcelable {
+ ctor public ParcelablePeerHandle(android.net.wifi.aware.PeerHandle);
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.wifi.aware.PeerHandle> CREATOR;
+ field public static final android.os.Parcelable.Creator<android.net.wifi.aware.ParcelablePeerHandle> CREATOR;
+ }
+
+ public class PeerHandle {
}
public final class PublishConfig implements android.os.Parcelable {
@@ -45593,6 +45597,483 @@ package android.telephony.gsm {
}
+package android.telephony.ims {
+
+ public class Rcs1To1Thread extends android.telephony.ims.RcsThread {
+ method @WorkerThread public long getFallbackThreadId() throws android.telephony.ims.RcsMessageStoreException;
+ method @NonNull @WorkerThread public android.telephony.ims.RcsParticipant getRecipient() throws android.telephony.ims.RcsMessageStoreException;
+ method public boolean isGroup();
+ method @WorkerThread public void setFallbackThreadId(long) throws android.telephony.ims.RcsMessageStoreException;
+ }
+
+ public abstract class RcsEvent {
+ ctor protected RcsEvent(long);
+ method public long getTimestamp();
+ }
+
+ public final class RcsEventQueryParams implements android.os.Parcelable {
+ method public int describeContents();
+ method @android.telephony.ims.RcsEventQueryParams.EventType public int getEventType();
+ method public int getLimit();
+ method public boolean getSortDirection();
+ method public int getSortingProperty();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ALL_EVENTS = -1; // 0xffffffff
+ field public static final int ALL_GROUP_THREAD_EVENTS = 0; // 0x0
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsEventQueryParams> CREATOR;
+ field public static final int GROUP_THREAD_ICON_CHANGED_EVENT = 8; // 0x8
+ field public static final int GROUP_THREAD_NAME_CHANGED_EVENT = 16; // 0x10
+ field public static final int GROUP_THREAD_PARTICIPANT_JOINED_EVENT = 2; // 0x2
+ field public static final int GROUP_THREAD_PARTICIPANT_LEFT_EVENT = 4; // 0x4
+ field public static final int PARTICIPANT_ALIAS_CHANGED_EVENT = 1; // 0x1
+ field public static final int SORT_BY_CREATION_ORDER = 0; // 0x0
+ field public static final int SORT_BY_TIMESTAMP = 1; // 0x1
+ }
+
+ public static class RcsEventQueryParams.Builder {
+ ctor public RcsEventQueryParams.Builder();
+ method public android.telephony.ims.RcsEventQueryParams build();
+ method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setEventType(@android.telephony.ims.RcsEventQueryParams.EventType int);
+ method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setGroupThread(@NonNull android.telephony.ims.RcsGroupThread);
+ method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setResultLimit(@IntRange(from=0) int) throws java.security.InvalidParameterException;
+ method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setSortDirection(boolean);
+ method @CheckResult public android.telephony.ims.RcsEventQueryParams.Builder setSortProperty(@android.telephony.ims.RcsEventQueryParams.SortingProperty int);
+ }
+
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsEventQueryParams.ALL_EVENTS, android.telephony.ims.RcsEventQueryParams.ALL_GROUP_THREAD_EVENTS, android.telephony.ims.RcsEventQueryParams.PARTICIPANT_ALIAS_CHANGED_EVENT, android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_PARTICIPANT_JOINED_EVENT, android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_PARTICIPANT_LEFT_EVENT, android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_NAME_CHANGED_EVENT, android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_ICON_CHANGED_EVENT}) public static @interface RcsEventQueryParams.EventType {
+ }
+
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsEventQueryParams.SORT_BY_CREATION_ORDER, android.telephony.ims.RcsEventQueryParams.SORT_BY_TIMESTAMP}) public static @interface RcsEventQueryParams.SortingProperty {
+ }
+
+ public final class RcsEventQueryResult implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.telephony.ims.RcsQueryContinuationToken getContinuationToken();
+ method public java.util.List<android.telephony.ims.RcsEvent> getEvents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsEventQueryResult> CREATOR;
+ }
+
+ public final class RcsFileTransferCreationParams implements android.os.Parcelable {
+ method public int describeContents();
+ method public String getContentMimeType();
+ method public android.net.Uri getContentUri();
+ method public long getFileSize();
+ method @android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus public int getFileTransferStatus();
+ method public int getHeight();
+ method public long getMediaDuration();
+ method public String getPreviewMimeType();
+ method public android.net.Uri getPreviewUri();
+ method public String getRcsFileTransferSessionId();
+ method public long getTransferOffset();
+ method public int getWidth();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsFileTransferCreationParams> CREATOR;
+ }
+
+ public class RcsFileTransferCreationParams.Builder {
+ ctor public RcsFileTransferCreationParams.Builder();
+ method public android.telephony.ims.RcsFileTransferCreationParams build();
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setContentMimeType(String);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setContentUri(android.net.Uri);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setFileSize(long);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setFileTransferSessionId(String);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setFileTransferStatus(@android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus int);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setHeight(int);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setMediaDuration(long);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setPreviewMimeType(String);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setPreviewUri(android.net.Uri);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setTransferOffset(long);
+ method @CheckResult public android.telephony.ims.RcsFileTransferCreationParams.Builder setWidth(int);
+ }
+
+ public class RcsFileTransferPart {
+ method @WorkerThread @Nullable public String getContentMimeType() throws android.telephony.ims.RcsMessageStoreException;
+ method @Nullable @WorkerThread public android.net.Uri getContentUri() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public long getFileSize() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public String getFileTransferSessionId() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus public int getFileTransferStatus() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public int getHeight() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public long getLength() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public String getPreviewMimeType() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public android.net.Uri getPreviewUri() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public long getTransferOffset() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public int getWidth() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setContentMimeType(String) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setContentUri(android.net.Uri) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setFileSize(long) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setFileTransferSessionId(String) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setFileTransferStatus(@android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus int) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setHeight(int) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setLength(long) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setPreviewMimeType(String) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setPreviewUri(android.net.Uri) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setTransferOffset(long) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setWidth(int) throws android.telephony.ims.RcsMessageStoreException;
+ field public static final int DOWNLOADING = 6; // 0x6
+ field public static final int DOWNLOADING_CANCELLED = 9; // 0x9
+ field public static final int DOWNLOADING_FAILED = 8; // 0x8
+ field public static final int DOWNLOADING_PAUSED = 7; // 0x7
+ field public static final int DRAFT = 1; // 0x1
+ field public static final int NOT_SET = 0; // 0x0
+ field public static final int SENDING = 2; // 0x2
+ field public static final int SENDING_CANCELLED = 5; // 0x5
+ field public static final int SENDING_FAILED = 4; // 0x4
+ field public static final int SENDING_PAUSED = 3; // 0x3
+ field public static final int SUCCEEDED = 10; // 0xa
+ }
+
+ @IntDef({android.telephony.ims.RcsFileTransferPart.DRAFT, android.telephony.ims.RcsFileTransferPart.SENDING, android.telephony.ims.RcsFileTransferPart.SENDING_PAUSED, android.telephony.ims.RcsFileTransferPart.SENDING_FAILED, android.telephony.ims.RcsFileTransferPart.SENDING_CANCELLED, android.telephony.ims.RcsFileTransferPart.DOWNLOADING, android.telephony.ims.RcsFileTransferPart.DOWNLOADING_PAUSED, android.telephony.ims.RcsFileTransferPart.DOWNLOADING_FAILED, android.telephony.ims.RcsFileTransferPart.DOWNLOADING_CANCELLED, android.telephony.ims.RcsFileTransferPart.SUCCEEDED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RcsFileTransferPart.RcsFileTransferStatus {
+ }
+
+ public class RcsGroupThread extends android.telephony.ims.RcsThread {
+ method @WorkerThread public void addParticipant(@NonNull android.telephony.ims.RcsParticipant) throws android.telephony.ims.RcsMessageStoreException;
+ method @Nullable @WorkerThread public android.net.Uri getConferenceUri() throws android.telephony.ims.RcsMessageStoreException;
+ method @Nullable public android.net.Uri getGroupIcon() throws android.telephony.ims.RcsMessageStoreException;
+ method @Nullable @WorkerThread public String getGroupName() throws android.telephony.ims.RcsMessageStoreException;
+ method @Nullable @WorkerThread public android.telephony.ims.RcsParticipant getOwner() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public java.util.Set<android.telephony.ims.RcsParticipant> getParticipants() throws android.telephony.ims.RcsMessageStoreException;
+ method public boolean isGroup();
+ method @WorkerThread public void removeParticipant(@NonNull android.telephony.ims.RcsParticipant) throws android.telephony.ims.RcsMessageStoreException;
+ method @Nullable @WorkerThread public void setConferenceUri(android.net.Uri) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setGroupIcon(@Nullable android.net.Uri) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setGroupName(String) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setOwner(@Nullable android.telephony.ims.RcsParticipant) throws android.telephony.ims.RcsMessageStoreException;
+ }
+
+ public abstract class RcsGroupThreadEvent extends android.telephony.ims.RcsEvent {
+ method @NonNull public android.telephony.ims.RcsParticipant getOriginatingParticipant();
+ method @NonNull public android.telephony.ims.RcsGroupThread getRcsGroupThread();
+ }
+
+ public final class RcsGroupThreadIconChangedEvent extends android.telephony.ims.RcsGroupThreadEvent implements android.os.Parcelable {
+ ctor public RcsGroupThreadIconChangedEvent(long, @NonNull android.telephony.ims.RcsGroupThread, @NonNull android.telephony.ims.RcsParticipant, @Nullable android.net.Uri);
+ method public int describeContents();
+ method @Nullable public android.net.Uri getNewIcon();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsGroupThreadIconChangedEvent> CREATOR;
+ }
+
+ public final class RcsGroupThreadNameChangedEvent extends android.telephony.ims.RcsGroupThreadEvent implements android.os.Parcelable {
+ ctor public RcsGroupThreadNameChangedEvent(long, @NonNull android.telephony.ims.RcsGroupThread, @NonNull android.telephony.ims.RcsParticipant, @Nullable String);
+ method public int describeContents();
+ method @Nullable public String getNewName();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsGroupThreadNameChangedEvent> CREATOR;
+ }
+
+ public final class RcsGroupThreadParticipantJoinedEvent extends android.telephony.ims.RcsGroupThreadEvent implements android.os.Parcelable {
+ ctor public RcsGroupThreadParticipantJoinedEvent(long, @NonNull android.telephony.ims.RcsGroupThread, @NonNull android.telephony.ims.RcsParticipant, @NonNull android.telephony.ims.RcsParticipant);
+ method public int describeContents();
+ method public android.telephony.ims.RcsParticipant getJoinedParticipant();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsGroupThreadParticipantJoinedEvent> CREATOR;
+ }
+
+ public final class RcsGroupThreadParticipantLeftEvent extends android.telephony.ims.RcsGroupThreadEvent implements android.os.Parcelable {
+ ctor public RcsGroupThreadParticipantLeftEvent(long, @NonNull android.telephony.ims.RcsGroupThread, @NonNull android.telephony.ims.RcsParticipant, @NonNull android.telephony.ims.RcsParticipant);
+ method public int describeContents();
+ method @NonNull public android.telephony.ims.RcsParticipant getLeavingParticipantId();
+ method public void persist() throws android.telephony.ims.RcsMessageStoreException;
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsGroupThreadParticipantLeftEvent> CREATOR;
+ }
+
+ public class RcsIncomingMessage extends android.telephony.ims.RcsMessage {
+ method @WorkerThread public long getArrivalTimestamp() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public long getSeenTimestamp() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public android.telephony.ims.RcsParticipant getSenderParticipant() throws android.telephony.ims.RcsMessageStoreException;
+ method public boolean isIncoming();
+ method @WorkerThread public void setArrivalTimestamp(long) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setSeenTimestamp(long) throws android.telephony.ims.RcsMessageStoreException;
+ }
+
+ public final class RcsIncomingMessageCreationParams extends android.telephony.ims.RcsMessageCreationParams implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getArrivalTimestamp();
+ method public long getSeenTimestamp();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsIncomingMessageCreationParams> CREATOR;
+ }
+
+ public static class RcsIncomingMessageCreationParams.Builder extends android.telephony.ims.RcsMessageCreationParams.Builder {
+ ctor public RcsIncomingMessageCreationParams.Builder(long, long, int);
+ method public android.telephony.ims.RcsIncomingMessageCreationParams build();
+ method @CheckResult public android.telephony.ims.RcsIncomingMessageCreationParams.Builder setArrivalTimestamp(long);
+ method @CheckResult public android.telephony.ims.RcsIncomingMessageCreationParams.Builder setSeenTimestamp(long);
+ method @CheckResult public android.telephony.ims.RcsIncomingMessageCreationParams.Builder setSenderParticipant(android.telephony.ims.RcsParticipant);
+ }
+
+ public class RcsManager {
+ method public android.telephony.ims.RcsMessageStore getRcsMessageStore();
+ }
+
+ public abstract class RcsMessage {
+ method @NonNull @WorkerThread public java.util.Set<android.telephony.ims.RcsFileTransferPart> getFileTransferParts() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public double getLatitude() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public double getLongitude() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public long getOriginationTimestamp() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public String getRcsMessageId() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @android.telephony.ims.RcsMessage.RcsMessageStatus public int getStatus() throws android.telephony.ims.RcsMessageStoreException;
+ method public int getSubscriptionId() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public String getText() throws android.telephony.ims.RcsMessageStoreException;
+ method @NonNull @WorkerThread public android.telephony.ims.RcsFileTransferPart insertFileTransfer(android.telephony.ims.RcsFileTransferCreationParams) throws android.telephony.ims.RcsMessageStoreException;
+ method public abstract boolean isIncoming();
+ method @WorkerThread public void removeFileTransferPart(@NonNull android.telephony.ims.RcsFileTransferPart) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setLatitude(double) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setLongitude(double) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setOriginationTimestamp(long) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setRcsMessageId(String) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setStatus(@android.telephony.ims.RcsMessage.RcsMessageStatus int) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setSubscriptionId(int) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setText(String) throws android.telephony.ims.RcsMessageStoreException;
+ field public static final int DRAFT = 1; // 0x1
+ field public static final int FAILED = 6; // 0x6
+ field public static final double LOCATION_NOT_SET = 4.9E-324;
+ field public static final int NOT_SET = 0; // 0x0
+ field public static final int QUEUED = 2; // 0x2
+ field public static final int RECEIVED = 7; // 0x7
+ field public static final int RETRYING = 5; // 0x5
+ field public static final int SEEN = 9; // 0x9
+ field public static final int SENDING = 3; // 0x3
+ field public static final int SENT = 4; // 0x4
+ }
+
+ @IntDef({android.telephony.ims.RcsMessage.DRAFT, android.telephony.ims.RcsMessage.QUEUED, android.telephony.ims.RcsMessage.SENDING, android.telephony.ims.RcsMessage.SENT, android.telephony.ims.RcsMessage.RETRYING, android.telephony.ims.RcsMessage.FAILED, android.telephony.ims.RcsMessage.RECEIVED, android.telephony.ims.RcsMessage.SEEN}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RcsMessage.RcsMessageStatus {
+ }
+
+ public class RcsMessageCreationParams {
+ ctor protected RcsMessageCreationParams(android.telephony.ims.RcsMessageCreationParams.Builder);
+ method public double getLatitude();
+ method public double getLongitude();
+ method public int getMessageStatus();
+ method public long getOriginationTimestamp();
+ method @Nullable public String getRcsMessageGlobalId();
+ method public int getSubId();
+ method @Nullable public String getText();
+ }
+
+ public static class RcsMessageCreationParams.Builder {
+ method public android.telephony.ims.RcsMessageCreationParams build();
+ method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setLatitude(double);
+ method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setLongitude(double);
+ method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setRcsMessageId(String);
+ method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setStatus(@android.telephony.ims.RcsMessage.RcsMessageStatus int);
+ method @CheckResult public android.telephony.ims.RcsMessageCreationParams.Builder setText(String);
+ }
+
+ public final class RcsMessageQueryParams implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getFileTransferPresence();
+ method public int getLimit();
+ method public String getMessageLike();
+ method public int getMessageType();
+ method public boolean getSortDirection();
+ method @android.telephony.ims.RcsMessageQueryParams.SortingProperty public int getSortingProperty();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsMessageQueryParams> CREATOR;
+ field public static final int MESSAGES_WITHOUT_FILE_TRANSFERS = 8; // 0x8
+ field public static final int MESSAGES_WITH_FILE_TRANSFERS = 4; // 0x4
+ field public static final int MESSAGE_TYPE_INCOMING = 1; // 0x1
+ field public static final int MESSAGE_TYPE_OUTGOING = 2; // 0x2
+ field public static final int SORT_BY_CREATION_ORDER = 0; // 0x0
+ field public static final int SORT_BY_TIMESTAMP = 1; // 0x1
+ }
+
+ public static class RcsMessageQueryParams.Builder {
+ ctor public RcsMessageQueryParams.Builder();
+ method public android.telephony.ims.RcsMessageQueryParams build();
+ method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setFileTransferPresence(int);
+ method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setMessageLike(String);
+ method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setMessageType(int);
+ method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setResultLimit(@IntRange(from=0) int) throws java.security.InvalidParameterException;
+ method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setSortDirection(boolean);
+ method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setSortProperty(@android.telephony.ims.RcsMessageQueryParams.SortingProperty int);
+ method @CheckResult public android.telephony.ims.RcsMessageQueryParams.Builder setThread(@Nullable android.telephony.ims.RcsThread);
+ }
+
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsMessageQueryParams.SORT_BY_CREATION_ORDER, android.telephony.ims.RcsMessageQueryParams.SORT_BY_TIMESTAMP}) public static @interface RcsMessageQueryParams.SortingProperty {
+ }
+
+ public final class RcsMessageQueryResult implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.telephony.ims.RcsQueryContinuationToken getContinuationToken();
+ method @NonNull public java.util.List<android.telephony.ims.RcsMessage> getMessages();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsMessageQueryResult> CREATOR;
+ }
+
+ public final class RcsMessageSnippet implements android.os.Parcelable {
+ method public int describeContents();
+ method @android.telephony.ims.RcsMessage.RcsMessageStatus public int getSnippetStatus();
+ method @Nullable public String getSnippetText();
+ method public long getSnippetTimestamp();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsMessageSnippet> CREATOR;
+ }
+
+ public class RcsMessageStore {
+ ctor public RcsMessageStore();
+ method @WorkerThread @NonNull public android.telephony.ims.RcsGroupThread createGroupThread(@Nullable java.util.List<android.telephony.ims.RcsParticipant>, @Nullable String, @Nullable android.net.Uri) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.Rcs1To1Thread createRcs1To1Thread(@NonNull android.telephony.ims.RcsParticipant) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsParticipant createRcsParticipant(String, @Nullable String) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void deleteThread(@NonNull android.telephony.ims.RcsThread) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsEventQueryResult getRcsEvents(@Nullable android.telephony.ims.RcsEventQueryParams) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsEventQueryResult getRcsEvents(@NonNull android.telephony.ims.RcsQueryContinuationToken) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsMessageQueryResult getRcsMessages(@Nullable android.telephony.ims.RcsMessageQueryParams) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsMessageQueryResult getRcsMessages(@NonNull android.telephony.ims.RcsQueryContinuationToken) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsParticipantQueryResult getRcsParticipants(@Nullable android.telephony.ims.RcsParticipantQueryParams) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsParticipantQueryResult getRcsParticipants(@NonNull android.telephony.ims.RcsQueryContinuationToken) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsThreadQueryResult getRcsThreads(@Nullable android.telephony.ims.RcsThreadQueryParams) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsThreadQueryResult getRcsThreads(@NonNull android.telephony.ims.RcsQueryContinuationToken) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public void persistRcsEvent(android.telephony.ims.RcsEvent) throws android.telephony.ims.RcsMessageStoreException;
+ }
+
+ public class RcsMessageStoreException extends java.lang.Exception {
+ ctor public RcsMessageStoreException(String);
+ }
+
+ public class RcsOutgoingMessage extends android.telephony.ims.RcsMessage {
+ method @NonNull @WorkerThread public java.util.List<android.telephony.ims.RcsOutgoingMessageDelivery> getOutgoingDeliveries() throws android.telephony.ims.RcsMessageStoreException;
+ method public boolean isIncoming();
+ }
+
+ public final class RcsOutgoingMessageCreationParams extends android.telephony.ims.RcsMessageCreationParams implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsOutgoingMessageCreationParams> CREATOR;
+ }
+
+ public static class RcsOutgoingMessageCreationParams.Builder extends android.telephony.ims.RcsMessageCreationParams.Builder {
+ ctor public RcsOutgoingMessageCreationParams.Builder(long, int);
+ method public android.telephony.ims.RcsOutgoingMessageCreationParams build();
+ }
+
+ public class RcsOutgoingMessageDelivery {
+ method @WorkerThread public long getDeliveredTimestamp() throws android.telephony.ims.RcsMessageStoreException;
+ method @NonNull public android.telephony.ims.RcsOutgoingMessage getMessage();
+ method @NonNull public android.telephony.ims.RcsParticipant getRecipient();
+ method @WorkerThread public long getSeenTimestamp() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @android.telephony.ims.RcsMessage.RcsMessageStatus public int getStatus() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setDeliveredTimestamp(long) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setSeenTimestamp(long) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setStatus(@android.telephony.ims.RcsMessage.RcsMessageStatus int) throws android.telephony.ims.RcsMessageStoreException;
+ }
+
+ public class RcsParticipant {
+ method @Nullable @WorkerThread public String getAlias() throws android.telephony.ims.RcsMessageStoreException;
+ method @Nullable @WorkerThread public String getCanonicalAddress() throws android.telephony.ims.RcsMessageStoreException;
+ method @Nullable @WorkerThread public String getContactId() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setAlias(String) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void setContactId(String) throws android.telephony.ims.RcsMessageStoreException;
+ }
+
+ public final class RcsParticipantAliasChangedEvent extends android.telephony.ims.RcsEvent implements android.os.Parcelable {
+ ctor public RcsParticipantAliasChangedEvent(long, @NonNull android.telephony.ims.RcsParticipant, @Nullable String);
+ method public int describeContents();
+ method @Nullable public String getNewAlias();
+ method @NonNull public android.telephony.ims.RcsParticipant getParticipantId();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsParticipantAliasChangedEvent> CREATOR;
+ }
+
+ public final class RcsParticipantQueryParams implements android.os.Parcelable {
+ method public int describeContents();
+ method public String getAliasLike();
+ method public String getCanonicalAddressLike();
+ method public int getLimit();
+ method public boolean getSortDirection();
+ method public int getSortingProperty();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsParticipantQueryParams> CREATOR;
+ field public static final int SORT_BY_ALIAS = 1; // 0x1
+ field public static final int SORT_BY_CANONICAL_ADDRESS = 2; // 0x2
+ field public static final int SORT_BY_CREATION_ORDER = 0; // 0x0
+ }
+
+ public static class RcsParticipantQueryParams.Builder {
+ ctor public RcsParticipantQueryParams.Builder();
+ method public android.telephony.ims.RcsParticipantQueryParams build();
+ method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setAliasLike(String);
+ method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setCanonicalAddressLike(String);
+ method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setResultLimit(@IntRange(from=0) int) throws java.security.InvalidParameterException;
+ method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setSortDirection(boolean);
+ method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setSortProperty(@android.telephony.ims.RcsParticipantQueryParams.SortingProperty int);
+ method @CheckResult public android.telephony.ims.RcsParticipantQueryParams.Builder setThread(android.telephony.ims.RcsThread);
+ }
+
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsParticipantQueryParams.SORT_BY_CREATION_ORDER, android.telephony.ims.RcsParticipantQueryParams.SORT_BY_ALIAS, android.telephony.ims.RcsParticipantQueryParams.SORT_BY_CANONICAL_ADDRESS}) public static @interface RcsParticipantQueryParams.SortingProperty {
+ }
+
+ public final class RcsParticipantQueryResult implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.telephony.ims.RcsQueryContinuationToken getContinuationToken();
+ method @NonNull public java.util.List<android.telephony.ims.RcsParticipant> getParticipants();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsParticipantQueryResult> CREATOR;
+ }
+
+ public final class RcsQueryContinuationToken implements android.os.Parcelable {
+ method public int describeContents();
+ method @android.telephony.ims.RcsQueryContinuationToken.ContinuationTokenType public int getQueryType();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsQueryContinuationToken> CREATOR;
+ field public static final int EVENT_QUERY_CONTINUATION_TOKEN_TYPE = 0; // 0x0
+ field public static final int MESSAGE_QUERY_CONTINUATION_TOKEN_TYPE = 1; // 0x1
+ field public static final int PARTICIPANT_QUERY_CONTINUATION_TOKEN_TYPE = 2; // 0x2
+ field public static final int THREAD_QUERY_CONTINUATION_TOKEN_TYPE = 3; // 0x3
+ }
+
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsQueryContinuationToken.EVENT_QUERY_CONTINUATION_TOKEN_TYPE, android.telephony.ims.RcsQueryContinuationToken.MESSAGE_QUERY_CONTINUATION_TOKEN_TYPE, android.telephony.ims.RcsQueryContinuationToken.PARTICIPANT_QUERY_CONTINUATION_TOKEN_TYPE, android.telephony.ims.RcsQueryContinuationToken.THREAD_QUERY_CONTINUATION_TOKEN_TYPE}) public static @interface RcsQueryContinuationToken.ContinuationTokenType {
+ }
+
+ public abstract class RcsThread {
+ method @WorkerThread @NonNull public android.telephony.ims.RcsIncomingMessage addIncomingMessage(@NonNull android.telephony.ims.RcsIncomingMessageCreationParams) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsOutgoingMessage addOutgoingMessage(@NonNull android.telephony.ims.RcsOutgoingMessageCreationParams) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread public void deleteMessage(@NonNull android.telephony.ims.RcsMessage) throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsMessageQueryResult getMessages() throws android.telephony.ims.RcsMessageStoreException;
+ method @WorkerThread @NonNull public android.telephony.ims.RcsMessageSnippet getSnippet() throws android.telephony.ims.RcsMessageStoreException;
+ method public abstract boolean isGroup();
+ }
+
+ public final class RcsThreadQueryParams implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getLimit();
+ method public boolean getSortDirection();
+ method @android.telephony.ims.RcsThreadQueryParams.SortingProperty public int getSortingProperty();
+ method public int getThreadType();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsThreadQueryParams> CREATOR;
+ field public static final int SORT_BY_CREATION_ORDER = 0; // 0x0
+ field public static final int SORT_BY_TIMESTAMP = 1; // 0x1
+ field public static final int THREAD_TYPE_1_TO_1 = 2; // 0x2
+ field public static final int THREAD_TYPE_GROUP = 1; // 0x1
+ }
+
+ public static class RcsThreadQueryParams.Builder {
+ ctor public RcsThreadQueryParams.Builder();
+ method public android.telephony.ims.RcsThreadQueryParams build();
+ method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setParticipant(@NonNull android.telephony.ims.RcsParticipant);
+ method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setParticipants(@NonNull java.util.List<android.telephony.ims.RcsParticipant>);
+ method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setResultLimit(@IntRange(from=0) int) throws java.security.InvalidParameterException;
+ method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setSortDirection(boolean);
+ method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setSortProperty(@android.telephony.ims.RcsThreadQueryParams.SortingProperty int);
+ method @CheckResult public android.telephony.ims.RcsThreadQueryParams.Builder setThreadType(int);
+ }
+
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef({android.telephony.ims.RcsThreadQueryParams.SORT_BY_CREATION_ORDER, android.telephony.ims.RcsThreadQueryParams.SORT_BY_TIMESTAMP}) public static @interface RcsThreadQueryParams.SortingProperty {
+ }
+
+ public final class RcsThreadQueryResult implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.telephony.ims.RcsQueryContinuationToken getContinuationToken();
+ method @NonNull public java.util.List<android.telephony.ims.RcsThread> getThreads();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.ims.RcsThreadQueryResult> CREATOR;
+ }
+
+}
+
package android.telephony.mbms {
public class DownloadProgressListener {
@@ -55869,11 +56350,16 @@ package android.widget {
method public boolean executeKeyEvent(android.view.KeyEvent);
method public void fling(int);
method public boolean fullScroll(int);
+ method @ColorInt public int getLeftEdgeEffectColor();
method public int getMaxScrollAmount();
+ method @ColorInt public int getRightEdgeEffectColor();
method public boolean isFillViewport();
method public boolean isSmoothScrollingEnabled();
method public boolean pageScroll(int);
+ method public void setEdgeEffectColor(@ColorInt int);
method public void setFillViewport(boolean);
+ method public void setLeftEdgeEffectColor(@ColorInt int);
+ method public void setRightEdgeEffectColor(@ColorInt int);
method public void setSmoothScrollingEnabled(boolean);
method public final void smoothScrollBy(int, int);
method public final void smoothScrollTo(int, int);
@@ -56672,13 +57158,18 @@ package android.widget {
method public boolean executeKeyEvent(android.view.KeyEvent);
method public void fling(int);
method public boolean fullScroll(int);
+ method @ColorInt public int getBottomEdgeEffectColor();
method public int getMaxScrollAmount();
+ method @ColorInt public int getTopEdgeEffectColor();
method public boolean isFillViewport();
method public boolean isSmoothScrollingEnabled();
method public boolean pageScroll(int);
method public void scrollToDescendant(android.view.View);
+ method public void setBottomEdgeEffectColor(@ColorInt int);
+ method public void setEdgeEffectColor(@ColorInt int);
method public void setFillViewport(boolean);
method public void setSmoothScrollingEnabled(boolean);
+ method public void setTopEdgeEffectColor(@ColorInt int);
method public final void smoothScrollBy(int, int);
method public final void smoothScrollTo(int, int);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index c9b8c3867e59..bb34f6859887 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -205,6 +205,7 @@ package android {
}
public static final class R.attr {
+ field public static final int allowClearUserDataOnFailedRestore = 16844198; // 0x10105a6
field public static final int inheritShowWhenLocked = 16844194; // 0x10105a2
field public static final int isVrOnly = 16844152; // 0x1010578
field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
@@ -1150,7 +1151,7 @@ package android.app.usage {
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getAppStandbyBucket(String);
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public java.util.Map<java.lang.String,java.lang.Integer> getAppStandbyBuckets();
method public int getUsageSource();
- method @RequiresPermission(allOf={android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(allOf={android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerAppUsageObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
method public void reportUsageStart(@NonNull android.app.Activity, @NonNull String);
@@ -5786,6 +5787,11 @@ package android.provider {
field public static final String NAMESPACE = "runtime_native_boot";
}
+ public static interface DeviceConfig.Scheduler {
+ field public static final String ENABLE_FAST_METRICS_COLLECTION = "enable_fast_metrics_collection";
+ field public static final String NAMESPACE = "scheduler";
+ }
+
public static interface DeviceConfig.Storage {
field public static final String ISOLATED_STORAGE_ENABLED = "isolated_storage_enabled";
field public static final String NAMESPACE = "storage";
@@ -7018,6 +7024,7 @@ package android.telephony {
method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers();
method public int getMultiSimPolicy();
method public boolean isAllCarriersAllowed();
+ method public java.util.List<java.lang.Boolean> isCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
method public void writeToParcel(android.os.Parcel, int);
field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1
field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0
@@ -7833,6 +7840,7 @@ package android.telephony {
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMultisimCarrierRestricted();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isRebootRequiredForModemConfigChange();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled();
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
diff --git a/api/test-current.txt b/api/test-current.txt
index b2ead4ab2464..1a7e4cb83c52 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1785,12 +1785,19 @@ package android.provider {
}
public final class DeviceConfig {
+ method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(String, String);
+ method public static void removeOnPropertyChangedListener(android.provider.DeviceConfig.OnPropertyChangedListener);
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_AUTOFILL = "autofill";
field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
}
+ public static interface DeviceConfig.OnPropertyChangedListener {
+ method public void onPropertyChanged(String, String, String);
+ }
+
public static interface DeviceConfig.Privacy {
field public static final String NAMESPACE = "privacy";
field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";
@@ -1813,7 +1820,6 @@ package android.provider {
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
- field public static final String AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS = "autofill_smart_suggestion_emulation_flags";
field public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode";
field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs";
field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
@@ -2694,6 +2700,8 @@ package android.view.autofill {
public final class AutofillManager {
method public void setAugmentedAutofillWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
+ field public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES = "smart_suggestion_supported_modes";
+ field public static final int FLAG_SMART_SUGGESTION_OFF = 0; // 0x0
field public static final int FLAG_SMART_SUGGESTION_SYSTEM = 1; // 0x1
field public static final int MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS = 120000; // 0x1d4c0
}
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index d6f045ea43fd..faf2053835fa 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -71,6 +71,7 @@ cc_defaults {
"src/external/Perfetto.cpp",
"src/external/Perfprofd.cpp",
"src/external/StatsPuller.cpp",
+ "src/external/StatsCallbackPuller.cpp",
"src/external/StatsCompanionServicePuller.cpp",
"src/external/SubsystemSleepStatePuller.cpp",
"src/external/PowerStatsPuller.cpp",
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 86bf3eca3ee6..bd21a955729d 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1057,6 +1057,24 @@ Status StatsService::sendAppBreadcrumbAtom(int32_t label, int32_t state) {
return Status::ok();
}
+Status StatsService::registerPullerCallback(int32_t atomTag,
+ const sp<android::os::IStatsPullerCallback>& pullerCallback,
+ const String16& packageName) {
+ ENFORCE_DUMP_AND_USAGE_STATS(packageName);
+
+ VLOG("StatsService::registerPullerCallback called.");
+ mPullerManager->RegisterPullerCallback(atomTag, pullerCallback);
+ return Status::ok();
+}
+
+Status StatsService::unregisterPullerCallback(int32_t atomTag, const String16& packageName) {
+ ENFORCE_DUMP_AND_USAGE_STATS(packageName);
+
+ VLOG("StatsService::unregisterPullerCallback called.");
+ mPullerManager->UnregisterPullerCallback(atomTag);
+ return Status::ok();
+}
+
hardware::Return<void> StatsService::reportSpeakerImpedance(
const SpeakerImpedance& speakerImpedance) {
LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), speakerImpedance);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index cdff50fcb62e..941ed462b303 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -173,6 +173,19 @@ public:
virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
/**
+ * Binder call to register a callback function for a vendor pulled atom.
+ * Note: this atom must NOT have uid as a field.
+ */
+ virtual Status registerPullerCallback(int32_t atomTag,
+ const sp<android::os::IStatsPullerCallback>& pullerCallback,
+ const String16& packageName) override;
+
+ /**
+ * Binder call to unregister any existing callback function for a vendor pulled atom.
+ */
+ virtual Status unregisterPullerCallback(int32_t atomTag, const String16& packageName) override;
+
+ /**
* Binder call to get SpeakerImpedance atom.
*/
virtual Return<void> reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) override;
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 7ddb783d71e1..da7e4daaf22b 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -297,6 +297,7 @@ message Atom {
NumBiometricsEnrolled num_faces_enrolled = 10048;
RoleHolder role_holder = 10049;
DangerousPermissionState dangerous_permission_state = 10050;
+ TrainInfo train_info = 10051;
}
// DO NOT USE field numbers above 100,000 in AOSP.
@@ -2176,6 +2177,7 @@ message HardwareFailed {
SPEAKER_SHORT = 3;
FINGERPRINT_SENSOR_BROKEN = 4;
FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5;
+ DEGRADE = 6;
}
optional int32 failure_code = 3;
}
@@ -5503,3 +5505,20 @@ message DeviceIdentifierAccessDenied {
// True if the package is privileged.
optional bool is_priv_app = 4;
}
+
+/**
+ * Potential experiment ids that goes with a train install.
+ */
+message TrainExperimentIds {
+ repeated int64 experiment_id = 1;
+}
+
+/**
+ * Pulls the ongoing mainline install train version code.
+ * Pulled from StatsCompanionService
+ */
+message TrainInfo {
+ optional int64 train_version_code = 1;
+
+ optional TrainExperimentIds train_experiment_id = 2;
+}
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp
new file mode 100644
index 000000000000..d718273e9b85
--- /dev/null
+++ b/cmds/statsd/src/external/StatsCallbackPuller.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#define DEBUG false // STOPSHIP if true
+#include "Log.h"
+
+#include <android/os/IStatsPullerCallback.h>
+
+#include "StatsCallbackPuller.h"
+#include "logd/LogEvent.h"
+#include "stats_log_util.h"
+
+using namespace android::binder;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+StatsCallbackPuller::StatsCallbackPuller(int tagId, const sp<IStatsPullerCallback>& callback) :
+ StatsPuller(tagId), mCallback(callback) {
+ VLOG("StatsCallbackPuller created for tag %d", tagId);
+}
+
+bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
+ VLOG("StatsCallbackPuller called for tag %d", mTagId)
+ if(mCallback == nullptr) {
+ ALOGW("No callback registered");
+ return false;
+ }
+ int64_t wallClockTimeNs = getWallClockNs();
+ int64_t elapsedTimeNs = getElapsedRealtimeNs();
+ vector<StatsLogEventWrapper> returned_value;
+ Status status = mCallback->pullData(mTagId, elapsedTimeNs, wallClockTimeNs, &returned_value);
+ if (!status.isOk()) {
+ ALOGW("StatsCallbackPuller::pull failed for %d", mTagId);
+ return false;
+ }
+ data->clear();
+ for (const StatsLogEventWrapper& it: returned_value) {
+ LogEvent::createLogEvents(it, *data);
+ }
+ VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
+ return true;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.h b/cmds/statsd/src/external/StatsCallbackPuller.h
new file mode 100644
index 000000000000..c4bfa89ba9a7
--- /dev/null
+++ b/cmds/statsd/src/external/StatsCallbackPuller.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/os/IStatsPullerCallback.h>
+#include <utils/String16.h>
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class StatsCallbackPuller : public StatsPuller {
+public:
+ explicit StatsCallbackPuller(int tagId, const sp<IStatsPullerCallback>& callback);
+
+private:
+ bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
+ const sp<IStatsPullerCallback> mCallback;
+};
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
index c7c22ee85f0f..9552c0a5e35e 100644
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ b/cmds/statsd/src/external/StatsPuller.cpp
@@ -33,7 +33,7 @@ sp<UidMap> StatsPuller::mUidMap = nullptr;
void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; }
StatsPuller::StatsPuller(const int tagId)
- : mTagId(tagId) {
+ : mTagId(tagId), mLastPullTimeNs(0) {
}
bool StatsPuller::Pull(std::vector<std::shared_ptr<LogEvent>>* data) {
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index ecdcd21d44dd..ed72b2914a34 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -18,6 +18,7 @@
#include "Log.h"
#include <android/os/IStatsCompanionService.h>
+#include <android/os/IStatsPullerCallback.h>
#include <cutils/log.h>
#include <math.h>
#include <stdint.h>
@@ -29,6 +30,7 @@
#include "PowerStatsPuller.h"
#include "ResourceHealthManagerPuller.h"
#include "StatsCompanionServicePuller.h"
+#include "StatsCallbackPuller.h"
#include "StatsPullerManager.h"
#include "SubsystemSleepStatePuller.h"
#include "statslog.h"
@@ -49,7 +51,7 @@ namespace statsd {
// Values smaller than this may require to update the alarm.
const int64_t NO_ALARM_UPDATE = INT64_MAX;
-const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
+std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
// wifi_bytes_transfer
{android::util::WIFI_BYTES_TRANSFER,
{.additiveFields = {2, 3, 4, 5},
@@ -420,6 +422,30 @@ int StatsPullerManager::ClearPullerCacheIfNecessary(int64_t timestampNs) {
return totalCleared;
}
+void StatsPullerManager::RegisterPullerCallback(int32_t atomTag,
+ const sp<IStatsPullerCallback>& callback) {
+ AutoMutex _l(mLock);
+ // Platform pullers cannot be changed.
+ if (atomTag < StatsdStats::kMaxPlatformAtomTag) {
+ VLOG("RegisterPullerCallback: atom tag %d is less than min tag %d",
+ atomTag, StatsdStats::kMaxPlatformAtomTag);
+ return;
+ }
+ VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
+ StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
+ kAllPullAtomInfo[atomTag] = {.puller = new StatsCallbackPuller(atomTag, callback)};
+}
+
+void StatsPullerManager::UnregisterPullerCallback(int32_t atomTag) {
+ AutoMutex _l(mLock);
+ // Platform pullers cannot be changed.
+ if (atomTag < StatsdStats::kMaxPlatformAtomTag) {
+ return;
+ }
+ StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
+ kAllPullAtomInfo.erase(atomTag);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 807e4af03dae..45f6b3568143 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -17,6 +17,7 @@
#pragma once
#include <android/os/IStatsCompanionService.h>
+#include <android/os/IStatsPullerCallback.h>
#include <binder/IServiceManager.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
@@ -91,7 +92,12 @@ public:
void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
- const static std::map<int, PullAtomInfo> kAllPullAtomInfo;
+ void RegisterPullerCallback(int32_t atomTag,
+ const sp<IStatsPullerCallback>& callback);
+
+ void UnregisterPullerCallback(int32_t atomTag);
+
+ static std::map<int, PullAtomInfo> kAllPullAtomInfo;
private:
sp<IStatsCompanionService> mStatsCompanionService = nullptr;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index c4034ffeee22..40329b7c86ab 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -423,6 +423,15 @@ void StatsdStats::noteEmptyData(int atomId) {
mPulledAtomStats[atomId].emptyData++;
}
+void StatsdStats::notePullerCallbackRegistrationChanged(int atomId, bool registered) {
+ lock_guard<std::mutex> lock(mLock);
+ if (registered) {
+ mPulledAtomStats[atomId].registeredCount++;
+ } else {
+ mPulledAtomStats[atomId].unregisteredCount++;
+ }
+}
+
void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) {
lock_guard<std::mutex> lock(mLock);
getAtomMetricStats(metricId).hardDimensionLimitReached++;
@@ -514,6 +523,8 @@ void StatsdStats::resetInternalLocked() {
pullStats.second.dataError = 0;
pullStats.second.pullTimeout = 0;
pullStats.second.pullExceedMaxDelay = 0;
+ pullStats.second.registeredCount = 0;
+ pullStats.second.unregisteredCount = 0;
}
mAtomMetricStats.clear();
}
@@ -625,12 +636,14 @@ void StatsdStats::dumpStats(int out) const {
" (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay "
"nanos)%lld, "
" (max pull delay nanos)%lld, (data error)%ld\n"
- " (pull timeout)%ld, (pull exceed max delay)%ld\n",
+ " (pull timeout)%ld, (pull exceed max delay)%ld\n"
+ " (registered count) %ld, (unregistered count) %ld\n",
(int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
(long)pair.second.minPullIntervalSec, (long long)pair.second.avgPullTimeNs,
(long long)pair.second.maxPullTimeNs, (long long)pair.second.avgPullDelayNs,
(long long)pair.second.maxPullDelayNs, pair.second.dataError,
- pair.second.pullTimeout, pair.second.pullExceedMaxDelay);
+ pair.second.pullTimeout, pair.second.pullExceedMaxDelay,
+ pair.second.registeredCount, pair.second.unregisteredCount);
}
if (mAnomalyAlarmRegisteredStats > 0) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index ea3f3b32b0c4..65e8a324d7d3 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -146,6 +146,10 @@ public:
// Max time to do a pull.
static const int64_t kPullMaxDelayNs = 10 * NS_PER_SEC;
+
+ // Max platform atom tag number.
+ static const int32_t kMaxPlatformAtomTag = 100000;
+
/**
* Report a new config has been received and report the static stats about the config.
*
@@ -340,6 +344,13 @@ public:
void noteEmptyData(int atomId);
/**
+ * Records that a puller callback for the given atomId was registered or unregistered.
+ *
+ * @param registered True if the callback was registered, false if was unregistered.
+ */
+ void notePullerCallbackRegistrationChanged(int atomId, bool registered);
+
+ /**
* Hard limit was reached in the cardinality of an atom
*/
void noteHardDimensionLimitReached(int64_t metricId);
@@ -416,6 +427,8 @@ public:
long statsCompanionPullFailed = 0;
long statsCompanionPullBinderTransactionFailed = 0;
long emptyData = 0;
+ long registeredCount = 0;
+ long unregisteredCount = 0;
} PulledAtomStats;
typedef struct {
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 6a07a3f169e0..863261ae1626 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -407,6 +407,8 @@ message StatsdStatsReport {
optional int64 stats_companion_pull_failed = 13;
optional int64 stats_companion_pull_binder_transaction_failed = 14;
optional int64 empty_data = 15;
+ optional int64 registered_count = 16;
+ optional int64 unregistered_count = 17;
}
repeated PulledAtomStats pulled_atom_stats = 10;
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index aa8cfc508861..0ebf2ca4e035 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -70,6 +70,8 @@ const int FIELD_ID_PULL_FAILED = 12;
const int FIELD_ID_STATS_COMPANION_FAILED = 13;
const int FIELD_ID_STATS_COMPANION_BINDER_TRANSACTION_FAILED = 14;
const int FIELD_ID_EMPTY_DATA = 15;
+const int FIELD_ID_PULL_REGISTERED_COUNT = 16;
+const int FIELD_ID_PULL_UNREGISTERED_COUNT = 17;
// for AtomMetricStats proto
const int FIELD_ID_ATOM_METRIC_STATS = 17;
const int FIELD_ID_METRIC_ID = 1;
@@ -480,6 +482,10 @@ void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>
(long long)pair.second.statsCompanionPullBinderTransactionFailed);
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_EMPTY_DATA,
(long long)pair.second.emptyData);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_REGISTERED_COUNT,
+ (long long) pair.second.registeredCount);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UNREGISTERED_COUNT,
+ (long long) pair.second.unregisteredCount);
protoOutput->end(token);
}
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index 92aa998d9720..44a88f049443 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -259,6 +259,10 @@ TEST(StatsdStatsTest, TestPullAtomStats) {
stats.notePullDelay(android::util::DISK_SPACE, 3335L);
stats.notePull(android::util::DISK_SPACE);
stats.notePullFromCache(android::util::DISK_SPACE);
+ stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
+ stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, false);
+ stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
+
vector<uint8_t> output;
stats.dumpStats(&output, false);
@@ -276,6 +280,8 @@ TEST(StatsdStatsTest, TestPullAtomStats) {
EXPECT_EQ(3333L, report.pulled_atom_stats(0).max_pull_time_nanos());
EXPECT_EQ(2223L, report.pulled_atom_stats(0).average_pull_delay_nanos());
EXPECT_EQ(3335L, report.pulled_atom_stats(0).max_pull_delay_nanos());
+ EXPECT_EQ(2L, report.pulled_atom_stats(0).registered_count());
+ EXPECT_EQ(1L, report.pulled_atom_stats(0).unregistered_count());
}
TEST(StatsdStatsTest, TestAtomMetricsStats) {
diff --git a/core/java/android/accessibilityservice/OWNERS b/core/java/android/accessibilityservice/OWNERS
new file mode 100644
index 000000000000..265674a74b7e
--- /dev/null
+++ b/core/java/android/accessibilityservice/OWNERS
@@ -0,0 +1,3 @@
+svetoslavganov@google.com
+pweaver@google.com
+rhedjao@google.com
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 3119b37a686e..7746148d325a 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -24,6 +24,7 @@ import android.annotation.SystemApi;
import android.content.Context;
import android.os.IBinder;
import android.os.IStatsManager;
+import android.os.IStatsPullerCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.AndroidException;
@@ -408,6 +409,39 @@ public final class StatsManager {
}
}
+ /**
+ * Registers a callback for an atom when that atom is to be pulled. The stats service will
+ * invoke pullData in the callback when the stats service determines that this atom needs to be
+ * pulled. Currently, this only works for atoms with tags above 100,000 that do not have a uid.
+ *
+ * @param atomTag The tag of the atom for this puller callback. Must be at least 100000.
+ * @param callback The callback to be invoked when the stats service pulls the atom.
+ * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
+ *
+ * @hide
+ */
+ @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
+ public void setPullerCallback(int atomTag, IStatsPullerCallback callback)
+ throws StatsUnavailableException {
+ synchronized (this) {
+ try {
+ IStatsManager service = getIStatsManagerLocked();
+ if (callback == null) {
+ service.unregisterPullerCallback(atomTag, mContext.getOpPackageName());
+ } else {
+ service.registerPullerCallback(atomTag, callback,
+ mContext.getOpPackageName());
+ }
+
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to connect to statsd when registering data listener.");
+ throw new StatsUnavailableException("could not connect", e);
+ } catch (SecurityException e) {
+ throw new StatsUnavailableException(e.getMessage(), e);
+ }
+ }
+ }
+
private class StatsdDeathRecipient implements IBinder.DeathRecipient {
@Override
public void binderDied() {
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 077b177be930..dd00e5a74382 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -97,6 +97,12 @@ public class TaskInfo {
public long lastActiveTime;
/**
+ * The id of the display this task is associated with.
+ * @hide
+ */
+ public int displayId;
+
+ /**
* The recent activity values for the highest activity in the stack to have set the values.
* {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}.
*/
@@ -152,6 +158,7 @@ public class TaskInfo {
userId = source.readInt();
stackId = source.readInt();
taskId = source.readInt();
+ displayId = source.readInt();
isRunning = source.readBoolean();
baseIntent = source.readInt() != 0
? Intent.CREATOR.createFromParcel(source)
@@ -179,6 +186,7 @@ public class TaskInfo {
dest.writeInt(userId);
dest.writeInt(stackId);
dest.writeInt(taskId);
+ dest.writeInt(displayId);
dest.writeBoolean(isRunning);
if (baseIntent != null) {
@@ -209,6 +217,7 @@ public class TaskInfo {
@Override
public String toString() {
return "TaskInfo{userId=" + userId + " stackId=" + stackId + " taskId=" + taskId
+ + " displayId=" + displayId
+ " isRunning=" + isRunning
+ " baseIntent=" + baseIntent + " baseActivity=" + baseActivity
+ " topActivity=" + topActivity + " origActivity=" + origActivity
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 51397a243420..dc5bdc673249 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -745,7 +745,11 @@ public final class UsageStatsManager {
* Registering an {@code observerId} that was already registered will override the previous one.
* No more than 1000 unique {@code observerId} may be registered by a single uid
* at any one time.
- * A limit may be unregistered via {@link #unregisterAppUsageLimitObserver}
+ * A limit is not cleared when the usage time is exceeded. It needs to be unregistered via
+ * {@link #unregisterAppUsageLimitObserver}.
+ * <p>
+ * Note: usage limits are not persisted in the system and are cleared on reboots. Callers
+ * must reset any limits that they need on reboots.
* <p>
* This method is similar to {@link #registerAppUsageObserver}, but the usage limit set here
* will be visible to the launcher so that it can report the limit to the user and how much
@@ -757,12 +761,15 @@ public final class UsageStatsManager {
* @param observedEntities The list of packages and token to observe for usage time. Cannot be
* null and must include at least one package or token.
* @param timeLimit The total time the set of apps can be in the foreground before the
- * callbackIntent is delivered. Must be at least one minute.
+ * callbackIntent is delivered. Must be at least one minute. Note: a limit of
+ * 0 can be set to indicate that the user has already exhausted the limit for
+ * a group, in which case, the given {@code callbackIntent} will be ignored.
* @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null.
- * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is
+ * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is
* exceeded by the group of apps. The delivered Intent will also contain
* the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and
- * {@link #EXTRA_TIME_USED}. Cannot be null.
+ * {@link #EXTRA_TIME_USED}. Cannot be {@code null} unless the observer is
+ * being registered with a {@code timeLimit} of 0.
* @throws SecurityException if the caller doesn't have both SUSPEND_APPS and OBSERVE_APP_USAGE
* permissions.
* @hide
@@ -772,7 +779,7 @@ public final class UsageStatsManager {
android.Manifest.permission.SUSPEND_APPS,
android.Manifest.permission.OBSERVE_APP_USAGE})
public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities,
- long timeLimit, @NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent) {
+ long timeLimit, @NonNull TimeUnit timeUnit, PendingIntent callbackIntent) {
try {
mService.registerAppUsageLimitObserver(observerId, observedEntities,
timeUnit.toMillis(timeLimit), callbackIntent, mContext.getOpPackageName());
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index b27c5dc1b457..6c6fcb2ea558 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -650,6 +650,18 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
public static final int PRIVATE_FLAG_USE_EMBEDDED_DEX = 1 << 25;
+ /**
+ * Value for {@link #privateFlags}: indicates whether this application's data will be cleared
+ * on a failed restore.
+ *
+ * <p>Comes from the
+ * android.R.styleable#AndroidManifestApplication_allowClearUserDataOnFailedRestore attribute
+ * of the &lt;application&gt; tag.
+ *
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE = 1 << 26;
+
/** @hide */
@IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = {
PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE,
@@ -676,6 +688,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
PRIVATE_FLAG_VENDOR,
PRIVATE_FLAG_VIRTUAL_PRELOAD,
PRIVATE_FLAG_HAS_FRAGILE_USER_DATA,
+ PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE
})
@Retention(RetentionPolicy.SOURCE)
public @interface ApplicationInfoPrivateFlags {}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 96b6eb527002..0abd5eaaf2aa 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3747,6 +3747,13 @@ public class PackageParser {
ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
}
+ if (sa.getBoolean(
+ com.android.internal.R.styleable
+ .AndroidManifestApplication_allowClearUserDataOnFailedRestore,
+ true)) {
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE;
+ }
+
ai.maxAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0);
ai.minAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0);
diff --git a/core/java/android/hardware/display/ColorDisplayManager.java b/core/java/android/hardware/display/ColorDisplayManager.java
index 27f0b0425ec3..f413d7cc92af 100644
--- a/core/java/android/hardware/display/ColorDisplayManager.java
+++ b/core/java/android/hardware/display/ColorDisplayManager.java
@@ -365,6 +365,17 @@ public final class ColorDisplayManager {
}
/**
+ * Gets whether or not a non-default saturation level is currently applied to the display.
+ *
+ * @return {@code true} if the display is not at full saturation
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
+ public boolean isSaturationActivated() {
+ return mManager.isSaturationActivated();
+ }
+
+ /**
* Set the level of color saturation to apply to a specific app.
*
* @param packageName the package name of the app whose windows should be desaturated
@@ -588,6 +599,14 @@ public final class ColorDisplayManager {
}
}
+ boolean isSaturationActivated() {
+ try {
+ return mCdm.isSaturationActivated();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
boolean setAppSaturationLevel(String packageName, int saturationLevel) {
try {
return mCdm.setAppSaturationLevel(packageName, saturationLevel);
diff --git a/core/java/android/hardware/display/IColorDisplayManager.aidl b/core/java/android/hardware/display/IColorDisplayManager.aidl
index 30e76cfe2787..88b59a6eb8db 100644
--- a/core/java/android/hardware/display/IColorDisplayManager.aidl
+++ b/core/java/android/hardware/display/IColorDisplayManager.aidl
@@ -24,6 +24,7 @@ interface IColorDisplayManager {
boolean setSaturationLevel(int saturationLevel);
boolean setAppSaturationLevel(String packageName, int saturationLevel);
+ boolean isSaturationActivated();
int getTransformCapabilities();
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 629289bb7a45..0384faa88be5 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1093,6 +1093,12 @@ public class FileUtils {
return buildUniqueFileWithExtension(parent, parts[0], parts[1]);
}
+ /** {@hide} */
+ public static File buildNonUniqueFile(File parent, String mimeType, String displayName) {
+ final String[] parts = splitFileName(mimeType, displayName);
+ return buildFile(parent, parts[0], parts[1]);
+ }
+
/**
* Generates a unique file name under the given parent directory, keeping
* any extension intact.
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index 93d6f4c12128..f1bba1ab2977 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -16,6 +16,8 @@
package android.os;
+import android.os.IStatsPullerCallback;
+
/**
* Binder interface to communicate with the statistics management service.
* {@hide}
@@ -178,4 +180,20 @@ interface IStatsManager {
* this label. This allows building custom metrics and predicates.
*/
void sendAppBreadcrumbAtom(int label, int state);
+
+ /**
+ * Registers a puller callback function that, when invoked, pulls the data
+ * for the specified vendor atom tag.
+ *
+ * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
+ */
+ oneway void registerPullerCallback(int atomTag, IStatsPullerCallback pullerCallback,
+ String packageName);
+
+ /**
+ * Unregisters a puller callback function for the given vendor atom.
+ *
+ * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
+ */
+ oneway void unregisterPullerCallback(int atomTag, String packageName);
}
diff --git a/core/java/android/os/IStatsPullerCallback.aidl b/core/java/android/os/IStatsPullerCallback.aidl
new file mode 100644
index 000000000000..1684aeb0d666
--- /dev/null
+++ b/core/java/android/os/IStatsPullerCallback.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.os;
+
+import android.os.StatsLogEventWrapper;
+
+/**
+ * Binder interface to pull atoms for the stats service.
+ * {@hide}
+ */
+interface IStatsPullerCallback {
+ /**
+ * Pull data for the specified atom tag. Returns an array of StatsLogEventWrapper containing
+ * the data.
+ *
+ * Note: These pulled atoms should not have uid/attribution chain. Additionally, the event
+ * timestamps will be truncated to the nearest 5 minutes.
+ */
+ StatsLogEventWrapper[] pullData(int atomTag, long elapsedNanos, long wallClocknanos);
+
+}
diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java
index acb9eac3572c..23342426693a 100644
--- a/core/java/android/os/StatsLogEventWrapper.java
+++ b/core/java/android/os/StatsLogEventWrapper.java
@@ -57,20 +57,18 @@ public final class StatsLogEventWrapper implements Parcelable {
public static final Parcelable.Creator<StatsLogEventWrapper> CREATOR = new
Parcelable.Creator<StatsLogEventWrapper>() {
public StatsLogEventWrapper createFromParcel(Parcel in) {
- android.util.EventLog.writeEvent(0x534e4554, "112550251",
- android.os.Binder.getCallingUid(), "");
- // Purposefully leaving this method not implemented.
- throw new RuntimeException("Not implemented");
+ return new StatsLogEventWrapper(in);
}
public StatsLogEventWrapper[] newArray(int size) {
- android.util.EventLog.writeEvent(0x534e4554, "112550251",
- android.os.Binder.getCallingUid(), "");
- // Purposefully leaving this method not implemented.
- throw new RuntimeException("Not implemented");
+ return new StatsLogEventWrapper[size];
}
};
+ private StatsLogEventWrapper(Parcel in) {
+ readFromParcel(in);
+ }
+
/**
* Set work source if any.
*/
@@ -197,6 +195,70 @@ public final class StatsLogEventWrapper implements Parcelable {
}
/**
+ * Reads from parcel and appropriately fills member fields.
+ */
+ public void readFromParcel(Parcel in) {
+ mTypes = new ArrayList<>();
+ mValues = new ArrayList<>();
+ mWorkSource = null;
+
+ mTag = in.readInt();
+ mElapsedTimeNs = in.readLong();
+ mWallClockTimeNs = in.readLong();
+
+ // Clear any data.
+ if (DEBUG) {
+ Slog.d(TAG, "Reading " + mTag + " " + mElapsedTimeNs + " " + mWallClockTimeNs);
+ }
+ // Set up worksource if present.
+ int numWorkChains = in.readInt();
+ if (numWorkChains > 0) {
+ mWorkSource = new WorkSource();
+ for (int i = 0; i < numWorkChains; i++) {
+ android.os.WorkSource.WorkChain workChain = mWorkSource.createWorkChain();
+ int workChainSize = in.readInt();
+ for (int j = 0; j < workChainSize; j++) {
+ int uid = in.readInt();
+ String tag = in.readString();
+ workChain.addNode(uid, tag);
+ }
+ }
+ }
+
+ // Do the rest of the types.
+ int numTypes = in.readInt();
+ if (DEBUG) {
+ Slog.d(TAG, "Reading " + numTypes + " elements");
+ }
+ for (int i = 0; i < numTypes; i++) {
+ int type = in.readInt();
+ mTypes.add(type);
+ switch (type) {
+ case EVENT_TYPE_INT:
+ mValues.add(in.readInt());
+ break;
+ case EVENT_TYPE_LONG:
+ mValues.add(in.readLong());
+ break;
+ case EVENT_TYPE_FLOAT:
+ mValues.add(in.readFloat());
+ break;
+ case EVENT_TYPE_DOUBLE:
+ mValues.add(in.readDouble());
+ break;
+ case EVENT_TYPE_STRING:
+ mValues.add(in.readString());
+ break;
+ case EVENT_TYPE_STORAGE:
+ mValues.add(in.createByteArray());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
* Boilerplate for Parcel.
*/
public int describeContents() {
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 41d3cbb88f5c..ec4f397ff70b 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -69,6 +69,7 @@ public final class DeviceConfig {
* @hide
*/
@SystemApi
+ @TestApi
public static final String NAMESPACE_AUTOFILL = "autofill";
/**
@@ -308,6 +309,25 @@ public final class DeviceConfig {
String ISOLATED_STORAGE_ENABLED = "isolated_storage_enabled";
}
+ /**
+ * Namespace for system scheduler related features. These features will be applied
+ * immediately upon change.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface Scheduler {
+ String NAMESPACE = "scheduler";
+
+ /**
+ * Flag for enabling fast metrics collection in system scheduler.
+ * A flag value of '' or '0' means the fast metrics collection is not
+ * enabled. Otherwise fast metrics collection is enabled and flag value
+ * is the order id.
+ */
+ String ENABLE_FAST_METRICS_COLLECTION = "enable_fast_metrics_collection";
+ }
+
private static final Object sLock = new Object();
@GuardedBy("sLock")
private static Map<OnPropertyChangedListener, Pair<String, Executor>> sListeners =
@@ -399,6 +419,7 @@ public final class DeviceConfig {
* @see #removeOnPropertyChangedListener(OnPropertyChangedListener)
*/
@SystemApi
+ @TestApi
@RequiresPermission(READ_DEVICE_CONFIG)
public static void addOnPropertyChangedListener(
@NonNull String namespace,
@@ -432,6 +453,7 @@ public final class DeviceConfig {
* @see #addOnPropertyChangedListener(String, Executor, OnPropertyChangedListener)
*/
@SystemApi
+ @TestApi
public static void removeOnPropertyChangedListener(
OnPropertyChangedListener onPropertyChangedListener) {
synchronized (sLock) {
@@ -528,6 +550,7 @@ public final class DeviceConfig {
* @hide
*/
@SystemApi
+ @TestApi
public interface OnPropertyChangedListener {
/**
* Called when a property has changed.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index de84e713a6f7..22329baa5109 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -13285,17 +13285,6 @@ public final class Settings {
public static final String AUTOFILL_MAX_VISIBLE_DATASETS = "autofill_max_visible_datasets";
/**
- * Used to emulate Smart Suggestion for Augmented Autofill during development
- *
- * <p>Valid values: {@code 0x1} for IME and/or {@code 0x2} for popup window.
- *
- * @hide
- */
- @TestApi
- public static final String AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS =
- "autofill_smart_suggestion_emulation_flags";
-
- /**
* Exemptions to the hidden API blacklist.
*
* @hide
@@ -13354,6 +13343,14 @@ public final class Settings {
public static final String ISOLATED_STORAGE_REMOTE = "isolated_storage_remote";
/**
+ * Indicates whether aware is available in the current location.
+ * @hide
+ */
+ public static final String AWARE_ALLOWED = "aware_allowed";
+
+ private static final Validator AWARE_ALLOWED_VALIDATOR = BOOLEAN_VALIDATOR;
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
@@ -13399,6 +13396,7 @@ public final class Settings {
SOFT_AP_TIMEOUT_ENABLED,
ZEN_DURATION,
CHARGING_VIBRATION_ENABLED,
+ AWARE_ALLOWED,
};
/**
@@ -13459,6 +13457,7 @@ public final class Settings {
VALIDATORS.put(WIFI_PNO_RECENCY_SORTING_ENABLED,
WIFI_PNO_RECENCY_SORTING_ENABLED_VALIDATOR);
VALIDATORS.put(WIFI_LINK_PROBING_ENABLED, WIFI_LINK_PROBING_ENABLED_VALIDATOR);
+ VALIDATORS.put(AWARE_ALLOWED, AWARE_ALLOWED_VALIDATOR);
}
/**
diff --git a/core/java/android/service/textclassifier/TEST_MAPPING b/core/java/android/service/textclassifier/TEST_MAPPING
new file mode 100644
index 000000000000..ccf26315852d
--- /dev/null
+++ b/core/java/android/service/textclassifier/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "imports": [
+ {
+ "path": "frameworks/base/core/java/android/view/textclassifier"
+ }
+ ]
+}
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 3f18d8b46e2a..39b6876d86c7 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -95,7 +95,12 @@ public abstract class LayoutInflater {
protected final Context mContext;
// these are optional, set by the caller
- @UnsupportedAppUsage
+ /**
+ * If any developer has desire to change this value, they should instead use
+ * {@link #cloneInContext(Context)} and set the new factory in thew newly-created
+ * LayoutInflater.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private boolean mFactorySet;
@UnsupportedAppUsage
private Factory mFactory;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3f2795ba1e00..83df33e9742e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4030,8 +4030,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* {@hide}
+ *
+ * Not available for general use. If you need help, hang up and then dial one of the following
+ * public APIs:
+ *
+ * @see #isAttachedToWindow() for current attach state
+ * @see #onAttachedToWindow() for subclasses performing work when becoming attached
+ * @see #onDetachedFromWindow() for subclasses performing work when becoming detached
+ * @see OnAttachStateChangeListener for other code performing work on attach/detach
+ * @see #getHandler() for posting messages to this view's UI thread/looper
+ * @see #getParent() for interacting with the parent chain
+ * @see #getWindowToken() for the current window token
+ * @see #getRootView() for the view at the root of the attached hierarchy
+ * @see #getDisplay() for the Display this view is presented on
+ * @see #getRootWindowInsets() for the current insets applied to the whole attached window
+ * @see #hasWindowFocus() for whether the attached window is currently focused
+ * @see #getWindowVisibility() for checking the visibility of the attached window
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
AttachInfo mAttachInfo;
/**
@@ -28193,18 +28209,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
View mViewRequestingLayout;
/**
- * Used to track views that need (at least) a partial relayout at their current size
- * during the next traversal.
- */
- List<View> mPartialLayoutViews = new ArrayList<>();
-
- /**
- * Swapped with mPartialLayoutViews during layout to avoid concurrent
- * modification. Lazily assigned during ViewRootImpl layout.
- */
- List<View> mEmptyPartialLayoutViews;
-
- /**
* Used to track the identity of the current drag operation.
*/
IBinder mDragToken;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d2b40f75a6a8..aaf1d110c8c2 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -703,7 +703,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
private void initFromAttributes(
Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewGroup, defStyleAttr,
+ final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewGroup,
+ defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.ViewGroup, attrs, a, defStyleAttr,
defStyleRes);
final int N = a.getIndexCount();
diff --git a/core/java/android/view/ViewStub.java b/core/java/android/view/ViewStub.java
index e9d1b8784914..9ca16327844c 100644
--- a/core/java/android/view/ViewStub.java
+++ b/core/java/android/view/ViewStub.java
@@ -108,6 +108,9 @@ public final class ViewStub extends View {
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ViewStub, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.ViewStub, attrs, a, defStyleAttr,
+ defStyleRes);
+
mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID);
diff --git a/core/java/android/view/accessibility/OWNERS b/core/java/android/view/accessibility/OWNERS
new file mode 100644
index 000000000000..265674a74b7e
--- /dev/null
+++ b/core/java/android/view/accessibility/OWNERS
@@ -0,0 +1,3 @@
+svetoslavganov@google.com
+pweaver@google.com
+rhedjao@google.com
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 83fc017373a6..5e5c8265f782 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -17,7 +17,6 @@
package android.view.autofill;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
-import static android.util.DebugUtils.flagsToString;
import static android.view.autofill.Helper.sDebug;
import static android.view.autofill.Helper.sVerbose;
@@ -338,6 +337,14 @@ public final class AutofillManager {
public static final int MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS = 1_000 * 60 * 2; // 2 minutes
/**
+ * Disables Augmented Autofill.
+ *
+ * @hide
+ */
+ @TestApi
+ public static final int FLAG_SMART_SUGGESTION_OFF = 0x0;
+
+ /**
* Displays the Augment Autofill window using the same mechanism (such as a popup-window
* attached to the focused view) as the standard autofill.
*
@@ -347,13 +354,21 @@ public final class AutofillManager {
public static final int FLAG_SMART_SUGGESTION_SYSTEM = 0x1;
/** @hide */
- @IntDef(flag = true, prefix = { "FLAG_SMART_SUGGESTION_" }, value = {
- FLAG_SMART_SUGGESTION_SYSTEM
- })
+ @IntDef(flag = false, value = { FLAG_SMART_SUGGESTION_OFF, FLAG_SMART_SUGGESTION_SYSTEM })
@Retention(RetentionPolicy.SOURCE)
public @interface SmartSuggestionMode {}
/**
+ * {@code DeviceConfig} property used to set which Smart Suggestion modes for Augmented Autofill
+ * are available.
+ *
+ * @hide
+ */
+ @TestApi
+ public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES =
+ "smart_suggestion_supported_modes";
+
+ /**
* Makes an authentication id from a request id and a dataset id.
*
* @param requestId The request id.
@@ -2347,7 +2362,14 @@ public final class AutofillManager {
/** @hide */
public static String getSmartSuggestionModeToString(@SmartSuggestionMode int flags) {
- return flagsToString(AutofillManager.class, "FLAG_SMART_SUGGESTION_", flags);
+ switch (flags) {
+ case FLAG_SMART_SUGGESTION_OFF:
+ return "OFF";
+ case FLAG_SMART_SUGGESTION_SYSTEM:
+ return "SYSTEM";
+ default:
+ return "INVALID:" + flags;
+ }
}
@GuardedBy("mLock")
diff --git a/core/java/android/view/textclassifier/TEST_MAPPING b/core/java/android/view/textclassifier/TEST_MAPPING
new file mode 100644
index 000000000000..0d3c3465f2d6
--- /dev/null
+++ b/core/java/android/view/textclassifier/TEST_MAPPING
@@ -0,0 +1,23 @@
+{
+ "presubmit": [
+ {
+ "name": "FrameworksCoreTests",
+ "options": [
+ {
+ "include-filter": "android.view.textclassifier"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsViewTestCases",
+ "options": [
+ {
+ "include-filter": "android.view.textclassifier.cts"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9d7a482aa611..4b7c393b1b96 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -657,7 +657,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private Runnable mClearScrollingCache;
Runnable mPositionScrollAfterLayout;
private int mMinimumVelocity;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124051740)
private int mMaximumVelocity;
private float mVelocityScale = 1.0f;
@@ -875,6 +875,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.AbsListView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.AbsListView, attrs, a, defStyleAttr,
+ defStyleRes);
final Drawable selector = a.getDrawable(R.styleable.AbsListView_listSelector);
if (selector != null) {
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index c8be1d66ed4a..cd5f2e222b39 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -107,6 +107,8 @@ public abstract class AbsSeekBar extends ProgressBar {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.SeekBar, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.SeekBar, attrs, a, defStyleAttr,
+ defStyleRes);
final Drawable thumb = a.getDrawable(R.styleable.SeekBar_thumb);
setThumb(thumb);
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index 816c9499e292..3dcba48b8dc8 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -82,6 +82,8 @@ public abstract class AbsSpinner extends AdapterView<SpinnerAdapter> {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.AbsSpinner, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.AbsSpinner, attrs, a, defStyleAttr,
+ defStyleRes);
final CharSequence[] entries = a.getTextArray(R.styleable.AbsSpinner_entries);
if (entries != null) {
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 58715eefc25e..89ea0747b532 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -232,6 +232,8 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
TypedArray attributesArray = context.obtainStyledAttributes(attrs,
R.styleable.ActivityChooserView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.ActivityChooserView, attrs,
+ attributesArray, defStyleAttr, defStyleRes);
mInitialActivityCount = attributesArray.getInt(
R.styleable.ActivityChooserView_initialActivityCount,
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 6f293684ad3c..5174c1a34fcd 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -180,6 +180,9 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
final TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.AdapterViewAnimator, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.AdapterViewAnimator,
+ attrs, a, defStyleAttr, defStyleRes);
+
int resource = a.getResourceId(
com.android.internal.R.styleable.AdapterViewAnimator_inAnimation, 0);
if (resource > 0) {
diff --git a/core/java/android/widget/AdapterViewFlipper.java b/core/java/android/widget/AdapterViewFlipper.java
index 18d74705773a..065089f53633 100644
--- a/core/java/android/widget/AdapterViewFlipper.java
+++ b/core/java/android/widget/AdapterViewFlipper.java
@@ -69,6 +69,8 @@ public class AdapterViewFlipper extends AdapterViewAnimator {
final TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.AdapterViewFlipper, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.AdapterViewFlipper,
+ attrs, a, defStyleAttr, defStyleRes);
mFlipInterval = a.getInt(
com.android.internal.R.styleable.AdapterViewFlipper_flipInterval, DEFAULT_INTERVAL);
mAutoStart = a.getBoolean(
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 795b03493efb..339947ac8d5a 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -81,6 +81,8 @@ public class AnalogClock extends View {
final Resources r = context.getResources();
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.AnalogClock, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.AnalogClock,
+ attrs, a, defStyleAttr, defStyleRes);
mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial);
if (mDial == null) {
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 7ed7aa293f21..904a86261e6c 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -227,6 +227,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.AutoCompleteTextView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.AutoCompleteTextView,
+ attrs, a, defStyleAttr, defStyleRes);
if (popupTheme != null) {
mPopupContext = new ContextThemeWrapper(context, popupTheme);
@@ -245,6 +247,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
if (mPopupContext != context) {
pa = mPopupContext.obtainStyledAttributes(
attrs, R.styleable.AutoCompleteTextView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.AutoCompleteTextView,
+ attrs, a, defStyleAttr, defStyleRes);
} else {
pa = a;
}
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 6c74c8c24c44..b552aa6c85c4 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -112,6 +112,8 @@ public class CalendarView extends FrameLayout {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.CalendarView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.CalendarView,
+ attrs, a, defStyleAttr, defStyleRes);
final int mode = a.getInt(R.styleable.CalendarView_calendarViewMode, MODE_HOLO);
a.recycle();
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index b7fdcbe2b399..99440f862871 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -90,6 +90,8 @@ public class CheckedTextView extends TextView implements Checkable {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.CheckedTextView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.CheckedTextView,
+ attrs, a, defStyleAttr, defStyleRes);
final Drawable d = a.getDrawable(R.styleable.CheckedTextView_checkMark);
if (d != null) {
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index 66c35d903366..0b67cad0112b 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -116,6 +116,8 @@ public class Chronometer extends TextView {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.Chronometer, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.Chronometer,
+ attrs, a, defStyleAttr, defStyleRes);
setFormat(a.getString(R.styleable.Chronometer_format));
setCountDown(a.getBoolean(R.styleable.Chronometer_countDown, false));
a.recycle();
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index a0f93da90847..3cfd373c2906 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -100,6 +100,8 @@ public abstract class CompoundButton extends Button implements Checkable {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.CompoundButton, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.CompoundButton,
+ attrs, a, defStyleAttr, defStyleRes);
final Drawable d = a.getDrawable(com.android.internal.R.styleable.CompoundButton_button);
if (d != null) {
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index cca951ca9298..ada4f00256eb 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -161,6 +161,8 @@ public class DatePicker extends FrameLayout {
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.DatePicker,
+ attrs, a, defStyleAttr, defStyleRes);
final boolean isDialogMode = a.getBoolean(R.styleable.DatePicker_dialogMode, false);
final int requestedMode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER);
final int firstDayOfWeek = a.getInt(R.styleable.DatePicker_firstDayOfWeek, 0);
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index f712d5fa65ca..67fef13d23f2 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -82,6 +82,8 @@ class DayPickerView extends ViewGroup {
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CalendarView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.CalendarView,
+ attrs, a, defStyleAttr, defStyleRes);
final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
LocaleData.get(Locale.getDefault()).firstDayOfWeek);
diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java
index 33d15394332e..2cc013ec4f78 100644
--- a/core/java/android/widget/ExpandableListView.java
+++ b/core/java/android/widget/ExpandableListView.java
@@ -242,6 +242,8 @@ public class ExpandableListView extends ListView {
final TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.ExpandableListView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.ExpandableListView,
+ attrs, a, defStyleAttr, defStyleRes);
mGroupIndicator = a.getDrawable(
com.android.internal.R.styleable.ExpandableListView_groupIndicator);
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 5723b9467aa2..3570c79430a4 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -100,6 +100,8 @@ public class FrameLayout extends ViewGroup {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.FrameLayout, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.FrameLayout,
+ attrs, a, defStyleAttr, defStyleRes);
if (a.getBoolean(R.styleable.FrameLayout_measureAllChildren, false)) {
setMeasureAllChildren(true);
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index d6a0ae48cc13..64192aaff1cf 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -213,6 +213,8 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.Gallery, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.Gallery,
+ attrs, a, defStyleAttr, defStyleRes);
int index = a.getInt(com.android.internal.R.styleable.Gallery_gravity, -1);
if (index >= 0) {
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index c8abf18f88f9..1c8bb0470e2e 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -303,6 +303,8 @@ public class GridLayout extends ViewGroup {
mDefaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.GridLayout, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.GridLayout,
+ attrs, a, defStyleAttr, defStyleRes);
try {
setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT));
setColumnCount(a.getInt(COLUMN_COUNT, DEFAULT_COUNT));
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index bbbe369d5262..a6129b04d14f 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -150,6 +150,8 @@ public class GridView extends AbsListView {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.GridView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.GridView,
+ attrs, a, defStyleAttr, defStyleRes);
int hSpacing = a.getDimensionPixelOffset(
R.styleable.GridView_horizontalSpacing, 0);
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 1c5f837728a0..25cfdc7e4411 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -80,10 +81,24 @@ public class HorizontalScrollView extends FrameLayout {
private final Rect mTempRect = new Rect();
@UnsupportedAppUsage
private OverScroller mScroller;
- @UnsupportedAppUsage
- private EdgeEffect mEdgeGlowLeft;
- @UnsupportedAppUsage
- private EdgeEffect mEdgeGlowRight;
+ /**
+ * Tracks the state of the left edge glow.
+ *
+ * Even though this field is practically final, we cannot make it final because there are apps
+ * setting it via reflection and they need to keep working until they target Q.
+ */
+ @NonNull
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124053130)
+ private EdgeEffect mEdgeGlowLeft = new EdgeEffect(getContext());
+
+ /**
+ * Tracks the state of the bottom edge glow.
+ *
+ * Even though this field is practically final, we cannot make it final because there are apps
+ * setting it via reflection and they need to keep working until they target Q.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124052619)
+ private EdgeEffect mEdgeGlowRight = new EdgeEffect(getContext());
/**
* Position of the last motion event.
@@ -175,6 +190,8 @@ public class HorizontalScrollView extends FrameLayout {
final TypedArray a = context.obtainStyledAttributes(
attrs, android.R.styleable.HorizontalScrollView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, android.R.styleable.HorizontalScrollView,
+ attrs, a, defStyleAttr, defStyleRes);
setFillViewport(a.getBoolean(android.R.styleable.HorizontalScrollView_fillViewport, false));
@@ -216,6 +233,74 @@ public class HorizontalScrollView extends FrameLayout {
}
/**
+ * Sets the edge effect color for both left and right edge effects.
+ *
+ * @param color The color for the edge effects.
+ * @see #setLeftEdgeEffectColor(int)
+ * @see #setRightEdgeEffectColor(int)
+ * @see #getLeftEdgeEffectColor()
+ * @see #getRightEdgeEffectColor()
+ */
+ public void setEdgeEffectColor(@ColorInt int color) {
+ setLeftEdgeEffectColor(color);
+ setRightEdgeEffectColor(color);
+ }
+
+ /**
+ * Sets the right edge effect color.
+ *
+ * @param color The color for the right edge effect.
+ * @see #setLeftEdgeEffectColor(int)
+ * @see #setEdgeEffectColor(int)
+ * @see #getLeftEdgeEffectColor()
+ * @see #getRightEdgeEffectColor()
+ */
+ public void setRightEdgeEffectColor(@ColorInt int color) {
+ mEdgeGlowRight.setColor(color);
+ }
+
+ /**
+ * Sets the left edge effect color.
+ *
+ * @param color The color for the left edge effect.
+ * @see #setRightEdgeEffectColor(int)
+ * @see #setEdgeEffectColor(int)
+ * @see #getLeftEdgeEffectColor()
+ * @see #getRightEdgeEffectColor()
+ */
+ public void setLeftEdgeEffectColor(@ColorInt int color) {
+ mEdgeGlowLeft.setColor(color);
+ }
+
+ /**
+ * Returns the left edge effect color.
+ *
+ * @return The left edge effect color.
+ * @see #setEdgeEffectColor(int)
+ * @see #setLeftEdgeEffectColor(int)
+ * @see #setRightEdgeEffectColor(int)
+ * @see #getRightEdgeEffectColor()
+ */
+ @ColorInt
+ public int getLeftEdgeEffectColor() {
+ return mEdgeGlowLeft.getColor();
+ }
+
+ /**
+ * Returns the right edge effect color.
+ *
+ * @return The right edge effect color.
+ * @see #setEdgeEffectColor(int)
+ * @see #setLeftEdgeEffectColor(int)
+ * @see #setRightEdgeEffectColor(int)
+ * @see #getLeftEdgeEffectColor()
+ */
+ @ColorInt
+ public int getRightEdgeEffectColor() {
+ return mEdgeGlowRight.getColor();
+ }
+
+ /**
* @return The maximum amount this scroll view will scroll in response to
* an arrow event.
*/
@@ -665,7 +750,7 @@ public class HorizontalScrollView extends FrameLayout {
mEdgeGlowLeft.onRelease();
}
}
- if (mEdgeGlowLeft != null
+ if (shouldDisplayEdgeEffects()
&& (!mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished())) {
postInvalidateOnAnimation();
}
@@ -693,7 +778,7 @@ public class HorizontalScrollView extends FrameLayout {
mIsBeingDragged = false;
recycleVelocityTracker();
- if (mEdgeGlowLeft != null) {
+ if (shouldDisplayEdgeEffects()) {
mEdgeGlowLeft.onRelease();
mEdgeGlowRight.onRelease();
}
@@ -708,7 +793,7 @@ public class HorizontalScrollView extends FrameLayout {
mIsBeingDragged = false;
recycleVelocityTracker();
- if (mEdgeGlowLeft != null) {
+ if (shouldDisplayEdgeEffects()) {
mEdgeGlowLeft.onRelease();
mEdgeGlowRight.onRelease();
}
@@ -1650,26 +1735,15 @@ public class HorizontalScrollView extends FrameLayout {
}
}
- @Override
- public void setOverScrollMode(int mode) {
- if (mode != OVER_SCROLL_NEVER) {
- if (mEdgeGlowLeft == null) {
- Context context = getContext();
- mEdgeGlowLeft = new EdgeEffect(context);
- mEdgeGlowRight = new EdgeEffect(context);
- }
- } else {
- mEdgeGlowLeft = null;
- mEdgeGlowRight = null;
- }
- super.setOverScrollMode(mode);
+ private boolean shouldDisplayEdgeEffects() {
+ return getOverScrollMode() != OVER_SCROLL_NEVER;
}
@SuppressWarnings({"SuspiciousNameCombination"})
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
- if (mEdgeGlowLeft != null) {
+ if (shouldDisplayEdgeEffects()) {
final int scrollX = mScrollX;
if (!mEdgeGlowLeft.isFinished()) {
final int restoreCount = canvas.save();
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 800b19cdd77e..9ae62ef8ab7a 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -200,6 +200,8 @@ public class ImageView extends View {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.ImageView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.ImageView,
+ attrs, a, defStyleAttr, defStyleRes);
final Drawable d = a.getDrawable(R.styleable.ImageView_src);
if (d != null) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 64769b5337df..e833df9d498a 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -264,6 +264,8 @@ public class LinearLayout extends ViewGroup {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.LinearLayout, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.LinearLayout,
+ attrs, a, defStyleAttr, defStyleRes);
int index = a.getInt(com.android.internal.R.styleable.LinearLayout_orientation, -1);
if (index >= 0) {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 311f8968150c..2aa019b5d0f4 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -236,6 +236,8 @@ public class ListView extends AbsListView {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.ListView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.ListView,
+ attrs, a, defStyleAttr, defStyleRes);
final CharSequence[] entries = a.getTextArray(R.styleable.ListView_entries);
if (entries != null) {
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 157992a98a4a..89bb2738b899 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -639,6 +639,8 @@ public class NumberPicker extends LinearLayout {
// process style attributes
final TypedArray attributesArray = context.obtainStyledAttributes(
attrs, R.styleable.NumberPicker, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.NumberPicker,
+ attrs, attributesArray, defStyleAttr, defStyleRes);
final int layoutResId = attributesArray.getResourceId(
R.styleable.NumberPicker_internalLayout, DEFAULT_LAYOUT_RESOURCE_ID);
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 30df5b5a09a3..29f070ed5a65 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -203,7 +203,7 @@ public class ProgressBar extends View {
private int mDuration;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private boolean mIndeterminate;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 124049927)
private boolean mOnlyIndeterminate;
private Transformation mTransformation;
private AlphaAnimation mAnimation;
@@ -267,6 +267,8 @@ public class ProgressBar extends View {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.ProgressBar, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.ProgressBar,
+ attrs, a, defStyleAttr, defStyleRes);
mNoInvalidate = true;
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 757a4ca04871..f3600b0de22b 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -404,6 +404,8 @@ public class RadialTimePickerView extends View {
final Context context = getContext();
final TypedArray a = getContext().obtainStyledAttributes(attrs,
R.styleable.TimePicker, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.TimePicker,
+ attrs, a, defStyleAttr, defStyleRes);
final ColorStateList numbersTextColor = a.getColorStateList(
R.styleable.TimePicker_numbersTextColor);
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index ab12eaccad45..c62c16c7e719 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -98,6 +98,8 @@ public class RadioGroup extends LinearLayout {
// XML layout file
TypedArray attributes = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.RadioGroup, com.android.internal.R.attr.radioButtonStyle, 0);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.RadioGroup,
+ attrs, attributes, com.android.internal.R.attr.radioButtonStyle, 0);
int value = attributes.getResourceId(R.styleable.RadioGroup_checkedButton, View.NO_ID);
if (value != View.NO_ID) {
diff --git a/core/java/android/widget/RatingBar.java b/core/java/android/widget/RatingBar.java
index 9f9fdee46fdf..3cf3d9102d21 100644
--- a/core/java/android/widget/RatingBar.java
+++ b/core/java/android/widget/RatingBar.java
@@ -93,6 +93,8 @@ public class RatingBar extends AbsSeekBar {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.RatingBar, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.RatingBar,
+ attrs, a, defStyleAttr, defStyleRes);
final int numStars = a.getInt(R.styleable.RatingBar_numStars, mNumStars);
setIsIndicator(a.getBoolean(R.styleable.RatingBar_isIndicator, !mIsUserSeekable));
final float rating = a.getFloat(R.styleable.RatingBar_rating, -1);
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 556bfd19f942..109c0a432c1b 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -257,6 +257,8 @@ public class RelativeLayout extends ViewGroup {
Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.RelativeLayout, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.RelativeLayout,
+ attrs, a, defStyleAttr, defStyleRes);
mIgnoreGravity = a.getResourceId(R.styleable.RelativeLayout_ignoreGravity, View.NO_ID);
mGravity = a.getInt(R.styleable.RelativeLayout_gravity, mGravity);
a.recycle();
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index c3609038b08f..7e72c6a4789c 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -89,10 +90,25 @@ public class ScrollView extends FrameLayout {
private final Rect mTempRect = new Rect();
@UnsupportedAppUsage
private OverScroller mScroller;
- @UnsupportedAppUsage
- private EdgeEffect mEdgeGlowTop;
- @UnsupportedAppUsage
- private EdgeEffect mEdgeGlowBottom;
+ /**
+ * Tracks the state of the top edge glow.
+ *
+ * Even though this field is practically final, we cannot make it final because there are apps
+ * setting it via reflection and they need to keep working until they target Q.
+ */
+ @NonNull
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768600)
+ private EdgeEffect mEdgeGlowTop = new EdgeEffect(getContext());
+
+ /**
+ * Tracks the state of the bottom edge glow.
+ *
+ * Even though this field is practically final, we cannot make it final because there are apps
+ * setting it via reflection and they need to keep working until they target Q.
+ */
+ @NonNull
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769386)
+ private EdgeEffect mEdgeGlowBottom = new EdgeEffect(getContext());
/**
* Position of the last motion event.
@@ -201,6 +217,8 @@ public class ScrollView extends FrameLayout {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.ScrollView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.ScrollView,
+ attrs, a, defStyleAttr, defStyleRes);
setFillViewport(a.getBoolean(R.styleable.ScrollView_fillViewport, false));
@@ -247,6 +265,74 @@ public class ScrollView extends FrameLayout {
}
/**
+ * Sets the edge effect color for both top and bottom edge effects.
+ *
+ * @param color The color for the edge effects.
+ * @see #setTopEdgeEffectColor(int)
+ * @see #setBottomEdgeEffectColor(int)
+ * @see #getTopEdgeEffectColor()
+ * @see #getBottomEdgeEffectColor()
+ */
+ public void setEdgeEffectColor(@ColorInt int color) {
+ setTopEdgeEffectColor(color);
+ setBottomEdgeEffectColor(color);
+ }
+
+ /**
+ * Sets the bottom edge effect color.
+ *
+ * @param color The color for the bottom edge effect.
+ * @see #setTopEdgeEffectColor(int)
+ * @see #setEdgeEffectColor(int)
+ * @see #getTopEdgeEffectColor()
+ * @see #getBottomEdgeEffectColor()
+ */
+ public void setBottomEdgeEffectColor(@ColorInt int color) {
+ mEdgeGlowBottom.setColor(color);
+ }
+
+ /**
+ * Sets the top edge effect color.
+ *
+ * @param color The color for the top edge effect.
+ * @see #setBottomEdgeEffectColor(int)
+ * @see #setEdgeEffectColor(int)
+ * @see #getTopEdgeEffectColor()
+ * @see #getBottomEdgeEffectColor()
+ */
+ public void setTopEdgeEffectColor(@ColorInt int color) {
+ mEdgeGlowTop.setColor(color);
+ }
+
+ /**
+ * Returns the top edge effect color.
+ *
+ * @return The top edge effect color.
+ * @see #setEdgeEffectColor(int)
+ * @see #setTopEdgeEffectColor(int)
+ * @see #setBottomEdgeEffectColor(int)
+ * @see #getBottomEdgeEffectColor()
+ */
+ @ColorInt
+ public int getTopEdgeEffectColor() {
+ return mEdgeGlowTop.getColor();
+ }
+
+ /**
+ * Returns the bottom edge effect color.
+ *
+ * @return The bottom edge effect color.
+ * @see #setEdgeEffectColor(int)
+ * @see #setTopEdgeEffectColor(int)
+ * @see #setBottomEdgeEffectColor(int)
+ * @see #getTopEdgeEffectColor()
+ */
+ @ColorInt
+ public int getBottomEdgeEffectColor() {
+ return mEdgeGlowBottom.getColor();
+ }
+
+ /**
* @return The maximum amount this scroll view will scroll in response to
* an arrow event.
*/
@@ -624,6 +710,10 @@ public class ScrollView extends FrameLayout {
return mIsBeingDragged;
}
+ private boolean shouldDisplayEdgeEffects() {
+ return getOverScrollMode() != OVER_SCROLL_NEVER;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent ev) {
initVelocityTrackerIfNotExists();
@@ -732,7 +822,7 @@ public class ScrollView extends FrameLayout {
mEdgeGlowTop.onRelease();
}
}
- if (mEdgeGlowTop != null
+ if (shouldDisplayEdgeEffects()
&& (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())) {
postInvalidateOnAnimation();
}
@@ -1670,7 +1760,7 @@ public class ScrollView extends FrameLayout {
recycleVelocityTracker();
- if (mEdgeGlowTop != null) {
+ if (shouldDisplayEdgeEffects()) {
mEdgeGlowTop.onRelease();
mEdgeGlowBottom.onRelease();
}
@@ -1700,21 +1790,6 @@ public class ScrollView extends FrameLayout {
}
@Override
- public void setOverScrollMode(int mode) {
- if (mode != OVER_SCROLL_NEVER) {
- if (mEdgeGlowTop == null) {
- Context context = getContext();
- mEdgeGlowTop = new EdgeEffect(context);
- mEdgeGlowBottom = new EdgeEffect(context);
- }
- } else {
- mEdgeGlowTop = null;
- mEdgeGlowBottom = null;
- }
- super.setOverScrollMode(mode);
- }
-
- @Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
return (nestedScrollAxes & SCROLL_AXIS_VERTICAL) != 0;
}
@@ -1758,7 +1833,7 @@ public class ScrollView extends FrameLayout {
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
- if (mEdgeGlowTop != null) {
+ if (shouldDisplayEdgeEffects()) {
final int scrollY = mScrollY;
final boolean clipToPadding = getClipToPadding();
if (!mEdgeGlowTop.isFinished()) {
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index af3b8c0afe08..630c38a734bd 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -283,6 +283,8 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.SearchView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.SearchView,
+ attrs, a, defStyleAttr, defStyleRes);
final LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
final int layoutResId = a.getResourceId(
diff --git a/core/java/android/widget/SlidingDrawer.java b/core/java/android/widget/SlidingDrawer.java
index 8011c3aef494..2ab2b2407a50 100644
--- a/core/java/android/widget/SlidingDrawer.java
+++ b/core/java/android/widget/SlidingDrawer.java
@@ -218,6 +218,8 @@ public class SlidingDrawer extends ViewGroup {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.SlidingDrawer, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.SlidingDrawer,
+ attrs, a, defStyleAttr, defStyleRes);
int orientation = a.getInt(R.styleable.SlidingDrawer_orientation, ORIENTATION_VERTICAL);
mVertical = orientation == ORIENTATION_VERTICAL;
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index fb56d9739435..d6c657b4dc21 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -247,6 +247,8 @@ public class Spinner extends AbsSpinner implements OnClickListener {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.Spinner, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.Spinner,
+ attrs, a, defStyleAttr, defStyleRes);
if (popupTheme != null) {
mPopupContext = new ContextThemeWrapper(context, popupTheme);
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 6cc86b9b871c..5091eea1898d 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -176,6 +176,8 @@ public class StackView extends AdapterViewAnimator {
super(context, attrs, defStyleAttr, defStyleRes);
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.StackView, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.StackView,
+ attrs, a, defStyleAttr, defStyleRes);
mResOutColor = a.getColor(
com.android.internal.R.styleable.StackView_resOutColor, 0);
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index af4f0202fd6a..ea9cd421d438 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -239,6 +239,8 @@ public class Switch extends CompoundButton {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.Switch, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.Switch,
+ attrs, a, defStyleAttr, defStyleRes);
mThumbDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_thumb);
if (mThumbDrawable != null) {
mThumbDrawable.setCallback(this);
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index b1fcbc33bbc9..481704c80287 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -93,6 +93,8 @@ public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchMode
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.TabWidget, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.TabWidget,
+ attrs, a, defStyleAttr, defStyleRes);
mTabLayoutId = a.getResourceId(R.styleable.TabWidget_tabLayout, 0);
a.recycle();
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index a90741b48684..49a0f39b3bad 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -95,6 +95,8 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.TabWidget, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.TabWidget,
+ attrs, a, defStyleAttr, defStyleRes);
mDrawBottomStrips = a.getBoolean(R.styleable.TabWidget_tabStripEnabled, mDrawBottomStrips);
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index 106b90959ba0..616c4b51eca0 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -242,6 +242,8 @@ public class TextClock extends TextView {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.TextClock, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.TextClock,
+ attrs, a, defStyleAttr, defStyleRes);
try {
mFormat12 = a.getText(R.styleable.TextClock_format12Hour);
mFormat24 = a.getText(R.styleable.TextClock_format24Hour);
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index b239ce638e68..97a8ade589d1 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -127,6 +127,8 @@ public class TimePicker extends FrameLayout {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.TimePicker,
+ attrs, a, defStyleAttr, defStyleRes);
final boolean isDialogMode = a.getBoolean(R.styleable.TimePicker_dialogMode, false);
final int requestedMode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER);
a.recycle();
diff --git a/core/java/android/widget/ToggleButton.java b/core/java/android/widget/ToggleButton.java
index bba6da6b7b4c..b76c2cafd912 100644
--- a/core/java/android/widget/ToggleButton.java
+++ b/core/java/android/widget/ToggleButton.java
@@ -48,6 +48,8 @@ public class ToggleButton extends CompoundButton {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.ToggleButton, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.ToggleButton,
+ attrs, a, defStyleAttr, defStyleRes);
mTextOn = a.getText(com.android.internal.R.styleable.ToggleButton_textOn);
mTextOff = a.getText(com.android.internal.R.styleable.ToggleButton_textOff);
mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.ToggleButton_disabledAlpha, 0.5f);
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index a33c47d86673..f25109ee82df 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -237,6 +237,8 @@ public class Toolbar extends ViewGroup {
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Toolbar,
defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, R.styleable.Toolbar,
+ attrs, a, defStyleAttr, defStyleRes);
mTitleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0);
mSubtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance, 0);
diff --git a/core/java/android/widget/TwoLineListItem.java b/core/java/android/widget/TwoLineListItem.java
index 553b86e1f0c2..4c613a71a3ac 100644
--- a/core/java/android/widget/TwoLineListItem.java
+++ b/core/java/android/widget/TwoLineListItem.java
@@ -62,6 +62,8 @@ public class TwoLineListItem extends RelativeLayout {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.TwoLineListItem, defStyleAttr, defStyleRes);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.TwoLineListItem,
+ attrs, a, defStyleAttr, defStyleRes);
a.recycle();
}
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 2c272dea073b..7f4d8a2d0587 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -52,6 +52,8 @@ public class BinderCallsStats implements BinderInternal.Observer {
public static final boolean ENABLED_DEFAULT = true;
public static final boolean DETAILED_TRACKING_DEFAULT = true;
public static final int PERIODIC_SAMPLING_INTERVAL_DEFAULT = 100;
+ public static final boolean DEFAULT_TRACK_SCREEN_INTERACTIVE = false;
+ public static final boolean DEFAULT_TRACK_DIRECT_CALLING_UID = true;
public static final int MAX_BINDER_CALL_STATS_COUNT_DEFAULT = 5000;
private static final String DEBUG_ENTRY_PREFIX = "__DEBUG_";
@@ -85,6 +87,8 @@ public class BinderCallsStats implements BinderInternal.Observer {
private long mStartElapsedTime = SystemClock.elapsedRealtime();
private long mCallStatsCount = 0;
private boolean mAddDebugEntries = false;
+ private boolean mTrackDirectCallingUid = DEFAULT_TRACK_DIRECT_CALLING_UID;
+ private boolean mTrackScreenInteractive = DEFAULT_TRACK_SCREEN_INTERACTIVE;
private CachedDeviceState.Readonly mDeviceState;
private CachedDeviceState.TimeInStateStopwatch mBatteryStopwatch;
@@ -160,7 +164,12 @@ public class BinderCallsStats implements BinderInternal.Observer {
duration = 0;
latencyDuration = 0;
}
- final int callingUid = getCallingUid();
+ final boolean screenInteractive = mTrackScreenInteractive
+ ? mDeviceState.isScreenInteractive()
+ : OVERFLOW_SCREEN_INTERACTIVE;
+ final int callingUid = mTrackDirectCallingUid
+ ? getCallingUid()
+ : OVERFLOW_DIRECT_CALLING_UID;
synchronized (mLock) {
// This was already checked in #callStart but check again while synchronized.
@@ -177,7 +186,7 @@ public class BinderCallsStats implements BinderInternal.Observer {
final CallStat callStat = uidEntry.getOrCreate(
callingUid, s.binderClass, s.transactionCode,
- mDeviceState.isScreenInteractive(),
+ screenInteractive,
mCallStatsCount >= mMaxBinderCallStatsCount);
final boolean isNewCallStat = callStat.callCount == 0;
if (isNewCallStat) {
@@ -484,6 +493,30 @@ public class BinderCallsStats implements BinderInternal.Observer {
}
}
+ /**
+ * Whether to track the screen state.
+ */
+ public void setTrackScreenInteractive(boolean enabled) {
+ synchronized (mLock) {
+ if (enabled != mTrackScreenInteractive) {
+ mTrackScreenInteractive = enabled;
+ reset();
+ }
+ }
+ }
+
+ /**
+ * Whether to track direct caller uid.
+ */
+ public void setTrackDirectCallerUid(boolean enabled) {
+ synchronized (mLock) {
+ if (enabled != mTrackDirectCallingUid) {
+ mTrackDirectCallingUid = enabled;
+ reset();
+ }
+ }
+ }
+
public void setAddDebugEntries(boolean addDebugEntries) {
mAddDebugEntries = addDebugEntries;
}
diff --git a/core/java/com/android/internal/os/LooperStats.java b/core/java/com/android/internal/os/LooperStats.java
index b3d9ca7670b5..c059721eb2d3 100644
--- a/core/java/com/android/internal/os/LooperStats.java
+++ b/core/java/com/android/internal/os/LooperStats.java
@@ -39,6 +39,7 @@ import java.util.concurrent.ThreadLocalRandom;
public class LooperStats implements Looper.Observer {
public static final String DEBUG_ENTRY_PREFIX = "__DEBUG_";
private static final int SESSION_POOL_SIZE = 50;
+ private static final boolean DISABLED_SCREEN_STATE_TRACKING_VALUE = false;
@GuardedBy("mLock")
private final SparseArray<Entry> mEntries = new SparseArray<>(512);
@@ -54,6 +55,7 @@ public class LooperStats implements Looper.Observer {
private long mStartCurrentTime = System.currentTimeMillis();
private long mStartElapsedTime = SystemClock.elapsedRealtime();
private boolean mAddDebugEntries = false;
+ private boolean mTrackScreenInteractive = false;
public LooperStats(int samplingInterval, int entriesSizeCap) {
this.mSamplingInterval = samplingInterval;
@@ -218,9 +220,15 @@ public class LooperStats implements Looper.Observer {
mSamplingInterval = samplingInterval;
}
+ public void setTrackScreenInteractive(boolean enabled) {
+ mTrackScreenInteractive = enabled;
+ }
+
@Nullable
private Entry findEntry(Message msg, boolean allowCreateNew) {
- final boolean isInteractive = mDeviceState.isScreenInteractive();
+ final boolean isInteractive = mTrackScreenInteractive
+ ? mDeviceState.isScreenInteractive()
+ : DISABLED_SCREEN_STATE_TRACKING_VALUE;
final int id = Entry.idFor(msg, isInteractive);
Entry entry;
synchronized (mLock) {
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index a9d75fd6aff7..15d1944205b6 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -107,6 +107,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);
@@ -238,6 +239,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return false;
}
return (jboolean)_returnValue;
}
@@ -335,6 +337,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return false;
}
return (jboolean)_returnValue;
}
@@ -454,6 +457,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return false;
}
return (jboolean)_returnValue;
}
@@ -509,6 +513,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return false;
}
return (jboolean)_returnValue;
}
@@ -582,6 +587,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return nullptr;
}
return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
}
@@ -664,6 +670,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return nullptr;
}
return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
}
@@ -721,6 +728,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return nullptr;
}
return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
}
@@ -731,7 +739,7 @@ android_eglCreatePixmapSurface
(JNIEnv *_env, jobject _this, jobject dpy, jobject config, jint pixmap, jintArray attrib_list_ref, jint offset) {
jniThrowException(_env, "java/lang/UnsupportedOperationException",
"eglCreatePixmapSurface");
- return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, (EGLSurface) 0);
+ return nullptr;
}
/* EGLBoolean eglDestroySurface ( EGLDisplay dpy, EGLSurface surface ) */
@@ -800,6 +808,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return false;
}
return (jboolean)_returnValue;
}
@@ -898,6 +907,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return nullptr;
}
return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
}
@@ -1034,6 +1044,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return nullptr;
}
return toEGLHandle(_env, eglcontextClass, eglcontextConstructor, _returnValue);
}
@@ -1152,6 +1163,7 @@ exit:
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
+ return false;
}
return (jboolean)_returnValue;
}
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 53cae638db80..1053184bc2fc 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -118,7 +118,7 @@
<attr name="manageSpaceActivity" format="string" />
<!-- Option to let applications specify that user data can/cannot be
- cleared. This flag is turned on by default.
+ cleared by the user in Settings. This flag is turned on by default.
<em>This attribute is usable only by applications
included in the system image. Third-party apps cannot use it.</em> -->
<attr name="allowClearUserData" format="boolean" />
@@ -1661,7 +1661,12 @@
<!-- If {@code true} the user is prompted to keep the app's data on uninstall -->
<attr name="hasFragileUserData" />
- <attr name="zygotePreloadName" />
+ <attr name="zygotePreloadName" />
+
+ <!-- If {@code true} the system will clear app's data if a restore operation fails.
+ This flag is turned on by default. <em>This attribute is usable only by system apps.
+ </em> -->
+ <attr name="allowClearUserDataOnFailedRestore"/>
</declare-styleable>
<!-- The <code>permission</code> tag declares a security permission that can be
used to control access from other packages to specific components or
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index d2c3b40cc3b6..5e65605a4c65 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2939,6 +2939,8 @@
<public name="zygotePreloadName" />
<public name="useEmbeddedDex" />
<public name="forceUriPermissions" />
+ <!-- @hide @SystemApi -->
+ <public name="allowClearUserDataOnFailedRestore"/>
</public-group>
<public-group type="drawable" first-id="0x010800b4">
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 0dc54e091f9d..93068ea975bd 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -41,9 +41,7 @@ easier.
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="textColor">@color/btn_colored_text_material</item>
</style>
- <style name="Widget.DeviceDefault.TextView" parent="Widget.Material.TextView">
- <item name="fontFamily">@string/config_bodyFontFamily</item>
- </style>
+ <style name="Widget.DeviceDefault.TextView" parent="Widget.Material.TextView" />
<style name="Widget.DeviceDefault.CheckedTextView" parent="Widget.Material.CheckedTextView"/>
<style name="Widget.DeviceDefault.AutoCompleteTextView" parent="Widget.Material.AutoCompleteTextView"/>
<style name="Widget.DeviceDefault.CompoundButton.CheckBox" parent="Widget.Material.CompoundButton.CheckBox"/>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ec57f793f15f..206682a1955b 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -128,7 +128,6 @@ public class SettingsBackupTest {
Settings.Global.AUTOFILL_LOGGING_LEVEL,
Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
- Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS,
Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
diff --git a/core/tests/coretests/src/android/view/contentcapture/ViewNodeTest.java b/core/tests/coretests/src/android/view/contentcapture/ViewNodeTest.java
index 213cd405e903..93315f11d242 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ViewNodeTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ViewNodeTest.java
@@ -20,11 +20,12 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.graphics.Matrix;
-import android.support.test.InstrumentationRegistry;
import android.view.View;
import android.view.ViewStructure.HtmlInfo;
import android.view.contentcapture.ViewNode.ViewStructureImpl;
+import androidx.test.InstrumentationRegistry;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
index bdd03707c1f1..d2d03e565522 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
@@ -382,7 +382,6 @@ public class TextClassifierTest {
assertThat(textLanguage, isTextLanguage("ja"));
}
- /* DISABLED: b/122467291
@Test
public void testSuggestConversationActions_textReplyOnly_maxThree() {
if (isTextClassifierDisabled()) return;
@@ -410,7 +409,7 @@ public class TextClassifierTest {
assertThat(conversationAction,
isConversationAction(ConversationAction.TYPE_TEXT_REPLY));
}
- }*/
+ }
@Test
public void testSuggestConversationActions_textReplyOnly_noMax() {
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 1d35143e3fab..e375af3f7b0e 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -658,6 +658,67 @@ public class BinderCallsStatsTest {
assertTrue(debugEntry3.latencyMicros >= 0);
}
+ @Test
+ public void testTrackScreenInteractiveDisabled() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setTrackScreenInteractive(false);
+ Binder binder = new Binder();
+
+ mDeviceState.setScreenInteractive(false);
+ CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+ mDeviceState.setScreenInteractive(true);
+ callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+ bcs.time += 1000; // shoud be ignored.
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+ SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
+ assertEquals(1, uidEntries.size());
+ BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
+ Assert.assertNotNull(uidEntry);
+ assertEquals(2, uidEntry.callCount);
+
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
+ assertEquals(1, callStatsList.size());
+ BinderCallsStats.CallStat callStats = callStatsList.get(0);
+ assertEquals(false, callStats.screenInteractive);
+ assertEquals(2, callStats.callCount);
+ assertEquals(2, callStats.recordedCallCount);
+ }
+
+ @Test
+ public void testTrackCallingUidDisabled() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setTrackDirectCallerUid(false);
+ Binder binder = new Binder();
+
+ bcs.setCallingUid(1);
+ CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+ bcs.setCallingUid(2);
+ callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+ bcs.time += 1000; // shoud be ignored.
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+ SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
+ assertEquals(1, uidEntries.size());
+ BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
+ Assert.assertNotNull(uidEntry);
+ assertEquals(2, uidEntry.callCount);
+
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
+ assertEquals(1, callStatsList.size());
+ BinderCallsStats.CallStat callStats = callStatsList.get(0);
+ assertEquals(-1, callStats.callingUid);
+ assertEquals(2, callStats.callCount);
+ assertEquals(2, callStats.recordedCallCount);
+ }
+
+
class TestBinderCallsStats extends BinderCallsStats {
public int callingUid = CALLING_UID;
public long time = 1234;
@@ -682,6 +743,8 @@ public class BinderCallsStatsTest {
});
setSamplingInterval(1);
setAddDebugEntries(false);
+ setTrackScreenInteractive(true);
+ setTrackDirectCallerUid(true);
if (deviceState != null) {
setDeviceState(deviceState.getReadonlyClient());
}
@@ -701,6 +764,10 @@ public class BinderCallsStatsTest {
protected int getCallingUid() {
return callingUid;
}
+
+ protected void setCallingUid(int uid) {
+ callingUid = uid;
+ }
}
}
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index 79b847754311..3edf5f87258b 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -476,6 +476,33 @@ public final class LooperStatsTest {
assertThat(debugEntry3.totalLatencyMicros).isAtLeast(0L);
}
+ @Test
+ public void testScreenStateTrackingDisabled() {
+ TestableLooperStats looperStats = new TestableLooperStats(1, 100);
+ looperStats.setTrackScreenInteractive(false);
+
+ Message message = mHandlerFirst.obtainMessage(1000);
+ message.workSourceUid = 1000;
+ message.when = looperStats.getSystemUptimeMillis();
+
+ looperStats.tickUptime(30);
+ mDeviceState.setScreenInteractive(false);
+ Object token = looperStats.messageDispatchStarting();
+ looperStats.messageDispatched(token, message);
+
+ looperStats.tickUptime(30);
+ mDeviceState.setScreenInteractive(true);
+ token = looperStats.messageDispatchStarting();
+ looperStats.messageDispatched(token, message);
+
+ List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
+ assertThat(entries).hasSize(1);
+ LooperStats.ExportedEntry entry = entries.get(0);
+ assertThat(entry.isInteractive).isEqualTo(false);
+ assertThat(entry.messageCount).isEqualTo(2);
+ assertThat(entry.recordedMessageCount).isEqualTo(2);
+ }
+
private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) {
try {
r.run();
@@ -501,6 +528,7 @@ public final class LooperStatsTest {
super(samplingInterval, sizeCap);
mSamplingInterval = samplingInterval;
setAddDebugEntries(false);
+ setTrackScreenInteractive(true);
if (deviceState != null) {
setDeviceState(deviceState.getReadonlyClient());
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 7c9529b8ff71..56be05b51d1a 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -175,7 +175,12 @@ public class Typeface {
private int[] mSupportedAxes;
private static final int[] EMPTY_AXES = {};
- @UnsupportedAppUsage
+ /**
+ * Please use font in xml and also your application global theme to change the default Typeface.
+ * android:textViewStyle and its attribute android:textAppearance can be used in order to change
+ * typeface and other text related properties.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static void setDefault(Typeface t) {
sDefaultTypeface = t;
nativeSetDefault(t.native_instance);
diff --git a/media/java/android/media/IRingtonePlayer.aidl b/media/java/android/media/IRingtonePlayer.aidl
index 5f6686a88a7e..c038f36206f6 100644
--- a/media/java/android/media/IRingtonePlayer.aidl
+++ b/media/java/android/media/IRingtonePlayer.aidl
@@ -17,6 +17,7 @@
package android.media;
import android.media.AudioAttributes;
+import android.media.VolumeShaper;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
@@ -27,6 +28,8 @@ import android.os.UserHandle;
interface IRingtonePlayer {
/** Used for Ringtone.java playback */
oneway void play(IBinder token, in Uri uri, in AudioAttributes aa, float volume, boolean looping);
+ oneway void playWithVolumeShaping(IBinder token, in Uri uri, in AudioAttributes aa,
+ float volume, boolean looping, in @nullable VolumeShaper.Configuration volumeShaperConfig);
oneway void stop(IBinder token);
boolean isPlaying(IBinder token);
oneway void setPlaybackProperties(IBinder token, float volume, boolean looping);
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 73d3d889e464..eb680c8377f4 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -381,7 +381,8 @@ public class Ringtone {
volume = mVolume;
}
try {
- mRemotePlayer.play(mRemoteToken, canonicalUri, mAudioAttributes, volume, looping);
+ mRemotePlayer.playWithVolumeShaping(mRemoteToken, canonicalUri, mAudioAttributes,
+ volume, looping, mVolumeShaperConfig);
} catch (RemoteException e) {
if (!playFallbackRingtone()) {
Log.w(TAG, "Problem playing ringtone: " + e);
diff --git a/media/java/android/media/VolumeShaper.aidl b/media/java/android/media/VolumeShaper.aidl
new file mode 100644
index 000000000000..e99c13f8a6f3
--- /dev/null
+++ b/media/java/android/media/VolumeShaper.aidl
@@ -0,0 +1,19 @@
+/* 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.media;
+
+parcelable VolumeShaper;
+parcelable VolumeShaper.Configuration;
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index e08dab48ce39..49066950a9fb 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -17,8 +17,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "SoundPool"
+#include <chrono>
#include <inttypes.h>
-
+#include <thread>
#include <utils/Log.h>
#define USE_SHARED_MEM_BUFFER
@@ -967,6 +968,12 @@ bool SoundChannel::doStop_l()
if (mState != IDLE) {
setVolume_l(0, 0);
ALOGV("stop");
+ // Since we're forcibly halting the previously playing content,
+ // we sleep here to ensure the volume is ramped down before we stop the track.
+ // Ideally the sleep time is the mixer period, or an approximation thereof
+ // (Fast vs Normal tracks are different).
+ // TODO: consider pausing instead of stop here.
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
mAudioTrack->stop();
mPrevSampleID = mSample->sampleID();
mSample.clear();
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 51afbc7d91b0..730c409a91fb 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -230,6 +230,7 @@ LIBANDROID {
ASurfaceTransaction_reparent; # introduced=29
ASurfaceTransaction_setBuffer; # introduced=29
ASurfaceTransaction_setBufferAlpha; # introduced=29
+ ASurfaceTransaction_setBufferDataSpace; # introduced=29
ASurfaceTransaction_setBufferTransparency; # introduced=29
ASurfaceTransaction_setColor; # introduced=29
ASurfaceTransaction_setDamageRegion; # introduced=29
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 7d2934b8554e..d07052bb3b3f 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -440,6 +440,20 @@ void ASurfaceTransaction_setBufferAlpha(ASurfaceTransaction* aSurfaceTransaction
transaction->setAlpha(surfaceControl, alpha);
}
+void ASurfaceTransaction_setBufferDataSpace(ASurfaceTransaction* aSurfaceTransaction,
+ ASurfaceControl* aSurfaceControl,
+ ADataSpace aDataSpace) {
+ CHECK_NOT_NULL(aSurfaceTransaction);
+ CHECK_NOT_NULL(aSurfaceControl);
+
+ sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+ LOG_ALWAYS_FATAL_IF(!isDataSpaceValid(surfaceControl, aDataSpace), "invalid dataspace");
+
+ Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+ transaction->setDataspace(surfaceControl, static_cast<ui::Dataspace>(aDataSpace));
+}
+
void ASurfaceTransaction_setHdrMetadata_smpte2086(ASurfaceTransaction* aSurfaceTransaction,
ASurfaceControl* aSurfaceControl,
struct AHdrMetadata_smpte2086* metadata) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index e28c894ff8f3..ab95910a77b5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -167,7 +167,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
// This is to ensure all the profiles are disconnected as some CK/Hs do not
// disconnect PBAP connection when HF connection is brought down
PbapServerProfile PbapProfile = mProfileManager.getPbapProfile();
- if (PbapProfile.getConnectionStatus(mDevice) == BluetoothProfile.STATE_CONNECTED)
+ if (PbapProfile != null && isConnectedProfile(PbapProfile))
{
PbapProfile.disconnect(mDevice);
}
diff --git a/packages/SystemUI/res-keyguard/layout/bubble_clock.xml b/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
index 6f7f39810608..c8dc8e43893c 100644
--- a/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
@@ -19,9 +19,21 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
>
- <include
+ <TextClock
android:id="@+id/digital_clock"
- layout="@layout/text_clock"
+ android:layout_marginLeft="20dp"
+ android:layout_marginTop="72dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|left"
+ android:textSize="44dp"
+ android:letterSpacing="0.05"
+ android:textColor="?attr/wallpaperTextColor"
+ android:singleLine="true"
+ style="@style/widget_big"
+ android:format12Hour="@string/keyguard_widget_12_hours_format"
+ android:format24Hour="@string/keyguard_widget_24_hours_format"
+ android:elegantTextHeight="false"
/>
<com.android.keyguard.clock.ImageClock
android:id="@+id/analog_clock"
diff --git a/packages/SystemUI/res-keyguard/layout/stretchanalog_clock.xml b/packages/SystemUI/res-keyguard/layout/stretchanalog_clock.xml
index 64b676f55fd6..116a044a7075 100644
--- a/packages/SystemUI/res-keyguard/layout/stretchanalog_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/stretchanalog_clock.xml
@@ -19,9 +19,21 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
>
- <include
+ <TextClock
android:id="@+id/digital_clock"
- layout="@layout/text_clock"
+ android:layout_marginLeft="20dp"
+ android:layout_marginTop="72dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|left"
+ android:textSize="44dp"
+ android:letterSpacing="0.05"
+ android:textColor="?attr/wallpaperTextColor"
+ android:singleLine="true"
+ style="@style/widget_big"
+ android:format12Hour="@string/keyguard_widget_12_hours_format"
+ android:format24Hour="@string/keyguard_widget_24_hours_format"
+ android:elegantTextHeight="false"
/>
<com.android.keyguard.clock.StretchAnalogClock
android:id="@+id/analog_clock"
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index d502baa956b0..91353d7fb8ba 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -71,18 +71,38 @@
android:maxLines="1"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/pkg_divider" />
- <!-- 24 dp icon with 16 dp padding all around to mirror notification content margins -->
- <ImageButton
- android:id="@+id/info"
- android:layout_width="56dp"
- android:layout_height="56dp"
- android:layout_alignParentEnd="true"
+ <LinearLayout
+ android:id="@+id/info_and_settings"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_centerVertical="true"
- android:background="@drawable/ripple_drawable"
- android:contentDescription="@string/notification_more_settings"
- android:padding="16dp"
- android:src="@drawable/ic_info"
- android:tint="?android:attr/colorAccent" />
+ android:layout_alignParentEnd="true"
+ android:paddingHorizontal="16dp"
+ android:orientation="horizontal">
+ <!-- Optional link to app. Only appears if the channel is not disabled and the app
+asked for it -->
+ <ImageButton
+ android:id="@+id/app_settings"
+ android:layout_width="40dp"
+ android:layout_height="56dp"
+ android:layout_centerVertical="true"
+ android:paddingRight="16dp"
+ android:visibility="gone"
+ android:background="@drawable/ripple_drawable"
+ android:contentDescription="@string/notification_app_settings"
+ android:src="@drawable/ic_settings"
+ android:tint="?android:attr/colorAccent" />
+ <!-- 24 dp icon with 16 dp padding all around to mirror notification content margins -->
+ <ImageButton
+ android:id="@+id/info"
+ android:layout_width="24dp"
+ android:layout_height="56dp"
+ android:layout_centerVertical="true"
+ android:background="@drawable/ripple_drawable"
+ android:contentDescription="@string/notification_more_settings"
+ android:src="@drawable/ic_info"
+ android:tint="?android:attr/colorAccent" />
+ </LinearLayout>
</RelativeLayout>
<LinearLayout
@@ -143,50 +163,61 @@
</LinearLayout>
<!-- Settings and Done buttons -->
- <LinearLayout
+ <RelativeLayout
android:id="@+id/block_or_minimize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/notification_guts_button_spacing"
android:layout_marginStart="@dimen/notification_guts_button_side_margin"
android:layout_marginEnd="@dimen/notification_guts_button_side_margin"
- android:gravity="end"
- android:orientation="horizontal">
-
- <!-- Optional link to app. Only appears if the channel is not disabled and the app
- asked for it -->
+ android:clipChildren="false"
+ android:clipToPadding="false">
<TextView
- android:id="@+id/app_settings"
- android:text="@string/notification_app_settings"
+ android:id="@+id/done"
+ android:text="@string/inline_done_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:visibility="gone"
- android:ellipsize="end"
- android:maxLines="1"
+ android:layout_centerVertical="true"
style="@style/TextAppearance.NotificationInfo.Button"/>
- <TextView
- android:id="@+id/block"
- android:text="@string/inline_stop_button"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- <TextView
- android:id="@+id/minimize"
- android:text="@string/inline_minimize_button"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
- style="@style/TextAppearance.NotificationInfo.Button" />
- <TextView
- android:id="@+id/keep"
- android:minWidth="48dp"
- android:text="@string/inline_keep_button"
+
+ <LinearLayout
+ android:id="@+id/block_buttons"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- </LinearLayout>
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentEnd="true"
+ android:orientation="horizontal">
+ <TextView
+ android:id="@+id/deliver_silently"
+ android:text="@string/inline_deliver_silently_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
+ android:paddingRight="24dp"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ <TextView
+ android:id="@+id/block"
+ android:text="@string/inline_block_button"
+ android:minWidth="48dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ <TextView
+ android:id="@+id/minimize"
+ android:text="@string/inline_minimize_button"
+ android:minWidth="48dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ </LinearLayout>
+
+
+ </RelativeLayout>
<LinearLayout
android:id="@+id/interruptiveness_settings"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 89c6c8a66231..db92ed258064 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1573,12 +1573,18 @@
<string name="inline_blocking_helper">You usually dismiss these notifications.
\nKeep showing them?</string>
+ <!-- Notification Inline controls: button to dismiss the blocking helper [CHAR_LIMIT=25] -->
+ <string name="inline_done_button">Done</string>
+
<!-- Notification Inline controls: continue receiving notifications prompt, channel level -->
<string name="inline_keep_showing">Keep showing these notifications?</string>
<!-- Notification inline controls: block notifications button -->
<string name="inline_stop_button">Stop notifications</string>
+ <!-- Notification inline controls: button to deliver notifications silently from this channel [CHAR_LIMIT=35] -->
+ <string name="inline_deliver_silently_button">Deliver Silently</string>
+
<!-- Notification inline controls: button to block notifications from this channel [CHAR_LIMIT=35] -->
<string name="inline_block_button">Block</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index fc1843ba982a..822920e63460 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -187,7 +187,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
View bigClockView = mClockPlugin.getBigClockView();
if (bigClockView != null) {
container.addView(bigClockView);
- container.setVisibility(View.VISIBLE);
+ if (container.getVisibility() == View.GONE) {
+ container.setVisibility(View.VISIBLE);
+ }
}
}
mBigClockContainer = container;
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
index 3591dc82c8ec..4d8cf963ff50 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
@@ -22,6 +22,7 @@ import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
+import android.widget.FrameLayout.LayoutParams;
import com.android.keyguard.R;
@@ -80,8 +81,9 @@ public class ClockLayout extends FrameLayout {
// Put digital clock in two left corner of the screen.
if (mDigitalClock != null) {
- mDigitalClock.setX(0.1f * getWidth() + offsetX);
- mDigitalClock.setY(0.1f * getHeight() + offsetY);
+ LayoutParams params = (LayoutParams) mDigitalClock.getLayoutParams();
+ mDigitalClock.setX(offsetX + params.leftMargin);
+ mDigitalClock.setY(offsetY + params.topMargin);
}
// Put the analog clock in the middle of the screen.
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index ddd9cbf209d6..aebadf936e0c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -16,6 +16,7 @@
package com.android.systemui.media;
+import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -24,6 +25,7 @@ import android.media.AudioAttributes;
import android.media.IAudioService;
import android.media.IRingtonePlayer;
import android.media.Ringtone;
+import android.media.VolumeShaper;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
@@ -78,11 +80,16 @@ public class RingtonePlayer extends SystemUI {
private final Ringtone mRingtone;
public Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa) {
+ this(token, uri, user, aa, null);
+ }
+
+ Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa,
+ @Nullable VolumeShaper.Configuration volumeShaperConfig) {
mToken = token;
mRingtone = new Ringtone(getContextForUser(user), false);
mRingtone.setAudioAttributes(aa);
- mRingtone.setUri(uri);
+ mRingtone.setUri(uri, volumeShaperConfig);
}
@Override
@@ -99,6 +106,12 @@ public class RingtonePlayer extends SystemUI {
@Override
public void play(IBinder token, Uri uri, AudioAttributes aa, float volume, boolean looping)
throws RemoteException {
+ playWithVolumeShaping(token, uri, aa, volume, looping, null);
+ }
+ @Override
+ public void playWithVolumeShaping(IBinder token, Uri uri, AudioAttributes aa, float volume,
+ boolean looping, @Nullable VolumeShaper.Configuration volumeShaperConfig)
+ throws RemoteException {
if (LOGD) {
Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
+ Binder.getCallingUid() + ")");
@@ -108,7 +121,7 @@ public class RingtonePlayer extends SystemUI {
client = mClients.get(token);
if (client == null) {
final UserHandle user = Binder.getCallingUserHandle();
- client = new Client(token, uri, user, aa);
+ client = new Client(token, uri, user, aa, volumeShaperConfig);
token.linkToDeath(client, 0);
mClients.put(token, client);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java
index 43b5503682cc..a1fcbebecea1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java
@@ -30,6 +30,9 @@ public class NotificationCounters {
/** Counter tag for when the user hits 'stop notifications' in the blocking helper. */
public static final String BLOCKING_HELPER_STOP_NOTIFICATIONS =
"blocking_helper_stop_notifications";
+ /** Counter tag for when the user hits 'deliver silently' in the blocking helper. */
+ public static final String BLOCKING_HELPER_DELIVER_SILENTLY =
+ "blocking_helper_deliver_silently";
/** Counter tag for when the user hits 'show silently' in the blocking helper. */
public static final String BLOCKING_HELPER_TOGGLE_SILENT =
"blocking_helper_toggle_silent";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index c7b2fab54fff..37237317fc95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -84,6 +84,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
public static final int ACTION_UNDO = 1;
public static final int ACTION_TOGGLE_SILENT = 2;
public static final int ACTION_BLOCK = 3;
+ public static final int ACTION_DELIVER_SILENTLY = 4;
private INotificationManager mINotificationManager;
private PackageManager mPm;
@@ -135,30 +136,26 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
};
private OnClickListener mOnToggleSilent = v -> {
- Runnable saveImportance = () -> {
- swapContent(ACTION_TOGGLE_SILENT, true /* animate */);
- if (mIsForBlockingHelper) {
- mMetricsLogger.write(getLogMaker()
- .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
- .setType(MetricsEvent.TYPE_ACTION)
- .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_ALERT_ME));
- }
- };
- if (mCheckSaveListener != null) {
- mCheckSaveListener.checkSave(saveImportance, mSbn);
- } else {
- saveImportance.run();
- }
+ handleSaveImportance(ACTION_TOGGLE_SILENT, MetricsEvent.BLOCKING_HELPER_CLICK_ALERT_ME);
+ };
+
+ private OnClickListener mOnDeliverSilently = v -> {
+ handleSaveImportance(
+ ACTION_DELIVER_SILENTLY, MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT);
};
private OnClickListener mOnStopOrMinimizeNotifications = v -> {
+ handleSaveImportance(ACTION_BLOCK, MetricsEvent.BLOCKING_HELPER_CLICK_BLOCKED);
+ };
+
+ private void handleSaveImportance(int action, int metricsSubtype) {
Runnable saveImportance = () -> {
- swapContent(ACTION_BLOCK, true /* animate */);
+ swapContent(action, true /* animate */);
if (mIsForBlockingHelper) {
mMetricsLogger.write(getLogMaker()
.setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
.setType(MetricsEvent.TYPE_ACTION)
- .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_BLOCKED));
+ .setSubtype(metricsSubtype));
}
};
if (mCheckSaveListener != null) {
@@ -166,7 +163,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
} else {
saveImportance.run();
}
- };
+ }
private OnClickListener mOnUndo = v -> {
// Reset exit counter that we'll log and record an undo event separately (not an exit event)
@@ -283,8 +280,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
mMetricsLogger.write(notificationControlsLogMaker());
}
-
-
private void bindHeader() throws RemoteException {
// Package name
Drawable pkgicon = null;
@@ -479,17 +474,21 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
findViewById(R.id.block_or_minimize).setVisibility(VISIBLE);
findViewById(R.id.interruptiveness_settings).setVisibility(GONE);
View block = findViewById(R.id.block);
- TextView keep = findViewById(R.id.keep);
+ TextView done = findViewById(R.id.done);
View minimize = findViewById(R.id.minimize);
+ View deliverSilently = findViewById(R.id.deliver_silently);
+
block.setOnClickListener(mOnStopOrMinimizeNotifications);
- keep.setOnClickListener(mOnKeepShowing);
+ done.setOnClickListener(mOnKeepShowing);
minimize.setOnClickListener(mOnStopOrMinimizeNotifications);
+ deliverSilently.setOnClickListener(mOnDeliverSilently);
if (mIsNonblockable) {
- keep.setText(android.R.string.ok);
+ done.setText(android.R.string.ok);
block.setVisibility(GONE);
minimize.setVisibility(GONE);
+ deliverSilently.setVisibility(GONE);
} else if (mIsForeground) {
block.setVisibility(GONE);
minimize.setVisibility(VISIBLE);
@@ -499,7 +498,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
}
// Set up app settings link (i.e. Customize)
- TextView settingsLinkView = findViewById(R.id.app_settings);
+ View settingsLinkView = findViewById(R.id.app_settings);
Intent settingsIntent = getAppSettingsIntent(mPm, mPackageName,
mSingleNotificationChannel,
mSbn.getId(), mSbn.getTag());
@@ -507,7 +506,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
&& settingsIntent != null
&& !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
settingsLinkView.setVisibility(VISIBLE);
- settingsLinkView.setText(mContext.getString(R.string.notification_app_settings));
settingsLinkView.setOnClickListener((View view) -> {
mAppSettingsClickListener.onClick(view, settingsIntent);
});
@@ -531,6 +529,11 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
case ACTION_UNDO:
mChosenImportance = mStartingChannelImportance;
break;
+ case ACTION_DELIVER_SILENTLY:
+ mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
+ mChosenImportance = IMPORTANCE_LOW;
+ confirmationText.setText(R.string.notification_channel_silenced);
+ break;
case ACTION_TOGGLE_SILENT:
mExitReason = NotificationCounters.BLOCKING_HELPER_TOGGLE_SILENT;
if (mWasShownHighPriority) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 5d03f19f4655..b0d1106ecb24 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -35,7 +35,6 @@ import android.testing.TestableLooper.RunWithLooper;
import android.text.TextPaint;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextClock;
@@ -60,6 +59,8 @@ import org.mockito.MockitoAnnotations;
@RunWithLooper(setAsMainLooper = true)
public class KeyguardClockSwitchTest extends SysuiTestCase {
private FrameLayout mClockContainer;
+ private FrameLayout mBigClockContainer;
+ private TextClock mBigClock;
private StatusBarStateController.StateListener mStateListener;
@Mock
@@ -73,6 +74,8 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
mKeyguardClockSwitch =
(KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view);
+ mBigClockContainer = new FrameLayout(getContext());
+ mBigClock = new TextClock(getContext());
MockitoAnnotations.initMocks(this);
when(mClockView.getPaint()).thenReturn(mock(TextPaint.class));
mStateListener = mKeyguardClockSwitch.getStateListener();
@@ -93,19 +96,17 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
@Test
public void onPluginConnected_showPluginBigClock() {
// GIVEN that the container for the big clock has visibility GONE
- FrameLayout bigClockContainer = new FrameLayout(getContext());
- bigClockContainer.setVisibility(GONE);
- mKeyguardClockSwitch.setBigClockContainer(bigClockContainer);
+ mBigClockContainer.setVisibility(GONE);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
// AND the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
- TextClock pluginView = new TextClock(getContext());
- when(plugin.getBigClockView()).thenReturn(pluginView);
+ when(plugin.getBigClockView()).thenReturn(mBigClock);
// WHEN the plugin is connected
mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
// THEN the big clock container is visible and it is the parent of the
// big clock view.
- assertThat(bigClockContainer.getVisibility()).isEqualTo(VISIBLE);
- assertThat(pluginView.getParent()).isEqualTo(bigClockContainer);
+ assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(mBigClock.getParent()).isEqualTo(mBigClockContainer);
}
@Test
@@ -246,24 +247,64 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
@Test
public void onStateChanged_InvisibleInShade() {
// GIVEN that the big clock container is visible
- ViewGroup container = mock(ViewGroup.class);
- when(container.getVisibility()).thenReturn(View.VISIBLE);
- mKeyguardClockSwitch.setBigClockContainer(container);
+ mBigClockContainer.setVisibility(View.VISIBLE);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
// WHEN transitioned to SHADE state
mStateListener.onStateChanged(StatusBarState.SHADE);
// THEN the container is invisible.
- verify(container).setVisibility(View.INVISIBLE);
+ assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.INVISIBLE);
}
@Test
public void onStateChanged_VisibleInKeyguard() {
// GIVEN that the big clock container is invisible
- ViewGroup container = mock(ViewGroup.class);
- when(container.getVisibility()).thenReturn(View.INVISIBLE);
- mKeyguardClockSwitch.setBigClockContainer(container);
+ mBigClockContainer.setVisibility(View.INVISIBLE);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
// WHEN transitioned to KEYGUARD state
mStateListener.onStateChanged(StatusBarState.KEYGUARD);
// THEN the container is visible.
- verify(container).setVisibility(View.VISIBLE);
+ assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void setBigClockContainer_visible() {
+ // GIVEN that the big clock container is visible
+ mBigClockContainer.setVisibility(View.VISIBLE);
+ // AND GIVEN that a plugin is active.
+ ClockPlugin plugin = mock(ClockPlugin.class);
+ when(plugin.getBigClockView()).thenReturn(mBigClock);
+ mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ // WHEN the container is associated with the clock switch
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ // THEN the container remains visible.
+ assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void setBigClockContainer_invisible() {
+ // GIVEN that the big clock container is invisible
+ mBigClockContainer.setVisibility(View.INVISIBLE);
+ // AND GIVEN that a plugin is active.
+ ClockPlugin plugin = mock(ClockPlugin.class);
+ when(plugin.getBigClockView()).thenReturn(mBigClock);
+ mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ // WHEN the container is associated with the clock switch
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ // THEN the container remains invisible.
+ assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.INVISIBLE);
+ }
+
+ @Test
+ public void setBigClockContainer_gone() {
+ // GIVEN that the big clock container is gone
+ mBigClockContainer.setVisibility(View.GONE);
+ // AND GIVEN that a plugin is active.
+ ClockPlugin plugin = mock(ClockPlugin.class);
+ when(plugin.getBigClockView()).thenReturn(mBigClock);
+ mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ // WHEN the container is associated with the clock switch
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ // THEN the container is made visible.
+ assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 105bd9dd8793..19a73f6c2d5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -737,7 +737,7 @@ public class NotificationInfoTest extends SysuiTestCase {
guts.setGutsContent(mNotificationInfo);
mNotificationInfo.setGutsParent(guts);
- mNotificationInfo.findViewById(R.id.keep).performClick();
+ mNotificationInfo.findViewById(R.id.done).performClick();
verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
mTestableLooper.processAllMessages();
@@ -765,7 +765,7 @@ public class NotificationInfoTest extends SysuiTestCase {
guts.setGutsContent(mNotificationInfo);
mNotificationInfo.setGutsParent(guts);
- mNotificationInfo.findViewById(R.id.keep).performClick();
+ mNotificationInfo.findViewById(R.id.done).performClick();
verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
mTestableLooper.processAllMessages();
@@ -961,6 +961,41 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
+ public void testSilentlyChangedCallsUpdateNotificationChannel_blockingHelper()
+ throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(
+ mMockPackageManager,
+ mMockINotificationManager,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ 1 /* numChannels */,
+ mSbn,
+ null /* checkSaveListener */,
+ null /* onSettingsClick */,
+ null /* onAppSettingsClick */,
+ true /*provisioned */,
+ false /* isNonblockable */,
+ true /* isForBlockingHelper */,
+ true /* isUserSentimentNegative */,
+ IMPORTANCE_DEFAULT,
+ false);
+
+ mNotificationInfo.findViewById(R.id.deliver_silently).performClick();
+ waitForUndoButton();
+ mNotificationInfo.handleCloseControls(true, false);
+
+ mTestableLooper.processAllMessages();
+ ArgumentCaptor<NotificationChannel> updated =
+ ArgumentCaptor.forClass(NotificationChannel.class);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), updated.capture());
+ assertTrue((updated.getValue().getUserLockedFields()
+ & USER_LOCKED_IMPORTANCE) != 0);
+ assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
+ }
+
+ @Test
public void testKeepUpdatesNotificationChannel() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
diff --git a/sax/tests/saxtests/Android.bp b/sax/tests/saxtests/Android.bp
new file mode 100644
index 000000000000..5889f769a645
--- /dev/null
+++ b/sax/tests/saxtests/Android.bp
@@ -0,0 +1,11 @@
+android_test {
+ name: "FrameworksSaxTests",
+ // Include all test java files.
+ srcs: ["src/**/*.java"],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ ],
+ static_libs: ["junit"],
+ platform_apis: true,
+}
diff --git a/sax/tests/saxtests/Android.mk b/sax/tests/saxtests/Android.mk
deleted file mode 100644
index c4517a9a954a..000000000000
--- a/sax/tests/saxtests/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-LOCAL_STATIC_JAVA_LIBRARIES := junit
-LOCAL_PACKAGE_NAME := FrameworksSaxTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-include $(BUILD_PACKAGE)
-
diff --git a/services/accessibility/OWNERS b/services/accessibility/OWNERS
new file mode 100644
index 000000000000..265674a74b7e
--- /dev/null
+++ b/services/accessibility/OWNERS
@@ -0,0 +1,3 @@
+svetoslavganov@google.com
+pweaver@google.com
+rhedjao@google.com
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 2e45fa72eaac..4a3f12674eb7 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -49,6 +49,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.service.autofill.FillEventHistory;
import android.service.autofill.UserData;
@@ -167,10 +168,14 @@ public final class AutofillManagerService
mUi = new AutoFillUI(ActivityThread.currentActivityThread().getSystemUiContext());
mAm = LocalServices.getService(ActivityManagerInternal.class);
+ DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_AUTOFILL,
+ ActivityThread.currentApplication().getMainExecutor(),
+ (namespace, name, value) -> setSmartSuggestionModesFromDeviceConfig(value));
+
setLogLevelFromSettings();
setMaxPartitionsFromSettings();
setMaxVisibleDatasetsFromSettings();
- setSmartSuggestionEmulationFromSettings();
+ setSmartSuggestionModesFromDeviceConfig();
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
@@ -197,9 +202,6 @@ public final class AutofillManagerService
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS), false, observer,
UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Global.getUriFor(
- Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS), false, observer,
- UserHandle.USER_ALL);
}
@Override // from AbstractMasterSystemService
@@ -214,9 +216,6 @@ public final class AutofillManagerService
case Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS:
setMaxVisibleDatasetsFromSettings();
break;
- case Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS:
- setSmartSuggestionEmulationFromSettings();
- break;
default:
Slog.w(TAG, "Unexpected property (" + property + "); updating cache instead");
// fall through
@@ -457,14 +456,25 @@ public final class AutofillManagerService
}
}
- private void setSmartSuggestionEmulationFromSettings() {
- final int flags = Settings.Global.getInt(getContext().getContentResolver(),
- Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS, 0);
- if (sDebug) {
- Slog.d(TAG, "setSmartSuggestionEmulationFromSettings(): "
- + getSmartSuggestionModeToString(flags));
- }
+ private void setSmartSuggestionModesFromDeviceConfig() {
+ final String value = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_AUTOFILL,
+ AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES);
+ setSmartSuggestionModesFromDeviceConfig(value);
+ }
+ private void setSmartSuggestionModesFromDeviceConfig(@Nullable String value) {
+ if (sDebug) Slog.d(TAG, "setSmartSuggestionEmulationFromDeviceConfig(): value=" + value);
+ final int flags;
+ if (value == null) {
+ flags = AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
+ } else {
+ try {
+ flags = Integer.parseInt(value);
+ } catch (Exception e) {
+ Slog.w(TAG, "setSmartSuggestionEmulationFromDeviceConfig(): NAN:" + value);
+ return;
+ }
+ }
synchronized (mLock) {
mSupportedSmartSuggestionModes = flags;
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
index 39d5c9d0b777..86ad52d9a42b 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
@@ -77,15 +77,12 @@ public final class ContentCaptureManagerServiceShellCommand extends ShellCommand
pw.println(" Temporarily (for DURATION ms) changes the service implemtation.");
pw.println(" To reset, call with just the USER_ID argument.");
pw.println("");
- pw.println("");
pw.println(" set default-service-enabled USER_ID [true|false]");
pw.println(" Enable / disable the default service for the user.");
pw.println("");
- pw.println("");
pw.println(" get default-service-enabled USER_ID");
pw.println(" Checks whether the default service is enabled for the user.");
pw.println("");
- pw.println("");
pw.println(" list sessions [--user USER_ID]");
pw.println(" Lists all pending sessions.");
pw.println("");
diff --git a/services/core/java/com/android/server/AlarmManagerInternal.java b/services/core/java/com/android/server/AlarmManagerInternal.java
index 275661084aa3..5b0de5e2aae0 100644
--- a/services/core/java/com/android/server/AlarmManagerInternal.java
+++ b/services/core/java/com/android/server/AlarmManagerInternal.java
@@ -26,6 +26,8 @@ public interface AlarmManagerInternal {
void broadcastAlarmComplete(int recipientUid);
}
+ /** Returns true if AlarmManager is delaying alarms due to device idle. */
+ boolean isIdling();
public void removeAlarmsForUid(int uid);
public void registerInFlightListener(InFlightListener callback);
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 10b532700d1b..a400cc384a58 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1991,6 +1991,11 @@ class AlarmManagerService extends SystemService {
*/
private final class LocalService implements AlarmManagerInternal {
@Override
+ public boolean isIdling() {
+ return isIdlingImpl();
+ }
+
+ @Override
public void removeAlarmsForUid(int uid) {
synchronized (mLock) {
removeLocked(uid);
@@ -2823,6 +2828,12 @@ class AlarmManagerService extends SystemService {
}
}
+ private boolean isIdlingImpl() {
+ synchronized (mLock) {
+ return mPendingIdleUntil != null;
+ }
+ }
+
AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) {
synchronized (mLock) {
return mNextAlarmClockForUser.get(userId);
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index eafa0e2a6786..e51025943df4 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -121,6 +121,8 @@ public class BinderCallsStatsService extends Binder {
private static final String SETTINGS_DETAILED_TRACKING_KEY = "detailed_tracking";
private static final String SETTINGS_UPLOAD_DATA_KEY = "upload_data";
private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval";
+ private static final String SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY = "track_screen_state";
+ private static final String SETTINGS_TRACK_DIRECT_CALLING_UID_KEY = "track_calling_uid";
private static final String SETTINGS_MAX_CALL_STATS_KEY = "max_call_stats_count";
private boolean mEnabled;
@@ -169,6 +171,12 @@ public class BinderCallsStatsService extends Binder {
mBinderCallsStats.setMaxBinderCallStats(mParser.getInt(
SETTINGS_MAX_CALL_STATS_KEY,
BinderCallsStats.MAX_BINDER_CALL_STATS_COUNT_DEFAULT));
+ mBinderCallsStats.setTrackScreenInteractive(
+ mParser.getBoolean(SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY,
+ BinderCallsStats.DEFAULT_TRACK_SCREEN_INTERACTIVE));
+ mBinderCallsStats.setTrackDirectCallerUid(
+ mParser.getBoolean(SETTINGS_TRACK_DIRECT_CALLING_UID_KEY,
+ BinderCallsStats.DEFAULT_TRACK_DIRECT_CALLING_UID));
final boolean enabled =
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 39030aaf3eb4..6b663941f8fb 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -271,6 +271,7 @@ public class DeviceIdleController extends SystemService
private static final int EVENT_BUFFER_SIZE = 100;
private AlarmManager mAlarmManager;
+ private AlarmManagerInternal mLocalAlarmManager;
private IBatteryStats mBatteryStats;
private ActivityManagerInternal mLocalActivityManager;
private ActivityTaskManagerInternal mLocalActivityTaskManager;
@@ -616,7 +617,8 @@ public class DeviceIdleController extends SystemService
}
};
- private final AlarmManager.OnAlarmListener mDeepAlarmListener
+ @VisibleForTesting
+ final AlarmManager.OnAlarmListener mDeepAlarmListener
= new AlarmManager.OnAlarmListener() {
@Override
public void onAlarm() {
@@ -1874,6 +1876,7 @@ public class DeviceIdleController extends SystemService
if (phase == PHASE_SYSTEM_SERVICES_READY) {
synchronized (this) {
mAlarmManager = mInjector.getAlarmManager();
+ mLocalAlarmManager = getLocalService(AlarmManagerInternal.class);
mBatteryStats = BatteryStatsService.getService();
mLocalActivityManager = getLocalService(ActivityManagerInternal.class);
mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class);
@@ -2605,6 +2608,16 @@ public class DeviceIdleController extends SystemService
// next natural time to come out of it.
}
+
+ /** Returns true if the screen is locked. */
+ @VisibleForTesting
+ boolean isKeyguardShowing() {
+ synchronized (this) {
+ return mScreenLocked;
+ }
+ }
+
+ @VisibleForTesting
void keyguardShowingLocked(boolean showing) {
if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing);
if (mScreenLocked != showing) {
@@ -2616,25 +2629,38 @@ public class DeviceIdleController extends SystemService
}
}
+ @VisibleForTesting
void scheduleReportActiveLocked(String activeReason, int activeUid) {
Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason);
mHandler.sendMessage(msg);
}
void becomeActiveLocked(String activeReason, int activeUid) {
- if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
+ becomeActiveLocked(activeReason, activeUid, mConstants.INACTIVE_TIMEOUT, true);
+ }
+
+ private void becomeActiveLocked(String activeReason, int activeUid,
+ long newInactiveTimeout, boolean changeLightIdle) {
+ if (DEBUG) {
+ Slog.i(TAG, "becomeActiveLocked, reason=" + activeReason
+ + ", changeLightIdle=" + changeLightIdle);
+ }
if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
- EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
- scheduleReportActiveLocked(activeReason, activeUid);
mState = STATE_ACTIVE;
- mLightState = LIGHT_STATE_ACTIVE;
- mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
+ mInactiveTimeout = newInactiveTimeout;
mCurIdleBudget = 0;
mMaintenanceStartTime = 0;
resetIdleManagementLocked();
- resetLightIdleManagementLocked();
- addEvent(EVENT_NORMAL, activeReason);
+
+ if (changeLightIdle) {
+ EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
+ mLightState = LIGHT_STATE_ACTIVE;
+ resetLightIdleManagementLocked();
+ // Only report active if light is also ACTIVE.
+ scheduleReportActiveLocked(activeReason, activeUid);
+ addEvent(EVENT_NORMAL, activeReason);
+ }
}
}
@@ -2654,50 +2680,82 @@ public class DeviceIdleController extends SystemService
}
}
+ /** Sanity check to make sure DeviceIdleController and AlarmManager are on the same page. */
+ private void verifyAlarmStateLocked() {
+ if (mState == STATE_ACTIVE && mNextAlarmTime != 0) {
+ Slog.wtf(TAG, "mState=ACTIVE but mNextAlarmTime=" + mNextAlarmTime);
+ }
+ if (mState != STATE_IDLE && mLocalAlarmManager.isIdling()) {
+ Slog.wtf(TAG, "mState=" + stateToString(mState) + " but AlarmManager is idling");
+ }
+ if (mState == STATE_IDLE && !mLocalAlarmManager.isIdling()) {
+ Slog.wtf(TAG, "mState=IDLE but AlarmManager is not idling");
+ }
+ if (mLightState == LIGHT_STATE_ACTIVE && mNextLightAlarmTime != 0) {
+ Slog.wtf(TAG, "mLightState=ACTIVE but mNextLightAlarmTime is "
+ + TimeUtils.formatDuration(mNextLightAlarmTime - SystemClock.elapsedRealtime())
+ + " from now");
+ }
+ }
+
void becomeInactiveIfAppropriateLocked() {
- if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
- if ((!mScreenOn && !mCharging) || mForceIdle) {
- // Become inactive and determine if we will ultimately go idle.
- if (mDeepEnabled) {
- if (mQuickDozeActivated) {
- if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
- || mState == STATE_IDLE_MAINTENANCE) {
- // Already "idling". Don't want to restart the process.
- // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3
- // values, so returning here is safe.
- return;
- }
- if (DEBUG) {
- Slog.d(TAG, "Moved from "
- + stateToString(mState) + " to STATE_QUICK_DOZE_DELAY");
- }
- mState = STATE_QUICK_DOZE_DELAY;
- // Make sure any motion sensing or locating is stopped.
- resetIdleManagementLocked();
- // Wait a small amount of time in case something (eg: background service from
- // recently closed app) needs to finish running.
- scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
- EventLogTags.writeDeviceIdle(mState, "no activity");
- } else if (mState == STATE_ACTIVE) {
- mState = STATE_INACTIVE;
- if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
- resetIdleManagementLocked();
- long delay = mInactiveTimeout;
- if (shouldUseIdleTimeoutFactorLocked()) {
- delay = (long) (mPreIdleFactor * delay);
- }
- scheduleAlarmLocked(delay, false);
- EventLogTags.writeDeviceIdle(mState, "no activity");
+ verifyAlarmStateLocked();
+
+ final boolean isScreenBlockingInactive =
+ mScreenOn && (!mConstants.WAIT_FOR_UNLOCK || !mScreenLocked);
+ if (DEBUG) {
+ Slog.d(TAG, "becomeInactiveIfAppropriateLocked():"
+ + " isScreenBlockingInactive=" + isScreenBlockingInactive
+ + " (mScreenOn=" + mScreenOn
+ + ", WAIT_FOR_UNLOCK=" + mConstants.WAIT_FOR_UNLOCK
+ + ", mScreenLocked=" + mScreenLocked + ")"
+ + " mCharging=" + mCharging
+ + " mForceIdle=" + mForceIdle
+ );
+ }
+ if (!mForceIdle && (mCharging || isScreenBlockingInactive)) {
+ return;
+ }
+ // Become inactive and determine if we will ultimately go idle.
+ if (mDeepEnabled) {
+ if (mQuickDozeActivated) {
+ if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
+ || mState == STATE_IDLE_MAINTENANCE) {
+ // Already "idling". Don't want to restart the process.
+ // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3
+ // values, so returning here is safe.
+ return;
}
- }
- if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
- mLightState = LIGHT_STATE_INACTIVE;
- if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
- resetLightIdleManagementLocked();
- scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
- EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
+ if (DEBUG) {
+ Slog.d(TAG, "Moved from "
+ + stateToString(mState) + " to STATE_QUICK_DOZE_DELAY");
+ }
+ mState = STATE_QUICK_DOZE_DELAY;
+ // Make sure any motion sensing or locating is stopped.
+ resetIdleManagementLocked();
+ // Wait a small amount of time in case something (eg: background service from
+ // recently closed app) needs to finish running.
+ scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
+ EventLogTags.writeDeviceIdle(mState, "no activity");
+ } else if (mState == STATE_ACTIVE) {
+ mState = STATE_INACTIVE;
+ if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
+ resetIdleManagementLocked();
+ long delay = mInactiveTimeout;
+ if (shouldUseIdleTimeoutFactorLocked()) {
+ delay = (long) (mPreIdleFactor * delay);
+ }
+ scheduleAlarmLocked(delay, false);
+ EventLogTags.writeDeviceIdle(mState, "no activity");
}
}
+ if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
+ mLightState = LIGHT_STATE_INACTIVE;
+ if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
+ resetLightIdleManagementLocked();
+ scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
+ EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
+ }
}
private void resetIdleManagementLocked() {
@@ -3216,33 +3274,10 @@ public class DeviceIdleController extends SystemService
// The device is not yet active, so we want to go back to the pending idle
// state to wait again for no motion. Note that we only monitor for motion
// after moving out of the inactive state, so no need to worry about that.
- boolean becomeInactive = false;
- if (mState != STATE_ACTIVE) {
- // Motion shouldn't affect light state, if it's already in doze-light or maintenance
- boolean lightIdle = mLightState == LIGHT_STATE_IDLE
- || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK
- || mLightState == LIGHT_STATE_IDLE_MAINTENANCE;
- if (!lightIdle) {
- // Only switch to active state if we're not in either idle state
- scheduleReportActiveLocked(type, Process.myUid());
- addEvent(EVENT_NORMAL, type);
- }
- mActiveReason = ACTIVE_REASON_MOTION;
- mState = STATE_ACTIVE;
- mInactiveTimeout = timeout;
- mCurIdleBudget = 0;
- mMaintenanceStartTime = 0;
- EventLogTags.writeDeviceIdle(mState, type);
- becomeInactive = true;
- updateActiveConstraintsLocked();
- }
- if (mLightState == LIGHT_STATE_OVERRIDE) {
- // We went out of light idle mode because we had started deep idle mode... let's
- // now go back and reset things so we resume light idling if appropriate.
- mLightState = LIGHT_STATE_ACTIVE;
- EventLogTags.writeDeviceIdleLight(mLightState, type);
- becomeInactive = true;
- }
+ final boolean becomeInactive = mState != STATE_ACTIVE
+ || mLightState == LIGHT_STATE_OVERRIDE;
+ // We only want to change the IDLE state if it's OVERRIDE.
+ becomeActiveLocked(type, Process.myUid(), timeout, mLightState == LIGHT_STATE_OVERRIDE);
if (becomeInactive) {
becomeInactiveIfAppropriateLocked();
}
diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java
index 9184128d466f..c334540f48cc 100644
--- a/services/core/java/com/android/server/LooperStatsService.java
+++ b/services/core/java/com/android/server/LooperStatsService.java
@@ -51,16 +51,19 @@ public class LooperStatsService extends Binder {
private static final String LOOPER_STATS_SERVICE_NAME = "looper_stats";
private static final String SETTINGS_ENABLED_KEY = "enabled";
private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval";
+ private static final String SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY = "track_screen_state";
private static final String DEBUG_SYS_LOOPER_STATS_ENABLED =
"debug.sys.looper_stats_enabled";
private static final int DEFAULT_SAMPLING_INTERVAL = 100;
private static final int DEFAULT_ENTRIES_SIZE_CAP = 2000;
private static final boolean DEFAULT_ENABLED = true;
+ private static final boolean DEFAULT_TRACK_SCREEN_INTERACTIVE = false;
private final Context mContext;
private final LooperStats mStats;
// Default should be false so that the first call to #setEnabled installed the looper observer.
private boolean mEnabled = false;
+ private boolean mTrackScreenInteractive = false;
private LooperStatsService(Context context, LooperStats stats) {
this.mContext = context;
@@ -79,6 +82,9 @@ public class LooperStatsService extends Binder {
setSamplingInterval(
parser.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, DEFAULT_SAMPLING_INTERVAL));
+ setTrackScreenInteractive(
+ parser.getBoolean(SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY,
+ DEFAULT_TRACK_SCREEN_INTERACTIVE));
// Manually specified value takes precedence over Settings.
setEnabled(SystemProperties.getBoolean(
DEBUG_SYS_LOOPER_STATS_ENABLED,
@@ -155,6 +161,13 @@ public class LooperStatsService extends Binder {
}
}
+ private void setTrackScreenInteractive(boolean enabled) {
+ if (mTrackScreenInteractive != enabled) {
+ mTrackScreenInteractive = enabled;
+ mStats.reset();
+ }
+ }
+
private void setSamplingInterval(int samplingInterval) {
if (samplingInterval > 0) {
mStats.setSamplingInterval(samplingInterval);
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index eaf790bb05c4..8ccb6e20a614 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -328,6 +328,9 @@ public class AdbDebuggingManager {
mConnectedKey = key;
mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis());
scheduleJobToUpdateAdbKeyStore();
+ // write this key to adb_keys as well so that subsequent connections can
+ // go through the expected SIGNATURE interaction.
+ writeKey(key);
}
logAdbConnectionChanged(key, AdbProtoEnums.USER_ALLOWED, alwaysAllow);
}
@@ -360,20 +363,9 @@ public class AdbDebuggingManager {
}
break;
}
- // Check if the key should be allowed without user interaction.
- if (mAdbKeyStore.isKeyAuthorized(key)) {
- if (mThread != null) {
- mThread.sendResponse("OK");
- mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis());
- logAdbConnectionChanged(key, AdbProtoEnums.AUTOMATICALLY_ALLOWED, true);
- mConnectedKey = key;
- scheduleJobToUpdateAdbKeyStore();
- }
- } else {
- logAdbConnectionChanged(key, AdbProtoEnums.AWAITING_USER_APPROVAL, false);
- mFingerprints = fingerprints;
- startConfirmation(key, mFingerprints);
- }
+ logAdbConnectionChanged(key, AdbProtoEnums.AWAITING_USER_APPROVAL, false);
+ mFingerprints = fingerprints;
+ startConfirmation(key, mFingerprints);
break;
}
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index 9cb6eeec2126..45f169ca0b6f 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -387,8 +387,10 @@ public final class ColorDisplayService extends SystemService {
Slog.d(TAG, "Setting saturation level: " + saturationLevel);
if (saturationLevel == 100) {
+ setActivated(false);
Matrix.setIdentityM(mMatrixGlobalSaturation, 0);
} else {
+ setActivated(true);
float saturation = saturationLevel * 0.1f;
float desaturation = 1.0f - saturation;
float[] luminance = {0.231f * desaturation, 0.715f * desaturation,
@@ -556,14 +558,16 @@ public final class ColorDisplayService extends SystemService {
if (setting != null) {
switch (setting) {
case Secure.NIGHT_DISPLAY_ACTIVATED:
- final boolean activated = isNightDisplayActivatedSetting();
+ final boolean activated = mNightDisplayTintController
+ .isActivatedSetting();
if (mNightDisplayTintController.isActivatedStateNotSet()
|| mNightDisplayTintController.isActivated() != activated) {
- mNightDisplayTintController.onActivated(activated);
+ mNightDisplayTintController.setActivated(activated);
}
break;
case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
- final int temperature = getNightDisplayColorTemperatureSetting();
+ final int temperature = mNightDisplayTintController
+ .getColorTemperatureSetting();
if (mNightDisplayTintController.getColorTemperature()
!= temperature) {
mNightDisplayTintController
@@ -639,14 +643,16 @@ public final class ColorDisplayService extends SystemService {
// Prepare the night display color transformation matrix.
mNightDisplayTintController
.setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix());
- mNightDisplayTintController.setMatrix(getNightDisplayColorTemperatureSetting());
+ mNightDisplayTintController
+ .setMatrix(mNightDisplayTintController.getColorTemperatureSetting());
// Initialize the current auto mode.
onNightDisplayAutoModeChanged(getNightDisplayAutoModeInternal());
// Force the initialization of the current saved activation state.
if (mNightDisplayTintController.isActivatedStateNotSet()) {
- mNightDisplayTintController.onActivated(isNightDisplayActivatedSetting());
+ mNightDisplayTintController
+ .setActivated(mNightDisplayTintController.isActivatedSetting());
}
}
@@ -674,6 +680,10 @@ public final class ColorDisplayService extends SystemService {
if (mDisplayWhiteBalanceTintController.isAvailable(getContext())) {
mDisplayWhiteBalanceTintController.endAnimator();
}
+
+ if (mGlobalSaturationTintController.isAvailable(getContext())) {
+ mGlobalSaturationTintController.setActivated(null);
+ }
}
private void onNightDisplayAutoModeChanged(int autoMode) {
@@ -722,7 +732,8 @@ public final class ColorDisplayService extends SystemService {
if (mNightDisplayTintController.isAvailable(getContext())) {
mNightDisplayTintController
.setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode));
- mNightDisplayTintController.setMatrix(getNightDisplayColorTemperatureSetting());
+ mNightDisplayTintController
+ .setMatrix(mNightDisplayTintController.getColorTemperatureSetting());
}
updateDisplayWhiteBalanceStatus();
@@ -1040,8 +1051,7 @@ public final class ColorDisplayService extends SystemService {
*
* See {@link com.android.server.display.DisplayTransformManager}
*/
- private @ColorMode
- int getCurrentColorModeFromSystemProperties() {
+ private @ColorMode int getCurrentColorModeFromSystemProperties() {
final int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0);
if (displayColorSetting == 0) {
return "1.0".equals(SystemProperties.get("persist.sys.sf.color_saturation"))
@@ -1098,33 +1108,6 @@ public final class ColorDisplayService extends SystemService {
pw.println("Color mode: " + getColorModeInternal());
}
- private boolean isNightDisplayActivatedSetting() {
- return Secure.getIntForUser(getContext().getContentResolver(),
- Secure.NIGHT_DISPLAY_ACTIVATED, 0, mCurrentUser) == 1;
- }
-
- private int getNightDisplayColorTemperatureSetting() {
- return clampNightDisplayColorTemperature(Secure.getIntForUser(
- getContext().getContentResolver(), Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, NOT_SET,
- mCurrentUser));
- }
-
- private int clampNightDisplayColorTemperature(int colorTemperature) {
- if (colorTemperature == NOT_SET) {
- colorTemperature = getContext().getResources().getInteger(
- R.integer.config_nightDisplayColorTemperatureDefault);
- }
- final int minimumTemperature = ColorDisplayManager.getMinimumColorTemperature(getContext());
- final int maximumTemperature = ColorDisplayManager.getMaximumColorTemperature(getContext());
- if (colorTemperature < minimumTemperature) {
- colorTemperature = minimumTemperature;
- } else if (colorTemperature > maximumTemperature) {
- colorTemperature = maximumTemperature;
- }
-
- return colorTemperature;
- }
-
private abstract class NightDisplayAutoMode {
public abstract void onActivated(boolean activated);
@@ -1171,7 +1154,7 @@ public final class ColorDisplayService extends SystemService {
// Maintain the existing activated state if within the current period.
if (mLastActivatedTime.isBefore(now) && mLastActivatedTime.isAfter(start)
&& (mLastActivatedTime.isAfter(end) || now.isBefore(end))) {
- activate = isNightDisplayActivatedSetting();
+ activate = mNightDisplayTintController.isActivatedSetting();
}
}
@@ -1267,7 +1250,7 @@ public final class ColorDisplayService extends SystemService {
// Maintain the existing activated state if within the current period.
if (mLastActivatedTime.isBefore(now) && (mLastActivatedTime.isBefore(sunrise)
^ mLastActivatedTime.isBefore(sunset))) {
- activate = isNightDisplayActivatedSetting();
+ activate = mNightDisplayTintController.isActivatedSetting();
}
}
@@ -1466,9 +1449,11 @@ public final class ColorDisplayService extends SystemService {
if (isActivatedStateNotSet() || activationStateChanged) {
super.setActivated(activated);
- Secure.putIntForUser(getContext().getContentResolver(),
- Secure.NIGHT_DISPLAY_ACTIVATED,
- activated ? 1 : 0, mCurrentUser);
+ if (isActivatedSetting() != activated) {
+ Secure.putIntForUser(getContext().getContentResolver(),
+ Secure.NIGHT_DISPLAY_ACTIVATED,
+ activated ? 1 : 0, mCurrentUser);
+ }
onActivated(activated);
}
}
@@ -1486,7 +1471,7 @@ public final class ColorDisplayService extends SystemService {
return mIsAvailable;
}
- void onActivated(boolean activated) {
+ private void onActivated(boolean activated) {
Slog.i(TAG, activated ? "Turning on night display" : "Turning off night display");
if (mNightDisplayAutoMode != null) {
mNightDisplayAutoMode.onActivated(activated);
@@ -1501,7 +1486,7 @@ public final class ColorDisplayService extends SystemService {
int getColorTemperature() {
return mColorTemp != null ? clampNightDisplayColorTemperature(mColorTemp)
- : getNightDisplayColorTemperatureSetting();
+ : getColorTemperatureSetting();
}
boolean setColorTemperature(int temperature) {
@@ -1516,6 +1501,36 @@ public final class ColorDisplayService extends SystemService {
setMatrix(temperature);
mHandler.sendEmptyMessage(MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE);
}
+
+ boolean isActivatedSetting() {
+ return Secure.getIntForUser(getContext().getContentResolver(),
+ Secure.NIGHT_DISPLAY_ACTIVATED, 0, mCurrentUser) == 1;
+ }
+
+ int getColorTemperatureSetting() {
+ return clampNightDisplayColorTemperature(Secure.getIntForUser(
+ getContext().getContentResolver(), Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
+ NOT_SET,
+ mCurrentUser));
+ }
+
+ private int clampNightDisplayColorTemperature(int colorTemperature) {
+ if (colorTemperature == NOT_SET) {
+ colorTemperature = getContext().getResources().getInteger(
+ R.integer.config_nightDisplayColorTemperatureDefault);
+ }
+ final int minimumTemperature = ColorDisplayManager
+ .getMinimumColorTemperature(getContext());
+ final int maximumTemperature = ColorDisplayManager
+ .getMaximumColorTemperature(getContext());
+ if (colorTemperature < minimumTemperature) {
+ colorTemperature = minimumTemperature;
+ } else if (colorTemperature > maximumTemperature) {
+ colorTemperature = maximumTemperature;
+ }
+
+ return colorTemperature;
+ }
}
/**
@@ -1671,6 +1686,20 @@ public final class ColorDisplayService extends SystemService {
}
@Override
+ public boolean isSaturationActivated() {
+ getContext().enforceCallingPermission(
+ Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
+ "Permission required to get display saturation level");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return !mGlobalSaturationTintController.isActivatedStateNotSet()
+ && mGlobalSaturationTintController.isActivated();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
public boolean setAppSaturationLevel(String packageName, int level) {
getContext().enforceCallingPermission(
Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
diff --git a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
index cf84e22e7dd1..1b237949a543 100644
--- a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
@@ -187,7 +187,7 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
@Override
public boolean isDefaultServiceEnabled(int userId) {
synchronized (mLock) {
- return mDefaultServicesDisabled.get(userId);
+ return !mDefaultServicesDisabled.get(userId);
}
}
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 18e292feba30..7e4365dafbe4 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -119,6 +119,7 @@ public class UserRestrictionsUtils {
UserManager.DISALLOW_OEM_UNLOCK,
UserManager.DISALLOW_UNMUTE_DEVICE,
UserManager.DISALLOW_AUTOFILL,
+ UserManager.DISALLOW_CONTENT_CAPTURE,
UserManager.DISALLOW_USER_SWITCH,
UserManager.DISALLOW_UNIFIED_PASSWORD,
UserManager.DISALLOW_CONFIG_LOCATION,
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 5ea24518370b..35b8641371be 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -251,7 +251,7 @@ class SurfaceAnimator {
if (DEBUG_ANIM) Slog.i(TAG, "Cancelling animation restarting=" + restarting);
final SurfaceControl leash = mLeash;
final AnimationAdapter animation = mAnimation;
- reset(t, forwardCancel);
+ reset(t, false);
if (animation != null) {
if (!mAnimationStartDelayed && forwardCancel) {
animation.onAnimationCancelled(leash);
@@ -260,6 +260,12 @@ class SurfaceAnimator {
mAnimationFinishedCallback.run();
}
}
+
+ if (forwardCancel && leash != null) {
+ t.remove(leash);
+ mService.scheduleAnimationLocked();
+ }
+
if (!restarting) {
mAnimationStartDelayed = false;
}
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 69f0012b69ba..4aca9c8a1520 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -119,6 +119,7 @@ import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import android.view.Display;
import android.view.DisplayInfo;
import com.android.internal.annotations.VisibleForTesting;
@@ -2332,6 +2333,7 @@ class TaskRecord extends ConfigurationContainer {
info.userId = userId;
info.stackId = getStackId();
info.taskId = taskId;
+ info.displayId = mStack == null ? Display.INVALID_DISPLAY : mStack.mDisplayId;
info.isRunning = getTopActivity() != null;
info.baseIntent = new Intent(getBaseIntent());
info.baseActivity = reuseActivitiesReport.base != null
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 53d72bb9a415..e51ee947cba1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -19,6 +19,7 @@ import static androidx.test.InstrumentationRegistry.getContext;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -51,6 +52,9 @@ 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.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
@@ -82,6 +86,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
@@ -105,6 +110,8 @@ public class DeviceIdleControllerTest {
@Mock
private ContentResolver mContentResolver;
@Mock
+ private DeviceIdleController.MyHandler mHandler;
+ @Mock
private IActivityManager mIActivityManager;
@Mock
private LocationManager mLocationManager;
@@ -154,7 +161,7 @@ public class DeviceIdleControllerTest {
@Override
DeviceIdleController.MyHandler getHandler(DeviceIdleController controller) {
- return mock(DeviceIdleController.MyHandler.class, Answers.RETURNS_DEEP_STUBS);
+ return mHandler;
}
@Override
@@ -232,10 +239,12 @@ public class DeviceIdleControllerTest {
.when(() -> LocalServices.getService(ActivityManagerInternal.class));
doReturn(mock(ActivityTaskManagerInternal.class))
.when(() -> LocalServices.getService(ActivityTaskManagerInternal.class));
+ doReturn(mock(AlarmManagerInternal.class))
+ .when(() -> LocalServices.getService(AlarmManagerInternal.class));
doReturn(mPowerManagerInternal)
.when(() -> LocalServices.getService(PowerManagerInternal.class));
- when(mPowerManagerInternal.getLowPowerState(anyInt())).thenReturn(
- mock(PowerSaveState.class));
+ when(mPowerManagerInternal.getLowPowerState(anyInt()))
+ .thenReturn(mock(PowerSaveState.class));
doReturn(mock(NetworkPolicyManagerInternal.class))
.when(() -> LocalServices.getService(NetworkPolicyManagerInternal.class));
when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
@@ -246,8 +255,11 @@ public class DeviceIdleControllerTest {
doReturn(true).when(mSensorManager).registerListener(any(), any(), anyInt());
mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
mAnyMotionDetector = new AnyMotionDetectorForTest();
+ mHandler = mock(DeviceIdleController.MyHandler.class, Answers.RETURNS_DEEP_STUBS);
+ doNothing().when(mHandler).handleMessage(any());
mInjector = new InjectorForTest(getContext());
doNothing().when(mContentResolver).registerContentObserver(any(), anyBoolean(), any());
+
mDeviceIdleController = new DeviceIdleController(getContext(), mInjector);
spyOn(mDeviceIdleController);
doNothing().when(mDeviceIdleController).publishBinderService(any(), any());
@@ -423,6 +435,29 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
verifyStateConditions(STATE_ACTIVE);
+
+ mConstants.WAIT_FOR_UNLOCK = false;
+ setScreenLocked(true);
+ setScreenOn(true);
+ setChargingOn(false);
+
+ mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+ verifyStateConditions(STATE_ACTIVE);
+
+ setScreenLocked(false);
+ setScreenOn(true);
+ setChargingOn(false);
+
+ mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+ verifyStateConditions(STATE_ACTIVE);
+
+ mConstants.WAIT_FOR_UNLOCK = true;
+ setScreenLocked(false);
+ setScreenOn(true);
+ setChargingOn(false);
+
+ mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+ verifyStateConditions(STATE_ACTIVE);
}
@Test
@@ -1307,7 +1342,7 @@ public class DeviceIdleControllerTest {
}
@Test
- public void testbecomeActiveLocked_deep() {
+ public void testBecomeActiveLocked_deep() {
// becomeActiveLocked should put everything into ACTIVE.
enterDeepState(STATE_ACTIVE);
@@ -1344,7 +1379,7 @@ public class DeviceIdleControllerTest {
}
@Test
- public void testbecomeActiveLocked_light() {
+ public void testBecomeActiveLocked_light() {
// becomeActiveLocked should put everything into ACTIVE.
enterLightState(LIGHT_STATE_ACTIVE);
@@ -1376,6 +1411,163 @@ public class DeviceIdleControllerTest {
verifyLightStateConditions(LIGHT_STATE_ACTIVE);
}
+ /** Test based on b/119058625. */
+ @Test
+ public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_ScreenThenMotion() {
+ mConstants.WAIT_FOR_UNLOCK = true;
+ enterDeepState(STATE_IDLE);
+ reset(mAlarmManager);
+ spyOn(mDeviceIdleController);
+
+ mDeviceIdleController.keyguardShowingLocked(true);
+ setScreenOn(true);
+ // With WAIT_FOR_UNLOCK = true and the screen locked, turning the screen on by itself
+ // shouldn't bring the device out of deep IDLE.
+ verifyStateConditions(STATE_IDLE);
+ mDeviceIdleController.handleMotionDetectedLocked(1000, "test");
+ // Motion should bring the device out of Doze. Since the screen is still locked (albeit
+ // on), the states should go back into INACTIVE.
+ verifyStateConditions(STATE_INACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+ verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt());
+ }
+
+ /** Test based on b/119058625. */
+ @Test
+ public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_ScreenThenMotion() {
+ mConstants.WAIT_FOR_UNLOCK = true;
+ enterDeepState(STATE_IDLE);
+ reset(mAlarmManager);
+ spyOn(mDeviceIdleController);
+
+ mDeviceIdleController.keyguardShowingLocked(false);
+ setScreenOn(true);
+ // With WAIT_FOR_UNLOCK = true and the screen unlocked, turning the screen on by itself
+ // should bring the device out of deep IDLE.
+ verifyStateConditions(STATE_ACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+ verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt());
+ }
+
+ /** Test based on b/119058625. */
+ @Test
+ public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_MotionThenScreen() {
+ mConstants.WAIT_FOR_UNLOCK = true;
+ enterDeepState(STATE_IDLE);
+ reset(mAlarmManager);
+ spyOn(mDeviceIdleController);
+
+ InOrder alarmManagerInOrder = inOrder(mAlarmManager);
+ InOrder controllerInOrder = inOrder(mDeviceIdleController);
+
+ mDeviceIdleController.keyguardShowingLocked(true);
+ mDeviceIdleController.handleMotionDetectedLocked(1000, "test");
+ // The screen is still off, so motion should result in the INACTIVE state.
+ verifyStateConditions(STATE_INACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+ alarmManagerInOrder.verify(mAlarmManager)
+ .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ controllerInOrder.verify(mDeviceIdleController)
+ .scheduleReportActiveLocked(anyString(), anyInt());
+
+ setScreenOn(true);
+ // With WAIT_FOR_UNLOCK = true and the screen locked, turning the screen on by itself
+ // shouldn't bring the device all the way to ACTIVE.
+ verifyStateConditions(STATE_INACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+ alarmManagerInOrder.verify(mAlarmManager, never()).cancel(
+ eq(mDeviceIdleController.mDeepAlarmListener));
+
+ // User finally unlocks the device. Device should be fully active.
+ mDeviceIdleController.keyguardShowingLocked(false);
+ verifyStateConditions(STATE_ACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+ alarmManagerInOrder.verify(mAlarmManager)
+ .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ controllerInOrder.verify(mDeviceIdleController)
+ .scheduleReportActiveLocked(anyString(), anyInt());
+ }
+
+ /** Test based on b/119058625. */
+ @Test
+ public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_MotionThenScreen() {
+ mConstants.WAIT_FOR_UNLOCK = true;
+ enterDeepState(STATE_IDLE);
+ reset(mAlarmManager);
+ spyOn(mDeviceIdleController);
+
+ InOrder alarmManagerInOrder = inOrder(mAlarmManager);
+ InOrder controllerInOrder = inOrder(mDeviceIdleController);
+
+ mDeviceIdleController.keyguardShowingLocked(false);
+ mDeviceIdleController.handleMotionDetectedLocked(1000, "test");
+ // The screen is still off, so motion should result in the INACTIVE state.
+ verifyStateConditions(STATE_INACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+ alarmManagerInOrder.verify(mAlarmManager)
+ .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ controllerInOrder.verify(mDeviceIdleController)
+ .scheduleReportActiveLocked(anyString(), anyInt());
+
+ setScreenOn(true);
+ // With WAIT_FOR_UNLOCK = true and the screen unlocked, turning the screen on by itself
+ // should bring the device out of deep IDLE.
+ verifyStateConditions(STATE_ACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+ alarmManagerInOrder.verify(mAlarmManager)
+ .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ controllerInOrder.verify(mDeviceIdleController)
+ .scheduleReportActiveLocked(anyString(), anyInt());
+ }
+
+ @Test
+ public void testExitNotifiesDependencies_WaitForUnlockOff_Screen() {
+ mConstants.WAIT_FOR_UNLOCK = false;
+ enterDeepState(STATE_IDLE);
+ reset(mAlarmManager);
+ spyOn(mDeviceIdleController);
+
+ setScreenOn(true);
+ // With WAIT_FOR_UNLOCK = false and the screen locked, turning the screen on by itself
+ // should bring the device out of deep IDLE.
+ verifyStateConditions(STATE_ACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+ verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt());
+ }
+
+ @Test
+ public void testExitNotifiesDependencies_WaitForUnlockOff_MotionThenScreen() {
+ mConstants.WAIT_FOR_UNLOCK = false;
+ enterDeepState(STATE_IDLE);
+ reset(mAlarmManager);
+ spyOn(mDeviceIdleController);
+
+ InOrder alarmManagerInOrder = inOrder(mAlarmManager);
+ InOrder controllerInOrder = inOrder(mDeviceIdleController);
+
+ mDeviceIdleController.handleMotionDetectedLocked(1000, "test");
+ // The screen is still off, so motion should result in the INACTIVE state.
+ verifyStateConditions(STATE_INACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+ alarmManagerInOrder.verify(mAlarmManager)
+ .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ controllerInOrder.verify(mDeviceIdleController)
+ .scheduleReportActiveLocked(anyString(), anyInt());
+
+ setScreenOn(true);
+ // With WAIT_FOR_UNLOCK = false and the screen locked, turning the screen on by itself
+ // should bring the device out of deep IDLE.
+ verifyStateConditions(STATE_ACTIVE);
+ verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+ alarmManagerInOrder.verify(mAlarmManager)
+ .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
+ controllerInOrder.verify(mDeviceIdleController)
+ .scheduleReportActiveLocked(anyString(), anyInt());
+ }
+
@Test
public void testStepToIdleMode() {
float delta = mDeviceIdleController.MIN_PRE_IDLE_FACTOR_CHANGE;
@@ -1508,6 +1700,10 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.updateChargingLocked(on);
}
+ private void setScreenLocked(boolean locked) {
+ mDeviceIdleController.keyguardShowingLocked(locked);
+ }
+
private void setScreenOn(boolean on) {
doReturn(on).when(mPowerManager).isInteractive();
mDeviceIdleController.updateInteractivityLocked();
@@ -1549,7 +1745,8 @@ public class DeviceIdleControllerTest {
assertFalse(mDeviceIdleController.mMotionListener.isActive());
assertFalse(mAnyMotionDetector.isMonitoring);
assertFalse(mDeviceIdleController.isCharging());
- assertFalse(mDeviceIdleController.isScreenOn());
+ assertFalse(mDeviceIdleController.isScreenOn()
+ && !mDeviceIdleController.isKeyguardShowing());
break;
case STATE_IDLE_PENDING:
assertEquals(
@@ -1557,7 +1754,8 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.mMotionListener.isActive());
assertFalse(mAnyMotionDetector.isMonitoring);
assertFalse(mDeviceIdleController.isCharging());
- assertFalse(mDeviceIdleController.isScreenOn());
+ assertFalse(mDeviceIdleController.isScreenOn()
+ && !mDeviceIdleController.isKeyguardShowing());
break;
case STATE_SENSING:
assertEquals(
@@ -1567,14 +1765,16 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.hasMotionSensor(),
mAnyMotionDetector.isMonitoring);
assertFalse(mDeviceIdleController.isCharging());
- assertFalse(mDeviceIdleController.isScreenOn());
+ assertFalse(mDeviceIdleController.isScreenOn()
+ && !mDeviceIdleController.isKeyguardShowing());
break;
case STATE_LOCATING:
assertEquals(
mDeviceIdleController.hasMotionSensor(),
mDeviceIdleController.mMotionListener.isActive());
assertFalse(mDeviceIdleController.isCharging());
- assertFalse(mDeviceIdleController.isScreenOn());
+ assertFalse(mDeviceIdleController.isScreenOn()
+ && !mDeviceIdleController.isKeyguardShowing());
break;
case STATE_IDLE:
if (mDeviceIdleController.hasMotionSensor()) {
@@ -1584,7 +1784,8 @@ public class DeviceIdleControllerTest {
}
assertFalse(mAnyMotionDetector.isMonitoring);
assertFalse(mDeviceIdleController.isCharging());
- assertFalse(mDeviceIdleController.isScreenOn());
+ assertFalse(mDeviceIdleController.isScreenOn()
+ && !mDeviceIdleController.isKeyguardShowing());
// Light state should be OVERRIDE at this point.
verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
break;
@@ -1596,14 +1797,16 @@ public class DeviceIdleControllerTest {
}
assertFalse(mAnyMotionDetector.isMonitoring);
assertFalse(mDeviceIdleController.isCharging());
- assertFalse(mDeviceIdleController.isScreenOn());
+ assertFalse(mDeviceIdleController.isScreenOn()
+ && !mDeviceIdleController.isKeyguardShowing());
break;
case STATE_QUICK_DOZE_DELAY:
// If quick doze is enabled, the motion listener should NOT be active.
assertFalse(mDeviceIdleController.mMotionListener.isActive());
assertFalse(mAnyMotionDetector.isMonitoring);
assertFalse(mDeviceIdleController.isCharging());
- assertFalse(mDeviceIdleController.isScreenOn());
+ assertFalse(mDeviceIdleController.isScreenOn()
+ && !mDeviceIdleController.isKeyguardShowing());
break;
default:
fail("Conditions for " + stateToString(expectedState) + " unknown.");
@@ -1632,7 +1835,8 @@ public class DeviceIdleControllerTest {
case LIGHT_STATE_IDLE_MAINTENANCE:
case LIGHT_STATE_OVERRIDE:
assertFalse(mDeviceIdleController.isCharging());
- assertFalse(mDeviceIdleController.isScreenOn());
+ assertFalse(mDeviceIdleController.isScreenOn()
+ && !mDeviceIdleController.isKeyguardShowing());
break;
default:
fail("Conditions for " + lightStateToString(expectedLightState) + " unknown.");
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
index 4e43d002d4ae..8caa39dfc9e7 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
@@ -1035,6 +1035,15 @@ public class AppTimeLimitControllerTests {
0L, group.getUsageRemaining());
}
+ /** Verify that a limit of 0 is allowed for the special case of re-registering an observer. */
+ @Test
+ public void testAppUsageLimitObserver_ZeroTimeLimitIsAllowed() {
+ addAppUsageLimitObserver(OBS_ID1, GROUP1, 0);
+ AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1);
+ assertNotNull("Observer wasn't added", group);
+ assertEquals("Usage remaining was not 0.", 0, group.getUsageRemaining());
+ }
+
private void startUsage(String packageName) {
mController.noteUsageStart(packageName, USER_ID);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index e27dd94b1a2c..21a4e8417bab 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -72,8 +72,10 @@ import com.android.server.am.PendingIntentController;
import com.android.server.appop.AppOpsService;
import com.android.server.firewall.IntentFirewall;
import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.wm.utils.MockTracker;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
@@ -88,6 +90,8 @@ import java.util.List;
class ActivityTestsBase {
private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
+ private static MockTracker sMockTracker;
+
@Rule
public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
new DexmakerShareClassLoaderRule();
@@ -107,9 +111,17 @@ class ActivityTestsBase {
@BeforeClass
public static void setUpOnceBase() {
+ sMockTracker = new MockTracker();
+
AttributeCache.init(getInstrumentation().getTargetContext());
}
+ @AfterClass
+ public static void tearDownOnceBase() {
+ sMockTracker.close();
+ sMockTracker = null;
+ }
+
@Before
public void setUpBase() {
mTestInjector.setUp();
@@ -657,12 +669,11 @@ class ActivityTestsBase {
private static WindowManagerService sMockWindowManagerService;
private static WindowManagerService prepareMockWindowManager() {
- if (sMockWindowManagerService != null) {
- return sMockWindowManagerService;
+ if (sMockWindowManagerService == null) {
+ sMockWindowManagerService = mock(WindowManagerService.class);
}
- final WindowManagerService service = mock(WindowManagerService.class);
- service.mRoot = mock(RootWindowContainer.class);
+ sMockWindowManagerService.mRoot = mock(RootWindowContainer.class);
doAnswer((InvocationOnMock invocationOnMock) -> {
final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
@@ -670,10 +681,9 @@ class ActivityTestsBase {
runnable.run();
}
return null;
- }).when(service).inSurfaceTransaction(any());
+ }).when(sMockWindowManagerService).inSurfaceTransaction(any());
- sMockWindowManagerService = service;
- return service;
+ return sMockWindowManagerService;
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 67ee4ad91d91..94def2bb7846 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -67,6 +67,7 @@ import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -142,7 +143,8 @@ public class RootActivityContainerTests extends ActivityTestsBase {
private static void ensureStackPlacement(ActivityStack stack, TaskRecord... tasks) {
final ArrayList<TaskRecord> stackTasks = stack.getAllTasks();
- assertEquals(stackTasks.size(), tasks != null ? tasks.length : 0);
+ assertEquals("Expecting " + Arrays.deepToString(tasks) + " got " + stackTasks,
+ stackTasks.size(), tasks != null ? tasks.length : 0);
if (tasks == null) {
return;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 4a734e5256f6..dcca3167c752 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -35,9 +35,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
import android.support.test.uiautomator.UiDevice;
import android.text.TextUtils;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import com.android.internal.annotations.GuardedBy;
@@ -76,6 +78,7 @@ public class TaskStackChangedListenerTest {
}
@Test
+ @Presubmit
public void testTaskStackChanged_afterFinish() throws Exception {
registerTaskStackChangedListener(new TaskStackListener() {
@Override
@@ -87,7 +90,8 @@ public class TaskStackChangedListenerTest {
});
Context context = getInstrumentation().getContext();
- context.startActivity(new Intent(context, ActivityA.class));
+ context.startActivity(
+ new Intent(context, ActivityA.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
UiDevice.getInstance(getInstrumentation()).waitForIdle();
synchronized (sLock) {
assertTrue(sTaskStackChangedCalled);
@@ -96,6 +100,7 @@ public class TaskStackChangedListenerTest {
}
@Test
+ @FlakyTest(bugId = 119893767)
public void testTaskDescriptionChanged() throws Exception {
final Object[] params = new Object[2];
final CountDownLatch latch = new CountDownLatch(1);
@@ -124,6 +129,7 @@ public class TaskStackChangedListenerTest {
}
@Test
+ @FlakyTest(bugId = 119893767)
public void testActivityRequestedOrientationChanged() throws Exception {
final int[] params = new int[2];
final CountDownLatch latch = new CountDownLatch(1);
@@ -146,6 +152,7 @@ public class TaskStackChangedListenerTest {
* Tests for onTaskCreated, onTaskMovedToFront, onTaskRemoved and onTaskRemovalStarted.
*/
@Test
+ @FlakyTest(bugId = 119893767)
public void testTaskChangeCallBacks() throws Exception {
final Object[] params = new Object[2];
final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1);
@@ -221,7 +228,8 @@ public class TaskStackChangedListenerTest {
final ActivityMonitor monitor = new ActivityMonitor(activityClass.getName(), null, false);
getInstrumentation().addMonitor(monitor);
final Context context = getInstrumentation().getContext();
- context.startActivity(new Intent(context, activityClass));
+ context.startActivity(
+ new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
final TestActivity activity = (TestActivity) monitor.waitForActivityWithTimeout(1000);
if (activity == null) {
throw new RuntimeException("Timed out waiting for Activity");
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestSystemServices.java b/services/tests/wmtests/src/com/android/server/wm/TestSystemServices.java
index b151fb7a613c..1c1fe29bd7cc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestSystemServices.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestSystemServices.java
@@ -88,6 +88,7 @@ class TestSystemServices {
sPolicy = null;
sMockitoSession.finishMocking();
+ sMockitoSession = null;
}
private static void setUpTestWindowService() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 3cb28140e2ea..a83bf2af613e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -50,6 +50,7 @@ import android.view.IWindow;
import android.view.WindowManager;
import com.android.server.AttributeCache;
+import com.android.server.wm.utils.MockTracker;
import org.junit.After;
import org.junit.AfterClass;
@@ -77,6 +78,8 @@ class WindowTestsBase {
private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
static int sNextStackId = 1000;
+ private static MockTracker sMockTracker;
+
/** Non-default display. */
DisplayContent mDisplayContent;
DisplayInfo mDisplayInfo = new DisplayInfo();
@@ -109,11 +112,18 @@ class WindowTestsBase {
TestSystemServices.setUpWindowManagerService();
+ // MockTracker needs to be initialized after TestSystemServices because we don't want to
+ // track static mocks.
+ sMockTracker = new MockTracker();
+
sPowerManagerWrapper = mock(WindowState.PowerManagerWrapper.class);
}
@AfterClass
- public static void tearDonwOnceBase() {
+ public static void tearDownOnceBase() {
+ sMockTracker.close();
+ sMockTracker = null;
+
TestSystemServices.tearDownWindowManagerService();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/MockTracker.java b/services/tests/wmtests/src/com/android/server/wm/utils/MockTracker.java
new file mode 100644
index 000000000000..1ce463bbbd9e
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/MockTracker.java
@@ -0,0 +1,94 @@
+/*
+ * 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.server.wm.utils;
+
+import android.util.Log;
+
+import org.mockito.Mockito;
+import org.mockito.MockitoFramework;
+import org.mockito.internal.creation.settings.CreationSettings;
+import org.mockito.listeners.MockCreationListener;
+import org.mockito.mock.MockCreationSettings;
+
+import java.lang.reflect.Field;
+import java.util.IdentityHashMap;
+
+/**
+ * An util class used to track mock creation, and reset them when closing. Note only one instance is
+ * allowed at anytime, as Mockito framework throws exception if there is already a listener of the
+ * same type registered.
+ */
+public class MockTracker implements MockCreationListener, AutoCloseable {
+ private static final String TAG = "MockTracker";
+
+ private static final Field SPIED_INSTANCE_FIELD;
+
+ static {
+ try {
+ SPIED_INSTANCE_FIELD = CreationSettings.class.getDeclaredField("spiedInstance");
+ SPIED_INSTANCE_FIELD.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private final MockitoFramework mMockitoFramework = Mockito.framework();
+
+ private final IdentityHashMap<Object, Void> mMocks = new IdentityHashMap<>();
+
+ public MockTracker() {
+ mMockitoFramework.addListener(this);
+ }
+
+ @Override
+ public void onMockCreated(Object mock, MockCreationSettings settings) {
+ mMocks.put(mock, null);
+ clearSpiedInstanceIfNeeded(mock, settings);
+ }
+
+ // HACK: Changing Mockito core implementation details.
+ // TODO(b/123984854): Remove this once there is a real fix.
+ private void clearSpiedInstanceIfNeeded(Object mock, MockCreationSettings settings) {
+ if (mock != settings.getSpiedInstance()) {
+ // Not a spyOn instance.
+ return;
+ }
+ if (!(settings instanceof CreationSettings)) {
+ throw new IllegalStateException("Unexpected type of settings: " + settings.getClass());
+ }
+ try {
+ SPIED_INSTANCE_FIELD.set(settings, null);
+ Log.d(TAG, "Setting spiedInstance for " + mock + " to null.");
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void close() {
+ mMockitoFramework.removeListener(this);
+
+ for (final Object mock : mMocks.keySet()) {
+ try {
+ Mockito.reset(mock);
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to reset " + mock, e);
+ }
+ }
+ mMocks.clear();
+ }
+}
diff --git a/services/usage/java/com/android/server/usage/AppTimeLimitController.java b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
index 873ada05bc27..731cbf42eca7 100644
--- a/services/usage/java/com/android/server/usage/AppTimeLimitController.java
+++ b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
@@ -840,7 +840,8 @@ public class AppTimeLimitController {
*/
public void addAppUsageLimitObserver(int requestingUid, int observerId, String[] observed,
long timeLimit, PendingIntent callbackIntent, @UserIdInt int userId) {
- if (timeLimit < getMinTimeLimit()) {
+ // Allow the special case of the limit being 0, but with no callback.
+ if (timeLimit != 0L && timeLimit < getMinTimeLimit()) {
throw new IllegalArgumentException("Time limit must be >= " + getMinTimeLimit());
}
synchronized (mLock) {
@@ -858,7 +859,7 @@ public class AppTimeLimitController {
"Too many app usage observers added by uid " + requestingUid);
}
group = new AppUsageLimitGroup(user, observerApp, observerId, observed, timeLimit,
- callbackIntent);
+ timeLimit == 0L ? null : callbackIntent);
observerApp.appUsageLimitGroups.append(observerId, group);
if (DEBUG) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index df2f45512465..af5278f222b8 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1377,7 +1377,7 @@ public class UsageStatsService extends SystemService implements
if (packages == null || packages.length == 0) {
throw new IllegalArgumentException("Must specify at least one package");
}
- if (callbackIntent == null) {
+ if (callbackIntent == null && timeLimitMs != 0L) {
throw new NullPointerException("callbackIntent can't be null");
}
final int callingUid = Binder.getCallingUid();
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index aac0956d4339..e43b2b715321 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -22,7 +22,6 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
@@ -163,9 +162,7 @@ public class DefaultDialerManager {
final Intent dialIntentWithTelScheme = new Intent(Intent.ACTION_DIAL);
dialIntentWithTelScheme.setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, "", null));
- packageNames = filterByIntent(context, packageNames, dialIntentWithTelScheme, userId);
- packageNames = requireInCallService(packageNames, userId, context);
- return packageNames;
+ return filterByIntent(context, packageNames, dialIntentWithTelScheme, userId);
}
public static List<String> getInstalledDialerApplications(Context context) {
@@ -223,35 +220,6 @@ public class DefaultDialerManager {
return result;
}
- private static List<String> requireInCallService(List<String> packageNames, int userId,
- Context context) {
- if (packageNames == null || packageNames.isEmpty()) {
- return new ArrayList<>();
- }
-
- final Intent intent = new Intent(InCallService.SERVICE_INTERFACE);
- final List<ResolveInfo> resolveInfoList = context.getPackageManager()
- .queryIntentServicesAsUser(intent, PackageManager.GET_META_DATA, userId);
- final List<String> result = new ArrayList<>();
- final int length = resolveInfoList.size();
- for (int i = 0; i < length; i++) {
- final ServiceInfo info = resolveInfoList.get(i).serviceInfo;
- if (info == null || info.metaData == null) {
- continue;
- }
- if (!info.metaData.getBoolean(TelecomManager.METADATA_IN_CALL_SERVICE_UI)) {
- continue;
- }
- if (info.metaData.getBoolean(TelecomManager.METADATA_IN_CALL_SERVICE_CAR_MODE_UI)) {
- continue;
- }
- if (packageNames.contains(info.packageName) && !result.contains(info.packageName)) {
- result.add(info.packageName);
- }
- }
-
- return result;
- }
private static TelecomManager getTelecomManager(Context context) {
return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 068b68eeb73b..0c63b60b030d 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2589,6 +2589,16 @@ public class CarrierConfigManager {
}
}
+ /**
+ * An int array containing CDMA enhanced roaming indicator values for Home (non-roaming) network.
+ * The default values come from 3GPP2 C.R1001 table 8.1-1.
+ * Enhanced Roaming Indicator Number Assignments
+ *
+ * @hide
+ */
+ public static final String KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY =
+ "cdma_enhanced_roaming_indicator_for_home_network_int_array";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -2966,6 +2976,10 @@ public class CarrierConfigManager {
/* Default value is 10 seconds. */
sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG, 10000);
sDefaults.putAll(Gps.getDefaults());
+ sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
+ new int[] {
+ 1 /* Roaming Indicator Off */
+ });
}
/**
diff --git a/telephony/java/android/telephony/CarrierRestrictionRules.java b/telephony/java/android/telephony/CarrierRestrictionRules.java
index 37847aef9167..d47b55ca4372 100644
--- a/telephony/java/android/telephony/CarrierRestrictionRules.java
+++ b/telephony/java/android/telephony/CarrierRestrictionRules.java
@@ -27,6 +27,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* Contains the list of carrier restrictions.
@@ -93,6 +94,9 @@ public final class CarrierRestrictionRules implements Parcelable {
value = {CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED, CARRIER_RESTRICTION_DEFAULT_ALLOWED})
public @interface CarrierRestrictionDefault {}
+ /* Wild character for comparison */
+ private static final char WILD_CHARACTER = '?';
+
private List<CarrierIdentifier> mAllowedCarriers;
private List<CarrierIdentifier> mExcludedCarriers;
@CarrierRestrictionDefault
@@ -166,6 +170,124 @@ public final class CarrierRestrictionRules implements Parcelable {
}
/**
+ * Tests an array of carriers with the carrier restriction configuration. The list of carrier
+ * ids passed as argument does not need to be the same as currently present in the device.
+ *
+ * @param carrierIds list of {@link CarrierIdentifier}, one for each SIM slot on the device
+ * @return a list of boolean with the same size as input, indicating if each
+ * {@link CarrierIdentifier} is allowed or not.
+ */
+ public List<Boolean> isCarrierIdentifiersAllowed(@NonNull List<CarrierIdentifier> carrierIds) {
+ ArrayList<Boolean> result = new ArrayList<>(carrierIds.size());
+
+ // First calculate the result for each slot independently
+ for (int i = 0; i < carrierIds.size(); i++) {
+ boolean inAllowedList = isCarrierIdInList(carrierIds.get(i), mAllowedCarriers);
+ boolean inExcludedList = isCarrierIdInList(carrierIds.get(i), mExcludedCarriers);
+ if (mCarrierRestrictionDefault == CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED) {
+ result.add((inAllowedList && !inExcludedList) ? true : false);
+ } else {
+ result.add((inExcludedList && !inAllowedList) ? false : true);
+ }
+ }
+ // Apply the multi-slot policy, if needed.
+ if (mMultiSimPolicy == MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT) {
+ for (boolean b : result) {
+ if (b) {
+ result.replaceAll(x -> true);
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Indicates if a certain carrier {@code id} is present inside a {@code list}
+ *
+ * @return true if the carrier {@code id} is present, false otherwise
+ */
+ private static boolean isCarrierIdInList(CarrierIdentifier id, List<CarrierIdentifier> list) {
+ for (CarrierIdentifier listItem : list) {
+ // Compare MCC and MNC
+ if (!patternMatch(id.getMcc(), listItem.getMcc())
+ || !patternMatch(id.getMnc(), listItem.getMnc())) {
+ continue;
+ }
+
+ // Compare SPN. Comparison is on the complete strings, case insensitive and with wild
+ // characters.
+ String listItemValue = convertNullToEmpty(listItem.getSpn());
+ String idValue = convertNullToEmpty(id.getSpn());
+ if (!listItemValue.isEmpty()) {
+ if (!patternMatch(idValue, listItemValue)) {
+ continue;
+ }
+ }
+
+ // The IMSI of the configuration can be shorter than actual IMSI in the SIM card.
+ listItemValue = convertNullToEmpty(listItem.getImsi());
+ idValue = convertNullToEmpty(id.getImsi());
+ if (!patternMatch(
+ idValue.substring(0, Math.min(idValue.length(), listItemValue.length())),
+ listItemValue)) {
+ continue;
+ }
+
+ // The GID1 of the configuration can be shorter than actual GID1 in the SIM card.
+ listItemValue = convertNullToEmpty(listItem.getGid1());
+ idValue = convertNullToEmpty(id.getGid1());
+ if (!patternMatch(
+ idValue.substring(0, Math.min(idValue.length(), listItemValue.length())),
+ listItemValue)) {
+ continue;
+ }
+
+ // The GID2 of the configuration can be shorter than actual GID2 in the SIM card.
+ listItemValue = convertNullToEmpty(listItem.getGid2());
+ idValue = convertNullToEmpty(id.getGid2());
+ if (!patternMatch(
+ idValue.substring(0, Math.min(idValue.length(), listItemValue.length())),
+ listItemValue)) {
+ continue;
+ }
+
+ // Valid match was found in the list
+ return true;
+ }
+ return false;
+ }
+
+ private static String convertNullToEmpty(String value) {
+ return Objects.toString(value, "");
+ }
+
+ /**
+ * Performs a case insensitive string comparison against a given pattern. The character '?'
+ * is used in the pattern as wild character in the comparison. The string must have the same
+ * length as the pattern.
+ *
+ * @param str string to match
+ * @param pattern string containing the pattern
+ * @return true in case of match, false otherwise
+ */
+ private static boolean patternMatch(String str, String pattern) {
+ if (str.length() != pattern.length()) {
+ return false;
+ }
+ String lowerCaseStr = str.toLowerCase();
+ String lowerCasePattern = pattern.toLowerCase();
+
+ for (int i = 0; i < lowerCasePattern.length(); i++) {
+ if (lowerCasePattern.charAt(i) != lowerCaseStr.charAt(i)
+ && lowerCasePattern.charAt(i) != WILD_CHARACTER) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* {@link Parcelable#writeToParcel}
*/
@Override
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index fea1b7b08a20..2c9ba1dfff7b 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -45,7 +45,8 @@ import java.util.concurrent.Executor;
* <p>
* Override the methods for the state that you wish to receive updates for, and
* pass your PhoneStateListener object, along with bitwise-or of the LISTEN_
- * flags to {@link TelephonyManager#listen TelephonyManager.listen()}.
+ * flags to {@link TelephonyManager#listen TelephonyManager.listen()}. Methods are
+ * called when the state changes, os well as once on initial registration.
* <p>
* Note that access to some telephony information is
* permission-protected. Your application won't receive updates for protected
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f5d452e9721d..2a03924fd58c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -10309,11 +10309,14 @@ public class TelephonyManager {
/**
* Get whether reboot is required or not after making changes to modem configurations.
- * @Return {@code True} if reboot is required after making changes to modem configurations,
- * otherwise return {@code False}.
+ * The modem configuration change refers to switching from single SIM configuration to DSDS
+ * or the other way around.
+ * @Return {@code true} if reboot is required after making changes to modem configurations,
+ * otherwise return {@code false}.
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isRebootRequiredForModemConfigChange() {
try {
diff --git a/telephony/java/android/telephony/ims/Rcs1To1Thread.java b/telephony/java/android/telephony/ims/Rcs1To1Thread.java
index 3255f8d0786d..d4a78ffb77db 100644
--- a/telephony/java/android/telephony/ims/Rcs1To1Thread.java
+++ b/telephony/java/android/telephony/ims/Rcs1To1Thread.java
@@ -22,8 +22,6 @@ import android.annotation.WorkerThread;
* Rcs1To1Thread represents a single RCS conversation thread with a total of two
* {@link RcsParticipant}s. Please see Section 5 (1-to-1 Messaging) - GSMA RCC.71 (RCS Universal
* Profile Service Definition Document)
- *
- * @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 ef359a124d47..df62277f9ac1 100644
--- a/telephony/java/android/telephony/ims/RcsEvent.java
+++ b/telephony/java/android/telephony/ims/RcsEvent.java
@@ -19,8 +19,6 @@ import android.os.Parcel;
/**
* The base class for events that can happen on {@link RcsParticipant}s and {@link RcsThread}s.
- *
- * @hide - TODO: make public
*/
public abstract class RcsEvent {
/**
diff --git a/telephony/java/android/telephony/ims/RcsEventQueryParams.java b/telephony/java/android/telephony/ims/RcsEventQueryParams.java
index 5249becd476e..9dbfe4393213 100644
--- a/telephony/java/android/telephony/ims/RcsEventQueryParams.java
+++ b/telephony/java/android/telephony/ims/RcsEventQueryParams.java
@@ -37,8 +37,6 @@ import java.security.InvalidParameterException;
* The parameters to pass into
* {@link RcsMessageStore#getRcsEvents(RcsEventQueryParams)} in order to select a
* subset of {@link RcsEvent}s present in the message store.
- *
- * @hide - TODO: make public
*/
public final class RcsEventQueryParams implements Parcelable {
/**
@@ -152,8 +150,8 @@ public final class RcsEventQueryParams implements Parcelable {
}
/**
- * @return Returns the type of {@link RcsEvent}s that this {@link RcsEventQueryParams} is
- * set to query for.
+ * @return Returns the number of {@link RcsEvent}s to be returned from the query. A value of
+ * 0 means there is no set limit.
*/
public int getLimit() {
return mLimit;
diff --git a/telephony/java/android/telephony/ims/RcsEventQueryResult.java b/telephony/java/android/telephony/ims/RcsEventQueryResult.java
index f8d57fa5c09d..c30e4ccd7aa2 100644
--- a/telephony/java/android/telephony/ims/RcsEventQueryResult.java
+++ b/telephony/java/android/telephony/ims/RcsEventQueryResult.java
@@ -25,8 +25,6 @@ import java.util.List;
* 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 - TODO: make public
*/
public final class RcsEventQueryResult implements Parcelable {
private RcsQueryContinuationToken mContinuationToken;
diff --git a/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java b/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java
index 663def5df50f..14af8ea63a67 100644
--- a/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java
+++ b/telephony/java/android/telephony/ims/RcsFileTransferCreationParams.java
@@ -24,8 +24,6 @@ import android.os.Parcelable;
* Pass an instance of this class to
* {@link RcsMessage#insertFileTransfer(RcsFileTransferCreationParams)} create an
* {@link RcsFileTransferPart} and save it into storage.
- *
- * @hide - TODO: make public
*/
public final class RcsFileTransferCreationParams implements Parcelable {
private String mRcsFileTransferSessionId;
diff --git a/telephony/java/android/telephony/ims/RcsFileTransferPart.java b/telephony/java/android/telephony/ims/RcsFileTransferPart.java
index 1ce799919e09..9531c2e2f981 100644
--- a/telephony/java/android/telephony/ims/RcsFileTransferPart.java
+++ b/telephony/java/android/telephony/ims/RcsFileTransferPart.java
@@ -26,8 +26,6 @@ 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: make public
*/
public class RcsFileTransferPart {
/**
diff --git a/telephony/java/android/telephony/ims/RcsGroupThread.java b/telephony/java/android/telephony/ims/RcsGroupThread.java
index 2c42494ee924..6e17bc2a685f 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThread.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThread.java
@@ -29,8 +29,6 @@ import java.util.Set;
* RcsGroupThread represents a single RCS conversation thread where {@link RcsParticipant}s can join
* or leave. Please see Section 6 (Group Chat) - GSMA RCC.71 (RCS Universal Profile Service
* Definition Document)
- *
- * @hide - TODO: make public
*/
public class RcsGroupThread extends RcsThread {
/**
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java
index bc61877a81d6..609b1740a536 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java
@@ -20,8 +20,6 @@ import android.os.Parcel;
/**
* An event that happened on an {@link RcsGroupThread}.
- *
- * @hide - TODO: make public
*/
public abstract class RcsGroupThreadEvent extends RcsEvent {
private final int mRcsGroupThreadId;
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java
index 74af9738e976..e768439d6cfa 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java
@@ -24,8 +24,6 @@ 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: make public
*/
public final class RcsGroupThreadIconChangedEvent extends RcsGroupThreadEvent implements
Parcelable {
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java
index 06f4d5b10bb4..02030bc6a2ec 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java
@@ -23,8 +23,6 @@ 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: make public
*/
public final class RcsGroupThreadNameChangedEvent extends RcsGroupThreadEvent implements
Parcelable {
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java
index 493270795e01..0d1a5730f0a0 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java
@@ -22,8 +22,6 @@ 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: make public
*/
public final class RcsGroupThreadParticipantJoinedEvent extends RcsGroupThreadEvent implements
Parcelable {
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java
index 970a046e1105..cd525086749a 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java
@@ -22,8 +22,6 @@ 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: make public
*/
public final class RcsGroupThreadParticipantLeftEvent extends RcsGroupThreadEvent implements
Parcelable {
diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessage.java b/telephony/java/android/telephony/ims/RcsIncomingMessage.java
index f3b7815c2453..61911abd00c5 100644
--- a/telephony/java/android/telephony/ims/RcsIncomingMessage.java
+++ b/telephony/java/android/telephony/ims/RcsIncomingMessage.java
@@ -19,8 +19,6 @@ import android.annotation.WorkerThread;
/**
* This is a single instance of a message received over RCS.
- *
- * @hide - TODO: make public
*/
public class RcsIncomingMessage extends RcsMessage {
/**
diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java
index 64b2339905eb..61dedbc1578a 100644
--- a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java
+++ b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParams.java
@@ -24,8 +24,6 @@ import android.os.Parcelable;
* {@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
*/
public final class RcsIncomingMessageCreationParams extends RcsMessageCreationParams implements
Parcelable {
diff --git a/telephony/java/android/telephony/ims/RcsManager.java b/telephony/java/android/telephony/ims/RcsManager.java
index 90bd0446d6f3..22e4b2249c36 100644
--- a/telephony/java/android/telephony/ims/RcsManager.java
+++ b/telephony/java/android/telephony/ims/RcsManager.java
@@ -20,8 +20,6 @@ import android.content.Context;
/**
* The manager class for RCS related utilities.
- *
- * @hide - TODO: make public
*/
@SystemService(Context.TELEPHONY_RCS_SERVICE)
public class RcsManager {
diff --git a/telephony/java/android/telephony/ims/RcsMessage.java b/telephony/java/android/telephony/ims/RcsMessage.java
index 1700941b94ed..32274131a5ad 100644
--- a/telephony/java/android/telephony/ims/RcsMessage.java
+++ b/telephony/java/android/telephony/ims/RcsMessage.java
@@ -27,8 +27,6 @@ import java.util.Set;
/**
* This is a single instance of a message sent or received over RCS.
- *
- * @hide - TODO: make public
*/
public abstract class RcsMessage {
/**
diff --git a/telephony/java/android/telephony/ims/RcsMessageCreationParams.java b/telephony/java/android/telephony/ims/RcsMessageCreationParams.java
index 9ac4dcdf2d74..c46c605d861d 100644
--- a/telephony/java/android/telephony/ims/RcsMessageCreationParams.java
+++ b/telephony/java/android/telephony/ims/RcsMessageCreationParams.java
@@ -27,8 +27,6 @@ import android.os.Parcel;
* {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParams)} and
* {@link RcsThread#addOutgoingMessage(RcsOutgoingMessageCreationParams)} to create and persist
* {@link RcsMessage}s on an {@link RcsThread}
- *
- * @hide - TODO: make public
*/
public class RcsMessageCreationParams {
// The globally unique id of the RcsMessage to be created.
diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryParams.java b/telephony/java/android/telephony/ims/RcsMessageQueryParams.java
index fae0d97cd722..535a597f5e1e 100644
--- a/telephony/java/android/telephony/ims/RcsMessageQueryParams.java
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryParams.java
@@ -31,8 +31,6 @@ import java.security.InvalidParameterException;
* The parameters to pass into
* {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParams)} in order to select a
* subset of {@link RcsMessage}s present in the message store.
- *
- * @hide - TODO: make public
*/
public final class RcsMessageQueryParams implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java
index 5adab760d594..3514b48e80a1 100644
--- a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java
@@ -32,8 +32,6 @@ import java.util.List;
* 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 - TODO: make public
*/
public final class RcsMessageQueryResult implements Parcelable {
// The token to continue the query to get the next batch of results
diff --git a/telephony/java/android/telephony/ims/RcsMessageSnippet.java b/telephony/java/android/telephony/ims/RcsMessageSnippet.java
index 565bb99de89a..b0b930c56e91 100644
--- a/telephony/java/android/telephony/ims/RcsMessageSnippet.java
+++ b/telephony/java/android/telephony/ims/RcsMessageSnippet.java
@@ -23,8 +23,6 @@ import android.telephony.ims.RcsMessage.RcsMessageStatus;
/**
* An immutable summary of the latest {@link RcsMessage} on an {@link RcsThread}
- *
- * @hide - TODO: make public
*/
public final class RcsMessageSnippet implements Parcelable {
private final String mText;
diff --git a/telephony/java/android/telephony/ims/RcsMessageStore.java b/telephony/java/android/telephony/ims/RcsMessageStore.java
index eca5ed518521..d811c6e93a56 100644
--- a/telephony/java/android/telephony/ims/RcsMessageStore.java
+++ b/telephony/java/android/telephony/ims/RcsMessageStore.java
@@ -26,8 +26,6 @@ import java.util.List;
/**
* RcsMessageStore is the application interface to RcsProvider and provides access methods to
* RCS related database tables.
- *
- * @hide - TODO: make public
*/
public class RcsMessageStore {
/**
diff --git a/telephony/java/android/telephony/ims/RcsMessageStoreException.java b/telephony/java/android/telephony/ims/RcsMessageStoreException.java
index 7c00749b1690..f25bb173be37 100644
--- a/telephony/java/android/telephony/ims/RcsMessageStoreException.java
+++ b/telephony/java/android/telephony/ims/RcsMessageStoreException.java
@@ -19,8 +19,6 @@ 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
*/
public class RcsMessageStoreException extends Exception {
diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
index dfcdee4a803d..06fb83268afb 100644
--- a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
+++ b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
@@ -23,8 +23,6 @@ import java.util.List;
/**
* This is a single instance of a message sent over RCS.
- *
- * @hide - TODO: make public
*/
public class RcsOutgoingMessage extends RcsMessage {
RcsOutgoingMessage(int id) {
diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java b/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java
index ca466e8c9d3e..979634a069df 100644
--- a/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java
+++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageCreationParams.java
@@ -23,8 +23,6 @@ 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 {
diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java
index 5a3062a69e3f..1c87b13f0dfb 100644
--- a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java
+++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java
@@ -21,8 +21,6 @@ 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: 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 37b827b8e83c..7ba5d8e65f76 100644
--- a/telephony/java/android/telephony/ims/RcsParticipant.java
+++ b/telephony/java/android/telephony/ims/RcsParticipant.java
@@ -20,8 +20,6 @@ import android.annotation.WorkerThread;
/**
* RcsParticipant is an RCS capable contact that can participate in {@link RcsThread}s.
- *
- * @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 aa278b38cf81..c9a2b0d07bc8 100644
--- a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java
@@ -23,8 +23,6 @@ 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: make public
*/
public final class RcsParticipantAliasChangedEvent extends RcsEvent implements Parcelable {
// The ID of the participant that changed their alias
diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java b/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java
index 57c67fa7aa03..d24d079d7038 100644
--- a/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java
+++ b/telephony/java/android/telephony/ims/RcsParticipantQueryParams.java
@@ -30,8 +30,6 @@ import java.security.InvalidParameterException;
* The parameters to pass into
* {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParams)} in order to select a
* subset of {@link RcsThread}s present in the message store.
- *
- * @hide - TODO: make public
*/
public final class RcsParticipantQueryParams implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java
index 4eae39d1a2c6..505f1a55d1f0 100644
--- a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java
+++ b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java
@@ -28,8 +28,6 @@ import java.util.List;
* 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 - TODO: make public
*/
public final class RcsParticipantQueryResult implements Parcelable {
// A token for the caller to continue their query for the next batch of results
diff --git a/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java
index c1ff39652397..08643de51d40 100644
--- a/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java
+++ b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java
@@ -31,8 +31,6 @@ import java.lang.annotation.RetentionPolicy;
* @see RcsMessageQueryResult#getContinuationToken()
* @see RcsParticipantQueryResult#getContinuationToken()
* @see RcsThreadQueryResult#getContinuationToken()
- *
- * @hide - TODO: make public
*/
public final class RcsQueryContinuationToken implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java
index 88655865f47b..e015dd3e9c0a 100644
--- a/telephony/java/android/telephony/ims/RcsThread.java
+++ b/telephony/java/android/telephony/ims/RcsThread.java
@@ -27,8 +27,6 @@ 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: make public
*/
public abstract class RcsThread {
/**
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParams.java b/telephony/java/android/telephony/ims/RcsThreadQueryParams.java
index ba32e320c95b..05a5a3917691 100644
--- a/telephony/java/android/telephony/ims/RcsThreadQueryParams.java
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryParams.java
@@ -35,8 +35,6 @@ import java.util.Set;
/**
* 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 public
*/
public final class RcsThreadQueryParams implements Parcelable {
/**
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
index a91126b89cce..1cac61d1aa64 100644
--- a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
@@ -32,8 +32,6 @@ import java.util.List;
* 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 - TODO: make public
*/
public final class RcsThreadQueryResult implements Parcelable {
// A token for the caller to continue their query for the next batch of results
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index bc43feaf0e15..caa367fbaafe 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1837,7 +1837,7 @@ interface ITelephony {
* @hide
*/
boolean isMultisimCarrierRestricted();
-
+
/**
* Switch configs to enable multi-sim or switch back to single-sim
* @hide
@@ -1846,6 +1846,7 @@ interface ITelephony {
/**
* Get if reboot is required upon altering modems configurations
+ * @hide
*/
boolean isRebootRequiredForModemConfigChange();
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index b9ec7bf56370..9d78bf4bfb53 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -334,8 +334,7 @@ public final class TelephonyPermissions {
// settings to individually disable the new restrictions for privileged, preloaded
// non-privileged, and non-preinstalled apps.
if (!isIdentifierCheckDisabled() && (
- (isPrivApp && !relaxPrivDeviceIdentifierCheck)
- || (!isPreinstalled && !relax3PDeviceIdentifierCheck)
+ (!isPreinstalled && !relax3PDeviceIdentifierCheck)
|| (isPreinstalled && !isPrivApp && !relaxNonPrivDeviceIdentifierCheck))) {
// The current package should only be reported in StatsLog if it has not previously been
// reported for the currently invoked device identifier method.
diff --git a/test-runner/Android.mk b/test-runner/Android.mk
deleted file mode 100644
index 18bde8517351..000000000000
--- a/test-runner/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (C) 2008 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.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-# additionally, build unit tests in a separate .apk
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/test-runner/tests/Android.bp b/test-runner/tests/Android.bp
new file mode 100644
index 000000000000..03c73986118d
--- /dev/null
+++ b/test-runner/tests/Android.bp
@@ -0,0 +1,40 @@
+// Copyright 2010, 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.
+
+android_test {
+ name: "FrameworkTestRunnerTests",
+
+ // We only want this apk build for tests.
+ //
+ // Run the tests using the following commands:
+ // adb install -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworkTestRunnerTests/FrameworkTestRunnerTests.apk
+ // adb shell am instrument \
+ // -e notAnnotation android.test.suitebuilder.examples.error.RunAsPartOfSeparateTest \
+ // -w com.android.frameworks.testrunner.tests/android.test.InstrumentationTestRunner \
+ //
+
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ ],
+ static_libs: ["junit"],
+
+ // Include all test java files.
+ srcs: ["src/**/*.java"],
+
+ // Because of android.test.mock.
+ platform_apis: true,
+
+}
diff --git a/test-runner/tests/Android.mk b/test-runner/tests/Android.mk
deleted file mode 100644
index f97d1c986b1c..000000000000
--- a/test-runner/tests/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2010, 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.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-#
-# Run the tests using the following commands:
-# adb install -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworkTestRunnerTests/FrameworkTestRunnerTests.apk
-# adb shell am instrument \
- -e notAnnotation android.test.suitebuilder.examples.error.RunAsPartOfSeparateTest \
- -w com.android.frameworks.testrunner.tests/android.test.InstrumentationTestRunner
-#
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
-LOCAL_STATIC_JAVA_LIBRARIES := junit
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := FrameworkTestRunnerTests
-# Because of android.test.mock.
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-include $(BUILD_PACKAGE)
-
diff --git a/tools/preload/Android.bp b/tools/preload/Android.bp
new file mode 100644
index 000000000000..809ee474969a
--- /dev/null
+++ b/tools/preload/Android.bp
@@ -0,0 +1,17 @@
+java_library_host {
+ name: "preload",
+ srcs: [
+ "Compile.java",
+ "LoadedClass.java",
+ "MemoryUsage.java",
+ "Operation.java",
+ "Policy.java",
+ "PrintCsv.java",
+ "PrintHtmlDiff.java",
+ "PrintPsTree.java",
+ "Proc.java",
+ "Record.java",
+ "Root.java",
+ "WritePreloadedClassFile.java",
+ ],
+}
diff --git a/tools/preload/Android.mk b/tools/preload/Android.mk
deleted file mode 100644
index 14a4547cccbf..000000000000
--- a/tools/preload/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- Compile.java \
- LoadedClass.java \
- MemoryUsage.java \
- Operation.java \
- Policy.java \
- PrintCsv.java \
- PrintHtmlDiff.java \
- PrintPsTree.java \
- Proc.java \
- Record.java \
- Root.java \
- WritePreloadedClassFile.java
-
-LOCAL_MODULE:= preload
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/preload/loadclass/Android.bp b/tools/preload/loadclass/Android.bp
new file mode 100644
index 000000000000..6f12015dae2b
--- /dev/null
+++ b/tools/preload/loadclass/Android.bp
@@ -0,0 +1,4 @@
+java_test {
+ name: "loadclass",
+ srcs: ["**/*.java"],
+}
diff --git a/tools/preload/loadclass/Android.mk b/tools/preload/loadclass/Android.mk
deleted file mode 100644
index 65828be617df..000000000000
--- a/tools/preload/loadclass/Android.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_MODULE := loadclass
-
-include $(BUILD_JAVA_LIBRARY)
diff --git a/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java b/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java
new file mode 100644
index 000000000000..4ddf872f6cd2
--- /dev/null
+++ b/wifi/java/android/net/wifi/aware/ParcelablePeerHandle.java
@@ -0,0 +1,59 @@
+/*
+ * 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.net.wifi.aware;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A Parcelable {@link PeerHandle}. Can be constructed from a {@code PeerHandle} and then passed
+ * to any of the APIs which take a {@code PeerHandle} as inputs.
+ */
+public final class ParcelablePeerHandle extends PeerHandle implements Parcelable {
+ /**
+ * Construct a parcelable version of {@link PeerHandle}.
+ *
+ * @param peerHandle The {@link PeerHandle} to be made parcelable.
+ */
+ public ParcelablePeerHandle(PeerHandle peerHandle) {
+ super(peerHandle.peerId);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(peerId);
+ }
+
+ public static final Creator<ParcelablePeerHandle> CREATOR =
+ new Creator<ParcelablePeerHandle>() {
+ @Override
+ public ParcelablePeerHandle[] newArray(int size) {
+ return new ParcelablePeerHandle[size];
+ }
+
+ @Override
+ public ParcelablePeerHandle createFromParcel(Parcel in) {
+ int peerHandle = in.readInt();
+ return new ParcelablePeerHandle(new PeerHandle(peerHandle));
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/aware/PeerHandle.java b/wifi/java/android/net/wifi/aware/PeerHandle.java
index 1603d00fd88a..422e177ed7ad 100644
--- a/wifi/java/android/net/wifi/aware/PeerHandle.java
+++ b/wifi/java/android/net/wifi/aware/PeerHandle.java
@@ -16,9 +16,6 @@
package android.net.wifi.aware;
-import android.os.Parcel;
-import android.os.Parcelable;
-
/**
* Opaque object used to represent a Wi-Fi Aware peer. Obtained from discovery sessions in
* {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)} or
@@ -35,8 +32,9 @@ import android.os.Parcelable;
* configuration's service-specific information field,
* {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])}, or match filter,
* {@link PublishConfig.Builder#setMatchFilter(java.util.List)}.
+ * <p>A parcelable handle object is available with {@link ParcelablePeerHandle}.
*/
-public final class PeerHandle implements Parcelable {
+public class PeerHandle {
/** @hide */
public PeerHandle(int peerId) {
this.peerId = peerId;
@@ -62,29 +60,4 @@ public final class PeerHandle implements Parcelable {
public int hashCode() {
return peerId;
}
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(peerId);
- }
-
- public static final Creator<PeerHandle> CREATOR = new Creator<PeerHandle>() {
- @Override
- public PeerHandle[] newArray(int size) {
- return new PeerHandle[size];
- }
-
- @Override
- public PeerHandle createFromParcel(Parcel in) {
- int peerHandle = in.readInt();
-
- return new PeerHandle(peerHandle);
- }
- };
-
}
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 6da6d4adeb62..3cc96bf2c795 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -1614,23 +1614,31 @@ public class WifiAwareManagerTest {
assertEquals(cap.hashCode(), rereadCap.hashCode());
}
- // PeerHandle tests
+ // ParcelablePeerHandle tests
+ /**
+ * Verify parceling of ParcelablePeerHandle and interoperability with PeerHandle.
+ */
@Test
- public void testPeerHandleParcel() {
+ public void testParcelablePeerHandleParcel() {
final PeerHandle peerHandle = new PeerHandle(5);
+ final ParcelablePeerHandle parcelablePeerHandle = new ParcelablePeerHandle(peerHandle);
Parcel parcelW = Parcel.obtain();
- peerHandle.writeToParcel(parcelW, 0);
+ parcelablePeerHandle.writeToParcel(parcelW, 0);
byte[] bytes = parcelW.marshall();
parcelW.recycle();
Parcel parcelR = Parcel.obtain();
parcelR.unmarshall(bytes, 0, bytes.length);
parcelR.setDataPosition(0);
- PeerHandle rereadPeerHandle = PeerHandle.CREATOR.createFromParcel(parcelR);
+ ParcelablePeerHandle rereadParcelablePeerHandle =
+ ParcelablePeerHandle.CREATOR.createFromParcel(parcelR);
+
+ assertEquals(peerHandle, rereadParcelablePeerHandle);
+ assertEquals(peerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
+ assertEquals(parcelablePeerHandle, rereadParcelablePeerHandle);
+ assertEquals(parcelablePeerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
- assertEquals(peerHandle, rereadPeerHandle);
- assertEquals(peerHandle.hashCode(), rereadPeerHandle.hashCode());
}
}