diff options
104 files changed, 2927 insertions, 434 deletions
diff --git a/Android.bp b/Android.bp index 641ce5fdff3c..d1332bb4fe87 100644 --- a/Android.bp +++ b/Android.bp @@ -230,6 +230,7 @@ java_library { "core/java/android/os/ISchedulingPolicyService.aidl", "core/java/android/os/IStatsCompanionService.aidl", "core/java/android/os/IStatsManager.aidl", + "core/java/android/os/ISystemUpdateManager.aidl", "core/java/android/os/IThermalEventListener.aidl", "core/java/android/os/IThermalService.aidl", "core/java/android/os/IUpdateLock.aidl", diff --git a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java index 6975609d990a..682885b3120d 100644 --- a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java +++ b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java @@ -25,9 +25,12 @@ import android.support.test.filters.LargeTest; import android.support.test.runner.AndroidJUnit4; import android.content.res.ColorStateList; +import android.graphics.Canvas; import android.graphics.Typeface; import android.text.Layout; import android.text.style.TextAppearanceSpan; +import android.view.DisplayListCanvas; +import android.view.RenderNode; import org.junit.Before; import org.junit.Rule; @@ -285,4 +288,157 @@ public class StaticLayoutPerfTest { .build(); } } + + @Test + public void testDraw_FixedText_NoStyled() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + state.resumeTiming(); + + layout.draw(c); + } + } + + @Test + public void testDraw_RandomText_Styled() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final CharSequence text = generateRandomParagraph(WORD_LENGTH, STYLE_TEXT); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + state.resumeTiming(); + + layout.draw(c); + } + } + + @Test + public void testDraw_RandomText_NoStyled() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + state.resumeTiming(); + + layout.draw(c); + } + } + + @Test + public void testDraw_RandomText_Styled_WithoutCache() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final CharSequence text = generateRandomParagraph(WORD_LENGTH, STYLE_TEXT); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + Canvas.freeTextLayoutCaches(); + state.resumeTiming(); + + layout.draw(c); + } + } + + @Test + public void testDraw_RandomText_NoStyled_WithoutCache() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final CharSequence text = generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + Canvas.freeTextLayoutCaches(); + state.resumeTiming(); + + layout.draw(c); + } + } + + @Test + public void testDraw_MeasuredText_Styled() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final MeasuredText text = new MeasuredText.Builder( + generateRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT).build(); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + state.resumeTiming(); + + layout.draw(c); + } + } + + @Test + public void testDraw_MeasuredText_NoStyled() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final MeasuredText text = new MeasuredText.Builder( + generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT).build(); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + state.resumeTiming(); + + layout.draw(c); + } + } + + @Test + public void testDraw_MeasuredText_Styled_WithoutCache() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final MeasuredText text = new MeasuredText.Builder( + generateRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT).build(); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + Canvas.freeTextLayoutCaches(); + state.resumeTiming(); + + layout.draw(c); + } + } + + @Test + public void testDraw_MeasuredText_NoStyled_WithoutCache() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final RenderNode node = RenderNode.create("benchmark", null); + while (state.keepRunning()) { + state.pauseTiming(); + final MeasuredText text = new MeasuredText.Builder( + generateRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT).build(); + final StaticLayout layout = + StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build(); + final DisplayListCanvas c = node.start(1200, 200); + Canvas.freeTextLayoutCaches(); + state.resumeTiming(); + + layout.draw(c); + } + } + } diff --git a/api/current.txt b/api/current.txt index bb4c383e4c9a..5d175ceca3cd 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6474,6 +6474,7 @@ package android.app.admin { method public boolean isMasterVolumeMuted(android.content.ComponentName); method public boolean isNetworkLoggingEnabled(android.content.ComponentName); method public boolean isPackageSuspended(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; + method public boolean isPrintingEnabled(); method public boolean isProfileOwnerApp(java.lang.String); method public boolean isProvisioningAllowed(java.lang.String); method public boolean isResetPasswordTokenActive(android.content.ComponentName); @@ -6543,6 +6544,7 @@ package android.app.admin { method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>); method public boolean setPermittedCrossProfileNotificationListeners(android.content.ComponentName, java.util.List<java.lang.String>); method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>); + method public void setPrintingEnabled(android.content.ComponentName, boolean); method public void setProfileEnabled(android.content.ComponentName); method public void setProfileName(android.content.ComponentName, java.lang.String); method public void setRecommendedGlobalProxy(android.content.ComponentName, android.net.ProxyInfo); @@ -15575,6 +15577,7 @@ package android.hardware.camera2 { method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys(); method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableSessionKeys(); method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys(); + method public java.util.List<java.lang.String> getPhysicalCameraIds(); field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES; field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES; field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES; @@ -15613,6 +15616,7 @@ package android.hardware.camera2 { field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_ROTATION; field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_TRANSLATION; field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_RADIAL_DISTORTION; + field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE; field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES; field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REPROCESS_MAX_CAPTURE_STALL; field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES; @@ -15653,6 +15657,7 @@ package android.hardware.camera2 { field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES; field public static final android.hardware.camera2.CameraCharacteristics.Key<boolean[]> STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES; field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES; field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> STATISTICS_INFO_MAX_FACE_COUNT; field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> SYNC_MAX_LATENCY; field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> TONEMAP_AVAILABLE_TONE_MAP_MODES; @@ -15843,6 +15848,7 @@ package android.hardware.camera2 { field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2 field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3; // 0x3 + field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL = 4; // 0x4 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0 @@ -15858,6 +15864,8 @@ package android.hardware.camera2 { field public static final int LENS_POSE_REFERENCE_PRIMARY_CAMERA = 0; // 0x0 field public static final int LENS_STATE_MOVING = 1; // 0x1 field public static final int LENS_STATE_STATIONARY = 0; // 0x0 + field public static final int LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE = 0; // 0x0 + field public static final int LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED = 1; // 0x1 field public static final int NOISE_REDUCTION_MODE_FAST = 1; // 0x1 field public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2; // 0x2 field public static final int NOISE_REDUCTION_MODE_MINIMAL = 3; // 0x3 @@ -15867,6 +15875,7 @@ package android.hardware.camera2 { field public static final int REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6; // 0x6 field public static final int REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9; // 0x9 field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8 + field public static final int REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA = 11; // 0xb field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10; // 0xa @@ -15916,6 +15925,8 @@ package android.hardware.camera2 { field public static final int STATISTICS_FACE_DETECT_MODE_SIMPLE = 1; // 0x1 field public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0; // 0x0 field public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1; // 0x1 + field public static final int STATISTICS_OIS_DATA_MODE_OFF = 0; // 0x0 + field public static final int STATISTICS_OIS_DATA_MODE_ON = 1; // 0x1 field public static final int STATISTICS_SCENE_FLICKER_50HZ = 1; // 0x1 field public static final int STATISTICS_SCENE_FLICKER_60HZ = 2; // 0x2 field public static final int STATISTICS_SCENE_FLICKER_NONE = 0; // 0x0 @@ -15998,6 +16009,7 @@ package android.hardware.camera2 { field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> STATISTICS_FACE_DETECT_MODE; field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Boolean> STATISTICS_HOT_PIXEL_MAP_MODE; field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> STATISTICS_LENS_SHADING_MAP_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> STATISTICS_OIS_DATA_MODE; field public static final android.hardware.camera2.CaptureRequest.Key<android.hardware.camera2.params.TonemapCurve> TONEMAP_CURVE; field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Float> TONEMAP_GAMMA; field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> TONEMAP_MODE; @@ -16097,6 +16109,10 @@ package android.hardware.camera2 { field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> STATISTICS_HOT_PIXEL_MAP_MODE; field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.LensShadingMap> STATISTICS_LENS_SHADING_CORRECTION_MAP; field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_LENS_SHADING_MAP_MODE; + field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_OIS_DATA_MODE; + field public static final android.hardware.camera2.CaptureResult.Key<long[]> STATISTICS_OIS_TIMESTAMPS; + field public static final android.hardware.camera2.CaptureResult.Key<float[]> STATISTICS_OIS_X_SHIFTS; + field public static final android.hardware.camera2.CaptureResult.Key<float[]> STATISTICS_OIS_Y_SHIFTS; field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_SCENE_FLICKER; field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.TonemapCurve> TONEMAP_CURVE; field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> TONEMAP_GAMMA; @@ -16205,6 +16221,7 @@ package android.hardware.camera2.params { method public int getSurfaceGroupId(); method public java.util.List<android.view.Surface> getSurfaces(); method public void removeSurface(android.view.Surface); + method public void setPhysicalCameraId(java.lang.String); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR; field public static final int SURFACE_GROUP_ID_NONE = -1; // 0xffffffff @@ -21751,7 +21768,13 @@ package android.media { field public static final int CHANNEL_OUT_STEREO = 12; // 0xc field public static final int CHANNEL_OUT_SURROUND = 1052; // 0x41c field public static final android.os.Parcelable.Creator<android.media.AudioFormat> CREATOR; + field public static final int ENCODING_AAC_ELD = 15; // 0xf + field public static final int ENCODING_AAC_HE_V1 = 11; // 0xb + field public static final int ENCODING_AAC_HE_V2 = 12; // 0xc + field public static final int ENCODING_AAC_LC = 10; // 0xa + field public static final int ENCODING_AAC_XHE = 16; // 0x10 field public static final int ENCODING_AC3 = 5; // 0x5 + field public static final int ENCODING_AC4 = 17; // 0x11 field public static final int ENCODING_DEFAULT = 1; // 0x1 field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe field public static final int ENCODING_DTS = 7; // 0x7 @@ -21759,6 +21782,7 @@ package android.media { field public static final int ENCODING_E_AC3 = 6; // 0x6 field public static final int ENCODING_IEC61937 = 13; // 0xd field public static final int ENCODING_INVALID = 0; // 0x0 + field public static final int ENCODING_MP3 = 9; // 0x9 field public static final int ENCODING_PCM_16BIT = 2; // 0x2 field public static final int ENCODING_PCM_8BIT = 3; // 0x3 field public static final int ENCODING_PCM_FLOAT = 4; // 0x4 @@ -21801,6 +21825,7 @@ package android.media { method public boolean isBluetoothScoOn(); method public boolean isMicrophoneMute(); method public boolean isMusicActive(); + method public boolean isOffloadedPlaybackSupported(android.media.AudioFormat); method public boolean isSpeakerphoneOn(); method public boolean isStreamMute(int); method public boolean isVolumeFixed(); @@ -22101,6 +22126,7 @@ package android.media { method public int reloadStaticData(); method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener); method public deprecated void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener); + method public void removeStreamEventCallback(); method public int setAuxEffectSendLevel(float); method public int setBufferSizeInFrames(int); method public int setLoopPoints(int, int, int); @@ -22114,6 +22140,7 @@ package android.media { method public boolean setPreferredDevice(android.media.AudioDeviceInfo); method protected deprecated void setState(int); method public deprecated int setStereoVolume(float, float); + method public void setStreamEventCallback(java.util.concurrent.Executor, android.media.AudioTrack.StreamEventCallback); method public int setVolume(float); method public void stop() throws java.lang.IllegalStateException; method public int write(byte[], int, int); @@ -22149,6 +22176,7 @@ package android.media { method public android.media.AudioTrack.Builder setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException; method public android.media.AudioTrack.Builder setAudioFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException; method public android.media.AudioTrack.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException; + method public android.media.AudioTrack.Builder setOffloadedPlayback(boolean); method public android.media.AudioTrack.Builder setPerformanceMode(int); method public android.media.AudioTrack.Builder setSessionId(int) throws java.lang.IllegalArgumentException; method public android.media.AudioTrack.Builder setTransferMode(int) throws java.lang.IllegalArgumentException; @@ -22164,6 +22192,12 @@ package android.media { method public default void onRoutingChanged(android.media.AudioRouting); } + public static abstract class AudioTrack.StreamEventCallback { + method public void onStreamDataRequest(android.media.AudioTrack); + method public void onStreamPresentationEnd(android.media.AudioTrack); + method public void onTearDown(android.media.AudioTrack); + } + public class CamcorderProfile { method public static android.media.CamcorderProfile get(int); method public static android.media.CamcorderProfile get(int, int); @@ -27359,7 +27393,7 @@ package android.net.wifi { method public int addNetwork(android.net.wifi.WifiConfiguration); method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration); method public static int calculateSignalLevel(int, int); - method public void cancelWps(android.net.wifi.WifiManager.WpsCallback); + method public deprecated void cancelWps(android.net.wifi.WifiManager.WpsCallback); method public static int compareSignalLevel(int, int); method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String); method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String); @@ -27392,7 +27426,7 @@ package android.net.wifi { method public boolean setWifiEnabled(boolean); method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler); method public deprecated boolean startScan(); - method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback); + method public deprecated void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback); method public int updateNetwork(android.net.wifi.WifiConfiguration); field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE"; @@ -27422,11 +27456,11 @@ package android.net.wifi { field public static final int WIFI_STATE_ENABLED = 3; // 0x3 field public static final int WIFI_STATE_ENABLING = 2; // 0x2 field public static final int WIFI_STATE_UNKNOWN = 4; // 0x4 - field public static final int WPS_AUTH_FAILURE = 6; // 0x6 - field public static final int WPS_OVERLAP_ERROR = 3; // 0x3 - field public static final int WPS_TIMED_OUT = 7; // 0x7 - field public static final int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5 - field public static final int WPS_WEP_PROHIBITED = 4; // 0x4 + field public static final deprecated int WPS_AUTH_FAILURE = 6; // 0x6 + field public static final deprecated int WPS_OVERLAP_ERROR = 3; // 0x3 + field public static final deprecated int WPS_TIMED_OUT = 7; // 0x7 + field public static final deprecated int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5 + field public static final deprecated int WPS_WEP_PROHIBITED = 4; // 0x4 } public static class WifiManager.LocalOnlyHotspotCallback { @@ -27460,11 +27494,11 @@ package android.net.wifi { method public void setWorkSource(android.os.WorkSource); } - public static abstract class WifiManager.WpsCallback { + public static abstract deprecated class WifiManager.WpsCallback { ctor public WifiManager.WpsCallback(); - method public abstract void onFailed(int); - method public abstract void onStarted(java.lang.String); - method public abstract void onSucceeded(); + method public abstract deprecated void onFailed(int); + method public abstract deprecated void onStarted(java.lang.String); + method public abstract deprecated void onSucceeded(); } public class WpsInfo implements android.os.Parcelable { @@ -31530,7 +31564,7 @@ package android.os { } public final class Debug { - method public static void attachJvmtiAgent(java.lang.String, java.lang.String) throws java.io.IOException; + method public static void attachJvmtiAgent(java.lang.String, java.lang.String, java.lang.ClassLoader) throws java.io.IOException; method public static deprecated void changeDebugPort(int); method public static void dumpHprofData(java.lang.String) throws java.io.IOException; method public static boolean dumpService(java.lang.String, java.io.FileDescriptor, java.lang.String[]); @@ -34007,9 +34041,10 @@ package android.provider { field public static final java.lang.String DURATION = "duration"; field public static final java.lang.String EXTRA_CALL_TYPE_FILTER = "android.provider.extra.CALL_TYPE_FILTER"; field public static final java.lang.String FEATURES = "features"; + field public static final int FEATURES_ASSISTED_DIALING_USED = 16; // 0x10 field public static final int FEATURES_HD_CALL = 4; // 0x4 field public static final int FEATURES_PULLED_EXTERNALLY = 2; // 0x2 - field public static final int FEATURES_RTT = 16; // 0x10 + field public static final int FEATURES_RTT = 32; // 0x20 field public static final int FEATURES_VIDEO = 1; // 0x1 field public static final int FEATURES_WIFI = 8; // 0x8 field public static final java.lang.String GEOCODED_LOCATION = "geocoded_location"; @@ -39857,6 +39892,7 @@ package android.telecom { field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800 field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2 field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8 + field public static final int PROPERTY_ASSISTED_DIALING_USED = 512; // 0x200 field public static final int PROPERTY_CONFERENCE = 1; // 0x1 field public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 4; // 0x4 field public static final int PROPERTY_ENTERPRISE_CALL = 32; // 0x20 @@ -40077,6 +40113,7 @@ package android.telecom { field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS"; field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER"; + field public static final int PROPERTY_ASSISTED_DIALING_USED = 512; // 0x200 field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 32; // 0x20 field public static final int PROPERTY_IS_EXTERNAL_CALL = 16; // 0x10 field public static final int PROPERTY_IS_RTT = 256; // 0x100 @@ -40499,6 +40536,7 @@ package android.telecom { field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS"; field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ',' field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';' + field public static final java.lang.String EXTRA_ASSISTED_DIALING_TRANSFORMATION_INFO = "android.telecom.extra.ASSISTED_DIALING_TRANSFORMATION_INFO"; field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER"; field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE"; field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE"; @@ -40514,6 +40552,7 @@ package android.telecom { field public static final java.lang.String EXTRA_START_CALL_WITH_RTT = "android.telecom.extra.START_CALL_WITH_RTT"; field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE"; field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE"; + field public static final java.lang.String EXTRA_USE_ASSISTED_DIALING = "android.telecom.extra.USE_ASSISTED_DIALING"; field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS"; field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE"; field public static final java.lang.String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS"; @@ -40526,6 +40565,18 @@ package android.telecom { field public static final int PRESENTATION_UNKNOWN = 3; // 0x3 } + public final class TransformationInfo implements android.os.Parcelable { + ctor public TransformationInfo(java.lang.String, java.lang.String, java.lang.String, java.lang.String, int); + method public int describeContents(); + method public java.lang.String getOriginalNumber(); + method public java.lang.String getTransformedNumber(); + method public int getTransformedNumberCountryCallingCode(); + method public java.lang.String getUserHomeCountryCode(); + method public java.lang.String getUserRoamingCountryCode(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telecom.TransformationInfo> CREATOR; + } + public class VideoProfile implements android.os.Parcelable { ctor public VideoProfile(int); ctor public VideoProfile(int, int); @@ -40689,6 +40740,7 @@ package android.telephony { field public static final java.lang.String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool"; field public static final java.lang.String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool"; field public static final java.lang.String KEY_APN_EXPAND_BOOL = "apn_expand_bool"; + field public static final java.lang.String KEY_ASSISTED_DIALING_ENABLED_BOOL = "assisted_dialing_enabled_bool"; field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool"; field public static final java.lang.String KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY = "call_forwarding_blocks_while_roaming_string_array"; field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool"; @@ -41434,6 +41486,8 @@ package android.telephony { method public android.telephony.TelephonyManager createForPhoneAccountHandle(android.telecom.PhoneAccountHandle); method public android.telephony.TelephonyManager createForSubscriptionId(int); method public java.util.List<android.telephony.CellInfo> getAllCellInfo(); + method public int getAndroidCarrierIdForSubscription(); + method public java.lang.CharSequence getAndroidCarrierNameForSubscription(); method public int getCallState(); method public android.os.PersistableBundle getCarrierConfig(); method public deprecated android.telephony.CellLocation getCellLocation(); @@ -41471,8 +41525,6 @@ package android.telephony { method public int getSimState(); method public int getSimState(int); method public java.lang.String getSubscriberId(); - method public int getSubscriptionCarrierId(); - method public java.lang.String getSubscriptionCarrierName(); method public java.lang.String getVisualVoicemailPackageName(); method public java.lang.String getVoiceMailAlphaTag(); method public java.lang.String getVoiceMailNumber(); diff --git a/api/system-current.txt b/api/system-current.txt index 66b6d990ec0c..a1ec2c44cd49 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -131,6 +131,7 @@ package android { field public static final java.lang.String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE"; field public static final java.lang.String READ_RUNTIME_PROFILES = "android.permission.READ_RUNTIME_PROFILES"; field public static final java.lang.String READ_SEARCH_INDEXABLES = "android.permission.READ_SEARCH_INDEXABLES"; + field public static final java.lang.String READ_SYSTEM_UPDATE_INFO = "android.permission.READ_SYSTEM_UPDATE_INFO"; field public static final java.lang.String READ_WALLPAPER_INTERNAL = "android.permission.READ_WALLPAPER_INTERNAL"; field public static final java.lang.String READ_WIFI_CREDENTIAL = "android.permission.READ_WIFI_CREDENTIAL"; field public static final java.lang.String REAL_GET_TASKS = "android.permission.REAL_GET_TASKS"; @@ -380,6 +381,7 @@ package android.app.admin { method public java.lang.CharSequence getDeviceOwnerOrganizationName(); method public java.util.List<java.lang.String> getPermittedAccessibilityServices(int); method public java.util.List<java.lang.String> getPermittedInputMethodsForCurrentUser(); + method public java.lang.CharSequence getPrintingDisabledReason(); method public android.content.ComponentName getProfileOwner() throws java.lang.IllegalArgumentException; method public java.lang.String getProfileOwnerNameAsUser(int) throws java.lang.IllegalArgumentException; method public int getUserProvisioningState(); @@ -760,6 +762,7 @@ package android.content { field public static final java.lang.String OEM_LOCK_SERVICE = "oem_lock"; field public static final java.lang.String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block"; field public static final java.lang.String STATS_MANAGER = "stats"; + field public static final java.lang.String SYSTEM_UPDATE_SERVICE = "system_update"; field public static final java.lang.String VR_SERVICE = "vrmanager"; field public static final java.lang.String WIFI_RTT_SERVICE = "rttmanager"; field public static final java.lang.String WIFI_SCANNING_SERVICE = "wifiscanner"; @@ -3502,6 +3505,22 @@ package android.os { method public abstract void onResult(android.os.Bundle); } + public class SystemUpdateManager { + method public android.os.Bundle retrieveSystemUpdateInfo(); + method public void updateSystemUpdateInfo(android.os.PersistableBundle); + field public static final java.lang.String KEY_IS_SECURITY_UPDATE = "is_security_update"; + field public static final java.lang.String KEY_STATUS = "status"; + field public static final java.lang.String KEY_TARGET_BUILD_FINGERPRINT = "target_build_fingerprint"; + field public static final java.lang.String KEY_TARGET_SECURITY_PATCH_LEVEL = "target_security_patch_level"; + field public static final java.lang.String KEY_TITLE = "title"; + field public static final int STATUS_IDLE = 1; // 0x1 + field public static final int STATUS_IN_PROGRESS = 3; // 0x3 + field public static final int STATUS_UNKNOWN = 0; // 0x0 + field public static final int STATUS_WAITING_DOWNLOAD = 2; // 0x2 + field public static final int STATUS_WAITING_INSTALL = 4; // 0x4 + field public static final int STATUS_WAITING_REBOOT = 5; // 0x5 + } + public class UpdateEngine { ctor public UpdateEngine(); method public void applyPayload(java.lang.String, long, long, java.lang.String[]); diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 9d6d8a1f2b73..7a7a2f617e6a 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -127,6 +127,10 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event) { StatsdStats::getInstance().noteAtomLogged( event->GetTagId(), event->GetTimestampNs() / NS_PER_SEC); + if (mMetricsManagers.empty()) { + return; + } + // Hard-coded logic to update the isolated uid's in the uid-map. // The field numbers need to be currently updated by hand with atoms.proto if (event->GetTagId() == android::util::ISOLATED_UID_CHANGED) { diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index ef99c9f4d7e3..a07bd2f50607 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -327,8 +327,9 @@ message ScheduledJobStateChanged { optional string name = 2; enum State { - OFF = 0; - ON = 1; + FINISHED = 0; + STARTED = 1; + SCHEDULED = 2; } optional State state = 3; diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index ccb54f93ba33..da9f72855e09 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -339,4 +339,9 @@ public abstract class ActivityManagerInternal { * Returns maximum number of users that can run simultaneously. */ public abstract int getMaxRunningUsers(); + + /** + * Returns is the caller has the same uid as the Recents component + */ + public abstract boolean isCallerRecents(int callingUid); } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 33277eae0520..fb8d1017e205 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -112,6 +112,7 @@ import android.os.IBinder; import android.os.IHardwarePropertiesManager; import android.os.IPowerManager; import android.os.IRecoverySystem; +import android.os.ISystemUpdateManager; import android.os.IUserManager; import android.os.IncidentManager; import android.os.PowerManager; @@ -119,6 +120,7 @@ import android.os.Process; import android.os.RecoverySystem; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; +import android.os.SystemUpdateManager; import android.os.SystemVibrator; import android.os.UserHandle; import android.os.UserManager; @@ -485,6 +487,17 @@ final class SystemServiceRegistry { return new StorageStatsManager(ctx, service); }}); + registerService(Context.SYSTEM_UPDATE_SERVICE, SystemUpdateManager.class, + new CachedServiceFetcher<SystemUpdateManager>() { + @Override + public SystemUpdateManager createService(ContextImpl ctx) + throws ServiceNotFoundException { + IBinder b = ServiceManager.getServiceOrThrow( + Context.SYSTEM_UPDATE_SERVICE); + ISystemUpdateManager service = ISystemUpdateManager.Stub.asInterface(b); + return new SystemUpdateManager(service); + }}); + registerService(Context.TELEPHONY_SERVICE, TelephonyManager.class, new CachedServiceFetcher<TelephonyManager>() { @Override diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d465e0df6406..7fccda8c04e3 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -9210,10 +9210,13 @@ public class DevicePolicyManager { /** * Allows/disallows printing. * + * Called by a device owner or a profile owner. + * Device owner changes policy for all users. Profile owner can override it if present. + * Printing is enabled by default. If {@code FEATURE_PRINTING} is absent, the call is ignored. + * * @param admin which {@link DeviceAdminReceiver} this request is associated with. * @param enabled whether printing should be allowed or not. * @throws SecurityException if {@code admin} is neither device, nor profile owner. - * @hide */ public void setPrintingEnabled(@NonNull ComponentName admin, boolean enabled) { try { @@ -9224,10 +9227,12 @@ public class DevicePolicyManager { } /** - * Returns whether printing is enabled for current user. + * Returns whether printing is enabled for this user. + * + * Always {@code false} if {@code FEATURE_PRINTING} is absent. + * Otherwise, {@code true} by default. * * @return {@code true} iff printing is enabled. - * @hide */ public boolean isPrintingEnabled() { try { @@ -9242,9 +9247,9 @@ public class DevicePolicyManager { * * Used only by PrintService. * @return Localized error message. - * @throws SecurityException if caller is not system. * @hide */ + @SystemApi public CharSequence getPrintingDisabledReason() { try { return mService.getPrintingDisabledReason(); diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java index 8ffacf5280c1..c4316a0ba086 100644 --- a/core/java/android/app/slice/SliceProvider.java +++ b/core/java/android/app/slice/SliceProvider.java @@ -299,7 +299,7 @@ public abstract class SliceProvider extends ContentProvider { @Override public Bundle call(String method, String arg, Bundle extras) { if (method.equals(METHOD_SLICE)) { - Uri uri = extras.getParcelable(EXTRA_BIND_URI); + Uri uri = getUriWithoutUserId(extras.getParcelable(EXTRA_BIND_URI)); List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS); String callingPackage = getCallingPackage(); @@ -327,19 +327,19 @@ public abstract class SliceProvider extends ContentProvider { } return b; } else if (method.equals(METHOD_PIN)) { - Uri uri = extras.getParcelable(EXTRA_BIND_URI); + Uri uri = getUriWithoutUserId(extras.getParcelable(EXTRA_BIND_URI)); if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("Only the system can pin/unpin slices"); } handlePinSlice(uri); } else if (method.equals(METHOD_UNPIN)) { - Uri uri = extras.getParcelable(EXTRA_BIND_URI); + Uri uri = getUriWithoutUserId(extras.getParcelable(EXTRA_BIND_URI)); if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("Only the system can pin/unpin slices"); } handleUnpinSlice(uri); } else if (method.equals(METHOD_GET_DESCENDANTS)) { - Uri uri = extras.getParcelable(EXTRA_BIND_URI); + Uri uri = getUriWithoutUserId(extras.getParcelable(EXTRA_BIND_URI)); Bundle b = new Bundle(); b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS, new ArrayList<>(handleGetDescendants(uri))); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 265f7c7425db..f69aab01d821 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3024,7 +3024,8 @@ public abstract class Context { //@hide: INCIDENT_SERVICE, //@hide: STATS_COMPANION_SERVICE, COMPANION_DEVICE_SERVICE, - CROSS_PROFILE_APPS_SERVICE + CROSS_PROFILE_APPS_SERVICE, + //@hide: SYSTEM_UPDATE_SERVICE, }) @Retention(RetentionPolicy.SOURCE) public @interface ServiceName {} @@ -3242,6 +3243,17 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve a + * {@link android.os.SystemUpdateManager} for accessing the system update + * manager service. + * + * @see #getSystemService(String) + * @hide + */ + @SystemApi + public static final String SYSTEM_UPDATE_SERVICE = "system_update"; + + /** + * Use with {@link #getSystemService(String)} to retrieve a * {@link android.view.WindowManager} for accessing the system's window * manager. * diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 1201ef48220a..b1671fc90a0d 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -22,9 +22,11 @@ import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.impl.PublicKey; import android.hardware.camera2.impl.SyntheticKey; import android.hardware.camera2.params.SessionConfiguration; +import android.hardware.camera2.utils.ArrayUtils; import android.hardware.camera2.utils.TypeReference; import android.util.Rational; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -407,6 +409,47 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri return Collections.unmodifiableList(staticKeyList); } + /** + * Returns the list of physical camera ids that this logical {@link CameraDevice} is + * made up of. + * + * <p>A camera device is a logical camera if it has + * REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA capability. If the camera device + * doesn't have the capability, the return value will be an empty list. </p> + * + * <p>The list returned is not modifiable, so any attempts to modify it will throw + * a {@code UnsupportedOperationException}.</p> + * + * <p>Each physical camera id is only listed once in the list. The order of the keys + * is undefined.</p> + * + * @return List of physical camera ids for this logical camera device. + */ + @NonNull + public List<String> getPhysicalCameraIds() { + int[] availableCapabilities = get(REQUEST_AVAILABLE_CAPABILITIES); + if (availableCapabilities == null) { + throw new AssertionError("android.request.availableCapabilities must be non-null " + + "in the characteristics"); + } + + if (!ArrayUtils.contains(availableCapabilities, + REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA)) { + return Collections.emptyList(); + } + byte[] physicalCamIds = get(LOGICAL_MULTI_CAMERA_PHYSICAL_IDS); + + String physicalCamIdString = null; + try { + physicalCamIdString = new String(physicalCamIds, "UTF-8"); + } catch (java.io.UnsupportedEncodingException e) { + throw new AssertionError("android.logicalCam.physicalIds must be UTF-8 string"); + } + String[] physicalCameraIdList = physicalCamIdString.split("\0"); + + return Collections.unmodifiableList(Arrays.asList(physicalCameraIdList)); + } + /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ * The key entries below this point are generated from metadata * definitions in /system/media/camera/docs. Do not modify by hand or @@ -1579,6 +1622,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO CONSTRAINED_HIGH_SPEED_VIDEO}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING MOTION_TRACKING}</li> + * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA LOGICAL_MULTI_CAMERA}</li> * </ul></p> * <p>This key is available on all devices.</p> * @@ -1594,6 +1638,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @see #REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT * @see #REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO * @see #REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING + * @see #REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA */ @PublicKey public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES = @@ -2870,6 +2915,21 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri new Key<int[]>("android.statistics.info.availableLensShadingMapModes", int[].class); /** + * <p>List of OIS data output modes for {@link CaptureRequest#STATISTICS_OIS_DATA_MODE android.statistics.oisDataMode} that + * are supported by this camera device.</p> + * <p>If no OIS data output is available for this camera device, this key will + * contain only OFF.</p> + * <p><b>Range of valid values:</b><br> + * Any value listed in {@link CaptureRequest#STATISTICS_OIS_DATA_MODE android.statistics.oisDataMode}</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> + * + * @see CaptureRequest#STATISTICS_OIS_DATA_MODE + */ + @PublicKey + public static final Key<int[]> STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES = + new Key<int[]>("android.statistics.info.availableOisDataModes", int[].class); + + /** * <p>Maximum number of supported points in the * tonemap curve that can be used for {@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}.</p> * <p>If the actual number of points provided by the application (in {@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}*) is @@ -2978,6 +3038,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}</li> * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}</li> * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_3 3}</li> + * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL EXTERNAL}</li> * </ul></p> * <p>This key is available on all devices.</p> * @@ -2991,6 +3052,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL * @see #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY * @see #INFO_SUPPORTED_HARDWARE_LEVEL_3 + * @see #INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL */ @PublicKey public static final Key<Integer> INFO_SUPPORTED_HARDWARE_LEVEL = @@ -3167,6 +3229,54 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri public static final Key<Boolean> DEPTH_DEPTH_IS_EXCLUSIVE = new Key<Boolean>("android.depth.depthIsExclusive", boolean.class); + /** + * <p>String containing the ids of the underlying physical cameras.</p> + * <p>For a logical camera, this is concatenation of all underlying physical camera ids. + * The null terminator for physical camera id must be preserved so that the whole string + * can be tokenized using '\0' to generate list of physical camera ids.</p> + * <p>For example, if the physical camera ids of the logical camera are "2" and "3", the + * value of this tag will be ['2', '\0', '3', '\0'].</p> + * <p>The number of physical camera ids must be no less than 2.</p> + * <p><b>Units</b>: UTF-8 null-terminated string</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> + * <p><b>Limited capability</b> - + * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the + * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p> + * + * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL + * @hide + */ + public static final Key<byte[]> LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = + new Key<byte[]>("android.logicalMultiCamera.physicalIds", byte[].class); + + /** + * <p>The accuracy of frame timestamp synchronization between physical cameras</p> + * <p>The accuracy of the frame timestamp synchronization determines the physical cameras' + * ability to start exposure at the same time. If the sensorSyncType is CALIBRATED, + * the physical camera sensors usually run in master-slave mode so that their shutter + * time is synchronized. For APPROXIMATE sensorSyncType, the camera sensors usually run in + * master-master mode, and there could be offset between their start of exposure.</p> + * <p>In both cases, all images generated for a particular capture request still carry the same + * timestamps, so that they can be used to look up the matching frame number and + * onCaptureStarted callback.</p> + * <p><b>Possible values:</b> + * <ul> + * <li>{@link #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE APPROXIMATE}</li> + * <li>{@link #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED CALIBRATED}</li> + * </ul></p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> + * <p><b>Limited capability</b> - + * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the + * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p> + * + * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL + * @see #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE + * @see #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED + */ + @PublicKey + public static final Key<Integer> LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE = + new Key<Integer>("android.logicalMultiCamera.sensorSyncType", int.class); + /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ * End generated code *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/ diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index 2294ec56525f..e7c8961186ec 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -845,6 +845,53 @@ public abstract class CameraMetadata<TKey> { */ public static final int REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10; + /** + * <p>The camera device is a logical camera backed by two or more physical cameras that are + * also exposed to the application.</p> + * <p>This capability requires the camera device to support the following:</p> + * <ul> + * <li>This camera device must list the following static metadata entries in {@link android.hardware.camera2.CameraCharacteristics }:<ul> + * <li>android.logicalMultiCamera.physicalIds</li> + * <li>{@link CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE android.logicalMultiCamera.sensorSyncType}</li> + * </ul> + * </li> + * <li>The underlying physical cameras' static metadata must list the following entries, + * so that the application can correlate pixels from the physical streams:<ul> + * <li>{@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference}</li> + * <li>{@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation}</li> + * <li>{@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}</li> + * <li>{@link CameraCharacteristics#LENS_INTRINSIC_CALIBRATION android.lens.intrinsicCalibration}</li> + * <li>{@link CameraCharacteristics#LENS_RADIAL_DISTORTION android.lens.radialDistortion}</li> + * </ul> + * </li> + * <li>The logical camera device must be LIMITED or higher device.</li> + * </ul> + * <p>Both the logical camera device and its underlying physical devices support the + * mandatory stream combinations required for their device levels.</p> + * <p>Additionally, for each guaranteed stream combination, the logical camera supports:</p> + * <ul> + * <li>Replacing one logical {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888} + * or raw stream with two physical streams of the same size and format, each from a + * separate physical camera, given that the size and format are supported by both + * physical cameras.</li> + * <li>Adding two raw streams, each from one physical camera, if the logical camera doesn't + * advertise RAW capability, but the underlying physical cameras do. This is usually + * the case when the physical cameras have different sensor sizes.</li> + * </ul> + * <p>Using physical streams in place of a logical stream of the same size and format will + * not slow down the frame rate of the capture, as long as the minimum frame duration + * of the physical and logical streams are the same.</p> + * + * @see CameraCharacteristics#LENS_INTRINSIC_CALIBRATION + * @see CameraCharacteristics#LENS_POSE_REFERENCE + * @see CameraCharacteristics#LENS_POSE_ROTATION + * @see CameraCharacteristics#LENS_POSE_TRANSLATION + * @see CameraCharacteristics#LENS_RADIAL_DISTORTION + * @see CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES + */ + public static final int REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA = 11; + // // Enumeration values for CameraCharacteristics#SCALER_CROPPING_TYPE // @@ -1134,6 +1181,38 @@ public abstract class CameraMetadata<TKey> { */ public static final int INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3; + /** + * <p>This camera device is backed by an external camera connected to this Android device.</p> + * <p>The device has capability identical to a LIMITED level device, with the following + * exceptions:</p> + * <ul> + * <li>The device may not report lens/sensor related information such as<ul> + * <li>{@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}</li> + * <li>{@link CameraCharacteristics#LENS_INFO_HYPERFOCAL_DISTANCE android.lens.info.hyperfocalDistance}</li> + * <li>{@link CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE android.sensor.info.physicalSize}</li> + * <li>{@link CameraCharacteristics#SENSOR_INFO_WHITE_LEVEL android.sensor.info.whiteLevel}</li> + * <li>{@link CameraCharacteristics#SENSOR_BLACK_LEVEL_PATTERN android.sensor.blackLevelPattern}</li> + * <li>{@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT android.sensor.info.colorFilterArrangement}</li> + * <li>{@link CaptureResult#SENSOR_ROLLING_SHUTTER_SKEW android.sensor.rollingShutterSkew}</li> + * </ul> + * </li> + * <li>The device will report 0 for {@link CameraCharacteristics#SENSOR_ORIENTATION android.sensor.orientation}</li> + * <li>The device has less guarantee on stable framerate, as the framerate partly depends + * on the external camera being used.</li> + * </ul> + * + * @see CaptureRequest#LENS_FOCAL_LENGTH + * @see CameraCharacteristics#LENS_INFO_HYPERFOCAL_DISTANCE + * @see CameraCharacteristics#SENSOR_BLACK_LEVEL_PATTERN + * @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT + * @see CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE + * @see CameraCharacteristics#SENSOR_INFO_WHITE_LEVEL + * @see CameraCharacteristics#SENSOR_ORIENTATION + * @see CaptureResult#SENSOR_ROLLING_SHUTTER_SKEW + * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL + */ + public static final int INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL = 4; + // // Enumeration values for CameraCharacteristics#SYNC_MAX_LATENCY // @@ -1160,6 +1239,26 @@ public abstract class CameraMetadata<TKey> { public static final int SYNC_MAX_LATENCY_UNKNOWN = -1; // + // Enumeration values for CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE + // + + /** + * <p>A software mechanism is used to synchronize between the physical cameras. As a result, + * the timestamp of an image from a physical stream is only an approximation of the + * image sensor start-of-exposure time.</p> + * @see CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE + */ + public static final int LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE = 0; + + /** + * <p>The camera device supports frame timestamp synchronization at the hardware level, + * and the timestamp of a physical stream image accurately reflects its + * start-of-exposure time.</p> + * @see CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE + */ + public static final int LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED = 1; + + // // Enumeration values for CaptureRequest#COLOR_CORRECTION_MODE // @@ -2566,6 +2665,22 @@ public abstract class CameraMetadata<TKey> { public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1; // + // Enumeration values for CaptureRequest#STATISTICS_OIS_DATA_MODE + // + + /** + * <p>Do not include OIS data in the capture result.</p> + * @see CaptureRequest#STATISTICS_OIS_DATA_MODE + */ + public static final int STATISTICS_OIS_DATA_MODE_OFF = 0; + + /** + * <p>Include OIS data in the capture result.</p> + * @see CaptureRequest#STATISTICS_OIS_DATA_MODE + */ + public static final int STATISTICS_OIS_DATA_MODE_ON = 1; + + // // Enumeration values for CaptureRequest#TONEMAP_MODE // diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index ce75fa52eff7..437d6b0e629f 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -2619,6 +2619,29 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> new Key<Integer>("android.statistics.lensShadingMapMode", int.class); /** + * <p>Whether the camera device outputs the OIS data in output + * result metadata.</p> + * <p>When set to ON, + * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}, android.statistics.oisShiftPixelX, + * android.statistics.oisShiftPixelY will provide OIS data in the output result metadata.</p> + * <p><b>Possible values:</b> + * <ul> + * <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li> + * <li>{@link #STATISTICS_OIS_DATA_MODE_ON ON}</li> + * </ul></p> + * <p><b>Available values for this device:</b><br> + * android.Statistics.info.availableOisDataModes</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> + * + * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS + * @see #STATISTICS_OIS_DATA_MODE_OFF + * @see #STATISTICS_OIS_DATA_MODE_ON + */ + @PublicKey + public static final Key<Integer> STATISTICS_OIS_DATA_MODE = + new Key<Integer>("android.statistics.oisDataMode", int.class); + + /** * <p>Tonemapping / contrast / gamma curve for the blue * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is * CONTRAST_CURVE.</p> diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 237a92d3ca9f..4b9351183681 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -3911,6 +3911,76 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { new Key<Integer>("android.statistics.lensShadingMapMode", int.class); /** + * <p>Whether the camera device outputs the OIS data in output + * result metadata.</p> + * <p>When set to ON, + * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}, android.statistics.oisShiftPixelX, + * android.statistics.oisShiftPixelY will provide OIS data in the output result metadata.</p> + * <p><b>Possible values:</b> + * <ul> + * <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li> + * <li>{@link #STATISTICS_OIS_DATA_MODE_ON ON}</li> + * </ul></p> + * <p><b>Available values for this device:</b><br> + * android.Statistics.info.availableOisDataModes</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> + * + * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS + * @see #STATISTICS_OIS_DATA_MODE_OFF + * @see #STATISTICS_OIS_DATA_MODE_ON + */ + @PublicKey + public static final Key<Integer> STATISTICS_OIS_DATA_MODE = + new Key<Integer>("android.statistics.oisDataMode", int.class); + + /** + * <p>An array of timestamps of OIS samples, in nanoseconds.</p> + * <p>The array contains the timestamps of OIS samples. The timestamps are in the same + * timebase as and comparable to {@link CaptureResult#SENSOR_TIMESTAMP android.sensor.timestamp}.</p> + * <p><b>Units</b>: nanoseconds</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> + * + * @see CaptureResult#SENSOR_TIMESTAMP + */ + @PublicKey + public static final Key<long[]> STATISTICS_OIS_TIMESTAMPS = + new Key<long[]>("android.statistics.oisTimestamps", long[].class); + + /** + * <p>An array of shifts of OIS samples, in x direction.</p> + * <p>The array contains the amount of shifts in x direction, in pixels, based on OIS samples. + * A positive value is a shift from left to right in active array coordinate system. For + * example, if the optical center is (1000, 500) in active array coordinates, an shift of + * (3, 0) puts the new optical center at (1003, 500).</p> + * <p>The number of shifts must match the number of timestamps in + * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}.</p> + * <p><b>Units</b>: Pixels in active array.</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> + * + * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS + */ + @PublicKey + public static final Key<float[]> STATISTICS_OIS_X_SHIFTS = + new Key<float[]>("android.statistics.oisXShifts", float[].class); + + /** + * <p>An array of shifts of OIS samples, in y direction.</p> + * <p>The array contains the amount of shifts in y direction, in pixels, based on OIS samples. + * A positive value is a shift from top to bottom in active array coordinate system. For + * example, if the optical center is (1000, 500) in active array coordinates, an shift of + * (0, 5) puts the new optical center at (1000, 505).</p> + * <p>The number of shifts must match the number of timestamps in + * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}.</p> + * <p><b>Units</b>: Pixels in active array.</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> + * + * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS + */ + @PublicKey + public static final Key<float[]> STATISTICS_OIS_Y_SHIFTS = + new Key<float[]>("android.statistics.oisYShifts", float[].class); + + /** * <p>Tonemapping / contrast / gamma curve for the blue * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is * CONTRAST_CURVE.</p> diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index 4455d45d4160..8d1c96f6fb7f 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -18,13 +18,14 @@ package android.hardware.camera2.impl; import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable; +import android.hardware.ICameraService; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; +import android.hardware.camera2.CaptureFailure; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; -import android.hardware.camera2.CaptureFailure; import android.hardware.camera2.ICameraDeviceCallbacks; import android.hardware.camera2.ICameraDeviceUser; import android.hardware.camera2.TotalCaptureResult; @@ -34,7 +35,6 @@ import android.hardware.camera2.params.SessionConfiguration; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.utils.SubmitInfo; import android.hardware.camera2.utils.SurfaceUtils; -import android.hardware.ICameraService; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -49,16 +49,14 @@ import android.view.Surface; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.LinkedList; +import java.util.List; import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicBoolean; /** * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate @@ -956,7 +954,8 @@ public class CameraDeviceImpl extends CameraDevice // callback is valid handler = checkHandler(handler, callback); - // Make sure that there all requests have at least 1 surface; all surfaces are non-null + // Make sure that there all requests have at least 1 surface; all surfaces are non-null; + // the surface isn't a physical stream surface for reprocessing request for (CaptureRequest request : requestList) { if (request.getTargets().isEmpty()) { throw new IllegalArgumentException( @@ -967,7 +966,20 @@ public class CameraDeviceImpl extends CameraDevice if (surface == null) { throw new IllegalArgumentException("Null Surface targets are not allowed"); } + + if (!request.isReprocess()) { + continue; + } + for (int i = 0; i < mConfiguredOutputs.size(); i++) { + OutputConfiguration configuration = mConfiguredOutputs.valueAt(i); + if (configuration.isForPhysicalCamera() + && configuration.getSurfaces().contains(surface)) { + throw new IllegalArgumentException( + "Reprocess request on physical stream is not allowed"); + } + } } + } synchronized(mInterfaceLock) { diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java index a85b5f710696..f47cd665fd9c 100644 --- a/core/java/android/hardware/camera2/params/OutputConfiguration.java +++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java @@ -31,13 +31,12 @@ import android.util.Log; import android.util.Size; import android.view.Surface; -import java.util.Arrays; -import java.util.List; -import java.util.Collections; -import java.util.ArrayList; - import static com.android.internal.util.Preconditions.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * A class for describing camera output, which contains a {@link Surface} and its specific * configuration for creating capture session. @@ -266,6 +265,7 @@ public final class OutputConfiguration implements Parcelable { mConfiguredGenerationId = surface.getGenerationId(); mIsDeferredConfig = false; mIsShared = false; + mPhysicalCameraId = null; } /** @@ -319,6 +319,7 @@ public final class OutputConfiguration implements Parcelable { mConfiguredGenerationId = 0; mIsDeferredConfig = true; mIsShared = false; + mPhysicalCameraId = null; } /** @@ -348,8 +349,9 @@ public final class OutputConfiguration implements Parcelable { * </ol> * * <p>To enable surface sharing, this function must be called before {@link - * CameraDevice#createCaptureSessionByOutputConfigurations}. Calling this function after {@link - * CameraDevice#createCaptureSessionByOutputConfigurations} has no effect.</p> + * CameraDevice#createCaptureSessionByOutputConfigurations} or {@link + * CameraDevice#createReprocessableCaptureSessionByConfigurations}. Calling this function after + * {@link CameraDevice#createCaptureSessionByOutputConfigurations} has no effect.</p> * * <p>Up to {@link #getMaxSharedSurfaceCount} surfaces can be shared for an OutputConfiguration. * The supported surfaces for sharing must be of type SurfaceTexture, SurfaceView, @@ -360,6 +362,44 @@ public final class OutputConfiguration implements Parcelable { } /** + * Set the id of the physical camera for this OutputConfiguration + * + * <p>In the case one logical camera is made up of multiple physical cameras, it could be + * desirable for the camera application to request streams from individual physical cameras. + * This call achieves it by mapping the OutputConfiguration to the physical camera id.</p> + * + * <p>The valid physical camera id can be queried by {@link + * android.hardware.camera2.CameraCharacteristics#getPhysicalCameraIds}. + * </p> + * + * <p>Passing in a null physicalCameraId means that the OutputConfiguration is for a logical + * stream.</p> + * + * <p>This function must be called before {@link + * CameraDevice#createCaptureSessionByOutputConfigurations} or {@link + * CameraDevice#createReprocessableCaptureSessionByConfigurations}. Calling this function + * after {@link CameraDevice#createCaptureSessionByOutputConfigurations} or {@link + * CameraDevice#createReprocessableCaptureSessionByConfigurations} has no effect.</p> + * + * <p>The surface belonging to a physical camera OutputConfiguration must not be used as input + * or output of a reprocessing request. </p> + */ + public void setPhysicalCameraId(@Nullable String physicalCameraId) { + mPhysicalCameraId = physicalCameraId; + } + + /** + * Check if this configuration is for a physical camera. + * + * <p>This returns true if the output configuration was for a physical camera making up a + * logical multi camera via {@link OutputConfiguration#setPhysicalCameraId}.</p> + * @hide + */ + public boolean isForPhysicalCamera() { + return (mPhysicalCameraId != null); + } + + /** * Check if this configuration has deferred configuration. * * <p>This will return true if the output configuration was constructed with surface deferred by @@ -487,6 +527,7 @@ public final class OutputConfiguration implements Parcelable { this.mConfiguredGenerationId = other.mConfiguredGenerationId; this.mIsDeferredConfig = other.mIsDeferredConfig; this.mIsShared = other.mIsShared; + this.mPhysicalCameraId = other.mPhysicalCameraId; } /** @@ -502,6 +543,7 @@ public final class OutputConfiguration implements Parcelable { boolean isShared = source.readInt() == 1; ArrayList<Surface> surfaces = new ArrayList<Surface>(); source.readTypedList(surfaces, Surface.CREATOR); + String physicalCameraId = source.readString(); checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant"); @@ -524,6 +566,7 @@ public final class OutputConfiguration implements Parcelable { StreamConfigurationMap.imageFormatToDataspace(ImageFormat.PRIVATE); mConfiguredGenerationId = 0; } + mPhysicalCameraId = physicalCameraId; } /** @@ -622,6 +665,7 @@ public final class OutputConfiguration implements Parcelable { dest.writeInt(mIsDeferredConfig ? 1 : 0); dest.writeInt(mIsShared ? 1 : 0); dest.writeTypedList(mSurfaces); + dest.writeString(mPhysicalCameraId); } /** @@ -675,13 +719,15 @@ public final class OutputConfiguration implements Parcelable { if (mIsDeferredConfig) { return HashCodeHelpers.hashCode( mRotation, mConfiguredSize.hashCode(), mConfiguredFormat, mConfiguredDataspace, - mSurfaceGroupId, mSurfaceType, mIsShared ? 1 : 0); + mSurfaceGroupId, mSurfaceType, mIsShared ? 1 : 0, + mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode()); } return HashCodeHelpers.hashCode( mRotation, mSurfaces.hashCode(), mConfiguredGenerationId, mConfiguredSize.hashCode(), mConfiguredFormat, - mConfiguredDataspace, mSurfaceGroupId, mIsShared ? 1 : 0); + mConfiguredDataspace, mSurfaceGroupId, mIsShared ? 1 : 0, + mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode()); } private static final String TAG = "OutputConfiguration"; @@ -701,4 +747,6 @@ public final class OutputConfiguration implements Parcelable { private final boolean mIsDeferredConfig; // Flag indicating if this config has shared surfaces private boolean mIsShared; + // The physical camera id that this output configuration is for. + private String mPhysicalCameraId; } diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl index 790c80b1d934..eeb30e23d000 100644 --- a/core/java/android/net/IIpSecService.aidl +++ b/core/java/android/net/IIpSecService.aidl @@ -39,9 +39,9 @@ interface IIpSecService void closeUdpEncapsulationSocket(int resourceId); - IpSecTransformResponse createTransportModeTransform(in IpSecConfig c, in IBinder binder); + IpSecTransformResponse createTransform(in IpSecConfig c, in IBinder binder); - void deleteTransportModeTransform(int transformId); + void deleteTransform(int transformId); void applyTransportModeTransform(in ParcelFileDescriptor socket, int direction, int transformId); diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java index be6026ff376e..37e2c4fbf04a 100644 --- a/core/java/android/net/IpSecTransform.java +++ b/core/java/android/net/IpSecTransform.java @@ -124,8 +124,7 @@ public final class IpSecTransform implements AutoCloseable { synchronized (this) { try { IIpSecService svc = getIpSecService(); - IpSecTransformResponse result = - svc.createTransportModeTransform(mConfig, new Binder()); + IpSecTransformResponse result = svc.createTransform(mConfig, new Binder()); int status = result.status; checkResultStatus(status); mResourceId = result.resourceId; @@ -170,7 +169,7 @@ public final class IpSecTransform implements AutoCloseable { * still want to clear out the transform. */ IIpSecService svc = getIpSecService(); - svc.deleteTransportModeTransform(mResourceId); + svc.deleteTransform(mResourceId); stopKeepalive(); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 49879a8a84a7..03a8dba5a82c 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -336,6 +336,9 @@ public abstract class BatteryStats implements Parcelable { private final StringBuilder mFormatBuilder = new StringBuilder(32); private final Formatter mFormatter = new Formatter(mFormatBuilder); + private static final String CELLULAR_CONTROLLER_NAME = "Cellular"; + private static final String WIFI_CONTROLLER_NAME = "WiFi"; + /** * Indicates times spent by the uid at each cpu frequency in all process states. * @@ -413,6 +416,13 @@ public abstract class BatteryStats implements Parcelable { /** * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the + * scan state. + */ + public abstract LongCounter getScanTimeCounter(); + + + /** + * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the * receive state. */ public abstract LongCounter getRxTimeCounter(); @@ -2399,6 +2409,14 @@ public abstract class BatteryStats implements Parcelable { public abstract long getWifiOnTime(long elapsedRealtimeUs, int which); /** + * Returns the time in microseconds that wifi has been active while the device was + * running on battery. + * + * {@hide} + */ + public abstract long getWifiActiveTime(long elapsedRealtimeUs, int which); + + /** * Returns the time in microseconds that wifi has been on and the driver has * been in the running state while the device was running on battery. * @@ -3345,6 +3363,20 @@ public abstract class BatteryStats implements Parcelable { final long sleepTimeMs = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + totalTxTimeMs); + if (controllerName.equals(WIFI_CONTROLLER_NAME)) { + final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); + sb.setLength(0); + sb.append(prefix); + sb.append(" "); + sb.append(controllerName); + sb.append(" Scan time: "); + formatTimeMs(sb, scanTimeMs); + sb.append("("); + sb.append(formatRatioLocked(scanTimeMs, totalControllerActivityTimeMs)); + sb.append(")"); + pw.println(sb.toString()); + } + sb.setLength(0); sb.append(prefix); sb.append(" "); @@ -3386,7 +3418,7 @@ public abstract class BatteryStats implements Parcelable { String [] powerLevel; switch(controllerName) { - case "Cellular": + case CELLULAR_CONTROLLER_NAME: powerLevel = new String[] { " less than 0dBm: ", " 0dBm to 8dBm: ", @@ -4674,7 +4706,7 @@ public abstract class BatteryStats implements Parcelable { if (!didOne) sb.append(" (no activity)"); pw.println(sb.toString()); - printControllerActivity(pw, sb, prefix, "Cellular", + printControllerActivity(pw, sb, prefix, CELLULAR_CONTROLLER_NAME, getModemControllerActivity(), which); pw.print(prefix); @@ -4683,6 +4715,16 @@ public abstract class BatteryStats implements Parcelable { sb.append(" Wifi Statistics:"); pw.println(sb.toString()); + pw.print(prefix); + sb.setLength(0); + sb.append(prefix); + sb.append(" Wifi kernel active time: "); + final long wifiActiveTime = getWifiActiveTime(rawRealtime, which); + formatTimeMs(sb, wifiActiveTime / 1000); + sb.append("("); sb.append(formatRatioLocked(wifiActiveTime, whichBatteryRealtime)); + sb.append(")"); + pw.println(sb.toString()); + pw.print(" Wifi data received: "); pw.println(formatBytesLocked(wifiRxTotalBytes)); pw.print(" Wifi data sent: "); pw.println(formatBytesLocked(wifiTxTotalBytes)); pw.print(" Wifi packets received: "); pw.println(wifiRxTotalPackets); @@ -4760,7 +4802,8 @@ public abstract class BatteryStats implements Parcelable { if (!didOne) sb.append(" (no activity)"); pw.println(sb.toString()); - printControllerActivity(pw, sb, prefix, "WiFi", getWifiControllerActivity(), which); + printControllerActivity(pw, sb, prefix, WIFI_CONTROLLER_NAME, + getWifiControllerActivity(), which); pw.print(prefix); sb.setLength(0); @@ -5238,8 +5281,8 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); } - printControllerActivityIfInteresting(pw, sb, prefix + " ", "Modem", - u.getModemControllerActivity(), which); + printControllerActivityIfInteresting(pw, sb, prefix + " ", + CELLULAR_CONTROLLER_NAME, u.getModemControllerActivity(), which); if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) { pw.print(prefix); pw.print(" Wi-Fi network: "); @@ -5293,7 +5336,7 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); } - printControllerActivityIfInteresting(pw, sb, prefix + " ", "WiFi", + printControllerActivityIfInteresting(pw, sb, prefix + " ", WIFI_CONTROLLER_NAME, u.getWifiControllerActivity(), which); if (btRxBytes > 0 || btTxBytes > 0) { diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 848ab88d3cbc..33e8c3e47b44 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -2352,22 +2352,28 @@ public final class Debug } /** - * Attach a library as a jvmti agent to the current runtime. + * Attach a library as a jvmti agent to the current runtime, with the given classloader + * determining the library search path. + * <p> + * Note: agents may only be attached to debuggable apps. Otherwise, this function will + * throw a SecurityException. * - * @param library library containing the agent - * @param options options passed to the agent + * @param library the library containing the agent. + * @param options the options passed to the agent. + * @param classLoader the classloader determining the library search path. * - * @throws IOException If the agent could not be attached + * @throws IOException if the agent could not be attached. + * @throws SecurityException if the app is not debuggable. */ - public static void attachJvmtiAgent(@NonNull String library, @Nullable String options) - throws IOException { + public static void attachJvmtiAgent(@NonNull String library, @Nullable String options, + @Nullable ClassLoader classLoader) throws IOException { Preconditions.checkNotNull(library); Preconditions.checkArgument(!library.contains("=")); if (options == null) { - VMDebug.attachAgent(library); + VMDebug.attachAgent(library, classLoader); } else { - VMDebug.attachAgent(library + "=" + options); + VMDebug.attachAgent(library + "=" + options, classLoader); } } } diff --git a/core/java/android/os/ISystemUpdateManager.aidl b/core/java/android/os/ISystemUpdateManager.aidl new file mode 100644 index 000000000000..f7f50791f528 --- /dev/null +++ b/core/java/android/os/ISystemUpdateManager.aidl @@ -0,0 +1,27 @@ +/* //device/java/android/android/os/ISystemUpdateInfo.aidl +** +** Copyright 2018, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.os; + +import android.os.Bundle; +import android.os.PersistableBundle; + +/** @hide */ +interface ISystemUpdateManager { + Bundle retrieveSystemUpdateInfo(); + void updateSystemUpdateInfo(in PersistableBundle data); +} diff --git a/core/java/android/os/SystemUpdateManager.java b/core/java/android/os/SystemUpdateManager.java new file mode 100644 index 000000000000..ce3e225975f0 --- /dev/null +++ b/core/java/android/os/SystemUpdateManager.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import static com.android.internal.util.Preconditions.checkNotNull; + +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.annotation.SystemService; +import android.content.Context; + +/** + * Allows querying and posting system update information. + * + * {@hide} + */ +@SystemApi +@SystemService(Context.SYSTEM_UPDATE_SERVICE) +public class SystemUpdateManager { + private static final String TAG = "SystemUpdateManager"; + + /** The status key of the system update info, expecting an int value. */ + @SystemApi + public static final String KEY_STATUS = "status"; + + /** The title of the current update, expecting a String value. */ + @SystemApi + public static final String KEY_TITLE = "title"; + + /** Whether it is a security update, expecting a boolean value. */ + @SystemApi + public static final String KEY_IS_SECURITY_UPDATE = "is_security_update"; + + /** The build fingerprint after installing the current update, expecting a String value. */ + @SystemApi + public static final String KEY_TARGET_BUILD_FINGERPRINT = "target_build_fingerprint"; + + /** The security patch level after installing the current update, expecting a String value. */ + @SystemApi + public static final String KEY_TARGET_SECURITY_PATCH_LEVEL = "target_security_patch_level"; + + /** + * The KEY_STATUS value that indicates there's no update status info available. + */ + @SystemApi + public static final int STATUS_UNKNOWN = 0; + + /** + * The KEY_STATUS value that indicates there's no pending update. + */ + @SystemApi + public static final int STATUS_IDLE = 1; + + /** + * The KEY_STATUS value that indicates an update is available for download, but pending user + * approval to start. + */ + @SystemApi + public static final int STATUS_WAITING_DOWNLOAD = 2; + + /** + * The KEY_STATUS value that indicates an update is in progress (i.e. downloading or installing + * has started). + */ + @SystemApi + public static final int STATUS_IN_PROGRESS = 3; + + /** + * The KEY_STATUS value that indicates an update is available for install. + */ + @SystemApi + public static final int STATUS_WAITING_INSTALL = 4; + + /** + * The KEY_STATUS value that indicates an update will be installed after a reboot. This applies + * to both of A/B and non-A/B OTAs. + */ + @SystemApi + public static final int STATUS_WAITING_REBOOT = 5; + + private final ISystemUpdateManager mService; + + /** @hide */ + public SystemUpdateManager(ISystemUpdateManager service) { + mService = checkNotNull(service, "missing ISystemUpdateManager"); + } + + /** + * Queries the current pending system update info. + * + * <p>Requires the {@link android.Manifest.permission#READ_SYSTEM_UPDATE_INFO} or + * {@link android.Manifest.permission#RECOVERY} permission. + * + * @return A {@code Bundle} that contains the pending system update information in key-value + * pairs. + * + * @throws SecurityException if the caller is not allowed to read the info. + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.READ_SYSTEM_UPDATE_INFO, + android.Manifest.permission.RECOVERY, + }) + public Bundle retrieveSystemUpdateInfo() { + try { + return mService.retrieveSystemUpdateInfo(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** + * Allows a system updater to publish the pending update info. + * + * <p>The reported info will not persist across reboots. Because only the reporting updater + * understands the criteria to determine a successful/failed update. + * + * <p>Requires the {@link android.Manifest.permission#RECOVERY} permission. + * + * @param infoBundle The {@code PersistableBundle} that contains the system update information, + * such as the current update status. {@link #KEY_STATUS} is required in the bundle. + * + * @throws IllegalArgumentException if @link #KEY_STATUS} does not exist. + * @throws SecurityException if the caller is not allowed to update the info. + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.RECOVERY) + public void updateSystemUpdateInfo(PersistableBundle infoBundle) { + if (infoBundle == null || !infoBundle.containsKey(KEY_STATUS)) { + throw new IllegalArgumentException("Missing status in the bundle"); + } + try { + mService.updateSystemUpdateInfo(infoBundle); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } +} diff --git a/core/java/android/os/connectivity/WifiBatteryStats.aidl b/core/java/android/os/connectivity/WifiBatteryStats.aidl new file mode 100644 index 000000000000..12ac73828eed --- /dev/null +++ b/core/java/android/os/connectivity/WifiBatteryStats.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2016 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.connectivity; + +/** {@hide} */ +parcelable WifiBatteryStats;
\ No newline at end of file diff --git a/core/java/android/os/connectivity/WifiBatteryStats.java b/core/java/android/os/connectivity/WifiBatteryStats.java new file mode 100644 index 000000000000..e5341eeeb17b --- /dev/null +++ b/core/java/android/os/connectivity/WifiBatteryStats.java @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2016 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.connectivity; + +import android.os.BatteryStats; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Arrays; + +/** + * API for Wifi power stats + * + * @hide + */ +public final class WifiBatteryStats implements Parcelable { + + private long mLoggingDurationMs; + private long mKernelActiveTimeMs; + private long mNumPacketsTx; + private long mNumBytesTx; + private long mNumPacketsRx; + private long mNumBytesRx; + private long mSleepTimeMs; + private long mScanTimeMs; + private long mIdleTimeMs; + private long mRxTimeMs; + private long mTxTimeMs; + private long mEnergyConsumedMaMs; + private long mNumAppScanRequest; + private long[] mTimeInStateMs; + private long[] mTimeInSupplicantStateMs; + private long[] mTimeInRxSignalStrengthLevelMs; + + public static final Parcelable.Creator<WifiBatteryStats> CREATOR = new + Parcelable.Creator<WifiBatteryStats>() { + public WifiBatteryStats createFromParcel(Parcel in) { + return new WifiBatteryStats(in); + } + + public WifiBatteryStats[] newArray(int size) { + return new WifiBatteryStats[size]; + } + }; + + public WifiBatteryStats() { + initialize(); + } + + public void writeToParcel(Parcel out, int flags) { + out.writeLong(mLoggingDurationMs); + out.writeLong(mKernelActiveTimeMs); + out.writeLong(mNumPacketsTx); + out.writeLong(mNumBytesTx); + out.writeLong(mNumPacketsRx); + out.writeLong(mNumBytesRx); + out.writeLong(mSleepTimeMs); + out.writeLong(mScanTimeMs); + out.writeLong(mIdleTimeMs); + out.writeLong(mRxTimeMs); + out.writeLong(mTxTimeMs); + out.writeLong(mEnergyConsumedMaMs); + out.writeLong(mNumAppScanRequest); + out.writeLongArray(mTimeInStateMs); + out.writeLongArray(mTimeInRxSignalStrengthLevelMs); + out.writeLongArray(mTimeInSupplicantStateMs); + } + + public void readFromParcel(Parcel in) { + mLoggingDurationMs = in.readLong(); + mKernelActiveTimeMs = in.readLong(); + mNumPacketsTx = in.readLong(); + mNumBytesTx = in.readLong(); + mNumPacketsRx = in.readLong(); + mNumBytesRx = in.readLong(); + mSleepTimeMs = in.readLong(); + mScanTimeMs = in.readLong(); + mIdleTimeMs = in.readLong(); + mRxTimeMs = in.readLong(); + mTxTimeMs = in.readLong(); + mEnergyConsumedMaMs = in.readLong(); + mNumAppScanRequest = in.readLong(); + in.readLongArray(mTimeInStateMs); + in.readLongArray(mTimeInRxSignalStrengthLevelMs); + in.readLongArray(mTimeInSupplicantStateMs); + } + + public long getLoggingDurationMs() { + return mLoggingDurationMs; + } + + public long getKernelActiveTimeMs() { + return mKernelActiveTimeMs; + } + + public long getNumPacketsTx() { + return mNumPacketsTx; + } + + public long getNumBytesTx() { + return mNumBytesTx; + } + + public long getNumPacketsRx() { + return mNumPacketsRx; + } + + public long getNumBytesRx() { + return mNumBytesRx; + } + + public long getSleepTimeMs() { + return mSleepTimeMs; + } + + public long getScanTimeMs() { + return mScanTimeMs; + } + + public long getIdleTimeMs() { + return mIdleTimeMs; + } + + public long getRxTimeMs() { + return mRxTimeMs; + } + + public long getTxTimeMs() { + return mTxTimeMs; + } + + public long getEnergyConsumedMaMs() { + return mEnergyConsumedMaMs; + } + + public long getNumAppScanRequest() { + return mNumAppScanRequest; + } + + public long[] getTimeInStateMs() { + return mTimeInStateMs; + } + + public long[] getTimeInRxSignalStrengthLevelMs() { + return mTimeInRxSignalStrengthLevelMs; + } + + public long[] getTimeInSupplicantStateMs() { + return mTimeInSupplicantStateMs; + } + + public void setLoggingDurationMs(long t) { + mLoggingDurationMs = t; + return; + } + + public void setKernelActiveTimeMs(long t) { + mKernelActiveTimeMs = t; + return; + } + + public void setNumPacketsTx(long n) { + mNumPacketsTx = n; + return; + } + + public void setNumBytesTx(long b) { + mNumBytesTx = b; + return; + } + + public void setNumPacketsRx(long n) { + mNumPacketsRx = n; + return; + } + + public void setNumBytesRx(long b) { + mNumBytesRx = b; + return; + } + + public void setSleepTimeMs(long t) { + mSleepTimeMs = t; + return; + } + + public void setScanTimeMs(long t) { + mScanTimeMs = t; + return; + } + + public void setIdleTimeMs(long t) { + mIdleTimeMs = t; + return; + } + + public void setRxTimeMs(long t) { + mRxTimeMs = t; + return; + } + + public void setTxTimeMs(long t) { + mTxTimeMs = t; + return; + } + + public void setEnergyConsumedMaMs(long e) { + mEnergyConsumedMaMs = e; + return; + } + + public void setNumAppScanRequest(long n) { + mNumAppScanRequest = n; + return; + } + + public void setTimeInStateMs(long[] t) { + mTimeInStateMs = Arrays.copyOfRange(t, 0, + Math.min(t.length, BatteryStats.NUM_WIFI_STATES)); + return; + } + + public void setTimeInRxSignalStrengthLevelMs(long[] t) { + mTimeInRxSignalStrengthLevelMs = Arrays.copyOfRange(t, 0, + Math.min(t.length, BatteryStats.NUM_WIFI_SIGNAL_STRENGTH_BINS)); + return; + } + + public void setTimeInSupplicantStateMs(long[] t) { + mTimeInSupplicantStateMs = Arrays.copyOfRange( + t, 0, Math.min(t.length, BatteryStats.NUM_WIFI_SUPPL_STATES)); + return; + } + + public int describeContents() { + return 0; + } + + private WifiBatteryStats(Parcel in) { + initialize(); + readFromParcel(in); + } + + private void initialize() { + mLoggingDurationMs = 0; + mKernelActiveTimeMs = 0; + mNumPacketsTx = 0; + mNumBytesTx = 0; + mNumPacketsRx = 0; + mNumBytesRx = 0; + mSleepTimeMs = 0; + mScanTimeMs = 0; + mIdleTimeMs = 0; + mRxTimeMs = 0; + mTxTimeMs = 0; + mEnergyConsumedMaMs = 0; + mNumAppScanRequest = 0; + mTimeInStateMs = new long[BatteryStats.NUM_WIFI_STATES]; + Arrays.fill(mTimeInStateMs, 0); + mTimeInRxSignalStrengthLevelMs = new long[BatteryStats.NUM_WIFI_SIGNAL_STRENGTH_BINS]; + Arrays.fill(mTimeInRxSignalStrengthLevelMs, 0); + mTimeInSupplicantStateMs = new long[BatteryStats.NUM_WIFI_SUPPL_STATES]; + Arrays.fill(mTimeInSupplicantStateMs, 0); + return; + } +}
\ No newline at end of file diff --git a/core/java/android/privacy/internal/rappor/RapporEncoder.java b/core/java/android/privacy/internal/rappor/RapporEncoder.java index 2eca4c98d235..9ac2b3e1136e 100644 --- a/core/java/android/privacy/internal/rappor/RapporEncoder.java +++ b/core/java/android/privacy/internal/rappor/RapporEncoder.java @@ -33,7 +33,6 @@ import java.util.Random; public class RapporEncoder implements DifferentialPrivacyEncoder { // Hard-coded seed and secret for insecure encoder - private static final long INSECURE_RANDOM_SEED = 0x12345678L; private static final byte[] INSECURE_SECRET = new byte[]{ (byte) 0xD7, (byte) 0x68, (byte) 0x99, (byte) 0x93, (byte) 0x94, (byte) 0x13, (byte) 0x53, (byte) 0x54, @@ -66,8 +65,8 @@ public class RapporEncoder implements DifferentialPrivacyEncoder { // Use SecureRandom as random generator. random = sSecureRandom; } else { - // Hard-coded random generator, to have deterministic result. - random = new Random(INSECURE_RANDOM_SEED); + // To have deterministic result by hard coding encoder id as seed. + random = new Random((long) config.mEncoderId.hashCode()); userSecret = INSECURE_SECRET; } mEncoder = new Encoder(random, null, null, diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java index 21694575631a..7ad9e013c617 100644 --- a/core/java/android/provider/AlarmClock.java +++ b/core/java/android/provider/AlarmClock.java @@ -154,9 +154,12 @@ public final class AlarmClock { public static final String ACTION_SET_TIMER = "android.intent.action.SET_TIMER"; /** - * Activity Action: Dismiss timers. + * Activity Action: Dismiss a timer. * <p> - * Dismiss all currently expired timers. If there are no expired timers, then this is a no-op. + * The timer to dismiss should be specified using the Intent's data URI, which represents a + * deeplink to the timer. + * </p><p> + * If no data URI is provided, dismiss all expired timers. * </p> */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 60df467bc20f..c6c8d9d69bfb 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -223,14 +223,13 @@ public class CallLog { /** Call was WIFI call. */ public static final int FEATURES_WIFI = 1 << 3; - /** Call was on RTT at some point */ - public static final int FEATURES_RTT = 1 << 4; - /** * Indicates the call underwent Assisted Dialing. - * @hide */ - public static final Integer FEATURES_ASSISTED_DIALING_USED = 0x10; + public static final int FEATURES_ASSISTED_DIALING_USED = 1 << 4; + + /** Call was on RTT at some point */ + public static final int FEATURES_RTT = 1 << 5; /** * The phone number as the user entered it. diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index b2cc18b94641..4228fbb7c40e 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -10128,7 +10128,8 @@ public final class Settings { * This is encoded as a key=value list, separated by commas. Ex: * * "battery_tip_enabled=true,summary_enabled=true,high_usage_enabled=true," - * "high_usage_app_count=3,reduced_battery_enabled=false,reduced_battery_percent=50" + * "high_usage_app_count=3,reduced_battery_enabled=false,reduced_battery_percent=50," + * "high_usage_battery_draining=25,high_usage_period_ms=3000" * * The following keys are supported: * @@ -10138,6 +10139,8 @@ public final class Settings { * battery_saver_tip_enabled (boolean) * high_usage_enabled (boolean) * high_usage_app_count (int) + * high_usage_period_ms (long) + * high_usage_battery_draining (int) * app_restriction_enabled (boolean) * reduced_battery_enabled (boolean) * reduced_battery_percent (int) @@ -10348,6 +10351,8 @@ public final class Settings { * The following keys are supported: * <pre> * track_cpu_times_by_proc_state (boolean) + * track_cpu_active_cluster_time (boolean) + * read_binary_cpu_time (boolean) * </pre> * * <p> @@ -10375,6 +10380,15 @@ public final class Settings { public static final String FORCED_APP_STANDBY_ENABLED = "forced_app_standby_enabled"; /** + * Whether or not to enable Forced App Standby on small battery devices. + * Type: int (0 for false, 1 for true) + * Default: 0 + * @hide + */ + public static final String FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED + = "forced_app_standby_for_small_battery_enabled"; + + /** * Whether or not Network Watchlist feature is enabled. * Type: int (0 for false, 1 for true) * Default: 0 diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java index 4e4caf04579f..df63a91790d8 100644 --- a/core/java/android/service/autofill/AutofillFieldClassificationService.java +++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java @@ -99,7 +99,9 @@ public abstract class AutofillFieldClassificationService extends Service { final String[] userDataValues = (String[]) args.arg5; final float[][] scores = onGetScores(algorithmName, algorithmArgs, actualValues, Arrays.asList(userDataValues)); - data.putParcelable(EXTRA_SCORES, new Scores(scores)); + if (scores != null) { + data.putParcelable(EXTRA_SCORES, new Scores(scores)); + } break; default: Log.w(TAG, "Handling unknown message: " + action); @@ -148,7 +150,8 @@ public abstract class AutofillFieldClassificationService extends Service { public float[][] onGetScores(@Nullable String algorithm, @Nullable Bundle args, @NonNull List<AutofillValue> actualValues, @NonNull List<String> userDataValues) { - throw new UnsupportedOperationException("Must be implemented by external service"); + Log.e(TAG, "service implementation (" + getClass() + " does not implement onGetScore()"); + return null; } private final class AutofillFieldClassificationServiceWrapper @@ -182,7 +185,7 @@ public abstract class AutofillFieldClassificationService extends Service { } } - private Scores(float[][] scores) { + private Scores(float[][] scores) { this.scores = scores; } diff --git a/core/java/android/text/style/AbsoluteSizeSpan.java b/core/java/android/text/style/AbsoluteSizeSpan.java index 908ef55a6ae9..3b4eea76b390 100644 --- a/core/java/android/text/style/AbsoluteSizeSpan.java +++ b/core/java/android/text/style/AbsoluteSizeSpan.java @@ -16,71 +16,105 @@ package android.text.style; +import android.annotation.NonNull; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; +/** + * A span that changes the size of the text it's attached to. + * <p> + * For example, the size of the text can be changed to 55dp like this: + * <pre>{@code + * SpannableString string = new SpannableString("Text with absolute size span"); + *string.setSpan(new AbsoluteSizeSpan(55, true), 10, 23, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/absolutesizespan.png" /> + * <figcaption>Text with text size updated.</figcaption> + */ public class AbsoluteSizeSpan extends MetricAffectingSpan implements ParcelableSpan { private final int mSize; - private boolean mDip; + private final boolean mDip; /** * Set the text size to <code>size</code> physical pixels. */ public AbsoluteSizeSpan(int size) { - mSize = size; + this(size, false); } /** - * Set the text size to <code>size</code> physical pixels, - * or to <code>size</code> device-independent pixels if - * <code>dip</code> is true. + * Set the text size to <code>size</code> physical pixels, or to <code>size</code> + * device-independent pixels if <code>dip</code> is true. */ public AbsoluteSizeSpan(int size, boolean dip) { mSize = size; mDip = dip; } - public AbsoluteSizeSpan(Parcel src) { + /** + * Creates an {@link AbsoluteSizeSpan} from a parcel. + */ + public AbsoluteSizeSpan(@NonNull Parcel src) { mSize = src.readInt(); mDip = src.readInt() != 0; } - + + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.ABSOLUTE_SIZE_SPAN; } - + + @Override public int describeContents() { return 0; } - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ - public void writeToParcelInternal(Parcel dest, int flags) { + @Override + public void writeToParcelInternal(@NonNull Parcel dest, int flags) { dest.writeInt(mSize); dest.writeInt(mDip ? 1 : 0); } + /** + * Get the text size. This is in physical pixels if {@link #getDip()} returns false or in + * device-independent pixels if {@link #getDip()} returns true. + * + * @return the text size, either in physical pixels or device-independent pixels. + * @see AbsoluteSizeSpan#AbsoluteSizeSpan(int, boolean) + */ public int getSize() { return mSize; } + /** + * Returns whether the size is in device-independent pixels or not, depending on the + * <code>dip</code> flag passed in {@link #AbsoluteSizeSpan(int, boolean)} + * + * @return <code>true</code> if the size is in device-independent pixels, <code>false</code> + * otherwise + * + * @see #AbsoluteSizeSpan(int, boolean) + */ public boolean getDip() { return mDip; } @Override - public void updateDrawState(TextPaint ds) { + public void updateDrawState(@NonNull TextPaint ds) { if (mDip) { ds.setTextSize(mSize * ds.density); } else { @@ -89,7 +123,7 @@ public class AbsoluteSizeSpan extends MetricAffectingSpan implements ParcelableS } @Override - public void updateMeasureState(TextPaint ds) { + public void updateMeasureState(@NonNull TextPaint ds) { if (mDip) { ds.setTextSize(mSize * ds.density); } else { diff --git a/core/java/android/text/style/BackgroundColorSpan.java b/core/java/android/text/style/BackgroundColorSpan.java index 4f471a8a2f85..44e35615ca55 100644 --- a/core/java/android/text/style/BackgroundColorSpan.java +++ b/core/java/android/text/style/BackgroundColorSpan.java @@ -27,11 +27,10 @@ import android.text.TextUtils; * Changes the background color of the text to which the span is attached. * <p> * For example, to set a green background color for a text you would create a {@link - * android.text.SpannableStringBuilder} based on the text and set the span. + * android.text.SpannableString} based on the text and set the span. * <pre>{@code * SpannableString string = new SpannableString("Text with a background color span"); - *string.setSpan(new BackgroundColorSpan(color), 12, 28, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - * }</pre> + *string.setSpan(new BackgroundColorSpan(color), 12, 28, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> * <img src="{@docRoot}reference/android/images/text/style/backgroundcolorspan.png" /> * <figcaption>Set a background color for the text.</figcaption> */ @@ -58,30 +57,29 @@ public class BackgroundColorSpan extends CharacterStyle mColor = src.readInt(); } + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.BACKGROUND_COLOR_SPAN; } + @Override public int describeContents() { return 0; } - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written. - */ + @Override public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ + @Override public void writeToParcelInternal(@NonNull Parcel dest, int flags) { dest.writeInt(mColor); } diff --git a/core/java/android/text/style/ForegroundColorSpan.java b/core/java/android/text/style/ForegroundColorSpan.java index 08ab2a1f1a20..f770674503f2 100644 --- a/core/java/android/text/style/ForegroundColorSpan.java +++ b/core/java/android/text/style/ForegroundColorSpan.java @@ -27,11 +27,10 @@ import android.text.TextUtils; * Changes the color of the text to which the span is attached. * <p> * For example, to set a green text color you would create a {@link - * android.text.SpannableStringBuilder} based on the text and set the span. + * android.text.SpannableString} based on the text and set the span. * <pre>{@code * SpannableString string = new SpannableString("Text with a foreground color span"); - *string.setSpan(new ForegroundColorSpan(color), 12, 28, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - * }</pre> + *string.setSpan(new ForegroundColorSpan(color), 12, 28, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> * <img src="{@docRoot}reference/android/images/text/style/foregroundcolorspan.png" /> * <figcaption>Set a text color.</figcaption> */ @@ -59,30 +58,29 @@ public class ForegroundColorSpan extends CharacterStyle mColor = src.readInt(); } + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.FOREGROUND_COLOR_SPAN; } + @Override public int describeContents() { return 0; } - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written. - */ + @Override public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ + @Override public void writeToParcelInternal(@NonNull Parcel dest, int flags) { dest.writeInt(mColor); } diff --git a/core/java/android/text/style/RelativeSizeSpan.java b/core/java/android/text/style/RelativeSizeSpan.java index 95f048a2e240..3094f27ab72d 100644 --- a/core/java/android/text/style/RelativeSizeSpan.java +++ b/core/java/android/text/style/RelativeSizeSpan.java @@ -16,56 +16,85 @@ package android.text.style; +import android.annotation.FloatRange; +import android.annotation.NonNull; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; +/** + * Uniformly scales the size of the text to which it's attached by a certain proportion. + * <p> + * For example, a <code>RelativeSizeSpan</code> that increases the text size by 50% can be + * constructed like this: + * <pre>{@code + * SpannableString string = new SpannableString("Text with relative size span"); + *string.setSpan(new RelativeSizeSpan(1.5f), 10, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/relativesizespan.png" /> + * <figcaption>Text increased by 50% with <code>RelativeSizeSpan</code>.</figcaption> + */ public class RelativeSizeSpan extends MetricAffectingSpan implements ParcelableSpan { private final float mProportion; - public RelativeSizeSpan(float proportion) { + /** + * Creates a {@link RelativeSizeSpan} based on a proportion. + * + * @param proportion the proportion with which the text is scaled. + */ + public RelativeSizeSpan(@FloatRange(from = 0) float proportion) { mProportion = proportion; } - public RelativeSizeSpan(Parcel src) { + /** + * Creates a {@link RelativeSizeSpan} from a parcel. + */ + public RelativeSizeSpan(@NonNull Parcel src) { mProportion = src.readFloat(); } - + + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.RELATIVE_SIZE_SPAN; } - + + @Override public int describeContents() { return 0; } - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ - public void writeToParcelInternal(Parcel dest, int flags) { + @Override + public void writeToParcelInternal(@NonNull Parcel dest, int flags) { dest.writeFloat(mProportion); } + /** + * @return the proportion with which the text size is changed. + */ public float getSizeChange() { return mProportion; } @Override - public void updateDrawState(TextPaint ds) { + public void updateDrawState(@NonNull TextPaint ds) { ds.setTextSize(ds.getTextSize() * mProportion); } @Override - public void updateMeasureState(TextPaint ds) { + public void updateMeasureState(@NonNull TextPaint ds) { ds.setTextSize(ds.getTextSize() * mProportion); } } diff --git a/core/java/android/text/style/ScaleXSpan.java b/core/java/android/text/style/ScaleXSpan.java index d085018572ec..6ef4ceccced1 100644 --- a/core/java/android/text/style/ScaleXSpan.java +++ b/core/java/android/text/style/ScaleXSpan.java @@ -16,45 +16,79 @@ package android.text.style; +import android.annotation.FloatRange; +import android.annotation.NonNull; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; +/** + * Scales horizontally the size of the text to which it's attached by a certain factor. + * <p> + * Values > 1.0 will stretch the text wider. Values < 1.0 will stretch the text narrower. + * <p> + * For example, a <code>ScaleXSpan</code> that stretches the text size by 100% can be + * constructed like this: + * <pre>{@code + * SpannableString string = new SpannableString("Text with ScaleX span"); + *string.setSpan(new ScaleXSpan(2f), 10, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/scalexspan.png" /> + * <figcaption>Text scaled by 100% with <code>ScaleXSpan</code>.</figcaption> + */ public class ScaleXSpan extends MetricAffectingSpan implements ParcelableSpan { private final float mProportion; - public ScaleXSpan(float proportion) { + /** + * Creates a {@link ScaleXSpan} based on a proportion. Values > 1.0 will stretch the text wider. + * Values < 1.0 will stretch the text narrower. + * + * @param proportion the horizontal scale factor. + */ + public ScaleXSpan(@FloatRange(from = 0) float proportion) { mProportion = proportion; } - public ScaleXSpan(Parcel src) { + /** + * Creates a {@link ScaleXSpan} from a parcel. + */ + public ScaleXSpan(@NonNull Parcel src) { mProportion = src.readFloat(); } - + + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.SCALE_X_SPAN; } - + + @Override public int describeContents() { return 0; } - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ - public void writeToParcelInternal(Parcel dest, int flags) { + @Override + public void writeToParcelInternal(@NonNull Parcel dest, int flags) { dest.writeFloat(mProportion); } + /** + * Get the horizontal scale factor for the text. + * + * @return the horizontal scale factor. + */ public float getScaleX() { return mProportion; } diff --git a/core/java/android/text/style/StrikethroughSpan.java b/core/java/android/text/style/StrikethroughSpan.java index 1389704f6ad8..a6305050656a 100644 --- a/core/java/android/text/style/StrikethroughSpan.java +++ b/core/java/android/text/style/StrikethroughSpan.java @@ -16,42 +16,65 @@ package android.text.style; +import android.annotation.NonNull; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; +/** + * A span that strikes through the text it's attached to. + * <p> + * The span can be used like this: + * <pre>{@code + * SpannableString string = new SpannableString("Text with strikethrough span"); + *string.setSpan(new StrikethroughSpan(), 10, 23, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/strikethroughspan.png" /> + * <figcaption>Strikethrough text.</figcaption> + */ public class StrikethroughSpan extends CharacterStyle implements UpdateAppearance, ParcelableSpan { + + /** + * Creates a {@link StrikethroughSpan}. + */ public StrikethroughSpan() { } - - public StrikethroughSpan(Parcel src) { + + /** + * Creates a {@link StrikethroughSpan} from a parcel. + */ + public StrikethroughSpan(@NonNull Parcel src) { } - + + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.STRIKETHROUGH_SPAN; } - + + @Override public int describeContents() { return 0; } - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ - public void writeToParcelInternal(Parcel dest, int flags) { + @Override + public void writeToParcelInternal(@NonNull Parcel dest, int flags) { } @Override - public void updateDrawState(TextPaint ds) { + public void updateDrawState(@NonNull TextPaint ds) { ds.setStrikeThruText(true); } } diff --git a/core/java/android/text/style/SubscriptSpan.java b/core/java/android/text/style/SubscriptSpan.java index f1b0d38cf624..3d15aad662b1 100644 --- a/core/java/android/text/style/SubscriptSpan.java +++ b/core/java/android/text/style/SubscriptSpan.java @@ -16,46 +16,74 @@ package android.text.style; +import android.annotation.NonNull; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; +/** + * The span that moves the position of the text baseline lower. + * <p> + * The span can be used like this: + * <pre>{@code + * SpannableString string = new SpannableString("☕- C8H10N4O2\n"); + *string.setSpan(new SubscriptSpan(), 4, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + *string.setSpan(new SubscriptSpan(), 6, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + *string.setSpan(new SubscriptSpan(), 9, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + *string.setSpan(new SubscriptSpan(), 11, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/subscriptspan.png" /> + * <figcaption>Text with <code>SubscriptSpan</code>.</figcaption> + * Note: Since the span affects the position of the text, if the text is on the last line of a + * TextView, it may appear cut. + */ public class SubscriptSpan extends MetricAffectingSpan implements ParcelableSpan { + + /** + * Creates a {@link SubscriptSpan}. + */ public SubscriptSpan() { } - - public SubscriptSpan(Parcel src) { + + /** + * Creates a {@link SubscriptSpan} from a parcel. + */ + public SubscriptSpan(@NonNull Parcel src) { } - + + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.SUBSCRIPT_SPAN; } - + + @Override public int describeContents() { return 0; } + @Override public void writeToParcel(Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ + @Override public void writeToParcelInternal(Parcel dest, int flags) { } @Override - public void updateDrawState(TextPaint tp) { - tp.baselineShift -= (int) (tp.ascent() / 2); + public void updateDrawState(@NonNull TextPaint textPaint) { + textPaint.baselineShift -= (int) (textPaint.ascent() / 2); } @Override - public void updateMeasureState(TextPaint tp) { - tp.baselineShift -= (int) (tp.ascent() / 2); + public void updateMeasureState(@NonNull TextPaint textPaint) { + textPaint.baselineShift -= (int) (textPaint.ascent() / 2); } } diff --git a/core/java/android/text/style/SuperscriptSpan.java b/core/java/android/text/style/SuperscriptSpan.java index abcf688f10ff..3dc9d3fdfe05 100644 --- a/core/java/android/text/style/SuperscriptSpan.java +++ b/core/java/android/text/style/SuperscriptSpan.java @@ -16,46 +16,71 @@ package android.text.style; +import android.annotation.NonNull; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; +/** + * The span that moves the position of the text baseline higher. + * <p> + * The span can be used like this: + * <pre>{@code + * SpannableString string = new SpannableString("1st example"); + *string.setSpan(new SuperscriptSpan(), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/superscriptspan.png" /> + * <figcaption>Text with <code>SuperscriptSpan</code>.</figcaption> + * Note: Since the span affects the position of the text, if the text is on the first line of a + * TextView, it may appear cut. This can be avoided by decreasing the text size with an {@link + * AbsoluteSizeSpan} + */ public class SuperscriptSpan extends MetricAffectingSpan implements ParcelableSpan { + /** + * Creates a {@link SuperscriptSpan}. + */ public SuperscriptSpan() { } - - public SuperscriptSpan(Parcel src) { + + /** + * Creates a {@link SuperscriptSpan} from a parcel. + */ + public SuperscriptSpan(@NonNull Parcel src) { } - + + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.SUPERSCRIPT_SPAN; } - + + @Override public int describeContents() { return 0; } - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ - public void writeToParcelInternal(Parcel dest, int flags) { + @Override + public void writeToParcelInternal(@NonNull Parcel dest, int flags) { } @Override - public void updateDrawState(TextPaint tp) { - tp.baselineShift += (int) (tp.ascent() / 2); + public void updateDrawState(@NonNull TextPaint textPaint) { + textPaint.baselineShift += (int) (textPaint.ascent() / 2); } @Override - public void updateMeasureState(TextPaint tp) { - tp.baselineShift += (int) (tp.ascent() / 2); + public void updateMeasureState(@NonNull TextPaint textPaint) { + textPaint.baselineShift += (int) (textPaint.ascent() / 2); } } diff --git a/core/java/android/text/style/UnderlineSpan.java b/core/java/android/text/style/UnderlineSpan.java index 9024dcd39256..800838ef92e9 100644 --- a/core/java/android/text/style/UnderlineSpan.java +++ b/core/java/android/text/style/UnderlineSpan.java @@ -16,42 +16,65 @@ package android.text.style; +import android.annotation.NonNull; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; +/** + * A span that underlines the text it's attached to. + * <p> + * The span can be used like this: + * <pre>{@code + * SpannableString string = new SpannableString("Text with underline span"); + *string.setSpan(new UnderlineSpan(), 10, 19, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/underlinespan.png" /> + * <figcaption>Underlined text.</figcaption> + */ public class UnderlineSpan extends CharacterStyle implements UpdateAppearance, ParcelableSpan { + + /** + * Creates an {@link UnderlineSpan}. + */ public UnderlineSpan() { } - - public UnderlineSpan(Parcel src) { + + /** + * Creates an {@link UnderlineSpan} from a parcel. + */ + public UnderlineSpan(@NonNull Parcel src) { } - + + @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ + @Override public int getSpanTypeIdInternal() { return TextUtils.UNDERLINE_SPAN; } - + + @Override public int describeContents() { return 0; } - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ - public void writeToParcelInternal(Parcel dest, int flags) { + @Override + public void writeToParcelInternal(@NonNull Parcel dest, int flags) { } @Override - public void updateDrawState(TextPaint ds) { + public void updateDrawState(@NonNull TextPaint ds) { ds.setUnderlineText(true); } } diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index e94f91a12905..4e98d9b09318 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -43,7 +43,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put("settings_battery_v2", "false"); DEFAULT_FLAGS.put("settings_battery_display_app_list", "false"); DEFAULT_FLAGS.put("settings_security_settings_v2", "true"); - DEFAULT_FLAGS.put("settings_zone_picker_v2", "false"); + DEFAULT_FLAGS.put("settings_zone_picker_v2", "true"); DEFAULT_FLAGS.put("settings_suggestion_ui_v2", "false"); } diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 1f7f8b9a0c32..8830c90addac 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -283,6 +283,7 @@ public class Surface implements Parcelable { */ public long getNextFrameNumber() { synchronized (mLock) { + checkNotReleasedLocked(); return nativeGetNextFrameNumber(mNativeObject); } } diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index e2d1ad59043e..d3e807d99990 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -23,6 +23,7 @@ import android.net.wifi.WifiActivityEnergyInfo; import android.os.ParcelFileDescriptor; import android.os.WorkSource; import android.os.connectivity.CellularBatteryStats; +import android.os.connectivity.WifiBatteryStats; import android.os.connectivity.GpsBatteryStats; import android.os.health.HealthStatsParceler; import android.telephony.DataConnectionRealTimeInfo; @@ -143,6 +144,9 @@ interface IBatteryStats { CellularBatteryStats getCellularBatteryStats(); /** {@hide} */ + WifiBatteryStats getWifiBatteryStats(); + + /** {@hide} */ GpsBatteryStats getGpsBatteryStats(); HealthStatsParceler takeUidSnapshot(int uid); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 799e3e8d38d0..0df4d0a2c095 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -34,6 +34,7 @@ import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Build; import android.os.connectivity.CellularBatteryStats; +import android.os.connectivity.WifiBatteryStats; import android.os.connectivity.GpsBatteryStats; import android.os.FileUtils; import android.os.Handler; @@ -131,7 +132,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 173 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 174 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS; @@ -751,6 +752,8 @@ public class BatteryStatsImpl extends BatteryStats { final StopwatchTimer[] mWifiSignalStrengthsTimer = new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; + StopwatchTimer mWifiActiveTimer; + int mBluetoothScanNesting; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) protected StopwatchTimer mBluetoothScanTimer; @@ -2785,12 +2788,14 @@ public class BatteryStatsImpl extends BatteryStats { public static class ControllerActivityCounterImpl extends ControllerActivityCounter implements Parcelable { private final LongSamplingCounter mIdleTimeMillis; + private final LongSamplingCounter mScanTimeMillis; private final LongSamplingCounter mRxTimeMillis; private final LongSamplingCounter[] mTxTimeMillis; private final LongSamplingCounter mPowerDrainMaMs; public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { mIdleTimeMillis = new LongSamplingCounter(timeBase); + mScanTimeMillis = new LongSamplingCounter(timeBase); mRxTimeMillis = new LongSamplingCounter(timeBase); mTxTimeMillis = new LongSamplingCounter[numTxStates]; for (int i = 0; i < numTxStates; i++) { @@ -2801,6 +2806,7 @@ public class BatteryStatsImpl extends BatteryStats { public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { mIdleTimeMillis = new LongSamplingCounter(timeBase, in); + mScanTimeMillis = new LongSamplingCounter(timeBase, in); mRxTimeMillis = new LongSamplingCounter(timeBase, in); final int recordedTxStates = in.readInt(); if (recordedTxStates != numTxStates) { @@ -2816,6 +2822,7 @@ public class BatteryStatsImpl extends BatteryStats { public void readSummaryFromParcel(Parcel in) { mIdleTimeMillis.readSummaryFromParcelLocked(in); + mScanTimeMillis.readSummaryFromParcelLocked(in); mRxTimeMillis.readSummaryFromParcelLocked(in); final int recordedTxStates = in.readInt(); if (recordedTxStates != mTxTimeMillis.length) { @@ -2834,6 +2841,7 @@ public class BatteryStatsImpl extends BatteryStats { public void writeSummaryToParcel(Parcel dest) { mIdleTimeMillis.writeSummaryFromParcelLocked(dest); + mScanTimeMillis.writeSummaryFromParcelLocked(dest); mRxTimeMillis.writeSummaryFromParcelLocked(dest); dest.writeInt(mTxTimeMillis.length); for (LongSamplingCounter counter : mTxTimeMillis) { @@ -2845,6 +2853,7 @@ public class BatteryStatsImpl extends BatteryStats { @Override public void writeToParcel(Parcel dest, int flags) { mIdleTimeMillis.writeToParcel(dest); + mScanTimeMillis.writeToParcel(dest); mRxTimeMillis.writeToParcel(dest); dest.writeInt(mTxTimeMillis.length); for (LongSamplingCounter counter : mTxTimeMillis) { @@ -2855,6 +2864,7 @@ public class BatteryStatsImpl extends BatteryStats { public void reset(boolean detachIfReset) { mIdleTimeMillis.reset(detachIfReset); + mScanTimeMillis.reset(detachIfReset); mRxTimeMillis.reset(detachIfReset); for (LongSamplingCounter counter : mTxTimeMillis) { counter.reset(detachIfReset); @@ -2864,6 +2874,7 @@ public class BatteryStatsImpl extends BatteryStats { public void detach() { mIdleTimeMillis.detach(); + mScanTimeMillis.detach(); mRxTimeMillis.detach(); for (LongSamplingCounter counter : mTxTimeMillis) { counter.detach(); @@ -2881,6 +2892,15 @@ public class BatteryStatsImpl extends BatteryStats { } /** + * @return a LongSamplingCounter, measuring time spent in the scan state in + * milliseconds. + */ + @Override + public LongSamplingCounter getScanTimeCounter() { + return mScanTimeMillis; + } + + /** * @return a LongSamplingCounter, measuring time spent in the receive state in * milliseconds. */ @@ -3892,8 +3912,10 @@ public class BatteryStatsImpl extends BatteryStats { } mKernelUidCpuTimeReader.removeUid(isolatedUid); mKernelUidCpuFreqTimeReader.removeUid(isolatedUid); - mKernelUidCpuActiveTimeReader.removeUid(isolatedUid); - mKernelUidCpuClusterTimeReader.removeUid(isolatedUid); + if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { + mKernelUidCpuActiveTimeReader.removeUid(isolatedUid); + mKernelUidCpuClusterTimeReader.removeUid(isolatedUid); + } } public int mapUid(int uid) { @@ -5618,8 +5640,11 @@ public class BatteryStatsImpl extends BatteryStats { noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid); } mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; + mWifiActiveTimer.startRunningLocked(elapsedRealtime); } else { mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; + mWifiActiveTimer.stopRunningLocked( + timestampNs / (1000 * 1000)); } if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " + Integer.toHexString(mHistoryCur.states)); @@ -6270,6 +6295,10 @@ public class BatteryStatsImpl extends BatteryStats { return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); } + @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { + return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); + } + @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); } @@ -9916,6 +9945,7 @@ public class BatteryStatsImpl extends BatteryStats { mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, mOnBatteryTimeBase); } + mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, mOnBatteryTimeBase); for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, mOnBatteryTimeBase); @@ -10609,10 +10639,11 @@ public class BatteryStatsImpl extends BatteryStats { mWifiSignalStrengthsTimer[i].reset(false); } mWifiMulticastWakelockTimer.reset(false); + mWifiActiveTimer.reset(false); + mWifiActivity.reset(false); for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { mGpsSignalQualityTimer[i].reset(false); } - mWifiActivity.reset(false); mBluetoothActivity.reset(false); mModemActivity.reset(false); mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0; @@ -10875,6 +10906,7 @@ public class BatteryStatsImpl extends BatteryStats { // Measured in mAms final long txTimeMs = info.getControllerTxTimeMillis(); final long rxTimeMs = info.getControllerRxTimeMillis(); + final long scanTimeMs = info.getControllerScanTimeMillis(); final long idleTimeMs = info.getControllerIdleTimeMillis(); final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; @@ -10887,6 +10919,7 @@ public class BatteryStatsImpl extends BatteryStats { Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); + Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); } long totalWifiLockTimeMs = 0; @@ -11020,6 +11053,8 @@ public class BatteryStatsImpl extends BatteryStats { mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); mWifiActivity.getTxTimeCounters()[0].addCountLocked( info.getControllerTxTimeMillis()); + mWifiActivity.getScanTimeCounter().addCountLocked( + info.getControllerScanTimeMillis()); mWifiActivity.getIdleTimeCounter().addCountLocked( info.getControllerIdleTimeMillis()); @@ -11538,8 +11573,10 @@ public class BatteryStatsImpl extends BatteryStats { if (!mOnBatteryInternal) { mKernelUidCpuTimeReader.readDelta(null); mKernelUidCpuFreqTimeReader.readDelta(null); - mKernelUidCpuActiveTimeReader.readDelta(null); - mKernelUidCpuClusterTimeReader.readDelta(null); + if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { + mKernelUidCpuActiveTimeReader.readDelta(null); + mKernelUidCpuClusterTimeReader.readDelta(null); + } for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { mKernelCpuSpeedReaders[cluster].readDelta(); } @@ -11556,8 +11593,10 @@ public class BatteryStatsImpl extends BatteryStats { updateClusterSpeedTimes(updatedUids); } readKernelUidCpuFreqTimesLocked(partialTimersToConsider); - readKernelUidCpuActiveTimesLocked(); - readKernelUidCpuClusterTimesLocked(); + if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { + readKernelUidCpuActiveTimesLocked(); + readKernelUidCpuClusterTimesLocked(); + } } /** @@ -12530,6 +12569,56 @@ public class BatteryStatsImpl extends BatteryStats { return s; } + /*@hide */ + public WifiBatteryStats getWifiBatteryStats() { + WifiBatteryStats s = new WifiBatteryStats(); + final int which = STATS_SINCE_CHARGED; + final long rawRealTime = SystemClock.elapsedRealtime() * 1000; + final ControllerActivityCounter counter = getWifiControllerActivity(); + final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); + final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); + final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); + final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); + final long totalControllerActivityTimeMs + = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; + final long sleepTimeMs + = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); + final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); + long numAppScanRequest = 0; + for (int i = 0; i < mUidStats.size(); i++) { + numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); + } + long[] timeInStateMs = new long[NUM_WIFI_STATES]; + for (int i=0; i<NUM_WIFI_STATES; i++) { + timeInStateMs[i] = getWifiStateTime(i, rawRealTime, which) / 1000; + } + long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; + for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { + timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000; + } + long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; + for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { + timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000; + } + s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); + s.setKernelActiveTimeMs(getWifiActiveTime(rawRealTime, which) / 1000); + s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which)); + s.setNumBytesTx(getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which)); + s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which)); + s.setNumBytesRx(getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which)); + s.setSleepTimeMs(sleepTimeMs); + s.setIdleTimeMs(idleTimeMs); + s.setRxTimeMs(rxTimeMs); + s.setTxTimeMs(txTimeMs); + s.setScanTimeMs(scanTimeMs); + s.setEnergyConsumedMaMs(energyConsumedMaMs); + s.setNumAppScanRequest(numAppScanRequest); + s.setTimeInStateMs(timeInStateMs); + s.setTimeInSupplicantStateMs(timeInSupplStateMs); + s.setTimeInRxSignalStrengthLevelMs(timeSignalStrengthTimeMs); + return s; + } + /*@hide */ public GpsBatteryStats getGpsBatteryStats() { GpsBatteryStats s = new GpsBatteryStats(); @@ -12804,10 +12893,19 @@ public class BatteryStatsImpl extends BatteryStats { public final class Constants extends ContentObserver { public static final String KEY_TRACK_CPU_TIMES_BY_PROC_STATE = "track_cpu_times_by_proc_state"; + public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME + = "track_cpu_active_cluster_time"; + public static final String KEY_READ_BINARY_CPU_TIME + = "read_binary_cpu_time"; private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true; + private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; + private static final boolean DEFAULT_READ_BINARY_CPU_TIME = false; public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE; + public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; + // Not used right now. + public boolean READ_BINARY_CPU_TIME = DEFAULT_READ_BINARY_CPU_TIME; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); @@ -12843,6 +12941,11 @@ public class BatteryStatsImpl extends BatteryStats { updateTrackCpuTimesByProcStateLocked(TRACK_CPU_TIMES_BY_PROC_STATE, mParser.getBoolean(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE)); + TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( + KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); + READ_BINARY_CPU_TIME = mParser.getBoolean( + KEY_READ_BINARY_CPU_TIME, DEFAULT_READ_BINARY_CPU_TIME); + } } @@ -12857,6 +12960,10 @@ public class BatteryStatsImpl extends BatteryStats { public void dumpLocked(PrintWriter pw) { pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("="); pw.println(TRACK_CPU_TIMES_BY_PROC_STATE); + pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); + pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); + pw.print(KEY_READ_BINARY_CPU_TIME); pw.print("="); + pw.println(READ_BINARY_CPU_TIME); } } @@ -13222,10 +13329,11 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); } + mWifiActiveTimer.readSummaryFromParcelLocked(in); + mWifiActivity.readSummaryFromParcel(in); for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); } - mWifiActivity.readSummaryFromParcel(in); mBluetoothActivity.readSummaryFromParcel(in); mModemActivity.readSummaryFromParcel(in); mHasWifiReporting = in.readInt() != 0; @@ -13667,10 +13775,11 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); } + mWifiActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + mWifiActivity.writeSummaryToParcel(out); for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); } - mWifiActivity.writeSummaryToParcel(out); mBluetoothActivity.writeSummaryToParcel(out); mModemActivity.writeSummaryToParcel(out); out.writeInt(mHasWifiReporting ? 1 : 0); @@ -14145,12 +14254,14 @@ public class BatteryStatsImpl extends BatteryStats { mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, mOnBatteryTimeBase, in); } + mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, + mOnBatteryTimeBase, in); + mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, + NUM_WIFI_TX_LEVELS, in); for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, mOnBatteryTimeBase, in); } - mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, - NUM_WIFI_TX_LEVELS, in); mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_BT_TX_LEVELS, in); mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, @@ -14348,10 +14459,11 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); } + mWifiActiveTimer.writeToParcel(out, uSecRealtime); + mWifiActivity.writeToParcel(out, 0); for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); } - mWifiActivity.writeToParcel(out, 0); mBluetoothActivity.writeToParcel(out, 0); mModemActivity.writeToParcel(out, 0); out.writeInt(mHasWifiReporting ? 1 : 0); diff --git a/core/jni/android_database_SQLiteCommon.cpp b/core/jni/android_database_SQLiteCommon.cpp index eefcb74e0f70..34544d37a6bf 100644 --- a/core/jni/android_database_SQLiteCommon.cpp +++ b/core/jni/android_database_SQLiteCommon.cpp @@ -18,8 +18,108 @@ #include <utils/String8.h> +#include <map> + namespace android { +static const std::map<int, std::string> sErrorCodesMap = { + // Primary Result Code List + {4, "SQLITE_ABORT"}, + {23, "SQLITE_AUTH"}, + {5, "SQLITE_BUSY"}, + {14, "SQLITE_CANTOPEN"}, + {19, "SQLITE_CONSTRAINT"}, + {11, "SQLITE_CORRUPT"}, + {101, "SQLITE_DONE"}, + {16, "SQLITE_EMPTY"}, + {1, "SQLITE_ERROR"}, + {24, "SQLITE_FORMAT"}, + {13, "SQLITE_FULL"}, + {2, "SQLITE_INTERNAL"}, + {9, "SQLITE_INTERRUPT"}, + {10, "SQLITE_IOERR"}, + {6, "SQLITE_LOCKED"}, + {20, "SQLITE_MISMATCH"}, + {21, "SQLITE_MISUSE"}, + {22, "SQLITE_NOLFS"}, + {7, "SQLITE_NOMEM"}, + {26, "SQLITE_NOTADB"}, + {12, "SQLITE_NOTFOUND"}, + {27, "SQLITE_NOTICE"}, + {0, "SQLITE_OK"}, + {3, "SQLITE_PERM"}, + {15, "SQLITE_PROTOCOL"}, + {25, "SQLITE_RANGE"}, + {8, "SQLITE_READONLY"}, + {100, "SQLITE_ROW"}, + {17, "SQLITE_SCHEMA"}, + {18, "SQLITE_TOOBIG"}, + {28, "SQLITE_WARNING"}, + // Extended Result Code List + {516, "SQLITE_ABORT_ROLLBACK"}, + {261, "SQLITE_BUSY_RECOVERY"}, + {517, "SQLITE_BUSY_SNAPSHOT"}, + {1038, "SQLITE_CANTOPEN_CONVPATH"}, + {782, "SQLITE_CANTOPEN_FULLPATH"}, + {526, "SQLITE_CANTOPEN_ISDIR"}, + {270, "SQLITE_CANTOPEN_NOTEMPDIR"}, + {275, "SQLITE_CONSTRAINT_CHECK"}, + {531, "SQLITE_CONSTRAINT_COMMITHOOK"}, + {787, "SQLITE_CONSTRAINT_FOREIGNKEY"}, + {1043, "SQLITE_CONSTRAINT_FUNCTION"}, + {1299, "SQLITE_CONSTRAINT_NOTNULL"}, + {1555, "SQLITE_CONSTRAINT_PRIMARYKEY"}, + {2579, "SQLITE_CONSTRAINT_ROWID"}, + {1811, "SQLITE_CONSTRAINT_TRIGGER"}, + {2067, "SQLITE_CONSTRAINT_UNIQUE"}, + {2323, "SQLITE_CONSTRAINT_VTAB"}, + {267, "SQLITE_CORRUPT_VTAB"}, + {3338, "SQLITE_IOERR_ACCESS"}, + {2826, "SQLITE_IOERR_BLOCKED"}, + {3594, "SQLITE_IOERR_CHECKRESERVEDLOCK"}, + {4106, "SQLITE_IOERR_CLOSE"}, + {6666, "SQLITE_IOERR_CONVPATH"}, + {2570, "SQLITE_IOERR_DELETE"}, + {5898, "SQLITE_IOERR_DELETE_NOENT"}, + {4362, "SQLITE_IOERR_DIR_CLOSE"}, + {1290, "SQLITE_IOERR_DIR_FSYNC"}, + {1802, "SQLITE_IOERR_FSTAT"}, + {1034, "SQLITE_IOERR_FSYNC"}, + {6410, "SQLITE_IOERR_GETTEMPPATH"}, + {3850, "SQLITE_IOERR_LOCK"}, + {6154, "SQLITE_IOERR_MMAP"}, + {3082, "SQLITE_IOERR_NOMEM"}, + {2314, "SQLITE_IOERR_RDLOCK"}, + {266, "SQLITE_IOERR_READ"}, + {5642, "SQLITE_IOERR_SEEK"}, + {5130, "SQLITE_IOERR_SHMLOCK"}, + {5386, "SQLITE_IOERR_SHMMAP"}, + {4618, "SQLITE_IOERR_SHMOPEN"}, + {4874, "SQLITE_IOERR_SHMSIZE"}, + {522, "SQLITE_IOERR_SHORT_READ"}, + {1546, "SQLITE_IOERR_TRUNCATE"}, + {2058, "SQLITE_IOERR_UNLOCK"}, + {778, "SQLITE_IOERR_WRITE"}, + {262, "SQLITE_LOCKED_SHAREDCACHE"}, + {539, "SQLITE_NOTICE_RECOVER_ROLLBACK"}, + {283, "SQLITE_NOTICE_RECOVER_WAL"}, + {256, "SQLITE_OK_LOAD_PERMANENTLY"}, + {520, "SQLITE_READONLY_CANTLOCK"}, + {1032, "SQLITE_READONLY_DBMOVED"}, + {264, "SQLITE_READONLY_RECOVERY"}, + {776, "SQLITE_READONLY_ROLLBACK"}, + {284, "SQLITE_WARNING_AUTOINDEX"}, +}; + +static std::string sqlite3_error_code_to_msg(int errcode) { + auto it = sErrorCodesMap.find(errcode); + if (it != sErrorCodesMap.end()) { + return std::to_string(errcode) + " " + it->second; + } else { + return std::to_string(errcode); + } +} + /* throw a SQLiteException with a message appropriate for the error in handle */ void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle) { throw_sqlite3_exception(env, handle, NULL); @@ -123,7 +223,8 @@ void throw_sqlite3_exception(JNIEnv* env, int errcode, if (sqlite3Message) { String8 fullMessage; fullMessage.append(sqlite3Message); - fullMessage.appendFormat(" (code %d)", errcode); // print extended error code + const char* errcode_msg = sqlite3_error_code_to_msg(errcode).c_str(); + fullMessage.appendFormat(" (code %s)", errcode_msg); // print extended error code if (message) { fullMessage.append(": "); fullMessage.append(message); diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h index 51cefb9accb8..c79f5bd96e99 100644 --- a/core/jni/android_media_AudioFormat.h +++ b/core/jni/android_media_AudioFormat.h @@ -35,6 +35,7 @@ #define ENCODING_DOLBY_TRUEHD 14 #define ENCODING_AAC_ELD 15 #define ENCODING_AAC_XHE 16 +#define ENCODING_AC4 17 #define ENCODING_INVALID 0 #define ENCODING_DEFAULT 1 @@ -77,6 +78,8 @@ static inline audio_format_t audioFormatToNative(int audioFormat) return AUDIO_FORMAT_AAC_ELD; case ENCODING_AAC_XHE: return AUDIO_FORMAT_AAC; // FIXME temporary value, needs addition of xHE-AAC + case ENCODING_AC4: + return AUDIO_FORMAT_AC4; case ENCODING_DEFAULT: return AUDIO_FORMAT_DEFAULT; default: @@ -125,6 +128,8 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat) // FIXME needs addition of AUDIO_FORMAT_AAC_XHE //case AUDIO_FORMAT_AAC_XHE: // return ENCODING_AAC_XHE; + case AUDIO_FORMAT_AC4: + return ENCODING_AC4; case AUDIO_FORMAT_DEFAULT: return ENCODING_DEFAULT; default: diff --git a/core/proto/android/server/forceappstandbytracker.proto b/core/proto/android/server/forceappstandbytracker.proto index 8753bf768321..c9f7d52ae83f 100644 --- a/core/proto/android/server/forceappstandbytracker.proto +++ b/core/proto/android/server/forceappstandbytracker.proto @@ -41,4 +41,13 @@ message ForceAppStandbyTrackerProto { // Packages that are disallowed OP_RUN_ANY_IN_BACKGROUND. repeated RunAnyInBackgroundRestrictedPackages run_any_in_background_restricted_packages = 5; + + // Whether device is a small battery device + optional bool is_small_battery_device = 6; + + // Whether force app standby for small battery device setting is enabled + optional bool force_all_apps_standby_for_small_battery = 7; + + // Whether device is charging + optional bool is_charging = 8; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index ba30981e6377..bf9d79bc75dd 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2313,6 +2313,11 @@ <permission android:name="android.permission.RECOVERY" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows an application to read system update info. + @hide --> + <permission android:name="android.permission.READ_SYSTEM_UPDATE_INFO" + android:protectionLevel="signature" /> + <!-- Allows the system to bind to an application's task services @hide --> <permission android:name="android.permission.BIND_JOB_SERVICE" diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 0c844c9deb9d..170ba4264e04 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4821,4 +4821,7 @@ <!-- Text describing a permission request for one app to show another app's slices [CHAR LIMIT=NONE] --> <string name="slices_permission_request"><xliff:g id="app" example="Example App">%1$s</xliff:g> wants to show <xliff:g id="app_2" example="Other Example App">%2$s</xliff:g> slices</string> + + <!-- Notification action for editing a screenshot (drawing on it, cropping it, etc) --> + <string name="screenshot_edit">Edit</string> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 03a800d8bd6f..955065706006 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3227,5 +3227,8 @@ <java-symbol type="string" name="config_defaultAssistantAccessPackage" /> <java-symbol type="bool" name="config_supportBluetoothPersistedState" /> + <java-symbol type="string" name="slices_permission_request" /> + + <java-symbol type="string" name="screenshot_edit" /> </resources> diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index ec3a6ce18cce..fa0ea5c3aa85 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -213,6 +213,7 @@ public class SettingsBackupTest { Settings.Global.FANCY_IME_ANIMATIONS, Settings.Global.FORCE_ALLOW_ON_EXTERNAL, Settings.Global.FORCED_APP_STANDBY_ENABLED, + Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, Settings.Global.FSTRIM_MANDATORY_INTERVAL, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST, Settings.Global.GLOBAL_HTTP_PROXY_HOST, diff --git a/core/tests/privacytests/src/android/privacy/LongitudinalReportingEncoderTest.java b/core/tests/privacytests/src/android/privacy/LongitudinalReportingEncoderTest.java index 91664381efe0..6fe19a263e8b 100644 --- a/core/tests/privacytests/src/android/privacy/LongitudinalReportingEncoderTest.java +++ b/core/tests/privacytests/src/android/privacy/LongitudinalReportingEncoderTest.java @@ -72,13 +72,13 @@ public class LongitudinalReportingEncoderTest { final LongitudinalReportingEncoder encoder = LongitudinalReportingEncoder.createInsecureEncoderForTest( config); - assertEquals(1, encoder.encodeBoolean(true)[0]); + assertEquals(0, encoder.encodeBoolean(true)[0]); assertEquals(0, encoder.encodeBoolean(true)[0]); assertEquals(1, encoder.encodeBoolean(true)[0]); + assertEquals(0, encoder.encodeBoolean(true)[0]); assertEquals(1, encoder.encodeBoolean(true)[0]); assertEquals(1, encoder.encodeBoolean(true)[0]); assertEquals(1, encoder.encodeBoolean(true)[0]); - assertEquals(0, encoder.encodeBoolean(true)[0]); assertEquals(1, encoder.encodeBoolean(true)[0]); assertEquals(1, encoder.encodeBoolean(true)[0]); assertEquals(1, encoder.encodeBoolean(true)[0]); @@ -86,12 +86,12 @@ public class LongitudinalReportingEncoderTest { assertEquals(0, encoder.encodeBoolean(false)[0]); assertEquals(1, encoder.encodeBoolean(false)[0]); assertEquals(1, encoder.encodeBoolean(false)[0]); - assertEquals(0, encoder.encodeBoolean(false)[0]); + assertEquals(1, encoder.encodeBoolean(false)[0]); assertEquals(0, encoder.encodeBoolean(false)[0]); assertEquals(0, encoder.encodeBoolean(false)[0]); assertEquals(1, encoder.encodeBoolean(false)[0]); assertEquals(0, encoder.encodeBoolean(false)[0]); - assertEquals(0, encoder.encodeBoolean(false)[0]); + assertEquals(1, encoder.encodeBoolean(false)[0]); assertEquals(1, encoder.encodeBoolean(false)[0]); // Test if IRR returns original result when f = 0 diff --git a/core/tests/privacytests/src/android/privacy/RapporEncoderTest.java b/core/tests/privacytests/src/android/privacy/RapporEncoderTest.java index dad98b8e4a35..fa0343df88b4 100644 --- a/core/tests/privacytests/src/android/privacy/RapporEncoderTest.java +++ b/core/tests/privacytests/src/android/privacy/RapporEncoderTest.java @@ -80,7 +80,7 @@ public class RapporEncoderTest { int numBits = 8; final long inputValue = 254L; final long prrValue = 250L; - final long prrAndIrrValue = 184L; + final long prrAndIrrValue = 244L; final RapporConfig config1 = new RapporConfig( "Foo", // encoderId diff --git a/docs/html/reference/images/text/style/absolutesizespan.png b/docs/html/reference/images/text/style/absolutesizespan.png Binary files differnew file mode 100644 index 000000000000..40d5a79ae37e --- /dev/null +++ b/docs/html/reference/images/text/style/absolutesizespan.png diff --git a/docs/html/reference/images/text/style/relativesizespan.png b/docs/html/reference/images/text/style/relativesizespan.png Binary files differnew file mode 100644 index 000000000000..eaca5ad0e93f --- /dev/null +++ b/docs/html/reference/images/text/style/relativesizespan.png diff --git a/docs/html/reference/images/text/style/scalexspan.png b/docs/html/reference/images/text/style/scalexspan.png Binary files differnew file mode 100644 index 000000000000..a5ca26f571c6 --- /dev/null +++ b/docs/html/reference/images/text/style/scalexspan.png diff --git a/docs/html/reference/images/text/style/strikethroughspan.png b/docs/html/reference/images/text/style/strikethroughspan.png Binary files differnew file mode 100644 index 000000000000..a49ecadea063 --- /dev/null +++ b/docs/html/reference/images/text/style/strikethroughspan.png diff --git a/docs/html/reference/images/text/style/subscriptspan.png b/docs/html/reference/images/text/style/subscriptspan.png Binary files differnew file mode 100644 index 000000000000..aac7092a3322 --- /dev/null +++ b/docs/html/reference/images/text/style/subscriptspan.png diff --git a/docs/html/reference/images/text/style/superscriptspan.png b/docs/html/reference/images/text/style/superscriptspan.png Binary files differnew file mode 100644 index 000000000000..996f59d55dde --- /dev/null +++ b/docs/html/reference/images/text/style/superscriptspan.png diff --git a/docs/html/reference/images/text/style/underlinespan.png b/docs/html/reference/images/text/style/underlinespan.png Binary files differnew file mode 100644 index 000000000000..dbcd0d9f1498 --- /dev/null +++ b/docs/html/reference/images/text/style/underlinespan.png diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index 46fe89a74ce5..b07d04220046 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -238,25 +238,13 @@ public final class AudioFormat implements Parcelable { public static final int ENCODING_DTS = 7; /** Audio data format: DTS HD compressed */ public static final int ENCODING_DTS_HD = 8; - /** Audio data format: MP3 compressed - * @hide - * TODO unhide and add to @Encoding (intentional white space - * */ + /** Audio data format: MP3 compressed */ public static final int ENCODING_MP3 = 9; - /** Audio data format: AAC LC compressed - * @hide - * TODO unhide and add to @Encoding (intentional white space - * */ + /** Audio data format: AAC LC compressed */ public static final int ENCODING_AAC_LC = 10; - /** Audio data format: AAC HE V1 compressed - * @hide - * TODO unhide and add to @Encoding (intentional white space - * */ + /** Audio data format: AAC HE V1 compressed */ public static final int ENCODING_AAC_HE_V1 = 11; - /** Audio data format: AAC HE V2 compressed - * @hide - * TODO unhide and add to @Encoding (intentional white space - * */ + /** Audio data format: AAC HE V2 compressed */ public static final int ENCODING_AAC_HE_V2 = 12; /** Audio data format: compressed audio wrapped in PCM for HDMI @@ -271,16 +259,12 @@ public final class AudioFormat implements Parcelable { /** Audio data format: DOLBY TRUEHD compressed **/ public static final int ENCODING_DOLBY_TRUEHD = 14; - /** Audio data format: AAC ELD compressed - * @hide - * TODO unhide and add to @Encoding (intentional white space - * */ + /** Audio data format: AAC ELD compressed */ public static final int ENCODING_AAC_ELD = 15; - /** Audio data format: AAC xHE compressed - * @hide - * TODO unhide and add to @Encoding (intentional white space - * */ + /** Audio data format: AAC xHE compressed */ public static final int ENCODING_AAC_XHE = 16; + /** Audio data format: AC-4 sync frame transport format */ + public static final int ENCODING_AC4 = 17; /** @hide */ public static String toLogFriendlyEncoding(int enc) { @@ -317,6 +301,8 @@ public final class AudioFormat implements Parcelable { return "ENCODING_AAC_ELD"; case ENCODING_AAC_XHE: return "ENCODING_AAC_XHE"; + case ENCODING_AC4: + return "ENCODING_AC4"; default : return "invalid encoding " + enc; } @@ -535,6 +521,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_IEC61937: case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: + case ENCODING_AC4: return true; default: return false; @@ -553,13 +540,13 @@ public final class AudioFormat implements Parcelable { case ENCODING_DTS: case ENCODING_DTS_HD: case ENCODING_IEC61937: - //TODO not true yet (intended white space case ENCODING_MP3: case ENCODING_AAC_LC: case ENCODING_AAC_HE_V1: case ENCODING_AAC_HE_V2: case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: + case ENCODING_AC4: return true; default: return false; @@ -586,6 +573,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_IEC61937: // wrapped in PCM but compressed case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: + case ENCODING_AC4: return false; case ENCODING_INVALID: default: @@ -613,6 +601,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_AAC_HE_V2: case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: + case ENCODING_AC4: return false; case ENCODING_INVALID: default: @@ -849,6 +838,7 @@ public final class AudioFormat implements Parcelable { case ENCODING_AAC_HE_V2: case ENCODING_AAC_ELD: case ENCODING_AAC_XHE: + case ENCODING_AC4: mEncoding = encoding; break; case ENCODING_INVALID: @@ -1056,7 +1046,13 @@ public final class AudioFormat implements Parcelable { ENCODING_E_AC3, ENCODING_DTS, ENCODING_DTS_HD, - ENCODING_IEC61937 } + ENCODING_IEC61937, + ENCODING_AAC_HE_V1, + ENCODING_AAC_HE_V2, + ENCODING_AAC_LC, + ENCODING_AAC_ELD, + ENCODING_AAC_XHE, + ENCODING_AC4 } ) @Retention(RetentionPolicy.SOURCE) public @interface Encoding {} diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 4d5343c97b05..2ac4063d1b08 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1331,15 +1331,13 @@ public class AudioManager { //==================================================================== // Offload query /** - * @hide - * TODO unhide (intentional white space to attract attention: * Returns whether offloaded playback of an audio format is supported on the device. * Offloaded playback is where the decoding of an audio stream is not competing with other * software resources. In general, it is supported by dedicated hardware, such as audio DSPs. * @param format the audio format (codec, sample rate, channels) being checked. * @return true if the given audio format can be offloaded. */ - public static boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format) { + public boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format) { return AudioSystem.isOffloadSupported(format); } diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 6add381fc885..5928d03dc4a1 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -755,8 +755,8 @@ public class AudioTrack extends PlayerBase * <code>MODE_STREAM</code> will be used. * <br>If the session ID is not specified with {@link #setSessionId(int)}, a new one will * be generated. + * <br>Offload is false by default. */ - // TODO add that offload is false by default (intended white space public static class Builder { private AudioAttributes mAttributes; private AudioFormat mFormat; @@ -895,14 +895,11 @@ public class AudioTrack extends PlayerBase } /** - * @hide - * TODO unhide (intentional whitespace - * TODO should offload require POWER_SAVING? * Sets whether this track will play through the offloaded audio path. * When set to true, at build time, the audio format will be checked against * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat)} to verify the audio format * used by this track is supported on the device's offload path (if any). - * <br>Offload is only supported for media audio data, and therefore require that + * <br>Offload is only supported for media audio streams, and therefore requires that * the usage be {@link AudioAttributes#USAGE_MEDIA}. * @param offload true to require the offload path for playback. * @return the same Builder instance. @@ -962,7 +959,7 @@ public class AudioTrack extends PlayerBase throw new UnsupportedOperationException( "Cannot create AudioTrack, offload requires USAGE_MEDIA"); } - if (!AudioManager.isOffloadedPlaybackSupported(mFormat)) { + if (!AudioSystem.isOffloadSupported(mFormat)) { throw new UnsupportedOperationException( "Cannot create AudioTrack, offload format not supported"); } @@ -2942,14 +2939,31 @@ public class AudioTrack extends PlayerBase } /** - * @hide - * TODO unhide (intentional white space to attract attention: * Abstract class to receive event notification about the stream playback. + * See {@link AudioTrack#setStreamEventCallback(Executor, StreamEventCallback)} to register + * the callback on the given {@link AudioTrack} instance. */ public abstract static class StreamEventCallback { - // TODO rename if supported for non offload tracks + /** @hide */ // add hidden empty constructor so it doesn't show in SDK + public StreamEventCallback() { } + /** + * Called when an offloaded track is no longer valid and has been discarded by the system. + * An example of this happening is when an offloaded track has been paused too long, and + * gets invalidated by the system to prevent any other offload. + * @param track the {@link AudioTrack} on which the event happened + */ public void onTearDown(AudioTrack track) { } + /** + * Called when all the buffers of an offloaded track that were queued in the audio system + * (e.g. the combination of the Android audio framework and the device's audio hardware) + * have been played after {@link AudioTrack#stop()} has been called. + * @param track the {@link AudioTrack} on which the event happened + */ public void onStreamPresentationEnd(AudioTrack track) { } + /** + * Called when more audio data can be written without blocking on an offloaded track. + * @param track the {@link AudioTrack} on which the event happened + */ public void onStreamDataRequest(AudioTrack track) { } } @@ -2958,11 +2972,9 @@ public class AudioTrack extends PlayerBase private final Object mStreamEventCbLock = new Object(); /** - * @hide - * TODO unhide (intentional white space to attract attention: - * Registers a callback for notification of stream events. + * Sets the callback for the notification of stream events. * @param executor {@link Executor} to handle the callbacks - * @param eventCallback the callback to receive the stream events + * @param eventCallback the callback to receive the stream event notifications */ public void setStreamEventCallback(@NonNull @CallbackExecutor Executor executor, @NonNull StreamEventCallback eventCallback) { @@ -2979,9 +2991,8 @@ public class AudioTrack extends PlayerBase } /** - * @hide * Unregisters the callback for notification of stream events, previously set - * by {@link #setStreamEventCallback(StreamEventCallback, Executor)}. + * by {@link #setStreamEventCallback(Executor, StreamEventCallback)}. */ public void removeStreamEventCallback() { synchronized (mStreamEventCbLock) { diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 3c49b80b4b5e..78477f757e2a 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -1380,7 +1380,8 @@ public class MediaRecorder implements AudioRouting if (listener != null && !mRoutingChangeListeners.containsKey(listener)) { enableNativeRoutingCallbacksLocked(true); mRoutingChangeListeners.put( - listener, new NativeRoutingEventHandlerDelegate(this, listener, handler)); + listener, new NativeRoutingEventHandlerDelegate(this, listener, + handler != null ? handler : mEventHandler)); } } } @@ -1401,36 +1402,6 @@ public class MediaRecorder implements AudioRouting } } - /** - * Helper class to handle the forwarding of native events to the appropriate listener - * (potentially) handled in a different thread - */ - private class NativeRoutingEventHandlerDelegate { - private MediaRecorder mMediaRecorder; - private AudioRouting.OnRoutingChangedListener mOnRoutingChangedListener; - private Handler mHandler; - - NativeRoutingEventHandlerDelegate(final MediaRecorder mediaRecorder, - final AudioRouting.OnRoutingChangedListener listener, Handler handler) { - mMediaRecorder = mediaRecorder; - mOnRoutingChangedListener = listener; - mHandler = handler != null ? handler : mEventHandler; - } - - void notifyClient() { - if (mHandler != null) { - mHandler.post(new Runnable() { - @Override - public void run() { - if (mOnRoutingChangedListener != null) { - mOnRoutingChangedListener.onRoutingChanged(mMediaRecorder); - } - } - }); - } - } - } - private native final boolean native_setInputDevice(int deviceId); private native final int native_getRoutedDeviceId(); private native final void native_enableDeviceCallback(boolean enabled); diff --git a/packages/SystemUI/res/drawable/ic_screenshot_edit.xml b/packages/SystemUI/res/drawable/ic_screenshot_edit.xml new file mode 100644 index 000000000000..d90129260fcc --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_screenshot_edit.xml @@ -0,0 +1,27 @@ +<!-- +Copyright (C) 2014 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M3.0,17.25L3.0,21.0l3.75,0.0L17.81,9.94l-3.75,-3.75L3.0,17.25zM20.71,7.04c0.39,-0.3 0.39,-1.02 0.0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0.0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/> + <path + android:pathData="M0 0h24v24H0z" + android:fillColor="#00000000"/> +</vector> diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml index bfe1b6213c55..2c69501106a6 100644 --- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml +++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml @@ -41,6 +41,17 @@ systemui:showDark="false" /> + <com.android.systemui.statusbar.policy.DateView + android:id="@+id/date" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="4dp" + android:singleLine="true" + android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date" + android:textSize="@dimen/qs_time_collapsed_size" + android:gravity="center_vertical" + systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" /> + <android.widget.Space android:id="@+id/space" android:layout_width="0dp" diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 4837fefd04b2..bcce6d1d2ee8 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -173,7 +173,7 @@ <style name="TextAppearance.StatusBar.Expanded.Date"> <item name="android:textSize">@dimen/qs_time_expanded_size</item> <item name="android:textStyle">normal</item> - <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textColor">#ffffffff</item> <item name="android:fontFamily">sans-serif</item> </style> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java index 13f30b2c27b9..7d159b745254 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java @@ -20,6 +20,7 @@ import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.RectEvaluator; import android.annotation.FloatRange; +import android.annotation.Nullable; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; @@ -39,6 +40,7 @@ import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; +import android.view.ViewRootImpl; import android.view.ViewStub; import java.util.ArrayList; @@ -294,17 +296,25 @@ public class Utilities { } /** - * @return The next frame name for the specified surface. + * @return The next frame name for the specified surface or -1 if the surface is no longer + * valid. */ public static long getNextFrameNumber(Surface s) { - return s.getNextFrameNumber(); + return s != null && s.isValid() + ? s.getNextFrameNumber() + : -1; + } /** * @return The surface for the specified view. */ - public static Surface getSurface(View v) { - return v.getViewRootImpl().mSurface; + public static @Nullable Surface getSurface(View v) { + ViewRootImpl viewRoot = v.getViewRootImpl(); + if (viewRoot == null) { + return null; + } + return viewRoot.mSurface; } /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index e6fd2f4697dd..a97b35cba048 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -18,10 +18,12 @@ import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS; import static android.app.StatusBarManager.DISABLE_NONE; import android.content.Context; +import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; +import android.provider.AlarmClock; import android.support.annotation.VisibleForTesting; import android.util.AttributeSet; import android.view.View; @@ -41,7 +43,8 @@ import com.android.systemui.statusbar.SignalClusterView; import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; -public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue.Callbacks { +public class QuickStatusBarHeader extends RelativeLayout + implements CommandQueue.Callbacks, View.OnClickListener { private ActivityStarter mActivityStarter; @@ -54,6 +57,8 @@ public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue protected QuickQSPanel mHeaderQsPanel; protected QSTileHost mHost; + private View mDate; + public QuickStatusBarHeader(Context context, AttributeSet attrs) { super(context, attrs); } @@ -64,6 +69,8 @@ public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue Resources res = getResources(); mHeaderQsPanel = findViewById(R.id.quick_qs_panel); + mDate = findViewById(R.id.date); + mDate.setOnClickListener(this); // RenderThread is doing more harm than good when touching the header (to expand quick // settings), so disable it for this view @@ -145,6 +152,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue super.onDetachedFromWindow(); } + @Override + public void onClick(View v) { + if (v == mDate) { + Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(new Intent( + AlarmClock.ACTION_SHOW_ALARMS), 0); + } + } + public void setListening(boolean listening) { if (listening == mListening) { return; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 6db46b5917b6..675aa8f73a09 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -293,12 +293,13 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { sharingIntent.putExtra(Intent.EXTRA_STREAM, uri); sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject); - // Create a share action for the notification. Note, we proxy the call to ShareReceiver - // because RemoteViews currently forces an activity options on the PendingIntent being - // launched, and since we don't want to trigger the share sheet in this case, we will - // start the chooser activitiy directly in ShareReceiver. + // Create a share action for the notification. Note, we proxy the call to + // ScreenshotActionReceiver because RemoteViews currently forces an activity options + // on the PendingIntent being launched, and since we don't want to trigger the share + // sheet in this case, we start the chooser activity directly in + // ScreenshotActionReceiver. PendingIntent shareAction = PendingIntent.getBroadcast(context, 0, - new Intent(context, GlobalScreenshot.ShareReceiver.class) + new Intent(context, GlobalScreenshot.ScreenshotActionReceiver.class) .putExtra(SHARING_INTENT, sharingIntent), PendingIntent.FLAG_CANCEL_CURRENT); Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder( @@ -306,15 +307,19 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { r.getString(com.android.internal.R.string.share), shareAction); mNotificationBuilder.addAction(shareActionBuilder.build()); - // Create a delete action for the notification - PendingIntent deleteAction = PendingIntent.getBroadcast(context, 0, - new Intent(context, GlobalScreenshot.DeleteScreenshotReceiver.class) - .putExtra(GlobalScreenshot.SCREENSHOT_URI_ID, uri.toString()), - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); - Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder( - R.drawable.ic_screenshot_delete, - r.getString(com.android.internal.R.string.delete), deleteAction); - mNotificationBuilder.addAction(deleteActionBuilder.build()); + Intent editIntent = new Intent(Intent.ACTION_EDIT); + editIntent.setType("image/png"); + editIntent.putExtra(Intent.EXTRA_STREAM, uri); + + // Create a edit action for the notification the same way. + PendingIntent editAction = PendingIntent.getBroadcast(context, 1, + new Intent(context, GlobalScreenshot.ScreenshotActionReceiver.class) + .putExtra(SHARING_INTENT, editIntent), + PendingIntent.FLAG_CANCEL_CURRENT); + Notification.Action.Builder editActionBuilder = new Notification.Action.Builder( + R.drawable.ic_screenshot_edit, + r.getString(com.android.internal.R.string.screenshot_edit), editAction); + mNotificationBuilder.addAction(editActionBuilder.build()); mParams.imageUri = uri; mParams.image = null; @@ -879,9 +884,9 @@ class GlobalScreenshot { } /** - * Receiver to proxy the share intent. + * Receiver to proxy the share or edit intent. */ - public static class ShareReceiver extends BroadcastReceiver { + public static class ScreenshotActionReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { try { @@ -903,7 +908,7 @@ class GlobalScreenshot { } /** - * Removes the notification for a screenshot after a share target is chosen. + * Removes the notification for a screenshot after a share or edit target is chosen. */ public static class TargetChosenReceiver extends BroadcastReceiver { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java index 6220fcbdf13b..1130b6de2544 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java @@ -32,6 +32,8 @@ import com.android.systemui.Interpolators; public class SettingsButton extends AlphaOptimizedImageButton { + private static final boolean TUNER_ENABLE_AVAILABLE = false; + private static final long LONG_PRESS_LENGTH = 1000; private static final long ACCEL_LENGTH = 750; private static final long FULL_SPEED_LENGTH = 375; @@ -59,7 +61,7 @@ public class SettingsButton extends AlphaOptimizedImageButton { public boolean onTouchEvent(MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: - postDelayed(mLongPressCallback, LONG_PRESS_LENGTH); + if (TUNER_ENABLE_AVAILABLE) postDelayed(mLongPressCallback, LONG_PRESS_LENGTH); break; case MotionEvent.ACTION_UP: if (mUpToSpeed) { diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java index 8e584bc362eb..5a4478f072e0 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java @@ -58,7 +58,7 @@ public class TunerServiceImpl extends TunerService { private static final String TUNER_VERSION = "sysui_tuner_version"; - private static final int CURRENT_TUNER_VERSION = 1; + private static final int CURRENT_TUNER_VERSION = 2; private final Observer mObserver = new Observer(); // Map of Uris we listen on to their settings keys. @@ -116,6 +116,9 @@ public class TunerServiceImpl extends TunerService { TextUtils.join(",", iconBlacklist), mCurrentUser); } } + if (oldVersion < 2) { + setTunerEnabled(mContext, false); + } setValue(TUNER_VERSION, newVersion); } diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java index cc3af8c8c933..289dd140ee7f 100644 --- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java +++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java @@ -114,14 +114,14 @@ public class PerformBackupTask implements BackupRestoreTask { private RefactoredBackupManagerService backupManagerService; private final Object mCancelLock = new Object(); - ArrayList<BackupRequest> mQueue; - ArrayList<BackupRequest> mOriginalQueue; - File mStateDir; - @Nullable DataChangedJournal mJournal; - BackupState mCurrentState; - List<String> mPendingFullBackups; - IBackupObserver mObserver; - IBackupManagerMonitor mMonitor; + private ArrayList<BackupRequest> mQueue; + private ArrayList<BackupRequest> mOriginalQueue; + private File mStateDir; + @Nullable private DataChangedJournal mJournal; + private BackupState mCurrentState; + private List<String> mPendingFullBackups; + private IBackupObserver mObserver; + private IBackupManagerMonitor mMonitor; private final TransportClient mTransportClient; private final OnTaskFinishedListener mListener; @@ -130,18 +130,18 @@ public class PerformBackupTask implements BackupRestoreTask { private volatile int mEphemeralOpToken; // carried information about the current in-flight operation - IBackupAgent mAgentBinder; - PackageInfo mCurrentPackage; - File mSavedStateName; - File mBackupDataName; - File mNewStateName; - ParcelFileDescriptor mSavedState; - ParcelFileDescriptor mBackupData; - ParcelFileDescriptor mNewState; - int mStatus; - boolean mFinished; - final boolean mUserInitiated; - final boolean mNonIncremental; + private IBackupAgent mAgentBinder; + private PackageInfo mCurrentPackage; + private File mSavedStateName; + private File mBackupDataName; + private File mNewStateName; + private ParcelFileDescriptor mSavedState; + private ParcelFileDescriptor mBackupData; + private ParcelFileDescriptor mNewState; + private int mStatus; + private boolean mFinished; + private final boolean mUserInitiated; + private final boolean mNonIncremental; private volatile boolean mCancelAll; @@ -241,7 +241,7 @@ public class PerformBackupTask implements BackupRestoreTask { // We're starting a backup pass. Initialize the transport and send // the PM metadata blob if we haven't already. - void beginBackup() { + private void beginBackup() { if (DEBUG_BACKUP_TRACE) { backupManagerService.clearBackupTrace(); StringBuilder b = new StringBuilder(256); @@ -369,7 +369,7 @@ public class PerformBackupTask implements BackupRestoreTask { // Transport has been initialized and the PM metadata submitted successfully // if that was warranted. Now we process the single next thing in the queue. - void invokeNextAgent() { + private void invokeNextAgent() { mStatus = BackupTransport.TRANSPORT_OK; backupManagerService.addBackupTrace("invoke q=" + mQueue.size()); @@ -511,7 +511,7 @@ public class PerformBackupTask implements BackupRestoreTask { } } - void finalizeBackup() { + private void finalizeBackup() { backupManagerService.addBackupTrace("finishing"); // Mark packages that we didn't backup (because backup was cancelled, etc.) as needing @@ -617,14 +617,14 @@ public class PerformBackupTask implements BackupRestoreTask { } // Remove the PM metadata state. This will generate an init on the next pass. - void clearMetadata() { + private void clearMetadata() { final File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL); if (pmState.exists()) pmState.delete(); } // Invoke an agent's doBackup() and start a timeout message spinning on the main // handler in case it doesn't get back to us. - int invokeAgentForBackup(String packageName, IBackupAgent agent) { + private int invokeAgentForBackup(String packageName, IBackupAgent agent) { if (DEBUG) { Slog.d(TAG, "invokeAgentForBackup on " + packageName); } @@ -711,7 +711,7 @@ public class PerformBackupTask implements BackupRestoreTask { return BackupTransport.TRANSPORT_OK; } - public void failAgent(IBackupAgent agent, String message) { + private void failAgent(IBackupAgent agent, String message) { try { agent.fail(message); } catch (Exception e) { @@ -1059,7 +1059,7 @@ public class PerformBackupTask implements BackupRestoreTask { } } - void revertAndEndBackup() { + private void revertAndEndBackup() { if (MORE_DEBUG) { Slog.i(TAG, "Reverting backup queue - restaging everything"); } @@ -1085,14 +1085,14 @@ public class PerformBackupTask implements BackupRestoreTask { } - void errorCleanup() { + private void errorCleanup() { mBackupDataName.delete(); mNewStateName.delete(); clearAgentState(); } // Cleanup common to both success and failure cases - void clearAgentState() { + private void clearAgentState() { try { if (mSavedState != null) mSavedState.close(); } catch (IOException e) { @@ -1123,7 +1123,7 @@ public class PerformBackupTask implements BackupRestoreTask { } } - void executeNextState(BackupState nextState) { + private void executeNextState(BackupState nextState) { if (MORE_DEBUG) { Slog.i(TAG, " => executing next step on " + this + " nextState=" + nextState); diff --git a/services/core/java/com/android/server/ForceAppStandbyTracker.java b/services/core/java/com/android/server/ForceAppStandbyTracker.java index a538bde7487e..de113a6a53e0 100644 --- a/services/core/java/com/android/server/ForceAppStandbyTracker.java +++ b/services/core/java/com/android/server/ForceAppStandbyTracker.java @@ -26,6 +26,8 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; +import android.net.Uri; +import android.os.BatteryManager; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -89,6 +91,9 @@ public class ForceAppStandbyTracker { private final MyHandler mHandler; + @VisibleForTesting + FeatureFlagsObserver mFlagsObserver; + /** * Pair of (uid (not user-id), packageName) with OP_RUN_ANY_IN_BACKGROUND *not* allowed. */ @@ -113,14 +118,36 @@ public class ForceAppStandbyTracker { @GuardedBy("mLock") boolean mStarted; + /** + * Only used for small battery use-case. + */ + @GuardedBy("mLock") + boolean mIsPluggedIn; + + @GuardedBy("mLock") + boolean mBatterySaverEnabled; + + /** + * True if the forced app standby is currently enabled + */ + @GuardedBy("mLock") + boolean mForceAllAppsStandby; + + /** + * True if the forced app standby for small battery devices feature is enabled in settings + */ @GuardedBy("mLock") - boolean mForceAllAppsStandby; // True if device is in extreme battery saver mode + boolean mForceAllAppStandbyForSmallBattery; + /** + * True if the forced app standby feature is enabled in settings + */ @GuardedBy("mLock") - boolean mForcedAppStandbyEnabled; // True if the forced app standby feature is enabled + boolean mForcedAppStandbyEnabled; - private class FeatureFlagObserver extends ContentObserver { - FeatureFlagObserver() { + @VisibleForTesting + class FeatureFlagsObserver extends ContentObserver { + FeatureFlagsObserver() { super(null); } @@ -128,6 +155,9 @@ public class ForceAppStandbyTracker { mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED), false, this); + + mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor( + Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this); } boolean isForcedAppStandbyEnabled() { @@ -135,20 +165,43 @@ public class ForceAppStandbyTracker { Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1; } + boolean isForcedAppStandbyForSmallBatteryEnabled() { + return Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1; + } + @Override - public void onChange(boolean selfChange) { - final boolean enabled = isForcedAppStandbyEnabled(); - synchronized (mLock) { - if (mForcedAppStandbyEnabled == enabled) { - return; + public void onChange(boolean selfChange, Uri uri) { + if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) { + final boolean enabled = isForcedAppStandbyEnabled(); + synchronized (mLock) { + if (mForcedAppStandbyEnabled == enabled) { + return; + } + mForcedAppStandbyEnabled = enabled; + if (DEBUG) { + Slog.d(TAG,"Forced app standby feature flag changed: " + + mForcedAppStandbyEnabled); + } } - mForcedAppStandbyEnabled = enabled; - if (DEBUG) { - Slog.d(TAG, - "Forced app standby feature flag changed: " + mForcedAppStandbyEnabled); + mHandler.notifyForcedAppStandbyFeatureFlagChanged(); + } else if (Settings.Global.getUriFor( + Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) { + final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled(); + synchronized (mLock) { + if (mForceAllAppStandbyForSmallBattery == enabled) { + return; + } + mForceAllAppStandbyForSmallBattery = enabled; + if (DEBUG) { + Slog.d(TAG, "Forced app standby for small battery feature flag changed: " + + mForceAllAppStandbyForSmallBattery); + } + updateForceAllAppStandbyState(); } + } else { + Slog.w(TAG, "Unexpected feature flag uri encountered: " + uri); } - mHandler.notifyFeatureFlagChanged(); } } @@ -289,9 +342,11 @@ public class ForceAppStandbyTracker { mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager()); mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService()); mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal()); - final FeatureFlagObserver flagObserver = new FeatureFlagObserver(); - flagObserver.register(); - mForcedAppStandbyEnabled = flagObserver.isForcedAppStandbyEnabled(); + mFlagsObserver = new FeatureFlagsObserver(); + mFlagsObserver.register(); + mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled(); + mForceAllAppStandbyForSmallBattery = + mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled(); try { mIActivityManager.registerUidObserver(new UidObserver(), @@ -306,16 +361,24 @@ public class ForceAppStandbyTracker { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_REMOVED); + filter.addAction(Intent.ACTION_BATTERY_CHANGED); mContext.registerReceiver(new MyReceiver(), filter); refreshForcedAppStandbyUidPackagesLocked(); mPowerManagerInternal.registerLowPowerModeObserver( ServiceType.FORCE_ALL_APPS_STANDBY, - (state) -> updateForceAllAppsStandby(state.batterySaverEnabled)); + (state) -> { + synchronized (mLock) { + mBatterySaverEnabled = state.batterySaverEnabled; + updateForceAllAppStandbyState(); + } + }); + + mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState( + ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled; - updateForceAllAppsStandby(mPowerManagerInternal.getLowPowerState( - ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled); + updateForceAllAppStandbyState(); } } @@ -340,6 +403,11 @@ public class ForceAppStandbyTracker { return LocalServices.getService(PowerManagerInternal.class); } + @VisibleForTesting + boolean isSmallBatteryDevice() { + return ActivityManager.isSmallBatteryDevice(); + } + /** * Update {@link #mRunAnyRestrictedPackages} with the current app ops state. */ @@ -369,18 +437,26 @@ public class ForceAppStandbyTracker { } } - /** - * Update {@link #mForceAllAppsStandby} and notifies the listeners. - */ - void updateForceAllAppsStandby(boolean enable) { + private void updateForceAllAppStandbyState() { synchronized (mLock) { - if (enable == mForceAllAppsStandby) { - return; + if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) { + toggleForceAllAppsStandbyLocked(!mIsPluggedIn); + } else { + toggleForceAllAppsStandbyLocked(mBatterySaverEnabled); } - mForceAllAppsStandby = enable; + } + } - mHandler.notifyForceAllAppsStandbyChanged(); + /** + * Update {@link #mForceAllAppsStandby} and notifies the listeners. + */ + private void toggleForceAllAppsStandbyLocked(boolean enable) { + if (enable == mForceAllAppsStandby) { + return; } + mForceAllAppsStandby = enable; + + mHandler.notifyForceAllAppsStandbyChanged(); } private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) { @@ -515,6 +591,11 @@ public class ForceAppStandbyTracker { if (userId > 0) { mHandler.doUserRemoved(userId); } + } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { + synchronized (mLock) { + mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0); + } + updateForceAllAppStandbyState(); } } } @@ -533,7 +614,7 @@ public class ForceAppStandbyTracker { private static final int MSG_TEMP_WHITELIST_CHANGED = 5; private static final int MSG_FORCE_ALL_CHANGED = 6; private static final int MSG_USER_REMOVED = 7; - private static final int MSG_FEATURE_FLAG_CHANGED = 8; + private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8; public MyHandler(Looper looper) { super(looper); @@ -563,8 +644,8 @@ public class ForceAppStandbyTracker { obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget(); } - public void notifyFeatureFlagChanged() { - obtainMessage(MSG_FEATURE_FLAG_CHANGED).sendToTarget(); + public void notifyForcedAppStandbyFeatureFlagChanged() { + obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget(); } public void doUserRemoved(int userId) { @@ -618,7 +699,7 @@ public class ForceAppStandbyTracker { l.onForceAllAppsStandbyChanged(sender); } return; - case MSG_FEATURE_FLAG_CHANGED: + case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED: // Feature flag for forced app standby changed. final boolean unblockAlarms; synchronized (mLock) { @@ -845,6 +926,18 @@ public class ForceAppStandbyTracker { pw.println(isForceAllAppsStandbyEnabled()); pw.print(indent); + pw.print("Small Battery Device: "); + pw.println(isSmallBatteryDevice()); + + pw.print(indent); + pw.print("Force all apps standby for small battery device: "); + pw.println(mForceAllAppStandbyForSmallBattery); + + pw.print(indent); + pw.print("Plugged In: "); + pw.println(mIsPluggedIn); + + pw.print(indent); pw.print("Foreground uids: ["); String sep = ""; @@ -883,6 +976,11 @@ public class ForceAppStandbyTracker { final long token = proto.start(fieldId); proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby); + proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE, + isSmallBatteryDevice()); + proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY, + mForceAllAppStandbyForSmallBattery); + proto.write(ForceAppStandbyTrackerProto.IS_CHARGING, mIsPluggedIn); for (int i = 0; i < mForegroundUids.size(); i++) { if (mForegroundUids.valueAt(i)) { diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index 46a35ec800ba..af33ab08cb9a 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -1105,10 +1105,10 @@ public class IpSecService extends IIpSecService.Stub { * receive data. */ @Override - public synchronized IpSecTransformResponse createTransportModeTransform( - IpSecConfig c, IBinder binder) throws RemoteException { + public synchronized IpSecTransformResponse createTransform(IpSecConfig c, IBinder binder) + throws RemoteException { checkIpSecConfig(c); - checkNotNull(binder, "Null Binder passed to createTransportModeTransform"); + checkNotNull(binder, "Null Binder passed to createTransform"); final int resourceId = mNextResourceId++; UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid()); @@ -1186,7 +1186,7 @@ public class IpSecService extends IIpSecService.Stub { * other reasons. */ @Override - public synchronized void deleteTransportModeTransform(int resourceId) throws RemoteException { + public synchronized void deleteTransform(int resourceId) throws RemoteException { UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid()); releaseResource(userRecord.mTransformRecords, resourceId); } diff --git a/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java b/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java index 80f8e519beb7..833def3e87b1 100644 --- a/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java +++ b/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java @@ -26,4 +26,7 @@ public interface PersistentDataBlockManagerInternal { /** Retrieves handle to a lockscreen credential to be used for Factory Reset Protection. */ byte[] getFrpCredentialHandle(); + + /** Update the OEM unlock enabled bit, bypassing user restriction checks. */ + void forceOemUnlockEnabled(boolean enabled); } diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java index c32a2d10b0bc..4298140d31a0 100644 --- a/services/core/java/com/android/server/PersistentDataBlockService.java +++ b/services/core/java/com/android/server/PersistentDataBlockService.java @@ -668,5 +668,13 @@ public class PersistentDataBlockService extends SystemService { IoUtils.closeQuietly(inputStream); } } + + @Override + public void forceOemUnlockEnabled(boolean enabled) { + synchronized (mLock) { + doSetOemUnlockEnabledLocked(enabled); + computeAndWriteDigestLocked(); + } + } }; } diff --git a/services/core/java/com/android/server/SystemUpdateManagerService.java b/services/core/java/com/android/server/SystemUpdateManagerService.java new file mode 100644 index 000000000000..6c1ffdd32d18 --- /dev/null +++ b/services/core/java/com/android/server/SystemUpdateManagerService.java @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import static android.os.SystemUpdateManager.KEY_STATUS; +import static android.os.SystemUpdateManager.STATUS_IDLE; +import static android.os.SystemUpdateManager.STATUS_UNKNOWN; + +import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; +import static org.xmlpull.v1.XmlPullParser.END_TAG; +import static org.xmlpull.v1.XmlPullParser.START_TAG; + +import android.Manifest; +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.ISystemUpdateManager; +import android.os.PersistableBundle; +import android.os.SystemUpdateManager; +import android.provider.Settings; +import android.util.AtomicFile; +import android.util.Slog; +import android.util.Xml; + +import com.android.internal.util.FastXmlSerializer; +import com.android.internal.util.XmlUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class SystemUpdateManagerService extends ISystemUpdateManager.Stub { + + private static final String TAG = "SystemUpdateManagerService"; + + private static final int UID_UNKNOWN = -1; + + private static final String INFO_FILE = "system-update-info.xml"; + private static final int INFO_FILE_VERSION = 0; + private static final String TAG_INFO = "info"; + private static final String KEY_VERSION = "version"; + private static final String KEY_UID = "uid"; + private static final String KEY_BOOT_COUNT = "boot-count"; + private static final String KEY_INFO_BUNDLE = "info-bundle"; + + private final Context mContext; + private final AtomicFile mFile; + private final Object mLock = new Object(); + private int mLastUid = UID_UNKNOWN; + private int mLastStatus = STATUS_UNKNOWN; + + public SystemUpdateManagerService(Context context) { + mContext = context; + mFile = new AtomicFile(new File(Environment.getDataSystemDirectory(), INFO_FILE)); + + // Populate mLastUid and mLastStatus. + synchronized (mLock) { + loadSystemUpdateInfoLocked(); + } + } + + @Override + public void updateSystemUpdateInfo(PersistableBundle infoBundle) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.RECOVERY, TAG); + + int status = infoBundle.getInt(KEY_STATUS, STATUS_UNKNOWN); + if (status == STATUS_UNKNOWN) { + Slog.w(TAG, "Invalid status info. Ignored"); + return; + } + + // There could be multiple updater apps running on a device. But only one at most should + // be active (i.e. with a pending update), with the rest reporting idle status. We will + // only accept the reported status if any of the following conditions holds: + // a) none has been reported before; + // b) the current on-file status was last reported by the same caller; + // c) an active update is being reported. + int uid = Binder.getCallingUid(); + if (mLastUid == UID_UNKNOWN || mLastUid == uid || status != STATUS_IDLE) { + synchronized (mLock) { + saveSystemUpdateInfoLocked(infoBundle, uid); + } + } else { + Slog.i(TAG, "Inactive updater reporting IDLE status. Ignored"); + } + } + + @Override + public Bundle retrieveSystemUpdateInfo() { + if (mContext.checkCallingOrSelfPermission(Manifest.permission.READ_SYSTEM_UPDATE_INFO) + == PackageManager.PERMISSION_DENIED + && mContext.checkCallingOrSelfPermission(Manifest.permission.RECOVERY) + == PackageManager.PERMISSION_DENIED) { + throw new SecurityException("Can't read system update info. Requiring " + + "READ_SYSTEM_UPDATE_INFO or RECOVERY permission."); + } + + synchronized (mLock) { + return loadSystemUpdateInfoLocked(); + } + } + + // Reads and validates the info file. Returns the loaded info bundle on success; or a default + // info bundle with UNKNOWN status. + private Bundle loadSystemUpdateInfoLocked() { + PersistableBundle loadedBundle = null; + try (FileInputStream fis = mFile.openRead()) { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(fis, StandardCharsets.UTF_8.name()); + loadedBundle = readInfoFileLocked(parser); + } catch (FileNotFoundException e) { + Slog.i(TAG, "No existing info file " + mFile.getBaseFile()); + } catch (XmlPullParserException e) { + Slog.e(TAG, "Failed to parse the info file:", e); + } catch (IOException e) { + Slog.e(TAG, "Failed to read the info file:", e); + } + + // Validate the loaded bundle. + if (loadedBundle == null) { + return removeInfoFileAndGetDefaultInfoBundleLocked(); + } + + int version = loadedBundle.getInt(KEY_VERSION, -1); + if (version == -1) { + Slog.w(TAG, "Invalid info file (invalid version). Ignored"); + return removeInfoFileAndGetDefaultInfoBundleLocked(); + } + + int lastUid = loadedBundle.getInt(KEY_UID, -1); + if (lastUid == -1) { + Slog.w(TAG, "Invalid info file (invalid UID). Ignored"); + return removeInfoFileAndGetDefaultInfoBundleLocked(); + } + + int lastBootCount = loadedBundle.getInt(KEY_BOOT_COUNT, -1); + if (lastBootCount == -1 || lastBootCount != getBootCount()) { + Slog.w(TAG, "Outdated info file. Ignored"); + return removeInfoFileAndGetDefaultInfoBundleLocked(); + } + + PersistableBundle infoBundle = loadedBundle.getPersistableBundle(KEY_INFO_BUNDLE); + if (infoBundle == null) { + Slog.w(TAG, "Invalid info file (missing info). Ignored"); + return removeInfoFileAndGetDefaultInfoBundleLocked(); + } + + int lastStatus = infoBundle.getInt(KEY_STATUS, STATUS_UNKNOWN); + if (lastStatus == STATUS_UNKNOWN) { + Slog.w(TAG, "Invalid info file (invalid status). Ignored"); + return removeInfoFileAndGetDefaultInfoBundleLocked(); + } + + // Everything looks good upon reaching this point. + mLastStatus = lastStatus; + mLastUid = lastUid; + return new Bundle(infoBundle); + } + + private void saveSystemUpdateInfoLocked(PersistableBundle infoBundle, int uid) { + // Wrap the incoming bundle with extra info (e.g. version, uid, boot count). We use nested + // PersistableBundle to avoid manually parsing XML attributes when loading the info back. + PersistableBundle outBundle = new PersistableBundle(); + outBundle.putPersistableBundle(KEY_INFO_BUNDLE, infoBundle); + outBundle.putInt(KEY_VERSION, INFO_FILE_VERSION); + outBundle.putInt(KEY_UID, uid); + outBundle.putInt(KEY_BOOT_COUNT, getBootCount()); + + // Only update the info on success. + if (writeInfoFileLocked(outBundle)) { + mLastUid = uid; + mLastStatus = infoBundle.getInt(KEY_STATUS); + } + } + + // Performs I/O work only, without validating the loaded info. + @Nullable + private PersistableBundle readInfoFileLocked(XmlPullParser parser) + throws XmlPullParserException, IOException { + int type; + while ((type = parser.next()) != END_DOCUMENT) { + if (type == START_TAG && TAG_INFO.equals(parser.getName())) { + return PersistableBundle.restoreFromXml(parser); + } + } + return null; + } + + private boolean writeInfoFileLocked(PersistableBundle outBundle) { + FileOutputStream fos = null; + try { + fos = mFile.startWrite(); + + XmlSerializer out = new FastXmlSerializer(); + out.setOutput(fos, StandardCharsets.UTF_8.name()); + out.startDocument(null, true); + + out.startTag(null, TAG_INFO); + outBundle.saveToXml(out); + out.endTag(null, TAG_INFO); + + out.endDocument(); + mFile.finishWrite(fos); + return true; + } catch (IOException | XmlPullParserException e) { + Slog.e(TAG, "Failed to save the info file:", e); + if (fos != null) { + mFile.failWrite(fos); + } + } + return false; + } + + private Bundle removeInfoFileAndGetDefaultInfoBundleLocked() { + if (mFile.exists()) { + Slog.i(TAG, "Removing info file"); + mFile.delete(); + } + + mLastStatus = STATUS_UNKNOWN; + mLastUid = UID_UNKNOWN; + Bundle infoBundle = new Bundle(); + infoBundle.putInt(KEY_STATUS, STATUS_UNKNOWN); + return infoBundle; + } + + private int getBootCount() { + return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.BOOT_COUNT, 0); + } +} diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c0c684c41bc5..00918f2ed090 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -27,9 +27,9 @@ import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW; +import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT; import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA; @@ -120,6 +120,7 @@ import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICAT import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; + import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; import static com.android.internal.util.XmlUtils.readLongAttribute; @@ -198,6 +199,7 @@ import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; + import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -277,8 +279,8 @@ import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.PathPermission; import android.content.pm.PermissionInfo; @@ -356,18 +358,18 @@ import android.text.style.SuggestionSpan; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; -import android.util.LongSparseArray; -import android.util.StatsLog; -import android.util.TimingsTraceLog; import android.util.DebugUtils; import android.util.EventLog; import android.util.Log; +import android.util.LongSparseArray; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; +import android.util.StatsLog; import android.util.TimeUtils; +import android.util.TimingsTraceLog; import android.util.Xml; import android.util.proto.ProtoOutputStream; import android.view.Gravity; @@ -440,6 +442,12 @@ import com.android.server.utils.PriorityDump; import com.android.server.vr.VrManagerInternal; import com.android.server.wm.PinnedStackWindowController; import com.android.server.wm.WindowManagerService; + +import dalvik.system.VMRuntime; + +import libcore.io.IoUtils; +import libcore.util.EmptyArray; + import com.google.android.collect.Lists; import com.google.android.collect.Maps; @@ -479,11 +487,6 @@ import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import dalvik.system.VMRuntime; - -import libcore.io.IoUtils; -import libcore.util.EmptyArray; - public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { @@ -10414,10 +10417,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public Bitmap getTaskDescriptionIcon(String filePath, int userId) { - if (userId != UserHandle.getCallingUserId()) { - enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, - "getTaskDescriptionIcon"); - } + userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null); + final File passedIconFile = new File(filePath); final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId), passedIconFile.getName()); @@ -25159,6 +25161,10 @@ public class ActivityManagerService extends IActivityManager.Stub public int getMaxRunningUsers() { return mUserController.mMaxRunningUsers; } + + public boolean isCallerRecents(int callingUid) { + return getRecentTasks().isCallerRecents(callingUid); + } } /** diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 89102748796a..26d65bc7414c 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -745,7 +745,7 @@ class AppErrors { mContext.getContentResolver(), Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION, 0, - UserHandle.USER_CURRENT) != 0; + mService.mUserController.getCurrentUserId()) != 0; final boolean crashSilenced = mAppsNotReportingCrashes != null && mAppsNotReportingCrashes.contains(proc.info.packageName); if ((mService.canShowErrorDialogs() || showBackground) && !crashSilenced diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java index 1fcaeef72dba..927b72ceb37e 100644 --- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java @@ -99,7 +99,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { // Keep the last WiFi stats so we can compute a delta. @GuardedBy("mWorkerLock") private WifiActivityEnergyInfo mLastInfo = - new WifiActivityEnergyInfo(0, 0, 0, new long[]{0}, 0, 0, 0); + new WifiActivityEnergyInfo(0, 0, 0, new long[]{0}, 0, 0, 0, 0); BatteryExternalStatsWorker(Context context, BatteryStatsImpl stats) { mContext = context; @@ -374,6 +374,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { private WifiActivityEnergyInfo extractDeltaLocked(WifiActivityEnergyInfo latest) { final long timePeriodMs = latest.mTimestamp - mLastInfo.mTimestamp; + final long lastScanMs = mLastInfo.mControllerScanTimeMs; final long lastIdleMs = mLastInfo.mControllerIdleTimeMs; final long lastTxMs = mLastInfo.mControllerTxTimeMs; final long lastRxMs = mLastInfo.mControllerRxTimeMs; @@ -388,14 +389,16 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { final long txTimeMs = latest.mControllerTxTimeMs - lastTxMs; final long rxTimeMs = latest.mControllerRxTimeMs - lastRxMs; final long idleTimeMs = latest.mControllerIdleTimeMs - lastIdleMs; + final long scanTimeMs = latest.mControllerScanTimeMs - lastScanMs; - if (txTimeMs < 0 || rxTimeMs < 0) { + if (txTimeMs < 0 || rxTimeMs < 0 || scanTimeMs < 0) { // The stats were reset by the WiFi system (which is why our delta is negative). // Returns the unaltered stats. delta.mControllerEnergyUsed = latest.mControllerEnergyUsed; delta.mControllerRxTimeMs = latest.mControllerRxTimeMs; delta.mControllerTxTimeMs = latest.mControllerTxTimeMs; delta.mControllerIdleTimeMs = latest.mControllerIdleTimeMs; + delta.mControllerScanTimeMs = latest.mControllerScanTimeMs; Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + delta); } else { final long totalActiveTimeMs = txTimeMs + rxTimeMs; @@ -433,6 +436,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { // These times seem to be the most reliable. delta.mControllerTxTimeMs = txTimeMs; delta.mControllerRxTimeMs = rxTimeMs; + delta.mControllerScanTimeMs = scanTimeMs; // WiFi calculates the idle time as a difference from the on time and the various // Rx + Tx times. There seems to be some missing time there because this sometimes // becomes negative. Just cap it at 0 and ensure that it is less than the expected idle diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 207aaa76e5b8..04b49ba3db33 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -40,6 +40,7 @@ import android.os.UserManagerInternal; import android.os.WorkSource; import android.os.WorkSource.WorkChain; import android.os.connectivity.CellularBatteryStats; +import android.os.connectivity.WifiBatteryStats; import android.os.connectivity.GpsBatteryStats; import android.os.health.HealthStatsParceler; import android.os.health.HealthStatsWriter; @@ -1455,6 +1456,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub } /** + * Gets a snapshot of Wifi stats + * @hide + */ + public WifiBatteryStats getWifiBatteryStats() { + synchronized (mStats) { + return mStats.getWifiBatteryStats(); + } + } + + /** * Gets a snapshot of Gps stats * @hide */ diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 1a47aa5cd777..5ada484e9e32 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -1431,7 +1431,13 @@ class UserController implements Handler.Callback { if (callingUid != 0 && callingUid != SYSTEM_UID) { final boolean allow; - if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, + if (mInjector.isCallerRecents(callingUid) + && callingUserId == getCurrentUserId() + && isSameProfileGroup(callingUserId, targetUserId)) { + // If the caller is Recents and it is running in the current user, we then allow it + // to access its profiles. + allow = true; + } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { // If the caller has this permission, they always pass go. And collect $200. allow = true; @@ -2149,5 +2155,9 @@ class UserController implements Handler.Callback { mService.mLockTaskController.clearLockedTasks(reason); } } + + protected boolean isCallerRecents(int callingUid) { + return mService.getRecentTasks().isCallerRecents(callingUid); + } } } diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index bd1dbf9c46e8..fa5fdf587b8d 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -63,6 +63,7 @@ import android.util.KeyValueListParser; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; +import android.util.StatsLog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; @@ -823,6 +824,8 @@ public final class JobSchedulerService extends com.android.server.SystemService jobStatus.enqueueWorkLocked(ActivityManager.getService(), work); } startTrackingJobLocked(jobStatus, toCancel); + StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, + uId, null, jobStatus.getBatteryName(), 2); // If the job is immediately ready to run, then we can just immediately // put it in the pending list and try to schedule it. This is especially diff --git a/services/core/java/com/android/server/oemlock/OemLockService.java b/services/core/java/com/android/server/oemlock/OemLockService.java index 2a2ff06b7a5a..a6200bf433e4 100644 --- a/services/core/java/com/android/server/oemlock/OemLockService.java +++ b/services/core/java/com/android/server/oemlock/OemLockService.java @@ -31,10 +31,10 @@ import android.os.UserManager; import android.os.UserManagerInternal; import android.os.UserManagerInternal.UserRestrictionsListener; import android.service.oemlock.IOemLockService; -import android.service.persistentdata.PersistentDataBlockManager; import android.util.Slog; import com.android.server.LocalServices; +import com.android.server.PersistentDataBlockManagerInternal; import com.android.server.SystemService; import com.android.server.pm.UserRestrictionsUtils; @@ -217,13 +217,12 @@ public class OemLockService extends SystemService { * is used to erase FRP information on a unlockable device. */ private void setPersistentDataBlockOemUnlockAllowedBit(boolean allowed) { - final PersistentDataBlockManager pdbm = (PersistentDataBlockManager) - mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); + final PersistentDataBlockManagerInternal pdbmi + = LocalServices.getService(PersistentDataBlockManagerInternal.class); // if mOemLock is PersistentDataBlockLock, then the bit should have already been set - if (pdbm != null && !(mOemLock instanceof PersistentDataBlockLock) - && pdbm.getOemUnlockEnabled() != allowed) { + if (pdbmi != null && !(mOemLock instanceof PersistentDataBlockLock)) { Slog.i(TAG, "Update OEM Unlock bit in pst partition to " + allowed); - pdbm.setOemUnlockEnabled(allowed); + pdbmi.forceOemUnlockEnabled(allowed); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 10b377d9a81e..faf6114237cd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -118,6 +118,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.ResourcesManager; @@ -992,6 +993,7 @@ public class PackageManagerService extends IPackageManager.Stub private List<String> mKeepUninstalledPackages; private UserManagerInternal mUserManagerInternal; + private ActivityManagerInternal mActivityManagerInternal; private DeviceIdleController.LocalService mDeviceIdleController; @@ -4575,6 +4577,14 @@ Slog.e("TODD", return mUserManagerInternal; } + private ActivityManagerInternal getActivityManagerInternal() { + if (mActivityManagerInternal == null) { + mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); + } + return mActivityManagerInternal; + } + + private DeviceIdleController.LocalService getDeviceIdleController() { if (mDeviceIdleController == null) { mDeviceIdleController = @@ -4735,8 +4745,12 @@ Slog.e("TODD", int filterCallingUid, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForComponent(flags, userId, component); - mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, - false /* requireFullPermission */, false /* checkShell */, "get activity info"); + + if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) { + mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get activity info"); + } + synchronized (mPackages) { PackageParser.Activity a = mActivities.mActivities.get(component); @@ -4758,6 +4772,22 @@ Slog.e("TODD", return null; } + private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) { + if (!getActivityManagerInternal().isCallerRecents(callingUid)) { + return false; + } + final long token = Binder.clearCallingIdentity(); + try { + final int callingUserId = UserHandle.getUserId(callingUid); + if (ActivityManager.getCurrentUser() != callingUserId) { + return false; + } + return sUserManager.isSameProfileGroup(callingUserId, targetUserId); + } finally { + Binder.restoreCallingIdentity(token); + } + } + @Override public boolean activitySupportsIntent(ComponentName component, Intent intent, String resolvedType) { diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index a33f0716c4cb..47cd81326932 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -236,6 +236,8 @@ class PackageManagerShellCommand extends ShellCommand { return runHasFeature(); case "set-harmful-app-warning": return runSetHarmfulAppWarning(); + case "get-harmful-app-warning": + return runGetHarmfulAppWarning(); default: { String nextArg = getNextArg(); if (nextArg == null) { @@ -2125,6 +2127,31 @@ class PackageManagerShellCommand extends ShellCommand { return 0; } + private int runGetHarmfulAppWarning() throws RemoteException { + int userId = UserHandle.USER_CURRENT; + + String opt; + while ((opt = getNextOption()) != null) { + if (opt.equals("--user")) { + userId = UserHandle.parseUserArg(getNextArgRequired()); + } else { + getErrPrintWriter().println("Error: Unknown option: " + opt); + return -1; + } + } + + userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning"); + + final String packageName = getNextArgRequired(); + final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId); + if (!TextUtils.isEmpty(warning)) { + getOutPrintWriter().println(warning); + return 0; + } else { + return 1; + } + } + private static String checkAbiArgument(String abi) { if (TextUtils.isEmpty(abi)) { throw new IllegalArgumentException("Missing ABI argument"); @@ -2684,6 +2711,9 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(""); pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]"); pw.println(" Mark the app as harmful with the given warning message."); + pw.println(""); + pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>"); + pw.println(" Return the harmful app warning message for the given app, if present"); pw.println(); Intent.printIntentArgsHelp(pw , ""); } diff --git a/services/core/java/com/android/server/slice/PinnedSliceState.java b/services/core/java/com/android/server/slice/PinnedSliceState.java index 09f6da92939c..5811714c73c4 100644 --- a/services/core/java/com/android/server/slice/PinnedSliceState.java +++ b/services/core/java/com/android/server/slice/PinnedSliceState.java @@ -21,6 +21,8 @@ import android.app.slice.SliceSpec; import android.content.ContentProviderClient; import android.net.Uri; import android.os.Bundle; +import android.os.IBinder; +import android.os.IBinder.DeathRecipient; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; @@ -49,11 +51,13 @@ public class PinnedSliceState { @GuardedBy("mLock") private final ArraySet<String> mPinnedPkgs = new ArraySet<>(); @GuardedBy("mLock") - private final ArraySet<ISliceListener> mListeners = new ArraySet<>(); + private final ArrayMap<IBinder, ISliceListener> mListeners = new ArrayMap<>(); @GuardedBy("mLock") private SliceSpec[] mSupportedSpecs = null; @GuardedBy("mLock") - private final ArrayMap<ISliceListener, String> mPkgMap = new ArrayMap<>(); + private final ArrayMap<IBinder, String> mPkgMap = new ArrayMap<>(); + + private final DeathRecipient mDeathRecipient = this::handleRecheckListeners; public PinnedSliceState(SliceManagerService service, Uri uri) { mService = service; @@ -107,20 +111,27 @@ public class PinnedSliceState { public void addSliceListener(ISliceListener listener, String pkg, SliceSpec[] specs) { synchronized (mLock) { - if (mListeners.add(listener) && mListeners.size() == 1) { + if (mListeners.size() == 0) { mService.listen(mUri); } - mPkgMap.put(listener, pkg); + try { + listener.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + } + mListeners.put(listener.asBinder(), listener); + mPkgMap.put(listener.asBinder(), pkg); mergeSpecs(specs); } } public boolean removeSliceListener(ISliceListener listener) { synchronized (mLock) { - mPkgMap.remove(listener); - if (mListeners.remove(listener) && mListeners.size() == 0) { + listener.asBinder().unlinkToDeath(mDeathRecipient, 0); + mPkgMap.remove(listener.asBinder()); + if (mListeners.containsKey(listener.asBinder()) && mListeners.size() == 1) { mService.unlisten(mUri); } + mListeners.remove(listener.asBinder()); } return !isPinned(); } @@ -159,25 +170,44 @@ public class PinnedSliceState { return client; } + private void handleRecheckListeners() { + if (!isPinned()) return; + synchronized (mLock) { + for (int i = mListeners.size() - 1; i >= 0; i--) { + ISliceListener l = mListeners.valueAt(i); + if (!l.asBinder().isBinderAlive()) { + mListeners.removeAt(i); + } + } + if (!isPinned()) { + // All the listeners died, remove from pinned state. + mService.removePinnedSlice(mUri); + } + } + } + private void handleBind() { Slice cachedSlice = doBind(null); synchronized (mLock) { - mListeners.removeIf(l -> { + if (!isPinned()) return; + for (int i = mListeners.size() - 1; i >= 0; i--) { + ISliceListener l = mListeners.valueAt(i); Slice s = cachedSlice; if (s == null || s.hasHint(Slice.HINT_CALLER_NEEDED)) { s = doBind(mPkgMap.get(l)); } if (s == null) { - return true; + mListeners.removeAt(i); + continue; } try { l.onSliceUpdated(s); - return false; } catch (RemoteException e) { Log.e(TAG, "Unable to notify slice " + mUri, e); - return true; + mListeners.removeAt(i); + continue; } - }); + } if (!isPinned()) { // All the listeners died, remove from pinned state. mService.removePinnedSlice(mUri); diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java index ca7632c354d1..c1915801b61b 100644 --- a/services/core/java/com/android/server/slice/SliceManagerService.java +++ b/services/core/java/com/android/server/slice/SliceManagerService.java @@ -91,9 +91,9 @@ public class SliceManagerService extends ISliceManager.Stub { mObserver = new ContentObserver(mHandler) { @Override - public void onChange(boolean selfChange, Uri uri) { + public void onChange(boolean selfChange, Uri uri, int userId) { try { - getPinnedSlice(uri).onChange(); + getPinnedSlice(maybeAddUserId(uri, userId)).onChange(); } catch (IllegalStateException e) { Log.e(TAG, "Received change for unpinned slice " + uri, e); } @@ -204,7 +204,7 @@ public class SliceManagerService extends ISliceManager.Stub { } /// ----- internal code ----- - void removePinnedSlice(Uri uri) { + protected void removePinnedSlice(Uri uri) { synchronized (mLock) { mPinnedSlicesByUri.remove(uri).destroy(); } @@ -233,7 +233,7 @@ public class SliceManagerService extends ISliceManager.Stub { } @VisibleForTesting - PinnedSliceState createPinnedSlice(Uri uri) { + protected PinnedSliceState createPinnedSlice(Uri uri) { return new PinnedSliceState(this, uri); } @@ -352,7 +352,7 @@ public class SliceManagerService extends ISliceManager.Stub { // Based on getDefaultHome in ShortcutService. // TODO: Unify if possible @VisibleForTesting - String getDefaultHome(int userId) { + protected String getDefaultHome(int userId) { final long token = Binder.clearCallingIdentity(); try { final List<ResolveInfo> allHomeCandidates = new ArrayList<>(); diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index 688b4ffcee4b..8515dcb69970 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -99,11 +99,15 @@ class RemoteAnimationController { } private RemoteAnimationTarget[] createAnimations() { - final RemoteAnimationTarget[] result = new RemoteAnimationTarget[mPendingAnimations.size()]; + final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>(); for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { - result[i] = mPendingAnimations.get(i).createRemoteAppAnimation(); + final RemoteAnimationTarget target = + mPendingAnimations.get(i).createRemoteAppAnimation(); + if (target != null) { + targets.add(target); + } } - return result; + return targets.toArray(new RemoteAnimationTarget[targets.size()]); } private void onAnimationFinished() { @@ -145,9 +149,17 @@ class RemoteAnimationController { } RemoteAnimationTarget createRemoteAppAnimation() { - return new RemoteAnimationTarget(mAppWindowToken.getTask().mTaskId, getMode(), + final Task task = mAppWindowToken.getTask(); + final WindowState mainWindow = mAppWindowToken.findMainWindow(); + if (task == null) { + return null; + } + if (mainWindow == null) { + return null; + } + return new RemoteAnimationTarget(task.mTaskId, getMode(), mCapturedLeash, !mAppWindowToken.fillsParent(), - mAppWindowToken.findMainWindow().mWinAnimator.mLastClipRect, + mainWindow.mWinAnimator.mLastClipRect, mAppWindowToken.getPrefixOrderIndex(), mPosition, mStackBounds); } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index e660c50fcbc1..94a356e65878 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1172,6 +1172,15 @@ public final class SystemServer { } traceEnd(); + traceBeginAndSlog("StartSystemUpdateManagerService"); + try { + ServiceManager.addService(Context.SYSTEM_UPDATE_SERVICE, + new SystemUpdateManagerService(context)); + } catch (Throwable e) { + reportWtf("starting SystemUpdateManagerService", e); + } + traceEnd(); + traceBeginAndSlog("StartUpdateLockService"); try { ServiceManager.addService(Context.UPDATE_LOCK_SERVICE, diff --git a/services/tests/servicestests/src/com/android/server/ForceAppStandbyTrackerTest.java b/services/tests/servicestests/src/com/android/server/ForceAppStandbyTrackerTest.java index 429dd8fd1d3d..de54e52d4d0a 100644 --- a/services/tests/servicestests/src/com/android/server/ForceAppStandbyTrackerTest.java +++ b/services/tests/servicestests/src/com/android/server/ForceAppStandbyTrackerTest.java @@ -42,6 +42,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.BatteryManager; import android.os.Handler; import android.os.Looper; import android.os.PowerManager.ServiceType; @@ -51,6 +52,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; +import android.provider.Settings.Global; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.test.mock.MockContentResolver; @@ -105,6 +107,9 @@ public class ForceAppStandbyTrackerTest { PowerManagerInternal injectPowerManagerInternal() { return mMockPowerManagerInternal; } + + @Override + boolean isSmallBatteryDevice() { return mIsSmallBatteryDevice; }; } private static final int UID_1 = Process.FIRST_APPLICATION_UID + 1; @@ -144,6 +149,7 @@ public class ForceAppStandbyTrackerTest { private FakeSettingsProvider mFakeSettingsProvider; private boolean mPowerSaveMode; + private boolean mIsSmallBatteryDevice; private final ArraySet<Pair<Integer, String>> mRestrictedPackages = new ArraySet(); @@ -232,6 +238,7 @@ public class ForceAppStandbyTrackerTest { assertNotNull(mAppOpsCallback); assertNotNull(mPowerSaveObserver); assertNotNull(mReceiver); + assertNotNull(instance.mFlagsObserver); } private void setAppOps(int uid, String packageName, boolean restrict) throws RemoteException { @@ -852,6 +859,56 @@ public class ForceAppStandbyTrackerTest { assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); } + @Test + public void testSmallBatteryAndPluggedIn() throws Exception { + // This is a small battery device + mIsSmallBatteryDevice = true; + + final ForceAppStandbyTrackerTestable instance = newInstance(); + callStart(instance); + assertFalse(instance.isForceAllAppsStandbyEnabled()); + + // Setting/experiment for all app standby for small battery is enabled + Global.putInt(mMockContentResolver, Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 1); + instance.mFlagsObserver.onChange(true, + Global.getUriFor(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED)); + assertTrue(instance.isForceAllAppsStandbyEnabled()); + + // When battery is plugged in, force app standby is disabled + Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); + intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB); + mReceiver.onReceive(mMockContext, intent); + assertFalse(instance.isForceAllAppsStandbyEnabled()); + + // When battery stops plugged in, force app standby is enabled + mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED)); + assertTrue(instance.isForceAllAppsStandbyEnabled()); + } + + @Test + public void testNotSmallBatteryAndPluggedIn() throws Exception { + // Not a small battery device, so plugged in status should not affect forced app standby + mIsSmallBatteryDevice = false; + + final ForceAppStandbyTrackerTestable instance = newInstance(); + callStart(instance); + assertFalse(instance.isForceAllAppsStandbyEnabled()); + + mPowerSaveMode = true; + mPowerSaveObserver.accept(getPowerSaveState()); + assertTrue(instance.isForceAllAppsStandbyEnabled()); + + // When battery is plugged in, force app standby is unaffected + Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); + intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB); + mReceiver.onReceive(mMockContext, intent); + assertTrue(instance.isForceAllAppsStandbyEnabled()); + + // When battery stops plugged in, force app standby is unaffected + mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED)); + assertTrue(instance.isForceAllAppsStandbyEnabled()); + } + static int[] array(int... appIds) { Arrays.sort(appIds); return appIds; diff --git a/services/tests/servicestests/src/com/android/server/net/watchlist/PrivacyUtilsTests.java b/services/tests/servicestests/src/com/android/server/net/watchlist/PrivacyUtilsTests.java index a31b46ce5534..999dce51bd9c 100644 --- a/services/tests/servicestests/src/com/android/server/net/watchlist/PrivacyUtilsTests.java +++ b/services/tests/servicestests/src/com/android/server/net/watchlist/PrivacyUtilsTests.java @@ -77,9 +77,9 @@ public class PrivacyUtilsTests { assertEquals(6, result.size()); assertTrue(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB48")); assertTrue(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB49")); - assertFalse(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB47")); - assertTrue(result.get("E86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB45")); - assertFalse(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB44")); + assertTrue(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB47")); + assertFalse(result.get("E86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB45")); + assertTrue(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB44")); assertTrue(result.get("B86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB43")); } @@ -87,7 +87,7 @@ public class PrivacyUtilsTests { public void testPrivacyUtils_createInsecureDPEncoderForTest() throws Exception { DifferentialPrivacyEncoder encoder = PrivacyUtils.createInsecureDPEncoderForTest("foo"); assertEquals( - "EncoderId: watchlist_encoder:foo, ProbabilityF: 0.400, ProbabilityP: 0.250, " + "EncoderId: watchlist_encoder:foo, ProbabilityF: 0.469, ProbabilityP: 0.280, " + "ProbabilityQ: 1.000", encoder.getConfig().toString()); assertTrue(encoder.isInsecureEncoderForTest()); @@ -97,7 +97,7 @@ public class PrivacyUtilsTests { public void testPrivacyUtils_createSecureDPEncoderTest() throws Exception { DifferentialPrivacyEncoder encoder = PrivacyUtils.createSecureDPEncoder(TEST_SECRET, "foo"); assertEquals( - "EncoderId: watchlist_encoder:foo, ProbabilityF: 0.400, ProbabilityP: 0.250, " + "EncoderId: watchlist_encoder:foo, ProbabilityF: 0.469, ProbabilityP: 0.280, " + "ProbabilityQ: 1.000", encoder.getConfig().toString()); assertFalse(encoder.isInsecureEncoderForTest()); diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java index aada68273af0..d3bb80485dfb 100644 --- a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java +++ b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java @@ -6,6 +6,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; @@ -21,8 +22,11 @@ import android.app.slice.SliceSpec; import android.content.ContentProvider; import android.content.IContentProvider; import android.net.Uri; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; +import android.os.IBinder.DeathRecipient; import android.os.RemoteException; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; @@ -34,6 +38,7 @@ import com.android.server.UiServiceTestCase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -147,6 +152,7 @@ public class PinnedSliceStateTest extends UiServiceTestCase { @Test public void testListenerPin() { ISliceListener listener = mock(ISliceListener.class); + when(listener.asBinder()).thenReturn(new Binder()); assertFalse(mPinnedSliceManager.isPinned()); mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS); @@ -159,7 +165,11 @@ public class PinnedSliceStateTest extends UiServiceTestCase { @Test public void testMultiListenerPin() { ISliceListener listener = mock(ISliceListener.class); + Binder value = new Binder(); + when(listener.asBinder()).thenReturn(value); ISliceListener listener2 = mock(ISliceListener.class); + Binder value2 = new Binder(); + when(listener2.asBinder()).thenReturn(value2); assertFalse(mPinnedSliceManager.isPinned()); mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS); @@ -172,8 +182,30 @@ public class PinnedSliceStateTest extends UiServiceTestCase { } @Test + public void testListenerDeath() throws RemoteException { + ISliceListener listener = mock(ISliceListener.class); + IBinder binder = mock(IBinder.class); + when(binder.isBinderAlive()).thenReturn(true); + when(listener.asBinder()).thenReturn(binder); + assertFalse(mPinnedSliceManager.isPinned()); + + mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS); + assertTrue(mPinnedSliceManager.isPinned()); + + ArgumentCaptor<DeathRecipient> arg = ArgumentCaptor.forClass(DeathRecipient.class); + verify(binder).linkToDeath(arg.capture(), anyInt()); + + when(binder.isBinderAlive()).thenReturn(false); + arg.getValue().binderDied(); + + verify(mSliceService).removePinnedSlice(eq(TEST_URI)); + assertFalse(mPinnedSliceManager.isPinned()); + } + + @Test public void testPkgListenerPin() { ISliceListener listener = mock(ISliceListener.class); + when(listener.asBinder()).thenReturn(new Binder()); assertFalse(mPinnedSliceManager.isPinned()); mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS); @@ -191,6 +223,7 @@ public class PinnedSliceStateTest extends UiServiceTestCase { clearInvocations(mIContentProvider); ISliceListener listener = mock(ISliceListener.class); + when(listener.asBinder()).thenReturn(new Binder()); Slice s = new Slice.Builder(TEST_URI).build(); Bundle b = new Bundle(); b.putParcelable(SliceProvider.EXTRA_SLICE, s); diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 8c7d6b30ecdc..d17bdc85eb22 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -419,7 +419,6 @@ public final class Call { /** * Indicates the call used Assisted Dialing. * See also {@link Connection#PROPERTY_ASSISTED_DIALING_USED} - * @hide */ public static final int PROPERTY_ASSISTED_DIALING_USED = 0x00000200; diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index aaef8d3d3856..75224434bc1c 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -35,6 +35,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; +import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; import android.util.ArraySet; @@ -401,7 +402,6 @@ public abstract class Connection extends Conferenceable { /** * Set by the framework to indicate that a connection is using assisted dialing. - * @hide */ public static final int PROPERTY_ASSISTED_DIALING_USED = 1 << 9; @@ -2538,6 +2538,19 @@ public abstract class Connection extends Conferenceable { } /** + * Adds a parcelable extra to this {@code Connection}. + * + * @param key The extra key. + * @param value The value. + * @hide + */ + public final void putExtra(@NonNull String key, @NonNull Parcelable value) { + Bundle newExtras = new Bundle(); + newExtras.putParcelable(key, value); + putExtras(newExtras); + } + + /** * Removes extras from this {@code Connection}. * * @param keys The keys of the extras to remove. diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index d292db3efc82..91d5da30935b 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -602,12 +602,17 @@ public class TelecomManager { /** * The boolean indicated by this extra controls whether or not a call is eligible to undergo * assisted dialing. This extra is stored under {@link #EXTRA_OUTGOING_CALL_EXTRAS}. - * @hide */ public static final String EXTRA_USE_ASSISTED_DIALING = "android.telecom.extra.USE_ASSISTED_DIALING"; /** + * The bundle indicated by this extra store information related to the assisted dialing action. + */ + public static final String EXTRA_ASSISTED_DIALING_TRANSFORMATION_INFO = + "android.telecom.extra.ASSISTED_DIALING_TRANSFORMATION_INFO"; + + /** * The following 4 constants define how properties such as phone numbers and names are * displayed to the user. */ diff --git a/telecomm/java/android/telecom/TransformationInfo.java b/telecomm/java/android/telecom/TransformationInfo.java new file mode 100755 index 000000000000..3e848c6f2f80 --- /dev/null +++ b/telecomm/java/android/telecom/TransformationInfo.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2017 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.telecom; + +import android.os.Parcelable; +import android.os.Parcel; + +/** + * A container class to hold information related to the Assisted Dialing operation. All member + * variables must be set when constructing a new instance of this class. + */ +public final class TransformationInfo implements Parcelable { + private String mOriginalNumber; + private String mTransformedNumber; + private String mUserHomeCountryCode; + private String mUserRoamingCountryCode; + private int mTransformedNumberCountryCallingCode; + + public TransformationInfo(String originalNumber, + String transformedNumber, + String userHomeCountryCode, + String userRoamingCountryCode, + int transformedNumberCountryCallingCode) { + String missing = ""; + if (originalNumber == null) { + missing += " mOriginalNumber"; + } + if (transformedNumber == null) { + missing += " mTransformedNumber"; + } + if (userHomeCountryCode == null) { + missing += " mUserHomeCountryCode"; + } + if (userRoamingCountryCode == null) { + missing += " mUserRoamingCountryCode"; + } + + if (!missing.isEmpty()) { + throw new IllegalStateException("Missing required properties:" + missing); + } + this.mOriginalNumber = originalNumber; + this.mTransformedNumber = transformedNumber; + this.mUserHomeCountryCode = userHomeCountryCode; + this.mUserRoamingCountryCode = userRoamingCountryCode; + this.mTransformedNumberCountryCallingCode = transformedNumberCountryCallingCode; + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeString(mOriginalNumber); + out.writeString(mTransformedNumber); + out.writeString(mUserHomeCountryCode); + out.writeString(mUserRoamingCountryCode); + out.writeInt(mTransformedNumberCountryCallingCode); + } + + public static final Parcelable.Creator<TransformationInfo> CREATOR + = new Parcelable.Creator<TransformationInfo>() { + public TransformationInfo createFromParcel(Parcel in) { + return new TransformationInfo(in); + } + + public TransformationInfo[] newArray(int size) { + return new TransformationInfo[size]; + } + }; + + private TransformationInfo(Parcel in) { + mOriginalNumber = in.readString(); + mTransformedNumber = in.readString(); + mUserHomeCountryCode = in.readString(); + mUserRoamingCountryCode = in.readString(); + mTransformedNumberCountryCallingCode = in.readInt(); + } + + /** + * The original number that underwent Assisted Dialing. + */ + public String getOriginalNumber() { + return mOriginalNumber; + } + + /** + * The number after it underwent Assisted Dialing. + */ + public String getTransformedNumber() { + return mTransformedNumber; + } + + /** + * The user's home country code that was used when attempting to transform the number. + */ + public String getUserHomeCountryCode() { + return mUserHomeCountryCode; + } + + /** + * The users's roaming country code that was used when attempting to transform the number. + */ + public String getUserRoamingCountryCode() { + return mUserRoamingCountryCode; + } + + /** + * The country calling code that was used in the transformation. + */ + public int getTransformedNumberCountryCallingCode() { + return mTransformedNumberCountryCallingCode; + } +} diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index ce0b551311b0..649d4783cc7a 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1644,6 +1644,13 @@ public class CarrierConfigManager { "roaming_operator_string_array"; /** + * Controls whether Assisted Dialing is enabled and the preference is shown. This feature + * transforms numbers when the user is roaming. + */ + public static final String KEY_ASSISTED_DIALING_ENABLED_BOOL = + "assisted_dialing_enabled_bool"; + + /** * URL from which the proto containing the public key of the Carrier used for * IMSI encryption will be downloaded. * @hide @@ -2040,6 +2047,7 @@ public class CarrierConfigManager { false); sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null); sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null); + sDefaults.putBoolean(KEY_ASSISTED_DIALING_ENABLED_BOOL, true); sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false); sDefaults.putBoolean(KEY_RTT_SUPPORTED_BOOL, false); sDefaults.putBoolean(KEY_DISABLE_CHARGE_INDICATION_BOOL, false); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index de9e691eadcf..17f809d3863a 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1024,8 +1024,8 @@ public class TelephonyManager { /** * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates - * the updated carrier id {@link TelephonyManager#getSubscriptionCarrierId()} of the current - * subscription. + * the updated carrier id {@link TelephonyManager#getAndroidCarrierIdForSubscription()} of + * the current subscription. * <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or * the carrier cannot be identified. */ @@ -6900,14 +6900,19 @@ public class TelephonyManager { /** * Returns carrier id of the current subscription. - * <p>To recognize a carrier (including MVNO) as a first class identity, assign each carrier - * with a canonical integer a.k.a carrier id. + * <p>To recognize a carrier (including MVNO) as a first-class identity, Android assigns each + * carrier with a canonical integer a.k.a. android carrier id. The Android carrier ID is an + * Android platform-wide identifier for a carrier. AOSP maintains carrier ID assignments in + * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a> + * + * <p>Apps which have carrier-specific configurations or business logic can use the carrier id + * as an Android platform-wide identifier for carriers. * * @return Carrier id of the current subscription. Return {@link #UNKNOWN_CARRIER_ID} if the * subscription is unavailable or the carrier cannot be identified. * @throws IllegalStateException if telephony service is unavailable. */ - public int getSubscriptionCarrierId() { + public int getAndroidCarrierIdForSubscription() { try { ITelephony service = getITelephony(); return service.getSubscriptionCarrierId(getSubId()); @@ -6923,17 +6928,18 @@ public class TelephonyManager { /** * Returns carrier name of the current subscription. - * <p>Carrier name is a user-facing name of carrier id {@link #getSubscriptionCarrierId()}, - * usually the brand name of the subsidiary (e.g. T-Mobile). Each carrier could configure - * multiple {@link #getSimOperatorName() SPN} but should have a single carrier name. - * Carrier name is not a canonical identity, use {@link #getSubscriptionCarrierId()} instead. + * <p>Carrier name is a user-facing name of carrier id + * {@link #getAndroidCarrierIdForSubscription()}, usually the brand name of the subsidiary + * (e.g. T-Mobile). Each carrier could configure multiple {@link #getSimOperatorName() SPN} but + * should have a single carrier name. Carrier name is not a canonical identity, + * use {@link #getAndroidCarrierIdForSubscription()} instead. * <p>The returned carrier name is unlocalized. * * @return Carrier name of the current subscription. Return {@code null} if the subscription is * unavailable or the carrier cannot be identified. * @throws IllegalStateException if telephony service is unavailable. */ - public String getSubscriptionCarrierName() { + public CharSequence getAndroidCarrierNameForSubscription() { try { ITelephony service = getITelephony(); return service.getSubscriptionCarrierName(getSubId()); diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 253432755179..d14670725e8e 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -71,8 +71,18 @@ public class EuiccManager { * TODO(b/35851809): Make this a SystemApi. */ @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_OTA_STATUS_CHANGED - = "android.telephony.euicc.action.OTA_STATUS_CHANGED"; + public static final String ACTION_OTA_STATUS_CHANGED = + "android.telephony.euicc.action.OTA_STATUS_CHANGED"; + + /** + * Broadcast Action: The action sent to carrier app so it knows the carrier setup is not + * completed. + * + * TODO(b/35851809): Make this a public API. + */ + @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_NOTIFY_CARRIER_SETUP = + "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP"; /** * Intent action to provision an embedded subscription. diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java index 4fbb228e6e53..d9d4eeba900f 100644 --- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java +++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java @@ -204,13 +204,13 @@ public class IpSecServiceParameterizedTest { } @Test - public void testCreateTransportModeTransform() throws Exception { + public void testCreateTransform() throws Exception { IpSecConfig ipSecConfig = new IpSecConfig(); addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); addAuthAndCryptToIpSecConfig(ipSecConfig); IpSecTransformResponse createTransformResp = - mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); + mIpSecService.createTransform(ipSecConfig, new Binder()); assertEquals(IpSecManager.Status.OK, createTransformResp.status); verify(mMockNetd) @@ -236,14 +236,14 @@ public class IpSecServiceParameterizedTest { } @Test - public void testCreateTransportModeTransformAead() throws Exception { + public void testCreateTransformAead() throws Exception { IpSecConfig ipSecConfig = new IpSecConfig(); addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO); IpSecTransformResponse createTransformResp = - mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); + mIpSecService.createTransform(ipSecConfig, new Binder()); assertEquals(IpSecManager.Status.OK, createTransformResp.status); verify(mMockNetd) @@ -269,14 +269,14 @@ public class IpSecServiceParameterizedTest { } @Test - public void testDeleteTransportModeTransform() throws Exception { + public void testDeleteTransform() throws Exception { IpSecConfig ipSecConfig = new IpSecConfig(); addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); addAuthAndCryptToIpSecConfig(ipSecConfig); IpSecTransformResponse createTransformResp = - mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); - mIpSecService.deleteTransportModeTransform(createTransformResp.resourceId); + mIpSecService.createTransform(ipSecConfig, new Binder()); + mIpSecService.deleteTransform(createTransformResp.resourceId); verify(mMockNetd) .ipSecDeleteSecurityAssociation( @@ -302,7 +302,7 @@ public class IpSecServiceParameterizedTest { addAuthAndCryptToIpSecConfig(ipSecConfig); IpSecTransformResponse createTransformResp = - mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); + mIpSecService.createTransform(ipSecConfig, new Binder()); IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); @@ -334,7 +334,7 @@ public class IpSecServiceParameterizedTest { addAuthAndCryptToIpSecConfig(ipSecConfig); IpSecTransformResponse createTransformResp = - mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); + mIpSecService.createTransform(ipSecConfig, new Binder()); ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket()); int resourceId = createTransformResp.resourceId; diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java index 3eba881df427..659f9108c21a 100644 --- a/tests/net/java/com/android/server/IpSecServiceTest.java +++ b/tests/net/java/com/android/server/IpSecServiceTest.java @@ -412,9 +412,9 @@ public class IpSecServiceTest { } @Test - public void testDeleteInvalidTransportModeTransform() throws Exception { + public void testDeleteInvalidTransform() throws Exception { try { - mIpSecService.deleteTransportModeTransform(1); + mIpSecService.deleteTransform(1); fail("IllegalArgumentException not thrown"); } catch (IllegalArgumentException e) { } diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java index 29bf02cac8fe..03c9fbeec918 100644 --- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java +++ b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java @@ -56,6 +56,11 @@ public final class WifiActivityEnergyInfo implements Parcelable { /** * @hide */ + public long mControllerScanTimeMs; + + /** + * @hide + */ public long mControllerIdleTimeMs; /** @@ -69,13 +74,14 @@ public final class WifiActivityEnergyInfo implements Parcelable { public static final int STACK_STATE_STATE_IDLE = 3; public WifiActivityEnergyInfo(long timestamp, int stackState, - long txTime, long[] txTimePerLevel, long rxTime, long idleTime, - long energyUsed) { + long txTime, long[] txTimePerLevel, long rxTime, long scanTime, + long idleTime, long energyUsed) { mTimestamp = timestamp; mStackState = stackState; mControllerTxTimeMs = txTime; mControllerTxTimePerLevelMs = txTimePerLevel; mControllerRxTimeMs = rxTime; + mControllerScanTimeMs = scanTime; mControllerIdleTimeMs = idleTime; mControllerEnergyUsed = energyUsed; } @@ -88,6 +94,7 @@ public final class WifiActivityEnergyInfo implements Parcelable { + " mControllerTxTimeMs=" + mControllerTxTimeMs + " mControllerTxTimePerLevelMs=" + Arrays.toString(mControllerTxTimePerLevelMs) + " mControllerRxTimeMs=" + mControllerRxTimeMs + + " mControllerScanTimeMs=" + mControllerScanTimeMs + " mControllerIdleTimeMs=" + mControllerIdleTimeMs + " mControllerEnergyUsed=" + mControllerEnergyUsed + " }"; @@ -101,10 +108,11 @@ public final class WifiActivityEnergyInfo implements Parcelable { long txTime = in.readLong(); long[] txTimePerLevel = in.createLongArray(); long rxTime = in.readLong(); + long scanTime = in.readLong(); long idleTime = in.readLong(); long energyUsed = in.readLong(); return new WifiActivityEnergyInfo(timestamp, stackState, - txTime, txTimePerLevel, rxTime, idleTime, energyUsed); + txTime, txTimePerLevel, rxTime, scanTime, idleTime, energyUsed); } public WifiActivityEnergyInfo[] newArray(int size) { return new WifiActivityEnergyInfo[size]; @@ -117,6 +125,7 @@ public final class WifiActivityEnergyInfo implements Parcelable { out.writeLong(mControllerTxTimeMs); out.writeLongArray(mControllerTxTimePerLevelMs); out.writeLong(mControllerRxTimeMs); + out.writeLong(mControllerScanTimeMs); out.writeLong(mControllerIdleTimeMs); out.writeLong(mControllerEnergyUsed); } @@ -157,6 +166,13 @@ public final class WifiActivityEnergyInfo implements Parcelable { } /** + * @return scan time in ms + */ + public long getControllerScanTimeMillis() { + return mControllerScanTimeMs; + } + + /** * @return idle time in ms */ public long getControllerIdleTimeMillis() { @@ -183,6 +199,7 @@ public final class WifiActivityEnergyInfo implements Parcelable { public boolean isValid() { return ((mControllerTxTimeMs >=0) && (mControllerRxTimeMs >=0) && + (mControllerScanTimeMs >=0) && (mControllerIdleTimeMs >=0)); } -} +}
\ No newline at end of file diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 99080d6cc2c0..e4b510db68f4 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1625,6 +1625,7 @@ public class WifiManager { * * @return hex-string encoded configuration token or null if there is no current network * @hide + * @deprecated This API is deprecated */ public String getCurrentNetworkWpsNfcConfigurationToken() { try { @@ -2210,20 +2211,34 @@ public class WifiManager { /** @hide */ public static final int SAVE_NETWORK_SUCCEEDED = BASE + 9; - /** @hide */ + /** @hide + * @deprecated This is deprecated + */ public static final int START_WPS = BASE + 10; - /** @hide */ + /** @hide + * @deprecated This is deprecated + */ public static final int START_WPS_SUCCEEDED = BASE + 11; - /** @hide */ + /** @hide + * @deprecated This is deprecated + */ public static final int WPS_FAILED = BASE + 12; - /** @hide */ + /** @hide + * @deprecated This is deprecated + */ public static final int WPS_COMPLETED = BASE + 13; - /** @hide */ + /** @hide + * @deprecated This is deprecated + */ public static final int CANCEL_WPS = BASE + 14; - /** @hide */ + /** @hide + * @deprecated This is deprecated + */ public static final int CANCEL_WPS_FAILED = BASE + 15; - /** @hide */ + /** @hide + * @deprecated This is deprecated + */ public static final int CANCEL_WPS_SUCCEDED = BASE + 16; /** @hide */ @@ -2263,15 +2278,25 @@ public class WifiManager { public static final int BUSY = 2; /* WPS specific errors */ - /** WPS overlap detected */ + /** WPS overlap detected + * @deprecated This is deprecated + */ public static final int WPS_OVERLAP_ERROR = 3; - /** WEP on WPS is prohibited */ + /** WEP on WPS is prohibited + * @deprecated This is deprecated + */ public static final int WPS_WEP_PROHIBITED = 4; - /** TKIP only prohibited */ + /** TKIP only prohibited + * @deprecated This is deprecated + */ public static final int WPS_TKIP_ONLY_PROHIBITED = 5; - /** Authentication failure on WPS */ + /** Authentication failure on WPS + * @deprecated This is deprecated + */ public static final int WPS_AUTH_FAILURE = 6; - /** WPS timed out */ + /** WPS timed out + * @deprecated This is deprecated + */ public static final int WPS_TIMED_OUT = 7; /** @@ -2312,12 +2337,19 @@ public class WifiManager { public void onFailure(int reason); } - /** Interface for callback invocation on a start WPS action */ + /** Interface for callback invocation on a start WPS action + * @deprecated This is deprecated + */ public static abstract class WpsCallback { - /** WPS start succeeded */ + + /** WPS start succeeded + * @deprecated This API is deprecated + */ public abstract void onStarted(String pin); - /** WPS operation completed successfully */ + /** WPS operation completed successfully + * @deprecated This API is deprecated + */ public abstract void onSucceeded(); /** @@ -2326,6 +2358,7 @@ public class WifiManager { * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR}, * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE} * and some generic errors. + * @deprecated This API is deprecated */ public abstract void onFailed(int reason); } @@ -3032,6 +3065,7 @@ public class WifiManager { * @param listener for callbacks on success or failure. Can be null. * @throws IllegalStateException if the WifiManager instance needs to be * initialized again + * @deprecated This API is deprecated */ public void startWps(WpsInfo config, WpsCallback listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); @@ -3044,6 +3078,7 @@ public class WifiManager { * @param listener for callbacks on success or failure. Can be null. * @throws IllegalStateException if the WifiManager instance needs to be * initialized again + * @deprecated This API is deprecated */ public void cancelWps(WpsCallback listener) { getChannel().sendMessage(CANCEL_WPS, 0, putListener(listener)); |