diff options
999 files changed, 8547 insertions, 4112 deletions
@@ -216,6 +216,8 @@ LOCAL_SRC_FILES += \ core/java/android/service/wallpaper/IWallpaperEngine.aidl \ core/java/android/service/wallpaper/IWallpaperService.aidl \ core/java/android/tv/ITvInputClient.aidl \ + core/java/android/tv/ITvInputHardware.aidl \ + core/java/android/tv/ITvInputHardwareCallback.aidl \ core/java/android/tv/ITvInputManager.aidl \ core/java/android/tv/ITvInputService.aidl \ core/java/android/tv/ITvInputServiceCallback.aidl \ diff --git a/api/current.txt b/api/current.txt index 282f062..5ad6453 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1399,8 +1399,6 @@ package android { field public static final int l_resource_pad9 = 17104904; // 0x1050008 field public static final int notification_large_icon_height = 17104902; // 0x1050006 field public static final int notification_large_icon_width = 17104901; // 0x1050005 - field public static final int recents_thumbnail_height = 17104913; // 0x1050011 - field public static final int recents_thumbnail_width = 17104914; // 0x1050012 field public static final int thumbnail_height = 17104897; // 0x1050001 field public static final int thumbnail_width = 17104898; // 0x1050002 } @@ -11570,16 +11568,6 @@ package android.graphics.drawable { method public void startTransition(int); } - public class VectorDrawable extends android.graphics.drawable.Drawable { - ctor public VectorDrawable(); - method public void draw(android.graphics.Canvas); - method public int getOpacity(); - method public void setAlpha(int); - method public void setColorFilter(android.graphics.ColorFilter); - method public void setPadding(android.graphics.Rect); - method public void setPadding(int, int, int, int); - } - } package android.graphics.drawable.shapes { @@ -12150,9 +12138,11 @@ package android.hardware.camera2 { public static abstract class CameraCaptureSession.CaptureListener { ctor public CameraCaptureSession.CaptureListener(); - method public void onCaptureCompleted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult); + method public void onCaptureCompleted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.TotalCaptureResult); method public void onCaptureFailed(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure); - method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraDevice, int, int); + method public void onCaptureProgressed(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult); + method public void onCaptureSequenceAborted(android.hardware.camera2.CameraDevice, int); + method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraDevice, int, long); method public void onCaptureStarted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, long); } @@ -12166,70 +12156,75 @@ package android.hardware.camera2 { } public final class CameraCharacteristics extends android.hardware.camera2.CameraMetadata { - method public T get(android.hardware.camera2.CameraMetadata.Key<T>); - method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getAvailableCaptureRequestKeys(); - method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getAvailableCaptureResultKeys(); - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_ANTIBANDING_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_COMPENSATION_RANGE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_COMPENSATION_STEP; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_AVAILABLE_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_EFFECTS; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_SCENE_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_AVAILABLE_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MAX_REGIONS; - field public static final android.hardware.camera2.CameraMetadata.Key EDGE_AVAILABLE_EDGE_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key FLASH_INFO_AVAILABLE; - field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key INFO_SUPPORTED_HARDWARE_LEVEL; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_AVAILABLE_THUMBNAIL_SIZES; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_FACING; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_APERTURES; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_FILTER_DENSITIES; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_FOCAL_LENGTHS; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_FOCUS_DISTANCE_CALIBRATION; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_HYPERFOCAL_DISTANCE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_SHADING_MAP_SIZE; - field public static final android.hardware.camera2.CameraMetadata.Key NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_AVAILABLE_CAPABILITIES; - field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_MAX_NUM_INPUT_STREAMS; - field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_MAX_NUM_OUTPUT_STREAMS; - field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_PARTIAL_RESULT_COUNT; - field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_PIPELINE_MAX_DEPTH; - field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_MAX_DIGITAL_ZOOM; - field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROPPING_TYPE; - field public static final android.hardware.camera2.CameraMetadata.Key SCALER_STREAM_CONFIGURATION_MAP; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_AVAILABLE_TEST_PATTERN_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_BASE_GAIN_FACTOR; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_BLACK_LEVEL_PATTERN; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_CALIBRATION_TRANSFORM1; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_CALIBRATION_TRANSFORM2; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_COLOR_TRANSFORM1; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_COLOR_TRANSFORM2; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FORWARD_MATRIX1; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FORWARD_MATRIX2; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_ACTIVE_ARRAY_SIZE; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_COLOR_FILTER_ARRANGEMENT; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_EXPOSURE_TIME_RANGE; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_MAX_FRAME_DURATION; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_PHYSICAL_SIZE; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_PIXEL_ARRAY_SIZE; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_SENSITIVITY_RANGE; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_WHITE_LEVEL; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_MAX_ANALOG_SENSITIVITY; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_ORIENTATION; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_REFERENCE_ILLUMINANT1; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_REFERENCE_ILLUMINANT2; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_MAX_FACE_COUNT; - field public static final android.hardware.camera2.CameraMetadata.Key SYNC_MAX_LATENCY; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_AVAILABLE_TONE_MAP_MODES; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MAX_CURVE_POINTS; + method public T get(android.hardware.camera2.CameraCharacteristics.Key<T>); + method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys(); + method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys(); + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_AVAILABLE_ANTIBANDING_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_AVAILABLE_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_COMPENSATION_RANGE; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_COMPENSATION_STEP; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AF_AVAILABLE_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AVAILABLE_EFFECTS; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AVAILABLE_SCENE_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AWB_AVAILABLE_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_MAX_REGIONS; + field public static final android.hardware.camera2.CameraCharacteristics.Key EDGE_AVAILABLE_EDGE_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key FLASH_INFO_AVAILABLE; + field public static final android.hardware.camera2.CameraCharacteristics.Key HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key INFO_SUPPORTED_HARDWARE_LEVEL; + field public static final android.hardware.camera2.CameraCharacteristics.Key JPEG_AVAILABLE_THUMBNAIL_SIZES; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_FACING; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_AVAILABLE_APERTURES; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_AVAILABLE_FILTER_DENSITIES; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_AVAILABLE_FOCAL_LENGTHS; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_FOCUS_DISTANCE_CALIBRATION; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_HYPERFOCAL_DISTANCE; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE; + field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_SHADING_MAP_SIZE; + field public static final android.hardware.camera2.CameraCharacteristics.Key NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_AVAILABLE_CAPABILITIES; + field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_INPUT_STREAMS; + field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_STREAMS; + field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_PARTIAL_RESULT_COUNT; + field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_PIPELINE_MAX_DEPTH; + field public static final android.hardware.camera2.CameraCharacteristics.Key SCALER_AVAILABLE_MAX_DIGITAL_ZOOM; + field public static final android.hardware.camera2.CameraCharacteristics.Key SCALER_CROPPING_TYPE; + field public static final android.hardware.camera2.CameraCharacteristics.Key SCALER_STREAM_CONFIGURATION_MAP; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_AVAILABLE_TEST_PATTERN_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_BLACK_LEVEL_PATTERN; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_CALIBRATION_TRANSFORM1; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_CALIBRATION_TRANSFORM2; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_COLOR_TRANSFORM1; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_COLOR_TRANSFORM2; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_FORWARD_MATRIX1; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_FORWARD_MATRIX2; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_ACTIVE_ARRAY_SIZE; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_COLOR_FILTER_ARRANGEMENT; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_EXPOSURE_TIME_RANGE; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_MAX_FRAME_DURATION; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_PHYSICAL_SIZE; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_PIXEL_ARRAY_SIZE; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_SENSITIVITY_RANGE; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_WHITE_LEVEL; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_MAX_ANALOG_SENSITIVITY; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_ORIENTATION; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_REFERENCE_ILLUMINANT1; + field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_REFERENCE_ILLUMINANT2; + field public static final android.hardware.camera2.CameraCharacteristics.Key STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key STATISTICS_INFO_MAX_FACE_COUNT; + field public static final android.hardware.camera2.CameraCharacteristics.Key SYNC_MAX_LATENCY; + field public static final android.hardware.camera2.CameraCharacteristics.Key TONEMAP_AVAILABLE_TONE_MAP_MODES; + field public static final android.hardware.camera2.CameraCharacteristics.Key TONEMAP_MAX_CURVE_POINTS; + } + + public static final class CameraCharacteristics.Key { + method public final boolean equals(java.lang.Object); + method public java.lang.String getName(); + method public final int hashCode(); } public abstract interface CameraDevice implements java.lang.AutoCloseable { @@ -12254,9 +12249,11 @@ package android.hardware.camera2 { public static abstract deprecated class CameraDevice.CaptureListener { ctor public CameraDevice.CaptureListener(); - method public void onCaptureCompleted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult); + method public void onCaptureCompleted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.TotalCaptureResult); method public void onCaptureFailed(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure); - method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraDevice, int, int); + method public void onCaptureProgressed(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult); + method public void onCaptureSequenceAborted(android.hardware.camera2.CameraDevice, int); + method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraDevice, int, long); method public void onCaptureStarted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, long); } @@ -12292,8 +12289,7 @@ package android.hardware.camera2 { } public abstract class CameraMetadata { - method public abstract T get(android.hardware.camera2.CameraMetadata.Key<T>); - method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getKeys(); + method public java.util.List<TKey> getKeys(); field public static final int COLOR_CORRECTION_MODE_FAST = 1; // 0x1 field public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2; // 0x2 field public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0; // 0x0 @@ -12463,12 +12459,6 @@ package android.hardware.camera2 { field public static final int TONEMAP_MODE_HIGH_QUALITY = 2; // 0x2 } - public static class CameraMetadata.Key { - method public final boolean equals(java.lang.Object); - method public final java.lang.String getName(); - method public final int hashCode(); - } - public class CaptureFailure { method public int getFrameNumber(); method public int getReason(); @@ -12481,146 +12471,174 @@ package android.hardware.camera2 { public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable { method public int describeContents(); - method public T get(android.hardware.camera2.CameraMetadata.Key<T>); + method public T get(android.hardware.camera2.CaptureRequest.Key<T>); method public java.lang.Object getTag(); method public void writeToParcel(android.os.Parcel, int); - field public static final android.hardware.camera2.CameraMetadata.Key BLACK_LEVEL_LOCK; - field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_GAINS; - field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_TRANSFORM; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_ANTIBANDING_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_EXPOSURE_COMPENSATION; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_LOCK; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_PRECAPTURE_TRIGGER; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_REGIONS; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_TARGET_FPS_RANGE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_REGIONS; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_TRIGGER; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_LOCK; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_REGIONS; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_CAPTURE_INTENT; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_EFFECT_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_SCENE_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_VIDEO_STABILIZATION_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key BLACK_LEVEL_LOCK; + field public static final android.hardware.camera2.CaptureRequest.Key COLOR_CORRECTION_GAINS; + field public static final android.hardware.camera2.CaptureRequest.Key COLOR_CORRECTION_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key COLOR_CORRECTION_TRANSFORM; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_ANTIBANDING_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_EXPOSURE_COMPENSATION; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_LOCK; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_PRECAPTURE_TRIGGER; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_REGIONS; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_TARGET_FPS_RANGE; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AF_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AF_REGIONS; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AF_TRIGGER; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AWB_LOCK; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AWB_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AWB_REGIONS; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_CAPTURE_INTENT; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_EFFECT_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_SCENE_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_VIDEO_STABILIZATION_MODE; field public static final android.os.Parcelable.Creator CREATOR; - field public static final android.hardware.camera2.CameraMetadata.Key EDGE_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key FLASH_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_COORDINATES; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_PROCESSING_METHOD; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_TIMESTAMP; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_ORIENTATION; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_QUALITY; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_QUALITY; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_SIZE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_APERTURE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_FILTER_DENSITY; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCAL_LENGTH; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_DISTANCE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_OPTICAL_STABILIZATION_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key NOISE_REDUCTION_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROP_REGION; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_EXPOSURE_TIME; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEST_PATTERN_DATA; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEST_PATTERN_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key SHADING_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_RED; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key EDGE_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key FLASH_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key HOT_PIXEL_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key JPEG_GPS_COORDINATES; + field public static final android.hardware.camera2.CaptureRequest.Key JPEG_GPS_PROCESSING_METHOD; + field public static final android.hardware.camera2.CaptureRequest.Key JPEG_GPS_TIMESTAMP; + field public static final android.hardware.camera2.CaptureRequest.Key JPEG_ORIENTATION; + field public static final android.hardware.camera2.CaptureRequest.Key JPEG_QUALITY; + field public static final android.hardware.camera2.CaptureRequest.Key JPEG_THUMBNAIL_QUALITY; + field public static final android.hardware.camera2.CaptureRequest.Key JPEG_THUMBNAIL_SIZE; + field public static final android.hardware.camera2.CaptureRequest.Key LENS_APERTURE; + field public static final android.hardware.camera2.CaptureRequest.Key LENS_FILTER_DENSITY; + field public static final android.hardware.camera2.CaptureRequest.Key LENS_FOCAL_LENGTH; + field public static final android.hardware.camera2.CaptureRequest.Key LENS_FOCUS_DISTANCE; + field public static final android.hardware.camera2.CaptureRequest.Key LENS_OPTICAL_STABILIZATION_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key NOISE_REDUCTION_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key SCALER_CROP_REGION; + field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_EXPOSURE_TIME; + field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_FRAME_DURATION; + field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_SENSITIVITY; + field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_TEST_PATTERN_DATA; + field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_TEST_PATTERN_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key SHADING_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_FACE_DETECT_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_HOT_PIXEL_MAP_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_LENS_SHADING_MAP_MODE; + field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_CURVE_BLUE; + field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_CURVE_GREEN; + field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_CURVE_RED; + field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_MODE; } public static final class CaptureRequest.Builder { method public void addTarget(android.view.Surface); method public android.hardware.camera2.CaptureRequest build(); - method public T get(android.hardware.camera2.CameraMetadata.Key<T>); + method public T get(android.hardware.camera2.CaptureRequest.Key<T>); method public void removeTarget(android.view.Surface); - method public void set(android.hardware.camera2.CameraMetadata.Key<T>, T); + method public void set(android.hardware.camera2.CaptureRequest.Key<T>, T); method public void setTag(java.lang.Object); } - public final class CaptureResult extends android.hardware.camera2.CameraMetadata { - method public T get(android.hardware.camera2.CameraMetadata.Key<T>); + public static final class CaptureRequest.Key { + method public final boolean equals(java.lang.Object); + method public java.lang.String getName(); + method public final int hashCode(); + } + + public class CaptureResult extends android.hardware.camera2.CameraMetadata { + method public T get(android.hardware.camera2.CaptureResult.Key<T>); method public int getFrameNumber(); method public android.hardware.camera2.CaptureRequest getRequest(); method public int getSequenceId(); - field public static final android.hardware.camera2.CameraMetadata.Key BLACK_LEVEL_LOCK; - field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_GAINS; - field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_TRANSFORM; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_ANTIBANDING_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_EXPOSURE_COMPENSATION; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_LOCK; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_PRECAPTURE_TRIGGER; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_REGIONS; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_STATE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_TARGET_FPS_RANGE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_REGIONS; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_STATE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_TRIGGER; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_LOCK; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_REGIONS; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_STATE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_CAPTURE_INTENT; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_EFFECT_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_SCENE_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_VIDEO_STABILIZATION_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key EDGE_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key FLASH_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key FLASH_STATE; - field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_COORDINATES; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_PROCESSING_METHOD; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_TIMESTAMP; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_ORIENTATION; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_QUALITY; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_QUALITY; - field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_SIZE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_APERTURE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_FILTER_DENSITY; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCAL_LENGTH; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_DISTANCE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_RANGE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_OPTICAL_STABILIZATION_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key LENS_STATE; - field public static final android.hardware.camera2.CameraMetadata.Key NOISE_REDUCTION_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_FRAME_COUNT; - field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_PIPELINE_DEPTH; - field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROP_REGION; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_EXPOSURE_TIME; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_GREEN_SPLIT; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_NEUTRAL_COLOR_POINT; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEMPERATURE; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEST_PATTERN_DATA; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEST_PATTERN_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TIMESTAMP; - field public static final android.hardware.camera2.CameraMetadata.Key SHADING_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACES; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP_MODE; - field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_SCENE_FLICKER; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_RED; - field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE; + field public static final android.hardware.camera2.CaptureResult.Key BLACK_LEVEL_LOCK; + field public static final android.hardware.camera2.CaptureResult.Key COLOR_CORRECTION_GAINS; + field public static final android.hardware.camera2.CaptureResult.Key COLOR_CORRECTION_MODE; + field public static final android.hardware.camera2.CaptureResult.Key COLOR_CORRECTION_TRANSFORM; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_ANTIBANDING_MODE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_EXPOSURE_COMPENSATION; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_LOCK; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_MODE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_PRECAPTURE_TRIGGER; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_REGIONS; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_STATE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_TARGET_FPS_RANGE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AF_MODE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AF_REGIONS; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AF_STATE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AF_TRIGGER; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AWB_LOCK; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AWB_MODE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AWB_REGIONS; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AWB_STATE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_CAPTURE_INTENT; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_EFFECT_MODE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_MODE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_SCENE_MODE; + field public static final android.hardware.camera2.CaptureResult.Key CONTROL_VIDEO_STABILIZATION_MODE; + field public static final android.hardware.camera2.CaptureResult.Key EDGE_MODE; + field public static final android.hardware.camera2.CaptureResult.Key FLASH_MODE; + field public static final android.hardware.camera2.CaptureResult.Key FLASH_STATE; + field public static final android.hardware.camera2.CaptureResult.Key HOT_PIXEL_MODE; + field public static final android.hardware.camera2.CaptureResult.Key JPEG_GPS_COORDINATES; + field public static final android.hardware.camera2.CaptureResult.Key JPEG_GPS_PROCESSING_METHOD; + field public static final android.hardware.camera2.CaptureResult.Key JPEG_GPS_TIMESTAMP; + field public static final android.hardware.camera2.CaptureResult.Key JPEG_ORIENTATION; + field public static final android.hardware.camera2.CaptureResult.Key JPEG_QUALITY; + field public static final android.hardware.camera2.CaptureResult.Key JPEG_THUMBNAIL_QUALITY; + field public static final android.hardware.camera2.CaptureResult.Key JPEG_THUMBNAIL_SIZE; + field public static final android.hardware.camera2.CaptureResult.Key LENS_APERTURE; + field public static final android.hardware.camera2.CaptureResult.Key LENS_FILTER_DENSITY; + field public static final android.hardware.camera2.CaptureResult.Key LENS_FOCAL_LENGTH; + field public static final android.hardware.camera2.CaptureResult.Key LENS_FOCUS_DISTANCE; + field public static final android.hardware.camera2.CaptureResult.Key LENS_FOCUS_RANGE; + field public static final android.hardware.camera2.CaptureResult.Key LENS_OPTICAL_STABILIZATION_MODE; + field public static final android.hardware.camera2.CaptureResult.Key LENS_STATE; + field public static final android.hardware.camera2.CaptureResult.Key NOISE_REDUCTION_MODE; + field public static final android.hardware.camera2.CaptureResult.Key REQUEST_FRAME_COUNT; + field public static final android.hardware.camera2.CaptureResult.Key REQUEST_PIPELINE_DEPTH; + field public static final android.hardware.camera2.CaptureResult.Key SCALER_CROP_REGION; + field public static final android.hardware.camera2.CaptureResult.Key SENSOR_EXPOSURE_TIME; + field public static final android.hardware.camera2.CaptureResult.Key SENSOR_FRAME_DURATION; + field public static final android.hardware.camera2.CaptureResult.Key SENSOR_GREEN_SPLIT; + field public static final android.hardware.camera2.CaptureResult.Key SENSOR_NEUTRAL_COLOR_POINT; + field public static final android.hardware.camera2.CaptureResult.Key SENSOR_SENSITIVITY; + field public static final android.hardware.camera2.CaptureResult.Key SENSOR_TEST_PATTERN_DATA; + field public static final android.hardware.camera2.CaptureResult.Key SENSOR_TEST_PATTERN_MODE; + field public static final android.hardware.camera2.CaptureResult.Key SENSOR_TIMESTAMP; + field public static final android.hardware.camera2.CaptureResult.Key SHADING_MODE; + field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_FACES; + field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_FACE_DETECT_MODE; + field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_HOT_PIXEL_MAP; + field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_HOT_PIXEL_MAP_MODE; + field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_LENS_SHADING_MAP; + field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_LENS_SHADING_MAP_MODE; + field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_SCENE_FLICKER; + field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_CURVE_BLUE; + field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_CURVE_GREEN; + field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_CURVE_RED; + field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_MODE; + } + + public static final class CaptureResult.Key { + method public final boolean equals(java.lang.Object); + method public java.lang.String getName(); + method public final int hashCode(); + } + + public final class DngCreator implements java.lang.AutoCloseable { + ctor public DngCreator(android.hardware.camera2.CameraCharacteristics, android.hardware.camera2.CaptureResult); + method public void close(); + method public android.hardware.camera2.DngCreator setDescription(java.lang.String); + method public android.hardware.camera2.DngCreator setLocation(android.location.Location); + method public android.hardware.camera2.DngCreator setOrientation(int); + method public android.hardware.camera2.DngCreator setThumbnail(android.graphics.Bitmap); + method public android.hardware.camera2.DngCreator setThumbnail(android.media.Image); + method public void writeByteBuffer(java.io.OutputStream, android.util.Size, java.nio.ByteBuffer, long) throws java.io.IOException; + method public void writeImage(java.io.OutputStream, android.media.Image) throws java.io.IOException; + method public void writeInputStream(java.io.OutputStream, android.util.Size, java.io.InputStream, long) throws java.io.IOException; + } + + public final class TotalCaptureResult extends android.hardware.camera2.CaptureResult { + method public java.util.List<android.hardware.camera2.CaptureResult> getPartialResults(); } } @@ -14091,19 +14109,6 @@ package android.media { ctor public DeniedByServerException(java.lang.String); } - public final class DngCreator implements java.lang.AutoCloseable { - ctor public DngCreator(android.hardware.camera2.CameraCharacteristics, android.hardware.camera2.CaptureResult); - method public void close(); - method public android.media.DngCreator setDescription(java.lang.String); - method public android.media.DngCreator setLocation(android.location.Location); - method public android.media.DngCreator setOrientation(int); - method public android.media.DngCreator setThumbnail(android.graphics.Bitmap); - method public android.media.DngCreator setThumbnail(android.media.Image); - method public void writeByteBuffer(java.io.OutputStream, android.util.Size, java.nio.ByteBuffer, long) throws java.io.IOException; - method public void writeImage(java.io.OutputStream, android.media.Image) throws java.io.IOException; - method public void writeInputStream(java.io.OutputStream, android.util.Size, java.io.InputStream, long) throws java.io.IOException; - } - public class ExifInterface { ctor public ExifInterface(java.lang.String) throws java.io.IOException; method public double getAltitude(double); @@ -21684,9 +21689,7 @@ package android.os { method public abstract void cancel(); method public abstract boolean hasVibrator(); method public void vibrate(long); - method public void vibrate(long, int); method public void vibrate(long[], int); - method public void vibrate(long[], int, int); } public class WorkSource implements android.os.Parcelable { @@ -25061,7 +25064,9 @@ package android.provider { field public static final java.lang.String COLUMN_DESCRIPTION = "description"; field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name"; field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number"; + field public static final java.lang.String COLUMN_LOCKED = "locked"; field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id"; + field public static final java.lang.String COLUMN_SEARCHABLE = "searchable"; field public static final java.lang.String COLUMN_SERVICE_ID = "service_id"; field public static final java.lang.String COLUMN_SERVICE_NAME = "service_name"; field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type"; @@ -25099,10 +25104,12 @@ package android.provider { } public static final class TvContract.Programs implements android.provider.TvContract.BaseTvColumns { + field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language"; field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id"; field public static final java.lang.String COLUMN_DATA = "data"; field public static final java.lang.String COLUMN_DESCRIPTION = "description"; field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; + field public static final java.lang.String COLUMN_GENRE = "genre"; field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description"; field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis"; field public static final java.lang.String COLUMN_TITLE = "title"; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 5fd288f..d9adba3 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3010,8 +3010,8 @@ public final class ActivityThread { int h; if (w < 0) { Resources res = r.activity.getResources(); - int wId = com.android.internal.R.dimen.recents_thumbnail_width; - int hId = com.android.internal.R.dimen.recents_thumbnail_height; + int wId = com.android.internal.R.dimen.thumbnail_width; + int hId = com.android.internal.R.dimen.thumbnail_height; mThumbnailWidth = w = res.getDimensionPixelSize(wId); mThumbnailHeight = h = res.getDimensionPixelSize(hId); } else { diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 076f657..bd07470 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -45,6 +45,7 @@ import android.util.AttributeSet; import android.util.Log; import com.android.internal.util.XmlUtils; +import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.io.Serializable; @@ -604,6 +605,15 @@ import java.util.Set; * of all possible flags. */ public class Intent implements Parcelable, Cloneable { + private static final String ATTR_ACTION = "action"; + private static final String TAG_CATEGORIES = "categories"; + private static final String ATTR_CATEGORY = "category"; + private static final String TAG_EXTRA = "extra"; + private static final String ATTR_TYPE = "type"; + private static final String ATTR_COMPONENT = "component"; + private static final String ATTR_DATA = "data"; + private static final String ATTR_FLAGS = "flags"; + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard intent activity actions (see action variable). @@ -3729,32 +3739,27 @@ public class Intent implements Parcelable, Cloneable { */ public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000; /** - * This flag is used to break out "documents" into separate tasks that can - * be reached via the Recents mechanism. Such a document is any kind of - * item for which an application may want to maintain multiple simultaneous - * instances. Examples might be text files, web pages, spreadsheets, or - * emails. Each such document will be in a separate task in the Recents list. - * - * <p>When set, the activity specified by this Intent will launch into a - * separate task rooted at that activity. The activity launched must be - * defined with {@link android.R.attr#launchMode} <code>standard</code> - * or <code>singleTop</code>. + * This flag is used to open a document into a new task rooted at the activity launched + * by this Intent. Through the use of this flag, or its equivalent attribute, + * {@link android.R.attr#documentLaunchMode} multiple instances of the same activity + * containing different douments will appear in the recent tasks list. * - * <p>If FLAG_ACTIVITY_NEW_DOCUMENT is used without - * {@link #FLAG_ACTIVITY_MULTIPLE_TASK} then the activity manager will - * search for an existing task with a matching target activity and Intent - * data URI and relaunch that task, first finishing all activities down to - * the root activity and then calling the root activity's - * {@link android.app.Activity#onNewIntent(Intent)} method. If no existing - * task's root activity matches the Intent's data URI then a new task will - * be launched with the target activity as root. + * <p>The use of the activity attribute form of this, + * {@link android.R.attr#documentLaunchMode}, is + * preferred over the Intent flag described here. The attribute form allows the + * Activity to specify multiple document behavior for all launchers of the Activity + * whereas using this flag requires each Intent that launches the Activity to specify it. * - * <p>When paired with {@link #FLAG_ACTIVITY_MULTIPLE_TASK} this will - * always create a new task. Thus the same document may be made to appear - * more than one time in Recents. + * <p>FLAG_ACTIVITY_NEW_DOCUMENT may be used in conjunction with {@link + * #FLAG_ACTIVITY_MULTIPLE_TASK}. When used alone it is the + * equivalent of the Activity manifest specifying {@link + * android.R.attr#documentLaunchMode}="intoExisting". When used with + * FLAG_ACTIVITY_MULTIPLE_TASK it is the equivalent of the Activity manifest specifying + * {@link android.R.attr#documentLaunchMode}="always". * - * <p>This is equivalent to the attribute {@link android.R.attr#documentLaunchMode}. + * Refer to {@link android.R.attr#documentLaunchMode} for more information. * + * @see android.R.attr#documentLaunchMode * @see #FLAG_ACTIVITY_MULTIPLE_TASK */ public static final int FLAG_ACTIVITY_NEW_DOCUMENT = @@ -7347,7 +7352,7 @@ public class Intent implements Parcelable, Cloneable { } String nodeName = parser.getName(); - if (nodeName.equals("category")) { + if (nodeName.equals(TAG_CATEGORIES)) { sa = resources.obtainAttributes(attrs, com.android.internal.R.styleable.IntentCategory); String cat = sa.getString(com.android.internal.R.styleable.IntentCategory_name); @@ -7358,11 +7363,11 @@ public class Intent implements Parcelable, Cloneable { } XmlUtils.skipCurrentTag(parser); - } else if (nodeName.equals("extra")) { + } else if (nodeName.equals(TAG_EXTRA)) { if (intent.mExtras == null) { intent.mExtras = new Bundle(); } - resources.parseBundleExtra("extra", attrs, intent.mExtras); + resources.parseBundleExtra(TAG_EXTRA, attrs, intent.mExtras); XmlUtils.skipCurrentTag(parser); } else { @@ -7373,6 +7378,76 @@ public class Intent implements Parcelable, Cloneable { return intent; } + /** @hide */ + public void saveToXml(XmlSerializer out) throws IOException { + if (mAction != null) { + out.attribute(null, ATTR_ACTION, mAction); + } + if (mData != null) { + out.attribute(null, ATTR_DATA, mData.toString()); + } + if (mType != null) { + out.attribute(null, ATTR_TYPE, mType); + } + if (mComponent != null) { + out.attribute(null, ATTR_COMPONENT, mComponent.flattenToShortString()); + } + out.attribute(null, ATTR_FLAGS, Integer.toHexString(getFlags())); + + if (mCategories != null) { + out.startTag(null, TAG_CATEGORIES); + for (int categoryNdx = mCategories.size() - 1; categoryNdx >= 0; --categoryNdx) { + out.attribute(null, ATTR_CATEGORY, mCategories.valueAt(categoryNdx)); + } + } + } + + /** @hide */ + public static Intent restoreFromXml(XmlPullParser in) throws IOException, + XmlPullParserException { + Intent intent = new Intent(); + final int outerDepth = in.getDepth(); + + int attrCount = in.getAttributeCount(); + for (int attrNdx = attrCount - 1; attrNdx >= 0; --attrNdx) { + final String attrName = in.getAttributeName(attrNdx); + final String attrValue = in.getAttributeValue(attrNdx); + if (ATTR_ACTION.equals(attrName)) { + intent.setAction(attrValue); + } else if (ATTR_DATA.equals(attrName)) { + intent.setData(Uri.parse(attrValue)); + } else if (ATTR_TYPE.equals(attrName)) { + intent.setType(attrValue); + } else if (ATTR_COMPONENT.equals(attrName)) { + intent.setComponent(ComponentName.unflattenFromString(attrValue)); + } else if (ATTR_FLAGS.equals(attrName)) { + intent.setFlags(Integer.valueOf(attrValue, 16)); + } else { + Log.e("Intent", "restoreFromXml: unknown attribute=" + attrName); + } + } + + int event; + String name; + while (((event = in.next()) != XmlPullParser.END_DOCUMENT) && + (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) { + if (event == XmlPullParser.START_TAG) { + name = in.getName(); + if (TAG_CATEGORIES.equals(name)) { + attrCount = in.getAttributeCount(); + for (int attrNdx = attrCount - 1; attrNdx >= 0; --attrNdx) { + intent.addCategory(in.getAttributeValue(attrNdx)); + } + } else { + Log.w("Intent", "restoreFromXml: unknown name=" + name); + XmlUtils.skipCurrentTag(in); + } + } + } + + return intent; + } + /** * Normalize a MIME data type. * diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index a78f8e2..3737638 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -31,11 +31,11 @@ import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Trace; +import android.util.ArrayMap; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; -import android.util.SparseArray; import android.util.TypedValue; import android.util.LongSparseArray; @@ -104,10 +104,10 @@ public class Resources { // These are protected by mAccessLock. private final Object mAccessLock = new Object(); private final Configuration mTmpConfig = new Configuration(); - private final ThemedCaches<ConstantState> mDrawableCache = - new ThemedCaches<ConstantState>(); - private final ThemedCaches<ConstantState> mColorDrawableCache = - new ThemedCaches<ConstantState>(); + private final ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> mDrawableCache = + new ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>>(); + private final ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> mColorDrawableCache = + new ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>>(); private final LongSparseArray<WeakReference<ColorStateList>> mColorStateListCache = new LongSparseArray<WeakReference<ColorStateList>>(); @@ -1261,18 +1261,17 @@ public class Resources { * any of the style's attributes are already defined in the theme, the * current values in the theme will be overwritten. * - * @param resid The resource ID of a style resource from which to + * @param resId The resource ID of a style resource from which to * obtain attribute values. * @param force If true, values in the style resource will always be * used in the theme; otherwise, they will only be used * if not already defined in the theme. */ - public void applyStyle(int resid, boolean force) { - AssetManager.applyThemeStyle(mTheme, resid, force); + public void applyStyle(int resId, boolean force) { + AssetManager.applyThemeStyle(mTheme, resId, force); - // TODO: In very rare cases, we may end up with a hybrid theme - // that can't map to a single theme ID. - mThemeResId = resid; + mThemeResId = resId; + mKey += Integer.toHexString(resId) + (force ? "! " : " "); } /** @@ -1288,6 +1287,7 @@ public class Resources { AssetManager.copyTheme(mTheme, other.mTheme); mThemeResId = other.mThemeResId; + mKey = other.mKey; } /** @@ -1577,6 +1577,9 @@ public class Resources { /** Resource identifier for the theme. */ private int mThemeResId = 0; + /** Unique key for the series of styles applied to this theme. */ + private String mKey = ""; + // Needed by layoutlib. /*package*/ long getNativeTheme() { return mTheme; @@ -1585,6 +1588,10 @@ public class Resources { /*package*/ int getAppliedStyleResId() { return mThemeResId; } + + /*package*/ String getKey() { + return mKey; + } } /** @@ -1740,7 +1747,8 @@ public class Resources { } private void clearDrawableCachesLocked( - ThemedCaches<ConstantState> caches, int configChanges) { + ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches, + int configChanges) { final int N = caches.size(); for (int i = 0; i < N; i++) { clearDrawableCacheLocked(caches.valueAt(i), configChanges); @@ -1763,7 +1771,7 @@ public class Resources { configChanges, cs.getChangingConfigurations())) { if (DEBUG_CONFIG) { Log.d(TAG, "FLUSHING #0x" - + Long.toHexString(mDrawableCache.keyAt(i)) + + Long.toHexString(cache.keyAt(i)) + " / " + cs + " with changes: 0x" + Integer.toHexString(cs.getChangingConfigurations())); } @@ -2205,7 +2213,7 @@ public class Resources { } final boolean isColorDrawable; - final ThemedCaches<ConstantState> caches; + final ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches; final long key; if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && value.type <= TypedValue.TYPE_LAST_COLOR_INT) { @@ -2258,7 +2266,8 @@ public class Resources { } private void cacheDrawable(TypedValue value, Theme theme, boolean isColorDrawable, - ThemedCaches<ConstantState> caches, long key, Drawable dr) { + ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches, + long key, Drawable dr) { final ConstantState cs = dr.getConstantState(); if (cs == null) { return; @@ -2287,8 +2296,12 @@ public class Resources { } } else { synchronized (mAccessLock) { - final LongSparseArray<WeakReference<ConstantState>> themedCache; - themedCache = caches.getOrCreate(theme == null ? 0 : theme.mThemeResId); + final String themeKey = theme == null ? "" : theme.mKey; + LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey); + if (themedCache == null) { + themedCache = new LongSparseArray<WeakReference<ConstantState>>(1); + caches.put(themeKey, themedCache); + } themedCache.put(key, new WeakReference<ConstantState>(cs)); } } @@ -2347,7 +2360,9 @@ public class Resources { return dr; } - private Drawable getCachedDrawable(ThemedCaches<ConstantState> caches, long key, Theme theme) { + private Drawable getCachedDrawable( + ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches, + long key, Theme theme) { synchronized (mAccessLock) { final int themeKey = theme != null ? theme.mThemeResId : 0; final LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey); @@ -2584,21 +2599,4 @@ public class Resources { updateConfiguration(null, null); mAssets.ensureStringBlocks(); } - - static class ThemedCaches<T> extends SparseArray<LongSparseArray<WeakReference<T>>> { - /** - * Returns the cache of drawables styled for the specified theme. - * <p> - * Drawables that have themeable attributes but were loaded without - * specifying a theme are cached at themeResId = 0. - */ - public LongSparseArray<WeakReference<T>> getOrCreate(int themeResId) { - LongSparseArray<WeakReference<T>> result = get(themeResId); - if (result == null) { - result = new LongSparseArray<WeakReference<T>>(1); - put(themeResId, result); - } - return result; - } - } } diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index 8391209..7738d2d 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -508,14 +508,62 @@ public abstract class CameraCaptureSession implements AutoCloseable { } /** - * This method is called when an image capture has completed and the + * This method is called when an image capture makes partial forward progress; some + * (but not all) results from an image capture are available. + * + * <p>The result provided here will contain some subset of the fields of + * a full result. Multiple {@link #onCaptureProgressed} calls may happen per + * capture; a given result field will only be present in one partial + * capture at most. The final {@link #onCaptureCompleted} call will always + * contain all the fields (in particular, the union of all the fields of all + * the partial results composing the total result).</p> + * + * <p>For each request, some result data might be available earlier than others. The typical + * delay between each partial result (per request) is a single frame interval. + * For performance-oriented use-cases, applications should query the metadata they need + * to make forward progress from the partial results and avoid waiting for the completed + * result.</p> + * + * <p>Each request will generate at least {@code 1} partial results, and at most + * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT} partial results.</p> + * + * <p>Depending on the request settings, the number of partial results per request + * will vary, although typically the partial count could be the same as long as the + * camera device subsystems enabled stay the same.</p> + * + * <p>The default implementation of this method does nothing.</p> + * + * @param camera The CameraDevice sending the callback. + * @param request The request that was given to the CameraDevice + * @param partialResult The partial output metadata from the capture, which + * includes a subset of the {@link TotalCaptureResult} fields. + * + * @see #capture + * @see #captureBurst + * @see #setRepeatingRequest + * @see #setRepeatingBurst + */ + public void onCaptureProgressed(CameraDevice camera, + CaptureRequest request, CaptureResult partialResult) { + // default empty implementation + } + + /** + * This method is called when an image capture has fully completed and all the * result metadata is available. * + * <p>This callback will always fire after the last {@link #onCaptureProgressed}; + * in other words, no more partial results will be delivered once the completed result + * is available.</p> + * + * <p>For performance-intensive use-cases where latency is a factor, consider + * using {@link #onCaptureProgressed} instead.</p> + * * <p>The default implementation of this method does nothing.</p> * * @param camera The CameraDevice sending the callback. * @param request The request that was given to the CameraDevice - * @param result The output metadata from the capture, including the + * @param result The total output metadata from the capture, including the * final capture parameters and the state of the camera system during * capture. * @@ -525,7 +573,7 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @see #setRepeatingBurst */ public void onCaptureCompleted(CameraDevice camera, - CaptureRequest request, CaptureResult result) { + CaptureRequest request, TotalCaptureResult result) { // default empty implementation } @@ -563,24 +611,57 @@ public abstract class CameraCaptureSession implements AutoCloseable { * when a capture sequence finishes and all {@link CaptureResult} * or {@link CaptureFailure} for it have been returned via this listener. * + * <p>In total, there will be at least one result/failure returned by this listener + * before this callback is invoked. If the capture sequence is aborted before any + * requests have been processed, {@link #onCaptureSequenceAborted} is invoked instead.</p> + * + * <p>The default implementation does nothing.</p> + * * @param camera * The CameraDevice sending the callback. * @param sequenceId * A sequence ID returned by the {@link #capture} family of functions. - * @param lastFrameNumber + * @param frameNumber * The last frame number (returned by {@link CaptureResult#getFrameNumber} * or {@link CaptureFailure#getFrameNumber}) in the capture sequence. - * The last frame number may be equal to NO_FRAMES_CAPTURED if no images - * were captured for this sequence. This can happen, for example, when a - * repeating request or burst is cleared right after being set. * * @see CaptureResult#getFrameNumber() * @see CaptureFailure#getFrameNumber() * @see CaptureResult#getSequenceId() * @see CaptureFailure#getSequenceId() + * @see #onCaptureSequenceAborted */ public void onCaptureSequenceCompleted(CameraDevice camera, - int sequenceId, int lastFrameNumber) { + int sequenceId, long frameNumber) { + // default empty implementation + } + + /** + * This method is called independently of the others in CaptureListener, + * when a capture sequence aborts before any {@link CaptureResult} + * or {@link CaptureFailure} for it have been returned via this listener. + * + * <p>Due to the asynchronous nature of the camera device, not all submitted captures + * are immediately processed. It is possible to clear out the pending requests + * by a variety of operations such as {@link CameraDevice#stopRepeating} or + * {@link CameraDevice#flush}. When such an event happens, + * {@link #onCaptureSequenceCompleted} will not be called.</p> + * + * <p>The default implementation does nothing.</p> + * + * @param camera + * The CameraDevice sending the callback. + * @param sequenceId + * A sequence ID returned by the {@link #capture} family of functions. + * + * @see CaptureResult#getFrameNumber() + * @see CaptureFailure#getFrameNumber() + * @see CaptureResult#getSequenceId() + * @see CaptureFailure#getSequenceId() + * @see #onCaptureSequenceCompleted + */ + public void onCaptureSequenceAborted(CameraDevice camera, + int sequenceId) { // default empty implementation } } diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 164e683..c08424a 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -16,7 +16,9 @@ package android.hardware.camera2; +import android.hardware.camera2.CaptureResult.Key; import android.hardware.camera2.impl.CameraMetadataNative; +import android.hardware.camera2.utils.TypeReference; import android.util.Rational; import java.util.Collections; @@ -35,18 +37,109 @@ import java.util.List; * @see CameraDevice * @see CameraManager */ -public final class CameraCharacteristics extends CameraMetadata { +public final class CameraCharacteristics extends CameraMetadata<CameraCharacteristics.Key<?>> { + + /** + * A {@code Key} is used to do camera characteristics field lookups with + * {@link CameraCharacteristics#get}. + * + * <p>For example, to get the stream configuration map: + * <code><pre> + * StreamConfigurationMap map = cameraCharacteristics.get( + * CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); + * </pre></code> + * </p> + * + * <p>To enumerate over all possible keys for {@link CameraCharacteristics}, see + * {@link CameraCharacteristics#getKeys()}.</p> + * + * @see CameraCharacteristics#get + * @see CameraCharacteristics#getKeys() + */ + public static final class Key<T> { + private final CameraMetadataNative.Key<T> mKey; + + /** + * Visible for testing and vendor extensions only. + * + * @hide + */ + public Key(String name, Class<T> type) { + mKey = new CameraMetadataNative.Key<T>(name, type); + } + + /** + * Visible for testing and vendor extensions only. + * + * @hide + */ + public Key(String name, TypeReference<T> typeReference) { + mKey = new CameraMetadataNative.Key<T>(name, typeReference); + } + + /** + * Return a camelCase, period separated name formatted like: + * {@code "root.section[.subsections].name"}. + * + * <p>Built-in keys exposed by the Android SDK are always prefixed with {@code "android."}; + * keys that are device/platform-specific are prefixed with {@code "com."}.</p> + * + * <p>For example, {@code CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP} would + * have a name of {@code "android.scaler.streamConfigurationMap"}; whereas a device + * specific key might look like {@code "com.google.nexus.data.private"}.</p> + * + * @return String representation of the key name + */ + public String getName() { + return mKey.getName(); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return mKey.hashCode(); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + @Override + public final boolean equals(Object o) { + return o instanceof Key && ((Key<T>)o).mKey.equals(mKey); + } + + /** + * Visible for CameraMetadataNative implementation only; do not use. + * + * TODO: Make this private or remove it altogether. + * + * @hide + */ + public CameraMetadataNative.Key<T> getNativeKey() { + return mKey; + } + + @SuppressWarnings({ + "unused", "unchecked" + }) + private Key(CameraMetadataNative.Key<?> nativeKey) { + mKey = (CameraMetadataNative.Key<T>) nativeKey; + } + } private final CameraMetadataNative mProperties; - private List<Key<?>> mAvailableRequestKeys; - private List<Key<?>> mAvailableResultKeys; + private List<CaptureRequest.Key<?>> mAvailableRequestKeys; + private List<CaptureResult.Key<?>> mAvailableResultKeys; /** * Takes ownership of the passed-in properties object * @hide */ public CameraCharacteristics(CameraMetadataNative properties) { - mProperties = properties; + mProperties = CameraMetadataNative.move(properties); } /** @@ -57,12 +150,55 @@ public final class CameraCharacteristics extends CameraMetadata { return new CameraMetadataNative(mProperties); } - @Override + /** + * Get a camera characteristics field value. + * + * <p>The field definitions can be + * found in {@link CameraCharacteristics}.</p> + * + * <p>Querying the value for the same key more than once will return a value + * which is equal to the previous queried value.</p> + * + * @throws IllegalArgumentException if the key was not valid + * + * @param key The characteristics field to read. + * @return The value of that key, or {@code null} if the field is not set. + */ public <T> T get(Key<T> key) { return mProperties.get(key); } /** + * {@inheritDoc} + * @hide + */ + @SuppressWarnings("unchecked") + @Override + protected <T> T getProtected(Key<?> key) { + return (T) mProperties.get(key); + } + + /** + * {@inheritDoc} + * @hide + */ + @SuppressWarnings("unchecked") + @Override + protected Class<Key<?>> getKeyClass() { + Object thisClass = Key.class; + return (Class<Key<?>>)thisClass; + } + + /** + * {@inheritDoc} + */ + @Override + public List<Key<?>> getKeys() { + // Force the javadoc for this function to show up on the CameraCharacteristics page + return super.getKeys(); + } + + /** * Returns the list of keys supported by this {@link CameraDevice} for querying * with a {@link CaptureRequest}. * @@ -76,9 +212,14 @@ public final class CameraCharacteristics extends CameraMetadata { * * @return List of keys supported by this CameraDevice for CaptureRequests. */ - public List<Key<?>> getAvailableCaptureRequestKeys() { + @SuppressWarnings({"unchecked"}) + public List<CaptureRequest.Key<?>> getAvailableCaptureRequestKeys() { if (mAvailableRequestKeys == null) { - mAvailableRequestKeys = getAvailableKeyList(CaptureRequest.class); + Object crKey = CaptureRequest.Key.class; + Class<CaptureRequest.Key<?>> crKeyTyped = (Class<CaptureRequest.Key<?>>)crKey; + + mAvailableRequestKeys = Collections.unmodifiableList( + getAvailableKeyList(CaptureRequest.class, crKeyTyped)); } return mAvailableRequestKeys; } @@ -97,9 +238,14 @@ public final class CameraCharacteristics extends CameraMetadata { * * @return List of keys supported by this CameraDevice for CaptureResults. */ - public List<Key<?>> getAvailableCaptureResultKeys() { + @SuppressWarnings({"unchecked"}) + public List<CaptureResult.Key<?>> getAvailableCaptureResultKeys() { if (mAvailableResultKeys == null) { - mAvailableResultKeys = getAvailableKeyList(CaptureResult.class); + Object crKey = CaptureResult.Key.class; + Class<CaptureResult.Key<?>> crKeyTyped = (Class<CaptureResult.Key<?>>)crKey; + + mAvailableResultKeys = Collections.unmodifiableList( + getAvailableKeyList(CaptureResult.class, crKeyTyped)); } return mAvailableResultKeys; } @@ -113,12 +259,14 @@ public final class CameraCharacteristics extends CameraMetadata { * <p>Each key is only listed once in the list. The order of the keys is undefined.</p> * * @param metadataClass The subclass of CameraMetadata that you want to get the keys for. + * @param keyClass The class of the metadata key, e.g. CaptureRequest.Key.class * * @return List of keys supported by this CameraDevice for metadataClass. * * @throws IllegalArgumentException if metadataClass is not a subclass of CameraMetadata */ - private <T extends CameraMetadata> List<Key<?>> getAvailableKeyList(Class<T> metadataClass) { + private <TKey> List<TKey> + getAvailableKeyList(Class<?> metadataClass, Class<TKey> keyClass) { if (metadataClass.equals(CameraMetadata.class)) { throw new AssertionError( @@ -128,7 +276,9 @@ public final class CameraCharacteristics extends CameraMetadata { "metadataClass must be a subclass of CameraMetadata"); } - return Collections.unmodifiableList(getKeysStatic(metadataClass, /*instance*/null)); + List<TKey> staticKeyList = CameraCharacteristics.<TKey>getKeysStatic( + metadataClass, keyClass, /*instance*/null); + return Collections.unmodifiableList(staticKeyList); } /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ @@ -1346,19 +1496,6 @@ public final class CameraCharacteristics extends CameraMetadata { new Key<Rational[]>("android.sensor.forwardMatrix2", Rational[].class); /** - * <p>Gain factor from electrons to raw units when - * ISO=100</p> - * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> - * <p><b>Full capability</b> - - * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the - * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p> - * - * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL - */ - public static final Key<Rational> SENSOR_BASE_GAIN_FACTOR = - new Key<Rational>("android.sensor.baseGainFactor", Rational.class); - - /** * <p>A fixed black level offset for each of the color filter arrangement * (CFA) mosaic channels.</p> * <p>This tag specifies the zero light value for each of the CFA mosaic diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 77640d1..6f5099b 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -766,14 +766,62 @@ public interface CameraDevice extends AutoCloseable { } /** - * This method is called when an image capture has completed and the + * This method is called when an image capture makes partial forward progress; some + * (but not all) results from an image capture are available. + * + * <p>The result provided here will contain some subset of the fields of + * a full result. Multiple {@link #onCaptureProgressed} calls may happen per + * capture; a given result field will only be present in one partial + * capture at most. The final {@link #onCaptureCompleted} call will always + * contain all the fields (in particular, the union of all the fields of all + * the partial results composing the total result).</p> + * + * <p>For each request, some result data might be available earlier than others. The typical + * delay between each partial result (per request) is a single frame interval. + * For performance-oriented use-cases, applications should query the metadata they need + * to make forward progress from the partial results and avoid waiting for the completed + * result.</p> + * + * <p>Each request will generate at least {@code 1} partial results, and at most + * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT} partial results.</p> + * + * <p>Depending on the request settings, the number of partial results per request + * will vary, although typically the partial count could be the same as long as the + * camera device subsystems enabled stay the same.</p> + * + * <p>The default implementation of this method does nothing.</p> + * + * @param camera The CameraDevice sending the callback. + * @param request The request that was given to the CameraDevice + * @param partialResult The partial output metadata from the capture, which + * includes a subset of the {@link TotalCaptureResult} fields. + * + * @see #capture + * @see #captureBurst + * @see #setRepeatingRequest + * @see #setRepeatingBurst + */ + public void onCaptureProgressed(CameraDevice camera, + CaptureRequest request, CaptureResult partialResult) { + // default empty implementation + } + + /** + * This method is called when an image capture has fully completed and all the * result metadata is available. * + * <p>This callback will always fire after the last {@link #onCaptureProgressed}; + * in other words, no more partial results will be delivered once the completed result + * is available.</p> + * + * <p>For performance-intensive use-cases where latency is a factor, consider + * using {@link #onCaptureProgressed} instead.</p> + * * <p>The default implementation of this method does nothing.</p> * * @param camera The CameraDevice sending the callback. * @param request The request that was given to the CameraDevice - * @param result The output metadata from the capture, including the + * @param result The total output metadata from the capture, including the * final capture parameters and the state of the camera system during * capture. * @@ -783,7 +831,7 @@ public interface CameraDevice extends AutoCloseable { * @see #setRepeatingBurst */ public void onCaptureCompleted(CameraDevice camera, - CaptureRequest request, CaptureResult result) { + CaptureRequest request, TotalCaptureResult result) { // default empty implementation } @@ -796,6 +844,10 @@ public interface CameraDevice extends AutoCloseable { * the capture may have been pushed to their respective output * streams.</p> * + * <p>Some partial results may have been delivered before the capture fails; + * however after this callback fires, no more partial results will be delivered by + * {@link #onCaptureProgressed}.</p> + * * <p>The default implementation of this method does nothing.</p> * * @param camera @@ -821,24 +873,57 @@ public interface CameraDevice extends AutoCloseable { * when a capture sequence finishes and all {@link CaptureResult} * or {@link CaptureFailure} for it have been returned via this listener. * + * <p>In total, there will be at least one result/failure returned by this listener + * before this callback is invoked. If the capture sequence is aborted before any + * requests have been processed, {@link #onCaptureSequenceAborted} is invoked instead.</p> + * + * <p>The default implementation does nothing.</p> + * * @param camera * The CameraDevice sending the callback. * @param sequenceId * A sequence ID returned by the {@link #capture} family of functions. - * @param lastFrameNumber + * @param frameNumber * The last frame number (returned by {@link CaptureResult#getFrameNumber} * or {@link CaptureFailure#getFrameNumber}) in the capture sequence. - * The last frame number may be equal to NO_FRAMES_CAPTURED if no images - * were captured for this sequence. This can happen, for example, when a - * repeating request or burst is cleared right after being set. * * @see CaptureResult#getFrameNumber() * @see CaptureFailure#getFrameNumber() * @see CaptureResult#getSequenceId() * @see CaptureFailure#getSequenceId() + * @see #onCaptureSequenceAborted */ public void onCaptureSequenceCompleted(CameraDevice camera, - int sequenceId, int lastFrameNumber) { + int sequenceId, long frameNumber) { + // default empty implementation + } + + /** + * This method is called independently of the others in CaptureListener, + * when a capture sequence aborts before any {@link CaptureResult} + * or {@link CaptureFailure} for it have been returned via this listener. + * + * <p>Due to the asynchronous nature of the camera device, not all submitted captures + * are immediately processed. It is possible to clear out the pending requests + * by a variety of operations such as {@link CameraDevice#stopRepeating} or + * {@link CameraDevice#flush}. When such an event happens, + * {@link #onCaptureSequenceCompleted} will not be called.</p> + * + * <p>The default implementation does nothing.</p> + * + * @param camera + * The CameraDevice sending the callback. + * @param sequenceId + * A sequence ID returned by the {@link #capture} family of functions. + * + * @see CaptureResult#getFrameNumber() + * @see CaptureFailure#getFrameNumber() + * @see CaptureResult#getSequenceId() + * @see CaptureFailure#getSequenceId() + * @see #onCaptureSequenceCompleted + */ + public void onCaptureSequenceAborted(CameraDevice camera, + int sequenceId) { // default empty implementation } } diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index 5455189..4cde601 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -16,8 +16,7 @@ package android.hardware.camera2; -import android.hardware.camera2.impl.CameraMetadataNative; -import android.hardware.camera2.utils.TypeReference; +import android.util.Log; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -36,7 +35,7 @@ import java.util.List; * * <p> * All instances of CameraMetadata are immutable. The list of keys with {@link #getKeys()} - * never changes, nor do the values returned by any key with {@link #get} throughout + * never changes, nor do the values returned by any key with {@code #get} throughout * the lifetime of the object. * </p> * @@ -44,7 +43,10 @@ import java.util.List; * @see CameraManager * @see CameraCharacteristics **/ -public abstract class CameraMetadata { +public abstract class CameraMetadata<TKey> { + + private static final String TAG = "CameraMetadataAb"; + private static final boolean VERBOSE = false; /** * Set a camera metadata field to a value. The field definitions can be @@ -74,8 +76,15 @@ public abstract class CameraMetadata { * * @param key The metadata field to read. * @return The value of that key, or {@code null} if the field is not set. + * + * @hide */ - public abstract <T> T get(Key<T> key); + protected abstract <T> T getProtected(TKey key); + + /** + * @hide + */ + protected abstract Class<TKey> getKeyClass(); /** * Returns a list of the keys contained in this map. @@ -83,14 +92,16 @@ public abstract class CameraMetadata { * <p>The list returned is not modifiable, so any attempts to modify it will throw * a {@code UnsupportedOperationException}.</p> * - * <p>All values retrieved by a key from this list with {@link #get} are guaranteed to be + * <p>All values retrieved by a key from this list with {@code #get} are guaranteed to be * non-{@code null}. Each key is only listed once in the list. The order of the keys * is undefined.</p> * * @return List of the keys contained in this map. */ - public List<Key<?>> getKeys() { - return Collections.unmodifiableList(getKeysStatic(this.getClass(), this)); + @SuppressWarnings("unchecked") + public List<TKey> getKeys() { + Class<CameraMetadata<TKey>> thisClass = (Class<CameraMetadata<TKey>>) getClass(); + return Collections.unmodifiableList(getKeysStatic(thisClass, getKeyClass(), this)); } /** @@ -101,24 +112,31 @@ public abstract class CameraMetadata { * Optionally, if {@code instance} is not null, then filter out any keys with null values. * </p> */ - /*package*/ static ArrayList<Key<?>> getKeysStatic(Class<? extends CameraMetadata> type, - CameraMetadata instance) { - ArrayList<Key<?>> keyList = new ArrayList<Key<?>>(); + /*package*/ @SuppressWarnings("unchecked") + static <TKey> ArrayList<TKey> getKeysStatic( + Class<?> type, Class<TKey> keyClass, + CameraMetadata<TKey> instance) { + + if (VERBOSE) Log.v(TAG, "getKeysStatic for " + type); + + ArrayList<TKey> keyList = new ArrayList<TKey>(); Field[] fields = type.getDeclaredFields(); for (Field field : fields) { // Filter for Keys that are public - if (field.getType().isAssignableFrom(Key.class) && + if (field.getType().isAssignableFrom(keyClass) && (field.getModifiers() & Modifier.PUBLIC) != 0) { - Key<?> key; + + TKey key; try { - key = (Key<?>) field.get(instance); + key = (TKey) field.get(instance); } catch (IllegalAccessException e) { throw new AssertionError("Can't get IllegalAccessException", e); } catch (IllegalArgumentException e) { throw new AssertionError("Can't get IllegalArgumentException", e); } - if (instance == null || instance.get(key) != null) { + + if (instance == null || instance.getProtected(key) != null) { keyList.add(key); } } @@ -127,113 +145,6 @@ public abstract class CameraMetadata { return keyList; } - // TODO: make final or abstract - public static class Key<T> { - - private boolean mHasTag; - private int mTag; - private final Class<T> mType; - private final TypeReference<T> mTypeReference; - private final String mName; - - /** - * @hide - */ - public Key(String name, Class<T> type) { - if (name == null) { - throw new NullPointerException("Key needs a valid name"); - } else if (type == null) { - throw new NullPointerException("Type needs to be non-null"); - } - mName = name; - mType = type; - mTypeReference = TypeReference.createSpecializedTypeReference(type); - } - - /** - * @hide - */ - @SuppressWarnings("unchecked") - public Key(String name, TypeReference<T> typeReference) { - if (name == null) { - throw new NullPointerException("Key needs a valid name"); - } else if (typeReference == null) { - throw new NullPointerException("TypeReference needs to be non-null"); - } - mName = name; - mType = (Class<T>)typeReference.getRawType(); - mTypeReference = typeReference; - } - - public final String getName() { - return mName; - } - - @Override - public final int hashCode() { - return mName.hashCode() ^ mTypeReference.hashCode(); - } - - @Override - public final boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof Key)) { - return false; - } - - Key<?> lhs = (Key<?>)o; - return mName.equals(lhs.mName) && mTypeReference.equals(lhs.mTypeReference); - } - - /** - * <p> - * Get the tag corresponding to this key. This enables insertion into the - * native metadata. - * </p> - * - * <p>This value is looked up the first time, and cached subsequently.</p> - * - * @return The tag numeric value corresponding to the string - * - * @hide - */ - public final int getTag() { - if (!mHasTag) { - mTag = CameraMetadataNative.getTag(mName); - mHasTag = true; - } - return mTag; - } - - /** - * Get the raw class backing the type {@code T} for this key. - * - * <p>The distinction is only important if {@code T} is a generic, e.g. - * {@code Range<Integer>} since the nested type will be erased.</p> - * - * @hide - */ - public final Class<T> getType() { - // TODO: remove this; other places should use #getTypeReference() instead - return mType; - } - - /** - * Get the type reference backing the type {@code T} for this key. - * - * <p>The distinction is only important if {@code T} is a generic, e.g. - * {@code Range<Integer>} since the nested type will be retained.</p> - * - * @hide - */ - public final TypeReference<T> getTypeReference() { - return mTypeReference; - } - } - /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ * The enum values below this point are generated from metadata * definitions in /system/media/camera/docs. Do not modify by hand or @@ -336,7 +247,6 @@ public abstract class CameraMetadata { * <li>Manual sensitivity control<ul> * <li>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</li> * <li>{@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</li> - * <li>{@link CameraCharacteristics#SENSOR_BASE_GAIN_FACTOR android.sensor.baseGainFactor}</li> * </ul> * </li> * <li>Manual lens control<ul> @@ -357,7 +267,6 @@ public abstract class CameraMetadata { * result.</p> * * @see CaptureRequest#BLACK_LEVEL_LOCK - * @see CameraCharacteristics#SENSOR_BASE_GAIN_FACTOR * @see CaptureRequest#SENSOR_EXPOSURE_TIME * @see CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE @@ -1381,8 +1290,7 @@ public abstract class CameraMetadata { /** * <p>If the flash is available and charged, fire flash - * for this capture based on android.flash.firingPower and - * android.flash.firingTime.</p> + * for this capture.</p> * @see CaptureRequest#FLASH_MODE */ public static final int FLASH_MODE_SINGLE = 1; diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 8e0f2ae..a4aa296 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -16,7 +16,9 @@ package android.hardware.camera2; +import android.hardware.camera2.CameraCharacteristics.Key; import android.hardware.camera2.impl.CameraMetadataNative; +import android.hardware.camera2.utils.TypeReference; import android.os.Parcel; import android.os.Parcelable; import android.util.Rational; @@ -25,6 +27,7 @@ import android.view.Surface; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Objects; @@ -58,7 +61,98 @@ import java.util.Objects; * @see CameraDevice#setRepeatingRequest * @see CameraDevice#createCaptureRequest */ -public final class CaptureRequest extends CameraMetadata implements Parcelable { +public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> + implements Parcelable { + + /** + * A {@code Key} is used to do capture request field lookups with + * {@link CaptureResult#get} or to set fields with + * {@link CaptureRequest.Builder#set(Key, Object)}. + * + * <p>For example, to set the crop rectangle for the next capture: + * <code><pre> + * Rect cropRectangle = new Rect(0, 0, 640, 480); + * captureRequestBuilder.set(SCALER_CROP_REGION, cropRectangle); + * </pre></code> + * </p> + * + * <p>To enumerate over all possible keys for {@link CaptureResult}, see + * {@link CameraCharacteristics#getAvailableCaptureResultKeys}.</p> + * + * @see CaptureResult#get + * @see CameraCharacteristics#getAvailableCaptureResultKeys + */ + public final static class Key<T> { + private final CameraMetadataNative.Key<T> mKey; + + /** + * Visible for testing and vendor extensions only. + * + * @hide + */ + public Key(String name, Class<T> type) { + mKey = new CameraMetadataNative.Key<T>(name, type); + } + + /** + * Visible for testing and vendor extensions only. + * + * @hide + */ + public Key(String name, TypeReference<T> typeReference) { + mKey = new CameraMetadataNative.Key<T>(name, typeReference); + } + + /** + * Return a camelCase, period separated name formatted like: + * {@code "root.section[.subsections].name"}. + * + * <p>Built-in keys exposed by the Android SDK are always prefixed with {@code "android."}; + * keys that are device/platform-specific are prefixed with {@code "com."}.</p> + * + * <p>For example, {@code CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP} would + * have a name of {@code "android.scaler.streamConfigurationMap"}; whereas a device + * specific key might look like {@code "com.google.nexus.data.private"}.</p> + * + * @return String representation of the key name + */ + public String getName() { + return mKey.getName(); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return mKey.hashCode(); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + @Override + public final boolean equals(Object o) { + return o instanceof Key && ((Key<T>)o).mKey.equals(mKey); + } + + /** + * Visible for CameraMetadataNative implementation only; do not use. + * + * TODO: Make this private or remove it altogether. + * + * @hide + */ + public CameraMetadataNative.Key<T> getNativeKey() { + return mKey; + } + + @SuppressWarnings({ "unchecked" }) + /*package*/ Key(CameraMetadataNative.Key<?> nativeKey) { + mKey = (CameraMetadataNative.Key<T>) nativeKey; + } + } private final HashSet<Surface> mSurfaceSet; private final CameraMetadataNative mSettings; @@ -93,17 +187,58 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * Used by the Builder to create a mutable CaptureRequest. */ private CaptureRequest(CameraMetadataNative settings) { - mSettings = settings; + mSettings = CameraMetadataNative.move(settings); mSurfaceSet = new HashSet<Surface>(); } - @SuppressWarnings("unchecked") - @Override + /** + * Get a capture request field value. + * + * <p>The field definitions can be found in {@link CaptureRequest}.</p> + * + * <p>Querying the value for the same key more than once will return a value + * which is equal to the previous queried value.</p> + * + * @throws IllegalArgumentException if the key was not valid + * + * @param key The result field to read. + * @return The value of that key, or {@code null} if the field is not set. + */ public <T> T get(Key<T> key) { return mSettings.get(key); } /** + * {@inheritDoc} + * @hide + */ + @SuppressWarnings("unchecked") + @Override + protected <T> T getProtected(Key<?> key) { + return (T) mSettings.get(key); + } + + /** + * {@inheritDoc} + * @hide + */ + @SuppressWarnings("unchecked") + @Override + protected Class<Key<?>> getKeyClass() { + Object thisClass = Key.class; + return (Class<Key<?>>)thisClass; + } + + /** + * {@inheritDoc} + */ + @Override + public List<Key<?>> getKeys() { + // Force the javadoc for this function to show up on the CaptureRequest page + return super.getKeys(); + } + + /** * Retrieve the tag for this request, if any. * * <p>This tag is not used for anything by the camera device, but can be diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index e0ddd57..9aa56cf 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -17,13 +17,16 @@ package android.hardware.camera2; import android.hardware.camera2.impl.CameraMetadataNative; -import android.hardware.camera2.params.Face; +import android.hardware.camera2.utils.TypeReference; +import android.util.Log; import android.util.Rational; +import java.util.List; + /** - * <p>The results of a single image capture from the image sensor.</p> + * <p>The subset of the results of a single image capture from the image sensor.</p> * - * <p>Contains the final configuration for the capture hardware (sensor, lens, + * <p>Contains a subset of the final configuration for the capture hardware (sensor, lens, * flash), the processing pipeline, the control algorithms, and the output * buffers.</p> * @@ -33,10 +36,106 @@ import android.util.Rational; * capture. The result also includes additional metadata about the state of the * camera device during the capture.</p> * - * <p>{@link CameraCharacteristics} objects are immutable.</p> + * <p>Not all properties returned by {@link CameraCharacteristics#getAvailableCaptureResultKeys()} + * are necessarily available. Some results are {@link CaptureResult partial} and will + * not have every key set. Only {@link TotalCaptureResult total} results are guaranteed to have + * every key available that was enabled by the request.</p> + * + * <p>{@link CaptureResult} objects are immutable.</p> * */ -public final class CaptureResult extends CameraMetadata { +public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { + + private static final String TAG = "CaptureResult"; + private static final boolean VERBOSE = false; + + /** + * A {@code Key} is used to do capture result field lookups with + * {@link CaptureResult#get}. + * + * <p>For example, to get the timestamp corresponding to the exposure of the first row: + * <code><pre> + * long timestamp = captureResult.get(CaptureResult.SENSOR_TIMESTAMP); + * </pre></code> + * </p> + * + * <p>To enumerate over all possible keys for {@link CaptureResult}, see + * {@link CameraCharacteristics#getAvailableCaptureResultKeys}.</p> + * + * @see CaptureResult#get + * @see CameraCharacteristics#getAvailableCaptureResultKeys + */ + public final static class Key<T> { + private final CameraMetadataNative.Key<T> mKey; + + /** + * Visible for testing and vendor extensions only. + * + * @hide + */ + public Key(String name, Class<T> type) { + mKey = new CameraMetadataNative.Key<T>(name, type); + } + + /** + * Visible for testing and vendor extensions only. + * + * @hide + */ + public Key(String name, TypeReference<T> typeReference) { + mKey = new CameraMetadataNative.Key<T>(name, typeReference); + } + + /** + * Return a camelCase, period separated name formatted like: + * {@code "root.section[.subsections].name"}. + * + * <p>Built-in keys exposed by the Android SDK are always prefixed with {@code "android."}; + * keys that are device/platform-specific are prefixed with {@code "com."}.</p> + * + * <p>For example, {@code CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP} would + * have a name of {@code "android.scaler.streamConfigurationMap"}; whereas a device + * specific key might look like {@code "com.google.nexus.data.private"}.</p> + * + * @return String representation of the key name + */ + public String getName() { + return mKey.getName(); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return mKey.hashCode(); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + @Override + public final boolean equals(Object o) { + return o instanceof Key && ((Key<T>)o).mKey.equals(mKey); + } + + /** + * Visible for CameraMetadataNative implementation only; do not use. + * + * TODO: Make this private or remove it altogether. + * + * @hide + */ + public CameraMetadataNative.Key<T> getNativeKey() { + return mKey; + } + + @SuppressWarnings({ "unchecked" }) + /*package*/ Key(CameraMetadataNative.Key<?> nativeKey) { + mKey = (CameraMetadataNative.Key<T>) nativeKey; + } + } private final CameraMetadataNative mResults; private final CaptureRequest mRequest; @@ -55,7 +154,10 @@ public final class CaptureResult extends CameraMetadata { throw new IllegalArgumentException("parent was null"); } - mResults = results; + mResults = CameraMetadataNative.move(results); + if (mResults.isEmpty()) { + throw new AssertionError("Results must not be empty"); + } mRequest = parent; mSequenceId = sequenceId; } @@ -68,26 +170,103 @@ public final class CaptureResult extends CameraMetadata { return new CameraMetadataNative(mResults); } - @Override + /** + * Creates a request-less result. + * + * <p><strong>For testing only.</strong></p> + * @hide + */ + public CaptureResult(CameraMetadataNative results, int sequenceId) { + if (results == null) { + throw new IllegalArgumentException("results was null"); + } + + mResults = CameraMetadataNative.move(results); + if (mResults.isEmpty()) { + throw new AssertionError("Results must not be empty"); + } + + mRequest = null; + mSequenceId = sequenceId; + } + + /** + * Get a capture result field value. + * + * <p>The field definitions can be found in {@link CaptureResult}.</p> + * + * <p>Querying the value for the same key more than once will return a value + * which is equal to the previous queried value.</p> + * + * @throws IllegalArgumentException if the key was not valid + * + * @param key The result field to read. + * @return The value of that key, or {@code null} if the field is not set. + */ public <T> T get(Key<T> key) { - return mResults.get(key); + T value = mResults.get(key); + if (VERBOSE) Log.v(TAG, "#get for Key = " + key.getName() + ", returned value = " + value); + return value; + } + + /** + * {@inheritDoc} + * @hide + */ + @SuppressWarnings("unchecked") + @Override + protected <T> T getProtected(Key<?> key) { + return (T) mResults.get(key); + } + + /** + * {@inheritDoc} + * @hide + */ + @SuppressWarnings("unchecked") + @Override + protected Class<Key<?>> getKeyClass() { + Object thisClass = Key.class; + return (Class<Key<?>>)thisClass; + } + + /** + * Dumps the native metadata contents to logcat. + * + * <p>Visibility for testing/debugging only. The results will not + * include any synthesized keys, as they are invisible to the native layer.</p> + * + * @hide + */ + public void dumpToLog() { + mResults.dumpToLog(); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Key<?>> getKeys() { + // Force the javadoc for this function to show up on the CaptureResult page + return super.getKeys(); } /** * Get the request associated with this result. * - * <p>Whenever a request is successfully captured, with - * {@link CameraDevice.CaptureListener#onCaptureCompleted}, - * the {@code result}'s {@code getRequest()} will return that {@code request}. + * <p>Whenever a request has been fully or partially captured, with + * {@link CameraDevice.CaptureListener#onCaptureCompleted} or + * {@link CameraDevice.CaptureListener#onCaptureProgressed}, the {@code result}'s + * {@code getRequest()} will return that {@code request}. * </p> * - * <p>In particular, + * <p>For example, * <code><pre>cameraDevice.capture(someRequest, new CaptureListener() { * {@literal @}Override * void onCaptureCompleted(CaptureRequest myRequest, CaptureResult myResult) { * assert(myResult.getRequest.equals(myRequest) == true); * } - * }; + * }, null); * </code></pre> * </p> * @@ -110,6 +289,7 @@ public final class CaptureResult extends CameraMetadata { * @return int frame number */ public int getFrameNumber() { + // TODO: @hide REQUEST_FRAME_COUNT return get(REQUEST_FRAME_COUNT); } @@ -123,6 +303,7 @@ public final class CaptureResult extends CameraMetadata { * @return int The ID for the sequence of requests that this capture result is a part of * * @see CameraDevice.CaptureListener#onCaptureSequenceCompleted + * @see CameraDevice.CaptureListener#onCaptureSequenceAborted */ public int getSequenceId() { return mSequenceId; @@ -1888,21 +2069,6 @@ public final class CaptureResult extends CameraMetadata { new Key<Long>("android.sensor.timestamp", long.class); /** - * <p>The temperature of the sensor, sampled at the time - * exposure began for this frame.</p> - * <p>The thermal diode being queried should be inside the sensor PCB, or - * somewhere close to it.</p> - * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> - * <p><b>Full capability</b> - - * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the - * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p> - * - * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL - */ - public static final Key<Float> SENSOR_TEMPERATURE = - new Key<Float>("android.sensor.temperature", float.class); - - /** * <p>The estimated camera neutral color in the native sensor colorspace at * the time of capture.</p> * <p>This value gives the neutral color point encoded as an RGB value in the diff --git a/media/java/android/media/DngCreator.java b/core/java/android/hardware/camera2/DngCreator.java index 76c6d46..54568ed 100644 --- a/media/java/android/media/DngCreator.java +++ b/core/java/android/hardware/camera2/DngCreator.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package android.media; +package android.hardware.camera2; import android.graphics.Bitmap; import android.graphics.ImageFormat; -import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CaptureResult; import android.hardware.camera2.impl.CameraMetadataNative; import android.location.Location; +import android.media.ExifInterface; +import android.media.Image; import android.util.Size; import java.io.IOException; @@ -266,6 +266,7 @@ public final class DngCreator implements AutoCloseable { * </p> * * @param dngOutput an {@link java.io.OutputStream} to write the DNG file to. + * @param size the {@link Size} of the image to write, in pixels. * @param pixels an {@link java.nio.ByteBuffer} of pixel data to write. * @param offset the offset of the raw image in bytes. This indicates how many bytes will * be skipped in the input before any pixel data is read. @@ -362,7 +363,6 @@ public final class DngCreator implements AutoCloseable { long offset) throws IOException; static { - System.loadLibrary("media_jni"); nativeClassInit(); } } diff --git a/core/java/android/hardware/camera2/TotalCaptureResult.java b/core/java/android/hardware/camera2/TotalCaptureResult.java new file mode 100644 index 0000000..2647959 --- /dev/null +++ b/core/java/android/hardware/camera2/TotalCaptureResult.java @@ -0,0 +1,84 @@ +/* + * 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. + */ + +package android.hardware.camera2; + +import android.hardware.camera2.impl.CameraMetadataNative; + +import java.util.Collections; +import java.util.List; + +/** + * <p>The total assembled results of a single image capture from the image sensor.</p> + * + * <p>Contains the final configuration for the capture hardware (sensor, lens, + * flash), the processing pipeline, the control algorithms, and the output + * buffers.</p> + * + * <p>A {@code TotalCaptureResult} is produced by a {@link CameraDevice} after processing a + * {@link CaptureRequest}. All properties listed for capture requests can also + * be queried on the capture result, to determine the final values used for + * capture. The result also includes additional metadata about the state of the + * camera device during the capture.</p> + * + * <p>All properties returned by {@link CameraCharacteristics#getAvailableCaptureResultKeys()} + * are available (that is {@link CaptureResult#get} will return non-{@code null}, if and only if + * that key that was enabled by the request. A few keys such as + * {@link CaptureResult#STATISTICS_FACES} are disabled by default unless enabled with a switch (such + * as {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE}). Refer to each key documentation on + * a case-by-case basis.</p> + * + * <p>{@link TotalCaptureResult} objects are immutable.</p> + * + * @see CameraDevice.CaptureListener#onCaptureCompleted + */ +public final class TotalCaptureResult extends CaptureResult { + + /** + * Takes ownership of the passed-in properties object + * @hide + */ + public TotalCaptureResult(CameraMetadataNative results, CaptureRequest parent, int sequenceId) { + super(results, parent, sequenceId); + } + + /** + * Creates a request-less result. + * + * <p><strong>For testing only.</strong></p> + * @hide + */ + public TotalCaptureResult(CameraMetadataNative results, int sequenceId) { + super(results, sequenceId); + } + + /** + * Get the read-only list of partial results that compose this total result. + * + * <p>The list is returned is unmodifiable; attempting to modify it will result in a + * {@code UnsupportedOperationException} being thrown.</p> + * + * <p>The list size will be inclusive between {@code 1} and + * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT}, in ascending order + * of when {@link CameraDevice.CaptureListener#onCaptureProgressed} was invoked.</p> + * + * @return unmodifiable list of partial results + */ + public List<CaptureResult> getPartialResults() { + // TODO + return Collections.unmodifiableList(null); + } +} diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java index b082a70..7b24976 100644 --- a/core/java/android/hardware/camera2/impl/CameraDevice.java +++ b/core/java/android/hardware/camera2/impl/CameraDevice.java @@ -24,6 +24,7 @@ import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; import android.hardware.camera2.ICameraDeviceCallbacks; import android.hardware.camera2.ICameraDeviceUser; +import android.hardware.camera2.TotalCaptureResult; import android.hardware.camera2.utils.CameraBinderDecorator; import android.hardware.camera2.utils.CameraRuntimeException; import android.hardware.camera2.utils.LongParcelable; @@ -359,7 +360,7 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { holder.getListener().onCaptureSequenceCompleted( CameraDevice.this, requestId, - (int)lastFrameNumber); + lastFrameNumber); } } }; @@ -717,7 +718,7 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { holder.getListener().onCaptureSequenceCompleted( CameraDevice.this, requestId, - (int)lastFrameNumber); + lastFrameNumber); } } }; @@ -888,12 +889,15 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { } final CaptureRequest request = holder.getRequest(resultExtras.getSubsequenceId()); - final CaptureResult resultAsCapture = new CaptureResult(result, request, requestId); + Runnable resultDispatch = null; // Either send a partial result or the final capture completed result if (quirkIsPartialResult) { + final CaptureResult resultAsCapture = + new CaptureResult(result, request, requestId); + // Partial result resultDispatch = new Runnable() { @Override @@ -907,6 +911,9 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { } }; } else { + final TotalCaptureResult resultAsCapture = + new TotalCaptureResult(result, request, requestId); + // Final capture result resultDispatch = new Runnable() { @Override diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index 27cfd38..ab2c49a 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -20,7 +20,7 @@ import android.graphics.ImageFormat; import android.graphics.Point; import android.graphics.Rect; import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CameraMetadata; +import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; import android.hardware.camera2.marshal.Marshaler; import android.hardware.camera2.marshal.MarshalQueryable; @@ -46,10 +46,14 @@ import android.hardware.camera2.params.Face; import android.hardware.camera2.params.StreamConfiguration; import android.hardware.camera2.params.StreamConfigurationDuration; import android.hardware.camera2.params.StreamConfigurationMap; +import android.hardware.camera2.utils.TypeReference; import android.os.Parcelable; import android.os.Parcel; import android.util.Log; +import com.android.internal.util.Preconditions; + +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; @@ -58,7 +62,147 @@ import java.util.ArrayList; * Implementation of camera metadata marshal/unmarshal across Binder to * the camera service */ -public class CameraMetadataNative extends CameraMetadata implements Parcelable { +public class CameraMetadataNative implements Parcelable { + + public static class Key<T> { + private boolean mHasTag; + private int mTag; + private final Class<T> mType; + private final TypeReference<T> mTypeReference; + private final String mName; + + /** + * Visible for testing only. + * + * <p>Use the CameraCharacteristics.Key, CaptureResult.Key, or CaptureRequest.Key + * for application code or vendor-extended keys.</p> + */ + public Key(String name, Class<T> type) { + if (name == null) { + throw new NullPointerException("Key needs a valid name"); + } else if (type == null) { + throw new NullPointerException("Type needs to be non-null"); + } + mName = name; + mType = type; + mTypeReference = TypeReference.createSpecializedTypeReference(type); + } + + /** + * Visible for testing only. + * + * <p>Use the CameraCharacteristics.Key, CaptureResult.Key, or CaptureRequest.Key + * for application code or vendor-extended keys.</p> + */ + @SuppressWarnings("unchecked") + public Key(String name, TypeReference<T> typeReference) { + if (name == null) { + throw new NullPointerException("Key needs a valid name"); + } else if (typeReference == null) { + throw new NullPointerException("TypeReference needs to be non-null"); + } + mName = name; + mType = (Class<T>)typeReference.getRawType(); + mTypeReference = typeReference; + } + + /** + * Return a camelCase, period separated name formatted like: + * {@code "root.section[.subsections].name"}. + * + * <p>Built-in keys exposed by the Android SDK are always prefixed with {@code "android."}; + * keys that are device/platform-specific are prefixed with {@code "com."}.</p> + * + * <p>For example, {@code CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP} would + * have a name of {@code "android.scaler.streamConfigurationMap"}; whereas a device + * specific key might look like {@code "com.google.nexus.data.private"}.</p> + * + * @return String representation of the key name + */ + public final String getName() { + return mName; + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return mName.hashCode() ^ mTypeReference.hashCode(); + } + + /** + * Compare this key against other native keys, request keys, result keys, and + * characteristics keys. + * + * <p>Two keys are considered equal if their name and type reference are equal.</p> + * + * <p>Note that the equality against non-native keys is one-way. A native key may be equal + * to a result key; but that same result key will not be equal to a native key.</p> + */ + @SuppressWarnings("rawtypes") + @Override + public final boolean equals(Object o) { + if (this == o) { + return true; + } + + Key<?> lhs; + + if (o instanceof CaptureResult.Key) { + lhs = ((CaptureResult.Key)o).getNativeKey(); + } else if (o instanceof CaptureRequest.Key) { + lhs = ((CaptureRequest.Key)o).getNativeKey(); + } else if (o instanceof CameraCharacteristics.Key) { + lhs = ((CameraCharacteristics.Key)o).getNativeKey(); + } else if ((o instanceof Key)) { + lhs = (Key<?>)o; + } else { + return false; + } + + return mName.equals(lhs.mName) && mTypeReference.equals(lhs.mTypeReference); + } + + /** + * <p> + * Get the tag corresponding to this key. This enables insertion into the + * native metadata. + * </p> + * + * <p>This value is looked up the first time, and cached subsequently.</p> + * + * @return The tag numeric value corresponding to the string + */ + public final int getTag() { + if (!mHasTag) { + mTag = CameraMetadataNative.getTag(mName); + mHasTag = true; + } + return mTag; + } + + /** + * Get the raw class backing the type {@code T} for this key. + * + * <p>The distinction is only important if {@code T} is a generic, e.g. + * {@code Range<Integer>} since the nested type will be erased.</p> + */ + public final Class<T> getType() { + // TODO: remove this; other places should use #getTypeReference() instead + return mType; + } + + /** + * Get the type reference backing the type {@code T} for this key. + * + * <p>The distinction is only important if {@code T} is a generic, e.g. + * {@code Range<Integer>} since the nested type will be retained.</p> + */ + public final TypeReference<T> getTypeReference() { + return mTypeReference; + } + } private static final String TAG = "CameraMetadataJV"; private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); @@ -84,6 +228,20 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { } } + /** + * Move the contents from {@code other} into a new camera metadata instance.</p> + * + * <p>After this call, {@code other} will become empty.</p> + * + * @param other the previous metadata instance which will get pilfered + * @return a new metadata instance with the values from {@code other} moved into it + */ + public static CameraMetadataNative move(CameraMetadataNative other) { + CameraMetadataNative newObject = new CameraMetadataNative(); + newObject.swap(other); + return newObject; + } + public static final Parcelable.Creator<CameraMetadataNative> CREATOR = new Parcelable.Creator<CameraMetadataNative>() { @Override @@ -109,8 +267,36 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { nativeWriteToParcel(dest); } - @Override + /** + * @hide + */ + public <T> T get(CameraCharacteristics.Key<T> key) { + return get(key.getNativeKey()); + } + + /** + * @hide + */ + public <T> T get(CaptureResult.Key<T> key) { + return get(key.getNativeKey()); + } + + /** + * @hide + */ + public <T> T get(CaptureRequest.Key<T> key) { + return get(key.getNativeKey()); + } + + /** + * Look-up a metadata field value by its key. + * + * @param key a non-{@code null} key instance + * @return the field corresponding to the {@code key}, or {@code null} if no value was set + */ public <T> T get(Key<T> key) { + Preconditions.checkNotNull(key, "key must not be null"); + T value = getOverride(key); if (value != null) { return value; @@ -152,6 +338,18 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { setBase(key, value); } + public <T> void set(CaptureRequest.Key<T> key, T value) { + set(key.getNativeKey(), value); + } + + public <T> void set(CaptureResult.Key<T> key, T value) { + set(key.getNativeKey(), value); + } + + public <T> void set(CameraCharacteristics.Key<T> key, T value) { + set(key.getNativeKey(), value); + } + // Keep up-to-date with camera_metadata.h /** * @hide @@ -188,6 +386,18 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { mMetadataPtr = 0; // set it to 0 again to prevent eclipse from making this field final } + private <T> T getBase(CameraCharacteristics.Key<T> key) { + return getBase(key.getNativeKey()); + } + + private <T> T getBase(CaptureResult.Key<T> key) { + return getBase(key.getNativeKey()); + } + + private <T> T getBase(CaptureRequest.Key<T> key) { + return getBase(key.getNativeKey()); + } + private <T> T getBase(Key<T> key) { int tag = key.getTag(); byte[] values = readValues(tag); @@ -342,6 +552,18 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { return new StreamConfigurationMap(configurations, minFrameDurations, stallDurations); } + private <T> void setBase(CameraCharacteristics.Key<T> key, T value) { + setBase(key.getNativeKey(), value); + } + + private <T> void setBase(CaptureResult.Key<T> key, T value) { + setBase(key.getNativeKey(), value); + } + + private <T> void setBase(CaptureRequest.Key<T> key, T value) { + setBase(key.getNativeKey(), value); + } + private <T> void setBase(Key<T> key, T value) { int tag = key.getTag(); @@ -440,6 +662,7 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { private native synchronized byte[] nativeReadValues(int tag); private native synchronized void nativeWriteValues(int tag, byte[] src); + private native synchronized void nativeDump() throws IOException; // dump to ALOGD private static native int nativeGetTagFromKey(String keyName) throws IllegalArgumentException; @@ -531,6 +754,22 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { return nativeReadValues(tag); } + /** + * Dumps the native metadata contents to logcat. + * + * <p>Visibility for testing/debugging only. The results will not + * include any synthesized keys, as they are invisible to the native layer.</p> + * + * @hide + */ + public void dumpToLog() { + try { + nativeDump(); + } catch (IOException e) { + Log.wtf(TAG, "Dump logging failed", e); + } + } + @Override protected void finalize() throws Throwable { try { @@ -599,5 +838,4 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { nativeClassInit(); registerAllMarshalers(); } - } diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java index 71adf8b..22ff9c6 100644 --- a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java +++ b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java @@ -93,7 +93,7 @@ public class CameraDeviceState { * {@link CameraDeviceStateListener#onConfiguring()} will be called. * </p> * - * @returns {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. + * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. */ public synchronized int setConfiguring() { doStateTransition(STATE_CONFIGURING); @@ -108,7 +108,7 @@ public class CameraDeviceState { * {@link CameraDeviceStateListener#onIdle()} will be called. * </p> * - * @returns {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. + * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. */ public synchronized int setIdle() { doStateTransition(STATE_IDLE); @@ -124,7 +124,7 @@ public class CameraDeviceState { * </p> * * @param request A {@link RequestHolder} containing the request for the current capture. - * @returns {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. + * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. */ public synchronized int setCaptureStart(final RequestHolder request) { mCurrentRequest = request; @@ -144,7 +144,7 @@ public class CameraDeviceState { * * @param request the {@link RequestHolder} request that created this result. * @param result the {@link CameraMetadataNative} result to set. - * @returns {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. + * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. */ public synchronized int setCaptureResult(final RequestHolder request, final CameraMetadataNative result) { diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 80a9598..2f2aba3 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -35,15 +35,17 @@ import android.os.Messenger; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; +import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.Log; +import com.android.internal.telephony.ITelephony; +import com.android.internal.util.Protocol; + import java.net.InetAddress; import java.util.concurrent.atomic.AtomicInteger; import java.util.HashMap; -import com.android.internal.util.Protocol; - /** * Class that answers queries about the state of network connectivity. It also * notifies applications when network connectivity changes. Get an instance @@ -940,34 +942,18 @@ public class ConnectivityManager { } /** - * Gets the value of the setting for enabling Mobile data. - * - * @return Whether mobile data is enabled. - * - * <p>This method requires the call to hold the permission - * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}. * @hide + * @deprecated Talk to TelephonyManager directly */ public boolean getMobileDataEnabled() { - try { - return mService.getMobileDataEnabled(); - } catch (RemoteException e) { - return true; - } - } - - /** - * Sets the persisted value for enabling/disabling Mobile data. - * - * @param enabled Whether the user wants the mobile data connection used - * or not. - * @hide - */ - public void setMobileDataEnabled(boolean enabled) { - try { - mService.setMobileDataEnabled(enabled); - } catch (RemoteException e) { + IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE); + if (b != null) { + try { + ITelephony it = ITelephony.Stub.asInterface(b); + return it.getDataEnabled(); + } catch (RemoteException e) { } } + return false; } /** diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index d97b1e9..baec36a 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -74,9 +74,6 @@ interface IConnectivityManager boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName); - boolean getMobileDataEnabled(); - void setMobileDataEnabled(boolean enabled); - /** Policy control over specific {@link NetworkStateTracker}. */ void setPolicyDataEnable(int networkType, boolean enabled); diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index af45fa0..bc57b33 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -2443,8 +2443,10 @@ public abstract class BatteryStats implements Parcelable { pw.print(prefix); pw.print(" Capacity: "); printmAh(pw, helper.getPowerProfile().getBatteryCapacity()); pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower()); - pw.print(", Min drain: "); printmAh(pw, helper.getMinDrainedPower()); - pw.print(", Max drain: "); printmAh(pw, helper.getMaxDrainedPower()); + pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower()); + if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) { + pw.print("-"); printmAh(pw, helper.getMaxDrainedPower()); + } pw.println(); for (int i=0; i<sippers.size(); i++) { BatterySipper bs = sippers.get(i); @@ -3301,7 +3303,8 @@ public abstract class BatteryStats implements Parcelable { if (rec.time >= histStart) { if (histStart >= 0 && !printed) { if (rec.cmd == HistoryItem.CMD_CURRENT_TIME - || rec.cmd == HistoryItem.CMD_RESET) { + || rec.cmd == HistoryItem.CMD_RESET + || rec.cmd == HistoryItem.CMD_START) { printed = true; hprinter.printNextItem(pw, rec, baseTime, checkin, (flags&DUMP_VERBOSE) != 0); @@ -3351,7 +3354,10 @@ public abstract class BatteryStats implements Parcelable { } hprinter.printNextItem(pw, rec, baseTime, checkin, (flags&DUMP_VERBOSE) != 0); - } else if (rec.eventCode != HistoryItem.EVENT_NONE) { + } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) { + // This is an attempt to aggregate the previous state and generate + //Â fake events to reflect that state at the point where we start + // printing real events. It doesn't really work right, so is turned off. if (tracker == null) { tracker = new HistoryEventTracker(); } diff --git a/core/java/android/os/CommonBundle.java b/core/java/android/os/CommonBundle.java index e11f170..c1b202c 100644 --- a/core/java/android/os/CommonBundle.java +++ b/core/java/android/os/CommonBundle.java @@ -18,11 +18,10 @@ package android.os; import android.util.ArrayMap; import android.util.Log; -import android.util.SparseArray; import java.io.Serializable; import java.util.ArrayList; -import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -304,6 +303,16 @@ abstract class CommonBundle implements Parcelable, Cloneable { } /** + * Inserts all mappings from the given Map into this CommonBundle. + * + * @param map a Map + */ + void putAll(Map map) { + unparcel(); + mMap.putAll(map); + } + + /** * Returns a Set containing the Strings used as keys in this Bundle. * * @return a Set of String keys diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java index c2cd3be..cd8d515 100644 --- a/core/java/android/os/PersistableBundle.java +++ b/core/java/android/os/PersistableBundle.java @@ -17,7 +17,14 @@ package android.os; import android.util.ArrayMap; - +import com.android.internal.util.XmlUtils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; import java.util.Set; /** @@ -25,7 +32,8 @@ import java.util.Set; * restored. * */ -public final class PersistableBundle extends CommonBundle { +public final class PersistableBundle extends CommonBundle implements XmlUtils.WriteMapCallback { + private static final String TAG_PERSISTABLEMAP = "pbundle_as_map"; public static final PersistableBundle EMPTY; static final Parcel EMPTY_PARCEL; @@ -88,6 +96,38 @@ public final class PersistableBundle extends CommonBundle { } /** + * Constructs a PersistableBundle containing the mappings passed in. + * + * @param map a Map containing only those items that can be persisted. + * @throws IllegalArgumentException if any element of #map cannot be persisted. + */ + private PersistableBundle(Map<String, Object> map) { + super(); + + // First stuff everything in. + putAll(map); + + // Now verify each item throwing an exception if there is a violation. + Set<String> keys = map.keySet(); + Iterator<String> iterator = keys.iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + Object value = map.get(key); + if (value instanceof Map) { + // Fix up any Maps by replacing them with PersistableBundles. + putPersistableBundle(key, new PersistableBundle((Map<String, Object>) value)); + } else if (!(value instanceof Integer) && !(value instanceof Long) && + !(value instanceof Double) && !(value instanceof String) && + !(value instanceof int[]) && !(value instanceof long[]) && + !(value instanceof double[]) && !(value instanceof String[]) && + !(value instanceof PersistableBundle) && (value != null)) { + throw new IllegalArgumentException("Bad value in PersistableBundle key=" + key + + " value=" + value); + } + } + } + + /** * Make a PersistableBundle for a single key/value pair. * * @hide @@ -206,6 +246,7 @@ public final class PersistableBundle extends CommonBundle { * * @param bundle a PersistableBundle */ + @Override public void putAll(PersistableBundle bundle) { super.putAll(bundle); } @@ -323,6 +364,7 @@ public final class PersistableBundle extends CommonBundle { * @param key a String, or null * @param value a Bundle object, or null */ + @Override public void putPersistableBundle(String key, PersistableBundle value) { super.putPersistableBundle(key, value); } @@ -539,6 +581,57 @@ public final class PersistableBundle extends CommonBundle { super.readFromParcelInner(parcel); } + /** @hide */ + @Override + public void writeUnknownObject(Object v, String name, XmlSerializer out) + throws XmlPullParserException, IOException { + if (v instanceof PersistableBundle) { + out.startTag(null, TAG_PERSISTABLEMAP); + out.attribute(null, "name", name); + ((PersistableBundle) v).saveToXml(out); + out.endTag(null, TAG_PERSISTABLEMAP); + } else { + throw new XmlPullParserException("Unknown Object o=" + v); + } + } + + /** @hide */ + public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException { + unparcel(); + XmlUtils.writeMapXml(mMap, out, this); + } + + /** @hide */ + static class MyReadMapCallback implements XmlUtils.ReadMapCallback { + @Override + public Object readThisUnknownObjectXml(XmlPullParser in, String tag) + throws XmlPullParserException, IOException { + if (TAG_PERSISTABLEMAP.equals(tag)) { + return restoreFromXml(in); + } + throw new XmlPullParserException("Unknown tag=" + tag); + } + } + + /** + * @hide + */ + public static PersistableBundle restoreFromXml(XmlPullParser in) throws IOException, + XmlPullParserException { + final int outerDepth = in.getDepth(); + final String startTag = in.getName(); + final String[] tagName = new String[1]; + int event; + while (((event = in.next()) != XmlPullParser.END_DOCUMENT) && + (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) { + if (event == XmlPullParser.START_TAG) { + return new PersistableBundle((Map<String, Object>) + XmlUtils.readThisMapXml(in, startTag, tagName, new MyReadMapCallback())); + } + } + return EMPTY; + } + @Override synchronized public String toString() { if (mParcelledData != null) { diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java index c1d4d4c..cb0f142 100644 --- a/core/java/android/os/Vibrator.java +++ b/core/java/android/os/Vibrator.java @@ -74,6 +74,7 @@ public abstract class Vibrator { * @param streamHint An {@link AudioManager} stream type corresponding to the vibration type. * For example, specify {@link AudioManager#STREAM_ALARM} for alarm vibrations or * {@link AudioManager#STREAM_RING} for vibrations associated with incoming calls. + * @hide */ public void vibrate(long milliseconds, int streamHint) { vibrate(Process.myUid(), mPackageName, milliseconds, streamHint); @@ -125,6 +126,7 @@ public abstract class Vibrator { * @param streamHint An {@link AudioManager} stream type corresponding to the vibration type. * For example, specify {@link AudioManager#STREAM_ALARM} for alarm vibrations or * {@link AudioManager#STREAM_RING} for vibrations associated with incoming calls. + * @hide */ public void vibrate(long[] pattern, int repeat, int streamHint) { vibrate(Process.myUid(), mPackageName, pattern, repeat, streamHint); diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index d2d6ade..5e005d0 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -37,20 +37,22 @@ import android.widget.SeekBar.OnSeekBarChangeListener; * @hide */ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callback { + private static final String TAG = "SeekBarVolumizer"; public interface Callback { void onSampleStarting(SeekBarVolumizer sbv); } - private Context mContext; - private Handler mHandler; + private final Context mContext; + private final Handler mHandler; private final Callback mCallback; + private final Uri mDefaultUri; + private final AudioManager mAudioManager; + private final int mStreamType; + private final int mMaxStreamVolume; - private AudioManager mAudioManager; - private int mStreamType; private int mOriginalStreamVolume; private Ringtone mRingtone; - private int mLastProgress = -1; private SeekBar mSeekBar; private int mVolumeBeforeMute = -1; @@ -58,9 +60,10 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba private static final int MSG_SET_STREAM_VOLUME = 0; private static final int MSG_START_SAMPLE = 1; private static final int MSG_STOP_SAMPLE = 2; + private static final int MSG_INIT_SAMPLE = 3; private static final int CHECK_RINGTONE_PLAYBACK_DELAY_MS = 1000; - private ContentObserver mVolumeObserver = new ContentObserver(mHandler) { + private ContentObserver mVolumeObserver = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); @@ -71,27 +74,17 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } }; - public SeekBarVolumizer(Context context, SeekBar seekBar, int streamType, Uri defaultUri, + public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) { mContext = context; mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mStreamType = streamType; - mSeekBar = seekBar; - - HandlerThread thread = new HandlerThread(VolumePreference.TAG + ".CallbackHandler"); + mMaxStreamVolume = mAudioManager.getStreamMaxVolume(mStreamType); + HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler"); thread.start(); mHandler = new Handler(thread.getLooper(), this); mCallback = callback; - - initSeekBar(seekBar, defaultUri); - } - - private void initSeekBar(SeekBar seekBar, Uri defaultUri) { - seekBar.setMax(mAudioManager.getStreamMaxVolume(mStreamType)); mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType); - seekBar.setProgress(mOriginalStreamVolume); - seekBar.setOnSeekBarChangeListener(this); - mContext.getContentResolver().registerContentObserver( System.getUriFor(System.VOLUME_SETTINGS[mStreamType]), false, mVolumeObserver); @@ -105,12 +98,16 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba defaultUri = Settings.System.DEFAULT_ALARM_ALERT_URI; } } + mDefaultUri = defaultUri; + mHandler.sendEmptyMessage(MSG_INIT_SAMPLE); + } - mRingtone = RingtoneManager.getRingtone(mContext, defaultUri); - - if (mRingtone != null) { - mRingtone.setStreamType(mStreamType); - } + public void setSeekBar(SeekBar seekBar) { + mSeekBar = seekBar; + mSeekBar.setOnSeekBarChangeListener(null); + mSeekBar.setMax(mMaxStreamVolume); + mSeekBar.setProgress(mLastProgress > -1 ? mLastProgress : mOriginalStreamVolume); + mSeekBar.setOnSeekBarChangeListener(this); } @Override @@ -125,12 +122,22 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba case MSG_STOP_SAMPLE: onStopSample(); break; + case MSG_INIT_SAMPLE: + onInitSample(); + break; default: - Log.e(VolumePreference.TAG, "invalid SeekBarVolumizer message: "+msg.what); + Log.e(TAG, "invalid SeekBarVolumizer message: "+msg.what); } return true; } + private void onInitSample() { + mRingtone = RingtoneManager.getRingtone(mContext, mDefaultUri); + if (mRingtone != null) { + mRingtone.setStreamType(mStreamType); + } + } + private void postStartSample() { mHandler.removeMessages(MSG_START_SAMPLE); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_SAMPLE), diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index 171e5c3..df9e10e 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -66,7 +66,8 @@ public class VolumePreference extends SeekBarDialogPreference implements super.onBindDialogView(view); final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); - mSeekBarVolumizer = new SeekBarVolumizer(getContext(), seekBar, mStreamType, null, this); + mSeekBarVolumizer = new SeekBarVolumizer(getContext(), mStreamType, null, this); + mSeekBarVolumizer.setSeekBar(seekBar); getPreferenceManager().registerOnActivityStopListener(this); diff --git a/core/java/android/provider/TvContract.java b/core/java/android/provider/TvContract.java index 5ffffb5..e4f93a8 100644 --- a/core/java/android/provider/TvContract.java +++ b/core/java/android/provider/TvContract.java @@ -462,7 +462,7 @@ public final class TvContract { * <p> * A value of 1 indicates the channel is included in the channel list that applications use * to browse channels, a value of 0 indicates the channel is not included in the list. If - * not specified, this value is set to 1 by default. + * not specified, this value is set to 1 (browsable) by default. * </p><p> * Type: INTEGER (boolean) * </p> @@ -470,6 +470,36 @@ public final class TvContract { public static final String COLUMN_BROWSABLE = "browsable"; /** + * The flag indicating whether this TV channel is searchable or not. + * <p> + * In some regions, it is not allowed to surface search results for a given channel without + * broadcaster's consent. This is used to impose such restriction. A value of 1 indicates + * the channel is searchable and can be included in search results, a value of 0 indicates + * the channel and its TV programs are hidden from search. If not specified, this value is + * set to 1 (searchable) by default. + * </p> + * <p> + * Type: INTEGER (boolean) + * </p> + */ + public static final String COLUMN_SEARCHABLE = "searchable"; + + /** + * The flag indicating whether this TV channel is locked or not. + * <p> + * This is primarily used for alternative parental control to prevent unauthorized users + * from watching the current channel regardless of the content rating. A value of 1 + * indicates the channel is locked and the user is required to enter passcode to unlock it + * in order to watch the current program from the channel, a value of 0 indicates the + * channel is not locked thus the user is not prompted to enter passcode If not specified, + * this value is set to 0 (not locked) by default. + * </p><p> + * Type: INTEGER (boolean) + * </p> + */ + public static final String COLUMN_LOCKED = "locked"; + + /** * Generic data used by individual TV input services. * <p> * Type: BLOB @@ -544,6 +574,33 @@ public final class TvContract { public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis"; /** + * The comma-separated genre string of this TV program. + * <p> + * Use the same language appeared in the underlying broadcast standard, if applicable. (For + * example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or + * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, use one of the + * following genres: + * <ul> + * <li>Family/Kids</li> + * <li>Sports</li> + * <li>Shopping</li> + * <li>Movies</li> + * <li>Comedy</li> + * <li>Travel</li> + * <li>Drama</li> + * <li>Education</li> + * <li>Animal/Wildlife</li> + * <li>News</li> + * <li>Gaming</li> + * <li>Others</li> + * </ul> + * </p><p> + * Type: TEXT + * </p> + */ + public static final String COLUMN_GENRE = "genre"; + + /** * The description of this TV program that is displayed to the user by default. * <p> * The maximum length of this field is 256 characters. @@ -566,6 +623,17 @@ public final class TvContract { public static final String COLUMN_LONG_DESCRIPTION = "long_description"; /** + * The comma-separated audio languages of this TV program. + * <p> + * This is used to describe available audio languages included in the program. Use + * 3-character language code as specified by ISO 639-2. + * </p><p> + * Type: TEXT + * </p> + */ + public static final String COLUMN_AUDIO_LANGUAGE = "audio_language"; + + /** * Generic data used by TV input services. * <p> * Type: BLOB diff --git a/core/java/android/tv/ITvInputHardware.aidl b/core/java/android/tv/ITvInputHardware.aidl new file mode 100644 index 0000000..7250453 --- /dev/null +++ b/core/java/android/tv/ITvInputHardware.aidl @@ -0,0 +1,46 @@ +/* + * 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. + */ + +package android.tv; + +import android.tv.TvStreamConfig; +import android.view.KeyEvent; +import android.view.Surface; + +/** + * TvInputService representing a physical port should connect to HAL through this interface. + * Framework will take care of communication among system services including TvInputManagerService, + * HdmiControlService, AudioService, etc. + * + * @hide + */ +interface ITvInputHardware { + /** + * Make the input render on the surface according to the config. In case of HDMI, this will + * trigger CEC commands for adjusting active HDMI source. Returns true on success. + */ + boolean setSurface(in Surface surface, in TvStreamConfig config); + /** + * Set volume for this stream via AudioGain. (TBD) + */ + void setVolume(float volume); + + /** + * Dispatch key event to HDMI service. The events would be automatically converted to + * HDMI CEC commands. If the hardware is not representing an HDMI port, this method will fail. + */ + boolean dispatchKeyEventToHdmi(in KeyEvent event); +} diff --git a/core/java/android/tv/ITvInputHardwareCallback.aidl b/core/java/android/tv/ITvInputHardwareCallback.aidl new file mode 100644 index 0000000..83041be --- /dev/null +++ b/core/java/android/tv/ITvInputHardwareCallback.aidl @@ -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. + */ + +package android.tv; + +import android.tv.TvStreamConfig; + +/** + * @hide + */ +oneway interface ITvInputHardwareCallback { + void onReleased(); + void onStreamConfigChanged(in TvStreamConfig[] configs); +} diff --git a/core/java/android/tv/ITvInputManager.aidl b/core/java/android/tv/ITvInputManager.aidl index b756aba..c6f8d79 100644 --- a/core/java/android/tv/ITvInputManager.aidl +++ b/core/java/android/tv/ITvInputManager.aidl @@ -19,7 +19,10 @@ package android.tv; import android.content.ComponentName; import android.graphics.Rect; import android.net.Uri; +import android.tv.ITvInputHardware; +import android.tv.ITvInputHardwareCallback; import android.tv.ITvInputClient; +import android.tv.TvInputHardwareInfo; import android.tv.TvInputInfo; import android.view.Surface; @@ -46,4 +49,10 @@ interface ITvInputManager { int userId); void relayoutOverlayView(in IBinder sessionToken, in Rect frame, int userId); void removeOverlayView(in IBinder sessionToken, int userId); + + // For TV input hardware binding + List<TvInputHardwareInfo> getHardwareList(); + ITvInputHardware acquireTvInputHardware(int deviceId, in ITvInputHardwareCallback callback, + int userId); + void releaseTvInputHardware(int deviceId, in ITvInputHardware hardware, int userId); } diff --git a/core/java/android/tv/TvInputHardwareInfo.aidl b/core/java/android/tv/TvInputHardwareInfo.aidl new file mode 100644 index 0000000..484ab60 --- /dev/null +++ b/core/java/android/tv/TvInputHardwareInfo.aidl @@ -0,0 +1,20 @@ +/* + * + * Copyright 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. + */ + +package android.tv; + +parcelable TvInputHardwareInfo; diff --git a/core/java/android/tv/TvInputHardwareInfo.java b/core/java/android/tv/TvInputHardwareInfo.java new file mode 100644 index 0000000..b0dc58e --- /dev/null +++ b/core/java/android/tv/TvInputHardwareInfo.java @@ -0,0 +1,93 @@ +/* + * 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. + */ + +package android.tv; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * Simple container for information about TV input hardware. + * Not for third-party developers. + * + * @hide + */ +public final class TvInputHardwareInfo implements Parcelable { + static final String TAG = "TvInputHardwareInfo"; + + // Match hardware/libhardware/include/hardware/tv_input.h + public static final int TV_INPUT_TYPE_HDMI = 1; + public static final int TV_INPUT_TYPE_BUILT_IN_TUNER = 2; + public static final int TV_INPUT_TYPE_PASSTHROUGH = 3; + + public static final Parcelable.Creator<TvInputHardwareInfo> CREATOR = + new Parcelable.Creator<TvInputHardwareInfo>() { + @Override + public TvInputHardwareInfo createFromParcel(Parcel source) { + try { + TvInputHardwareInfo info = new TvInputHardwareInfo(); + info.readFromParcel(source); + return info; + } catch (Exception e) { + Log.e(TAG, "Exception creating TvInputHardwareInfo from parcel", e); + return null; + } + } + + @Override + public TvInputHardwareInfo[] newArray(int size) { + return new TvInputHardwareInfo[size]; + } + }; + + private int mDeviceId; + private int mType; + // TODO: Add audio port & audio address for audio service. + // TODO: Add HDMI handle for HDMI service. + + public TvInputHardwareInfo() { } + + public TvInputHardwareInfo(int deviceId, int type) { + mDeviceId = deviceId; + mType = type; + } + + public int getDeviceId() { + return mDeviceId; + } + + public int getType() { + return mType; + } + + // Parcelable + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mDeviceId); + dest.writeInt(mType); + } + + public void readFromParcel(Parcel source) { + mDeviceId = source.readInt(); + mType = source.readInt(); + } +} diff --git a/core/java/android/tv/TvStreamConfig.aidl b/core/java/android/tv/TvStreamConfig.aidl new file mode 100644 index 0000000..4d0add4 --- /dev/null +++ b/core/java/android/tv/TvStreamConfig.aidl @@ -0,0 +1,20 @@ +/* + * + * Copyright 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. + */ + +package android.tv; + +parcelable TvStreamConfig;
\ No newline at end of file diff --git a/core/java/android/tv/TvStreamConfig.java b/core/java/android/tv/TvStreamConfig.java new file mode 100644 index 0000000..03e63b1 --- /dev/null +++ b/core/java/android/tv/TvStreamConfig.java @@ -0,0 +1,157 @@ +/* + * 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. + */ + +package android.tv; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * @hide + */ +public class TvStreamConfig implements Parcelable { + static final String TAG = TvStreamConfig.class.getSimpleName(); + + public final static int STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE = 1; + public final static int STREAM_TYPE_BUFFER_PRODUCER = 2; + + private int mStreamId; + private int mType; + // TODO: Revisit if max widht/height really make sense. + private int mMaxWidth; + private int mMaxHeight; + /** + * Generations are incremented once framework receives STREAM_CONFIGURATION_CHANGED event from + * HAL module. Framework should throw away outdated configurations and get new configurations + * via tv_input_device::get_stream_configurations(). + */ + private int mGeneration; + + public static final Parcelable.Creator<TvStreamConfig> CREATOR = + new Parcelable.Creator<TvStreamConfig>() { + @Override + public TvStreamConfig createFromParcel(Parcel source) { + try { + return new Builder(). + streamId(source.readInt()). + type(source.readInt()). + maxWidth(source.readInt()). + maxHeight(source.readInt()). + generation(source.readInt()).build(); + } catch (Exception e) { + Log.e(TAG, "Exception creating TvStreamConfig from parcel", e); + return null; + } + } + + @Override + public TvStreamConfig[] newArray(int size) { + return new TvStreamConfig[size]; + } + }; + + private TvStreamConfig() {} + + public int getStreamId() { + return mStreamId; + } + + public int getType() { + return mType; + } + + public int getMaxWidth() { + return mMaxWidth; + } + + public int getMaxHeight() { + return mMaxHeight; + } + + public int getGeneration() { + return mGeneration; + } + + // Parcelable + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mStreamId); + dest.writeInt(mType); + dest.writeInt(mMaxWidth); + dest.writeInt(mMaxHeight); + dest.writeInt(mGeneration); + } + + /** + * A helper class for creating a TvStreamConfig object. + */ + public static final class Builder { + private Integer mStreamId; + private Integer mType; + private Integer mMaxWidth; + private Integer mMaxHeight; + private Integer mGeneration; + + public Builder() { + } + + public Builder streamId(int streamId) { + mStreamId = streamId; + return this; + } + + public Builder type(int type) { + mType = type; + return this; + } + + public Builder maxWidth(int maxWidth) { + mMaxWidth = maxWidth; + return this; + } + + public Builder maxHeight(int maxHeight) { + mMaxHeight = maxHeight; + return this; + } + + public Builder generation(int generation) { + mGeneration = generation; + return this; + } + + public TvStreamConfig build() { + if (mStreamId == null || mType == null || mMaxWidth == null || mMaxHeight == null + || mGeneration == null) { + throw new UnsupportedOperationException(); + } + + TvStreamConfig config = new TvStreamConfig(); + config.mStreamId = mStreamId; + config.mType = mType; + config.mMaxWidth = mMaxWidth; + config.mMaxHeight = mMaxHeight; + config.mGeneration = mGeneration; + return config; + } + } +}
\ No newline at end of file diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index a272296..424d860 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -41,10 +41,6 @@ import android.text.TextUtils; * An implementation of Canvas on top of OpenGL ES 2.0. */ class GLES20Canvas extends HardwareCanvas { - // Must match modifiers used in the JNI layer - private static final int MODIFIER_NONE = 0; - private static final int MODIFIER_SHADER = 2; - private final boolean mOpaque; protected long mRenderer; @@ -650,13 +646,8 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) { - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom, - startAngle, sweepAngle, useCenter, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom, + startAngle, sweepAngle, useCenter, paint.mNativePaint); } private static native void nDrawArc(long renderer, float left, float top, @@ -672,7 +663,6 @@ class GLES20Canvas extends HardwareCanvas { public void drawPatch(NinePatch patch, Rect dst, Paint paint) { Bitmap bitmap = patch.getBitmap(); throwIfCannotDraw(bitmap); - // Shaders are ignored when drawing patches final long nativePaint = paint == null ? 0 : paint.mNativePaint; nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); @@ -682,7 +672,6 @@ class GLES20Canvas extends HardwareCanvas { public void drawPatch(NinePatch patch, RectF dst, Paint paint) { Bitmap bitmap = patch.getBitmap(); throwIfCannotDraw(bitmap); - // Shaders are ignored when drawing patches final long nativePaint = paint == null ? 0 : paint.mNativePaint; nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); @@ -694,14 +683,8 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { throwIfCannotDraw(bitmap); - // Shaders are ignored when drawing bitmaps - int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; - try { - final long nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + final long nativePaint = paint == null ? 0 : paint.mNativePaint; + nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint); } private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer, @@ -710,15 +693,9 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { throwIfCannotDraw(bitmap); - // Shaders are ignored when drawing bitmaps - int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; - try { - final long nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, - matrix.native_instance, nativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + final long nativePaint = paint == null ? 0 : paint.mNativePaint; + nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, + matrix.native_instance, nativePaint); } private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer, @@ -727,55 +704,43 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { throwIfCannotDraw(bitmap); - // Shaders are ignored when drawing bitmaps - int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; - try { - final long nativePaint = paint == null ? 0 : paint.mNativePaint; - - int left, top, right, bottom; - if (src == null) { - left = top = 0; - right = bitmap.getWidth(); - bottom = bitmap.getHeight(); - } else { - left = src.left; - right = src.right; - top = src.top; - bottom = src.bottom; - } + final long nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom, - dst.left, dst.top, dst.right, dst.bottom, nativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); + int left, top, right, bottom; + if (src == null) { + left = top = 0; + right = bitmap.getWidth(); + bottom = bitmap.getHeight(); + } else { + left = src.left; + right = src.right; + top = src.top; + bottom = src.bottom; } + + nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom, + dst.left, dst.top, dst.right, dst.bottom, nativePaint); } @Override public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { throwIfCannotDraw(bitmap); - // Shaders are ignored when drawing bitmaps - int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; - try { - final long nativePaint = paint == null ? 0 : paint.mNativePaint; - - float left, top, right, bottom; - if (src == null) { - left = top = 0; - right = bitmap.getWidth(); - bottom = bitmap.getHeight(); - } else { - left = src.left; - right = src.right; - top = src.top; - bottom = src.bottom; - } - - nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom, - dst.left, dst.top, dst.right, dst.bottom, nativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); + final long nativePaint = paint == null ? 0 : paint.mNativePaint; + + float left, top, right, bottom; + if (src == null) { + left = top = 0; + right = bitmap.getWidth(); + bottom = bitmap.getHeight(); + } else { + left = src.left; + right = src.right; + top = src.top; + bottom = src.bottom; } + + nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom, + dst.left, dst.top, dst.right, dst.bottom, nativePaint); } private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer, @@ -805,7 +770,6 @@ class GLES20Canvas extends HardwareCanvas { throw new ArrayIndexOutOfBoundsException(); } - // Shaders are ignored when drawing bitmaps final long nativePaint = paint == null ? 0 : paint.mNativePaint; nDrawBitmap(mRenderer, colors, offset, stride, x, y, width, height, hasAlpha, nativePaint); @@ -817,7 +781,6 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width, int height, boolean hasAlpha, Paint paint) { - // Shaders are ignored when drawing bitmaps drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, hasAlpha, paint); } @@ -840,14 +803,9 @@ class GLES20Canvas extends HardwareCanvas { checkRange(colors.length, colorOffset, count); } - int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; - try { - final long nativePaint = paint == null ? 0 : paint.mNativePaint; - nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight, - verts, vertOffset, colors, colorOffset, nativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + final long nativePaint = paint == null ? 0 : paint.mNativePaint; + nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight, + verts, vertOffset, colors, colorOffset, nativePaint); } private static native void nDrawBitmapMesh(long renderer, long bitmap, byte[] buffer, @@ -856,12 +814,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawCircle(float cx, float cy, float radius, Paint paint) { - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint); } private static native void nDrawCircle(long renderer, float cx, float cy, @@ -906,12 +859,7 @@ class GLES20Canvas extends HardwareCanvas { if ((offset | count) < 0 || offset + count > pts.length) { throw new IllegalArgumentException("The lines array must contain 4 elements per line."); } - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint); } private static native void nDrawLines(long renderer, float[] points, @@ -924,12 +872,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawOval(RectF oval, Paint paint) { - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint); } private static native void nDrawOval(long renderer, float left, float top, @@ -944,17 +887,12 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawPath(Path path, Paint paint) { - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - if (path.isSimplePath) { - if (path.rects != null) { - nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint); - } - } else { - nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint); + if (path.isSimplePath) { + if (path.rects != null) { + nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint); } - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); + } else { + nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint); } } @@ -962,12 +900,7 @@ class GLES20Canvas extends HardwareCanvas { private static native void nDrawRects(long renderer, long region, long paint); void drawRects(float[] rects, int count, Paint paint) { - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - nDrawRects(mRenderer, rects, count, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawRects(mRenderer, rects, count, paint.mNativePaint); } private static native void nDrawRects(long renderer, float[] rects, int count, long paint); @@ -1029,12 +962,7 @@ class GLES20Canvas extends HardwareCanvas { public void drawPoints(float[] pts, int offset, int count, Paint paint) { if (count < 2) return; - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint); } private static native void nDrawPoints(long renderer, float[] points, @@ -1047,12 +975,7 @@ class GLES20Canvas extends HardwareCanvas { throw new IndexOutOfBoundsException(); } - int modifiers = setupModifiers(paint); - try { - nDrawPosText(mRenderer, text, index, count, pos, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawPosText(mRenderer, text, index, count, pos, paint.mNativePaint); } private static native void nDrawPosText(long renderer, char[] text, int index, int count, @@ -1065,12 +988,7 @@ class GLES20Canvas extends HardwareCanvas { throw new ArrayIndexOutOfBoundsException(); } - int modifiers = setupModifiers(paint); - try { - nDrawPosText(mRenderer, text, 0, text.length(), pos, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawPosText(mRenderer, text, 0, text.length(), pos, paint.mNativePaint); } private static native void nDrawPosText(long renderer, String text, int start, int end, @@ -1079,12 +997,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawRect(float left, float top, float right, float bottom, Paint paint) { if (left == right || top == bottom) return; - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint); } private static native void nDrawRect(long renderer, float left, float top, @@ -1108,12 +1021,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) { - int modifiers = setupModifiers(paint, MODIFIER_SHADER); - try { - nDrawRoundRect(mRenderer, left, top, right, bottom, rx, ry, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawRoundRect(mRenderer, left, top, right, bottom, rx, ry, paint.mNativePaint); } private static native void nDrawRoundRect(long renderer, float left, float top, @@ -1125,13 +1033,8 @@ class GLES20Canvas extends HardwareCanvas { throw new IndexOutOfBoundsException(); } - int modifiers = setupModifiers(paint); - try { - nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint, - paint.mNativeTypeface); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawText(mRenderer, text, index, count, x, y, + paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); } private static native void nDrawText(long renderer, char[] text, int index, int count, @@ -1139,24 +1042,18 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { - int modifiers = setupModifiers(paint); - try { - if (text instanceof String || text instanceof SpannedString || - text instanceof SpannableString) { - nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags, - paint.mNativePaint, paint.mNativeTypeface); - } else if (text instanceof GraphicsOperations) { - ((GraphicsOperations) text).drawText(this, start, end, x, y, - paint); - } else { - char[] buf = TemporaryBuffer.obtain(end - start); - TextUtils.getChars(text, start, end, buf, 0); - nDrawText(mRenderer, buf, 0, end - start, x, y, - paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); - TemporaryBuffer.recycle(buf); - } - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); + if (text instanceof String || text instanceof SpannedString || + text instanceof SpannableString) { + nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags, + paint.mNativePaint, paint.mNativeTypeface); + } else if (text instanceof GraphicsOperations) { + ((GraphicsOperations) text).drawText(this, start, end, x, y, paint); + } else { + char[] buf = TemporaryBuffer.obtain(end - start); + TextUtils.getChars(text, start, end, buf, 0); + nDrawText(mRenderer, buf, 0, end - start, x, y, + paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); + TemporaryBuffer.recycle(buf); } } @@ -1166,13 +1063,8 @@ class GLES20Canvas extends HardwareCanvas { throw new IndexOutOfBoundsException(); } - int modifiers = setupModifiers(paint); - try { - nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint, - paint.mNativeTypeface); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawText(mRenderer, text, start, end, x, y, + paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); } private static native void nDrawText(long renderer, String text, int start, int end, @@ -1180,13 +1072,8 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawText(String text, float x, float y, Paint paint) { - int modifiers = setupModifiers(paint); - try { - nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, - paint.mNativePaint, paint.mNativeTypeface); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawText(mRenderer, text, 0, text.length(), x, y, + paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface); } @Override @@ -1196,13 +1083,8 @@ class GLES20Canvas extends HardwareCanvas { throw new ArrayIndexOutOfBoundsException(); } - int modifiers = setupModifiers(paint); - try { - nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset, - paint.mBidiFlags, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset, + paint.mBidiFlags, paint.mNativePaint); } private static native void nDrawTextOnPath(long renderer, char[] text, int index, int count, @@ -1212,13 +1094,8 @@ class GLES20Canvas extends HardwareCanvas { public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { if (text.length() == 0) return; - int modifiers = setupModifiers(paint); - try { - nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset, - paint.mBidiFlags, paint.mNativePaint); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset, + paint.mBidiFlags, paint.mNativePaint); } private static native void nDrawTextOnPath(long renderer, String text, int start, int end, @@ -1234,13 +1111,8 @@ class GLES20Canvas extends HardwareCanvas { throw new IllegalArgumentException("Unknown direction: " + dir); } - int modifiers = setupModifiers(paint); - try { - nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir, - paint.mNativePaint, paint.mNativeTypeface); - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); - } + nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir, + paint.mNativePaint, paint.mNativeTypeface); } private static native void nDrawTextRun(long renderer, char[] text, int index, int count, @@ -1253,27 +1125,22 @@ class GLES20Canvas extends HardwareCanvas { throw new IndexOutOfBoundsException(); } - int modifiers = setupModifiers(paint); - try { - int flags = dir == 0 ? 0 : 1; - if (text instanceof String || text instanceof SpannedString || - text instanceof SpannableString) { - nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, - contextEnd, x, y, flags, paint.mNativePaint, paint.mNativeTypeface); - } else if (text instanceof GraphicsOperations) { - ((GraphicsOperations) text).drawTextRun(this, start, end, - contextStart, contextEnd, x, y, flags, paint); - } else { - int contextLen = contextEnd - contextStart; - int len = end - start; - char[] buf = TemporaryBuffer.obtain(contextLen); - TextUtils.getChars(text, contextStart, contextEnd, buf, 0); - nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, - x, y, flags, paint.mNativePaint, paint.mNativeTypeface); - TemporaryBuffer.recycle(buf); - } - } finally { - if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); + int flags = dir == 0 ? 0 : 1; + if (text instanceof String || text instanceof SpannedString || + text instanceof SpannableString) { + nDrawTextRun(mRenderer, text.toString(), start, end, contextStart, + contextEnd, x, y, flags, paint.mNativePaint, paint.mNativeTypeface); + } else if (text instanceof GraphicsOperations) { + ((GraphicsOperations) text).drawTextRun(this, start, end, + contextStart, contextEnd, x, y, flags, paint); + } else { + int contextLen = contextEnd - contextStart; + int len = end - start; + char[] buf = TemporaryBuffer.obtain(contextLen); + TextUtils.getChars(text, contextStart, contextEnd, buf, 0); + nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen, + x, y, flags, paint.mNativePaint, paint.mNativeTypeface); + TemporaryBuffer.recycle(buf); } } @@ -1286,40 +1153,4 @@ class GLES20Canvas extends HardwareCanvas { int indexOffset, int indexCount, Paint paint) { // TODO: Implement } - - private int setupModifiers(Bitmap b, Paint paint) { - if (b.getConfig() != Bitmap.Config.ALPHA_8) { - return MODIFIER_NONE; - } else { - return setupModifiers(paint); - } - } - - private int setupModifiers(Paint paint) { - int modifiers = MODIFIER_NONE; - - final Shader shader = paint.getShader(); - if (shader != null) { - nSetupShader(mRenderer, shader.native_shader); - modifiers |= MODIFIER_SHADER; - } - - return modifiers; - } - - private int setupModifiers(Paint paint, int flags) { - int modifiers = MODIFIER_NONE; - - final Shader shader = paint.getShader(); - if (shader != null && (flags & MODIFIER_SHADER) != 0) { - nSetupShader(mRenderer, shader.native_shader); - modifiers |= MODIFIER_SHADER; - } - - return modifiers; - } - - private static native void nSetupShader(long renderer, long shader); - - private static native void nResetModifiers(long renderer, int modifiers); } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index a902ce7..3c4d83f 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -579,6 +579,12 @@ public abstract class HardwareRenderer { abstract void fence(); /** + * Called by {@link ViewRootImpl} when a new performTraverals is scheduled. + */ + public void notifyFramePending() { + } + + /** * Describes a series of frames that should be drawn on screen as a graph. * Each frame is composed of 1 or more elements. */ diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 704d516..8417887 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -291,6 +291,11 @@ public class ThreadedRenderer extends HardwareRenderer { } @Override + public void notifyFramePending() { + nNotifyFramePending(mNativeProxy); + } + + @Override protected void finalize() throws Throwable { try { nDeleteProxy(mNativeProxy); @@ -364,4 +369,5 @@ public class ThreadedRenderer extends HardwareRenderer { private static native void nDestroyLayer(long nativeProxy, long layer); private static native void nFence(long nativeProxy); + private static native void nNotifyFramePending(long nativeProxy); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 799a406..fc7bf0e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -999,6 +999,17 @@ public final class ViewRootImpl implements ViewParent, } } + /** + * Notifies the HardwareRenderer that a new frame will be coming soon. + * Currently only {@link ThreadedRenderer} cares about this, and uses + * this knowledge to adjust the scheduling of off-thread animations + */ + void notifyRendererOfFramePending() { + if (mAttachInfo.mHardwareRenderer != null) { + mAttachInfo.mHardwareRenderer.notifyFramePending(); + } + } + void scheduleTraversals() { if (!mTraversalScheduled) { mTraversalScheduled = true; @@ -1006,6 +1017,7 @@ public final class ViewRootImpl implements ViewParent, mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); scheduleConsumeBatchedInput(); + notifyRendererOfFramePending(); } } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 4fde1e4..1bb20c9 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -1144,6 +1144,12 @@ public interface WindowManagerPolicy { public void setLastInputMethodWindowLw(WindowState ime, WindowState target); /** + * Show the recents task list app. + * @hide + */ + public void showRecentApps(); + + /** * @return The current height of the input method window. */ public int getInputMethodWindowVisibleHeightLw(); diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 1152e17..43f623b 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -256,6 +256,16 @@ public abstract class AbsSeekBar extends ProgressBar { } @Override + public void invalidateDrawable(Drawable dr) { + super.invalidateDrawable(dr); + + if (dr == mThumb) { + // Handle changes to thumb width and height. + requestLayout(); + } + } + + @Override void onProgressRefresh(float scale, boolean fromUser) { super.onProgressRefresh(scale, fromUser); diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index 1533510..3ae9508 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -24,6 +24,7 @@ import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.Gravity; +import android.view.RemotableViewMethod; import android.view.ViewDebug; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; @@ -156,10 +157,36 @@ public class CheckedTextView extends TextView implements Checkable { mCheckMarkWidth = 0; } mCheckMarkDrawable = d; - // Do padding resolution. This will call internalSetPadding() and do a requestLayout() if needed. + + // Do padding resolution. This will call internalSetPadding() and do a + // requestLayout() if needed. resolvePadding(); } + @RemotableViewMethod + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); + + if (mCheckMarkDrawable != null) { + mCheckMarkDrawable.setVisible(visibility == VISIBLE, false); + } + } + + @Override + public void jumpDrawablesToCurrentState() { + super.jumpDrawablesToCurrentState(); + + if (mCheckMarkDrawable != null) { + mCheckMarkDrawable.jumpToCurrentState(); + } + } + + @Override + protected boolean verifyDrawable(Drawable who) { + return who == mCheckMarkDrawable || super.verifyDrawable(who); + } + /** * Gets the checkmark drawable * @@ -249,6 +276,11 @@ public class CheckedTextView extends TextView implements Checkable { } checkMarkDrawable.setBounds(mScrollX + left, top, mScrollX + right, bottom); checkMarkDrawable.draw(canvas); + + final Drawable background = getBackground(); + if (background != null) { + background.setHotspotBounds(mScrollX + left, top, mScrollX + right, bottom); + } } } diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index ad1a023..c5c6e64 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -951,9 +951,8 @@ public class Switch extends CompoundButton { final int[] myDrawableState = getDrawableState(); - if (mThumbDrawable != null && mThumbDrawable.setState(myDrawableState)) { - // Handle changes to thumb width and height. - requestLayout(); + if (mThumbDrawable != null) { + mThumbDrawable.setState(myDrawableState); } if (mTrackDrawable != null) { @@ -964,6 +963,16 @@ public class Switch extends CompoundButton { } @Override + public void invalidateDrawable(Drawable drawable) { + super.invalidateDrawable(drawable); + + if (drawable == mThumbDrawable) { + // Handle changes to thumb width and height. + requestLayout(); + } + } + + @Override protected boolean verifyDrawable(Drawable who) { return super.verifyDrawable(who) || who == mThumbDrawable || who == mTrackDrawable; } diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java index 664f9db..5547a10 100644 --- a/core/java/com/android/internal/app/AlertController.java +++ b/core/java/com/android/internal/app/AlertController.java @@ -1026,7 +1026,7 @@ public class AlertController { ? dialog.mSingleChoiceItemLayout : dialog.mListItemLayout; if (mCursor == null) { adapter = (mAdapter != null) ? mAdapter - : new ArrayAdapter<CharSequence>(mContext, layout, R.id.text1, mItems); + : new CheckedItemAdapter(mContext, layout, R.id.text1, mItems); } else { adapter = new SimpleCursorAdapter(mContext, layout, mCursor, new String[]{mLabelColumn}, new int[]{R.id.text1}); @@ -1081,4 +1081,20 @@ public class AlertController { } } + private static class CheckedItemAdapter extends ArrayAdapter<CharSequence> { + public CheckedItemAdapter(Context context, int resource, int textViewResourceId, + CharSequence[] objects) { + super(context, resource, textViewResourceId, objects); + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public long getItemId(int position) { + return position; + } + } } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 24e55e4..ed9f9bc 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -2342,7 +2342,13 @@ public final class BatteryStatsImpl extends BatteryStats { // Only care about partial wake locks, since full wake locks // will be canceled when the user puts the screen to sleep. aggregateLastWakeupUptimeLocked(uptime); - historyName = historyName == null || mRecordAllWakeLocks ? name : historyName; + if (mRecordAllWakeLocks) { + if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, name, uid, 0)) { + addHistoryEventLocked(elapsedRealtime, uptime, + HistoryItem.EVENT_WAKE_LOCK_START, name, uid); + } + } + historyName = historyName == null ? name : historyName; if (mWakeLockNesting == 0) { mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " @@ -2352,7 +2358,7 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; mWakeLockImportant = !unimportantForLogging; addHistoryRecordLocked(elapsedRealtime, uptime); - } else if (!mRecordAllWakeLocks && !mWakeLockImportant && !unimportantForLogging) { + } else if (!mWakeLockImportant && !unimportantForLogging) { if (mHistoryLastWritten.wakelockTag != null) { // We'll try to update the last tag. mHistoryLastWritten.wakelockTag = null; @@ -2362,14 +2368,6 @@ public final class BatteryStatsImpl extends BatteryStats { addHistoryRecordLocked(elapsedRealtime, uptime); } mWakeLockImportant = true; - } else if (mRecordAllWakeLocks) { - if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, - uid, 0)) { - mWakeLockNesting++; - return; - } - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_WAKE_LOCK_START, - historyName, uid); } mWakeLockNesting++; } @@ -2387,28 +2385,19 @@ public final class BatteryStatsImpl extends BatteryStats { uid = mapUid(uid); if (type == WAKE_TYPE_PARTIAL) { mWakeLockNesting--; - historyName = historyName == null || mRecordAllWakeLocks ? name : historyName; + if (mRecordAllWakeLocks) { + if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, name, uid, 0)) { + addHistoryEventLocked(elapsedRealtime, uptime, + HistoryItem.EVENT_WAKE_LOCK_FINISH, name, uid); + } + } if (mWakeLockNesting == 0) { mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " + Integer.toHexString(mHistoryCur.states)); - if (mRecordAllWakeLocks - || (historyName != null && !historyName.equals(mInitialAcquireWakeName)) - || uid != mInitialAcquireWakeUid) { - mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; - mHistoryCur.wakelockTag.string = historyName; - mHistoryCur.wakelockTag.uid = uid; - } mInitialAcquireWakeName = null; mInitialAcquireWakeUid = -1; addHistoryRecordLocked(elapsedRealtime, uptime); - } else if (mRecordAllWakeLocks) { - if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, - uid, 0)) { - return; - } - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_WAKE_LOCK_FINISH, - historyName, uid); } } if (uid >= 0) { diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java index 5b59599..dca9921 100644 --- a/core/java/com/android/internal/util/XmlUtils.java +++ b/core/java/com/android/internal/util/XmlUtils.java @@ -220,28 +220,74 @@ public class XmlUtils { * @see #readMapXml */ public static final void writeMapXml(Map val, String name, XmlSerializer out) - throws XmlPullParserException, java.io.IOException - { + throws XmlPullParserException, java.io.IOException { + writeMapXml(val, name, out, null); + } + + /** + * Flatten a Map into an XmlSerializer. The map can later be read back + * with readThisMapXml(). + * + * @param val The map to be flattened. + * @param name Name attribute to include with this list's tag, or null for + * none. + * @param out XmlSerializer to write the map into. + * @param callback Method to call when an Object type is not recognized. + * + * @see #writeMapXml(Map, OutputStream) + * @see #writeListXml + * @see #writeValueXml + * @see #readMapXml + * + * @hide + */ + public static final void writeMapXml(Map val, String name, XmlSerializer out, + WriteMapCallback callback) throws XmlPullParserException, java.io.IOException { + if (val == null) { out.startTag(null, "null"); out.endTag(null, "null"); return; } - Set s = val.entrySet(); - Iterator i = s.iterator(); - out.startTag(null, "map"); if (name != null) { out.attribute(null, "name", name); } + writeMapXml(val, out, callback); + + out.endTag(null, "map"); + } + + /** + * Flatten a Map into an XmlSerializer. The map can later be read back + * with readThisMapXml(). This method presumes that the start tag and + * name attribute have already been written and does not write an end tag. + * + * @param val The map to be flattened. + * @param out XmlSerializer to write the map into. + * + * @see #writeMapXml(Map, OutputStream) + * @see #writeListXml + * @see #writeValueXml + * @see #readMapXml + * + * @hide + */ + public static final void writeMapXml(Map val, XmlSerializer out, + WriteMapCallback callback) throws XmlPullParserException, java.io.IOException { + if (val == null) { + return; + } + + Set s = val.entrySet(); + Iterator i = s.iterator(); + while (i.hasNext()) { Map.Entry e = (Map.Entry)i.next(); - writeValueXml(e.getValue(), (String)e.getKey(), out); + writeValueXml(e.getValue(), (String)e.getKey(), out, callback); } - - out.endTag(null, "map"); } /** @@ -387,6 +433,123 @@ public class XmlUtils { } /** + * Flatten a long[] into an XmlSerializer. The list can later be read back + * with readThisLongArrayXml(). + * + * @param val The long array to be flattened. + * @param name Name attribute to include with this array's tag, or null for + * none. + * @param out XmlSerializer to write the array into. + * + * @see #writeMapXml + * @see #writeValueXml + * @see #readThisIntArrayXml + */ + public static final void writeLongArrayXml(long[] val, String name, XmlSerializer out) + throws XmlPullParserException, java.io.IOException { + + if (val == null) { + out.startTag(null, "null"); + out.endTag(null, "null"); + return; + } + + out.startTag(null, "long-array"); + if (name != null) { + out.attribute(null, "name", name); + } + + final int N = val.length; + out.attribute(null, "num", Integer.toString(N)); + + for (int i=0; i<N; i++) { + out.startTag(null, "item"); + out.attribute(null, "value", Long.toString(val[i])); + out.endTag(null, "item"); + } + + out.endTag(null, "long-array"); + } + + /** + * Flatten a double[] into an XmlSerializer. The list can later be read back + * with readThisDoubleArrayXml(). + * + * @param val The double array to be flattened. + * @param name Name attribute to include with this array's tag, or null for + * none. + * @param out XmlSerializer to write the array into. + * + * @see #writeMapXml + * @see #writeValueXml + * @see #readThisIntArrayXml + */ + public static final void writeDoubleArrayXml(double[] val, String name, XmlSerializer out) + throws XmlPullParserException, java.io.IOException { + + if (val == null) { + out.startTag(null, "null"); + out.endTag(null, "null"); + return; + } + + out.startTag(null, "double-array"); + if (name != null) { + out.attribute(null, "name", name); + } + + final int N = val.length; + out.attribute(null, "num", Integer.toString(N)); + + for (int i=0; i<N; i++) { + out.startTag(null, "item"); + out.attribute(null, "value", Double.toString(val[i])); + out.endTag(null, "item"); + } + + out.endTag(null, "double-array"); + } + + /** + * Flatten a String[] into an XmlSerializer. The list can later be read back + * with readThisStringArrayXml(). + * + * @param val The long array to be flattened. + * @param name Name attribute to include with this array's tag, or null for + * none. + * @param out XmlSerializer to write the array into. + * + * @see #writeMapXml + * @see #writeValueXml + * @see #readThisIntArrayXml + */ + public static final void writeStringArrayXml(String[] val, String name, XmlSerializer out) + throws XmlPullParserException, java.io.IOException { + + if (val == null) { + out.startTag(null, "null"); + out.endTag(null, "null"); + return; + } + + out.startTag(null, "string-array"); + if (name != null) { + out.attribute(null, "name", name); + } + + final int N = val.length; + out.attribute(null, "num", Integer.toString(N)); + + for (int i=0; i<N; i++) { + out.startTag(null, "item"); + out.attribute(null, "value", val[i]); + out.endTag(null, "item"); + } + + out.endTag(null, "string-array"); + } + + /** * Flatten an object's value into an XmlSerializer. The value can later * be read back with readThisValueXml(). * @@ -403,8 +566,29 @@ public class XmlUtils { * @see #readValueXml */ public static final void writeValueXml(Object v, String name, XmlSerializer out) - throws XmlPullParserException, java.io.IOException - { + throws XmlPullParserException, java.io.IOException { + writeValueXml(v, name, out, null); + } + + /** + * Flatten an object's value into an XmlSerializer. The value can later + * be read back with readThisValueXml(). + * + * Currently supported value types are: null, String, Integer, Long, + * Float, Double Boolean, Map, List. + * + * @param v The object to be flattened. + * @param name Name attribute to include with this value's tag, or null + * for none. + * @param out XmlSerializer to write the object into. + * @param callback Handler for Object types not recognized. + * + * @see #writeMapXml + * @see #writeListXml + * @see #readValueXml + */ + private static final void writeValueXml(Object v, String name, XmlSerializer out, + WriteMapCallback callback) throws XmlPullParserException, java.io.IOException { String typeStr; if (v == null) { out.startTag(null, "null"); @@ -437,14 +621,23 @@ public class XmlUtils { } else if (v instanceof int[]) { writeIntArrayXml((int[])v, name, out); return; + } else if (v instanceof long[]) { + writeLongArrayXml((long[])v, name, out); + return; + } else if (v instanceof double[]) { + writeDoubleArrayXml((double[])v, name, out); + return; + } else if (v instanceof String[]) { + writeStringArrayXml((String[])v, name, out); + return; } else if (v instanceof Map) { writeMapXml((Map)v, name, out); return; } else if (v instanceof List) { - writeListXml((List)v, name, out); + writeListXml((List) v, name, out); return; } else if (v instanceof Set) { - writeSetXml((Set)v, name, out); + writeSetXml((Set) v, name, out); return; } else if (v instanceof CharSequence) { // XXX This is to allow us to at least write something if @@ -457,6 +650,9 @@ public class XmlUtils { out.text(v.toString()); out.endTag(null, "string"); return; + } else if (callback != null) { + callback.writeUnknownObject(v, name, out); + return; } else { throw new RuntimeException("writeValueXml: unable to write value " + v); } @@ -550,14 +746,35 @@ public class XmlUtils { * @see #readMapXml */ public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag, - String[] name) throws XmlPullParserException, java.io.IOException + String[] name) throws XmlPullParserException, java.io.IOException { + return readThisMapXml(parser, endTag, name, null); + } + + /** + * Read a HashMap object from an XmlPullParser. The XML data could + * previously have been generated by writeMapXml(). The XmlPullParser + * must be positioned <em>after</em> the tag that begins the map. + * + * @param parser The XmlPullParser from which to read the map data. + * @param endTag Name of the tag that will end the map, usually "map". + * @param name An array of one string, used to return the name attribute + * of the map's tag. + * + * @return HashMap The newly generated map. + * + * @see #readMapXml + * @hide + */ + public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag, + String[] name, ReadMapCallback callback) + throws XmlPullParserException, java.io.IOException { HashMap<String, Object> map = new HashMap<String, Object>(); int eventType = parser.getEventType(); do { if (eventType == parser.START_TAG) { - Object val = readThisValueXml(parser, name); + Object val = readThisValueXml(parser, name, callback); map.put(name[0], val); } else if (eventType == parser.END_TAG) { if (parser.getName().equals(endTag)) { @@ -587,15 +804,34 @@ public class XmlUtils { * * @see #readListXml */ - public static final ArrayList readThisListXml(XmlPullParser parser, String endTag, String[] name) - throws XmlPullParserException, java.io.IOException - { + public static final ArrayList readThisListXml(XmlPullParser parser, String endTag, + String[] name) throws XmlPullParserException, java.io.IOException { + return readThisListXml(parser, endTag, name, null); + } + + /** + * Read an ArrayList object from an XmlPullParser. The XML data could + * previously have been generated by writeListXml(). The XmlPullParser + * must be positioned <em>after</em> the tag that begins the list. + * + * @param parser The XmlPullParser from which to read the list data. + * @param endTag Name of the tag that will end the list, usually "list". + * @param name An array of one string, used to return the name attribute + * of the list's tag. + * + * @return HashMap The newly generated list. + * + * @see #readListXml + */ + private static final ArrayList readThisListXml(XmlPullParser parser, String endTag, + String[] name, ReadMapCallback callback) + throws XmlPullParserException, java.io.IOException { ArrayList list = new ArrayList(); int eventType = parser.getEventType(); do { if (eventType == parser.START_TAG) { - Object val = readThisValueXml(parser, name); + Object val = readThisValueXml(parser, name, callback); list.add(val); //System.out.println("Adding to list: " + val); } else if (eventType == parser.END_TAG) { @@ -611,7 +847,29 @@ public class XmlUtils { throw new XmlPullParserException( "Document ended before " + endTag + " end tag"); } - + + /** + * Read a HashSet object from an XmlPullParser. The XML data could previously + * have been generated by writeSetXml(). The XmlPullParser must be positioned + * <em>after</em> the tag that begins the set. + * + * @param parser The XmlPullParser from which to read the set data. + * @param endTag Name of the tag that will end the set, usually "set". + * @param name An array of one string, used to return the name attribute + * of the set's tag. + * + * @return HashSet The newly generated set. + * + * @throws XmlPullParserException + * @throws java.io.IOException + * + * @see #readSetXml + */ + public static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name) + throws XmlPullParserException, java.io.IOException { + return readThisSetXml(parser, endTag, name, null); + } + /** * Read a HashSet object from an XmlPullParser. The XML data could previously * have been generated by writeSetXml(). The XmlPullParser must be positioned @@ -628,15 +886,16 @@ public class XmlUtils { * @throws java.io.IOException * * @see #readSetXml + * @hide */ - public static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name) - throws XmlPullParserException, java.io.IOException { + private static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name, + ReadMapCallback callback) throws XmlPullParserException, java.io.IOException { HashSet set = new HashSet(); int eventType = parser.getEventType(); do { if (eventType == parser.START_TAG) { - Object val = readThisValueXml(parser, name); + Object val = readThisValueXml(parser, name, callback); set.add(val); //System.out.println("Adding to set: " + val); } else if (eventType == parser.END_TAG) { @@ -681,6 +940,7 @@ public class XmlUtils { throw new XmlPullParserException( "Not a number in num attribute in byte-array"); } + parser.next(); int[] array = new int[num]; int i = 0; @@ -722,6 +982,187 @@ public class XmlUtils { } /** + * Read a long[] object from an XmlPullParser. The XML data could + * previously have been generated by writeLongArrayXml(). The XmlPullParser + * must be positioned <em>after</em> the tag that begins the list. + * + * @param parser The XmlPullParser from which to read the list data. + * @param endTag Name of the tag that will end the list, usually "list". + * @param name An array of one string, used to return the name attribute + * of the list's tag. + * + * @return Returns a newly generated long[]. + * + * @see #readListXml + */ + public static final long[] readThisLongArrayXml(XmlPullParser parser, + String endTag, String[] name) + throws XmlPullParserException, java.io.IOException { + + int num; + try { + num = Integer.parseInt(parser.getAttributeValue(null, "num")); + } catch (NullPointerException e) { + throw new XmlPullParserException("Need num attribute in long-array"); + } catch (NumberFormatException e) { + throw new XmlPullParserException("Not a number in num attribute in long-array"); + } + parser.next(); + + long[] array = new long[num]; + int i = 0; + + int eventType = parser.getEventType(); + do { + if (eventType == parser.START_TAG) { + if (parser.getName().equals("item")) { + try { + array[i] = Long.parseLong(parser.getAttributeValue(null, "value")); + } catch (NullPointerException e) { + throw new XmlPullParserException("Need value attribute in item"); + } catch (NumberFormatException e) { + throw new XmlPullParserException("Not a number in value attribute in item"); + } + } else { + throw new XmlPullParserException("Expected item tag at: " + parser.getName()); + } + } else if (eventType == parser.END_TAG) { + if (parser.getName().equals(endTag)) { + return array; + } else if (parser.getName().equals("item")) { + i++; + } else { + throw new XmlPullParserException("Expected " + endTag + " end tag at: " + + parser.getName()); + } + } + eventType = parser.next(); + } while (eventType != parser.END_DOCUMENT); + + throw new XmlPullParserException("Document ended before " + endTag + " end tag"); + } + + /** + * Read a double[] object from an XmlPullParser. The XML data could + * previously have been generated by writeDoubleArrayXml(). The XmlPullParser + * must be positioned <em>after</em> the tag that begins the list. + * + * @param parser The XmlPullParser from which to read the list data. + * @param endTag Name of the tag that will end the list, usually "double-array". + * @param name An array of one string, used to return the name attribute + * of the list's tag. + * + * @return Returns a newly generated double[]. + * + * @see #readListXml + */ + public static final double[] readThisDoubleArrayXml(XmlPullParser parser, String endTag, + String[] name) throws XmlPullParserException, java.io.IOException { + + int num; + try { + num = Integer.parseInt(parser.getAttributeValue(null, "num")); + } catch (NullPointerException e) { + throw new XmlPullParserException("Need num attribute in double-array"); + } catch (NumberFormatException e) { + throw new XmlPullParserException("Not a number in num attribute in double-array"); + } + parser.next(); + + double[] array = new double[num]; + int i = 0; + + int eventType = parser.getEventType(); + do { + if (eventType == parser.START_TAG) { + if (parser.getName().equals("item")) { + try { + array[i] = Double.parseDouble(parser.getAttributeValue(null, "value")); + } catch (NullPointerException e) { + throw new XmlPullParserException("Need value attribute in item"); + } catch (NumberFormatException e) { + throw new XmlPullParserException("Not a number in value attribute in item"); + } + } else { + throw new XmlPullParserException("Expected item tag at: " + parser.getName()); + } + } else if (eventType == parser.END_TAG) { + if (parser.getName().equals(endTag)) { + return array; + } else if (parser.getName().equals("item")) { + i++; + } else { + throw new XmlPullParserException("Expected " + endTag + " end tag at: " + + parser.getName()); + } + } + eventType = parser.next(); + } while (eventType != parser.END_DOCUMENT); + + throw new XmlPullParserException("Document ended before " + endTag + " end tag"); + } + + /** + * Read a String[] object from an XmlPullParser. The XML data could + * previously have been generated by writeStringArrayXml(). The XmlPullParser + * must be positioned <em>after</em> the tag that begins the list. + * + * @param parser The XmlPullParser from which to read the list data. + * @param endTag Name of the tag that will end the list, usually "string-array". + * @param name An array of one string, used to return the name attribute + * of the list's tag. + * + * @return Returns a newly generated String[]. + * + * @see #readListXml + */ + public static final String[] readThisStringArrayXml(XmlPullParser parser, String endTag, + String[] name) throws XmlPullParserException, java.io.IOException { + + int num; + try { + num = Integer.parseInt(parser.getAttributeValue(null, "num")); + } catch (NullPointerException e) { + throw new XmlPullParserException("Need num attribute in string-array"); + } catch (NumberFormatException e) { + throw new XmlPullParserException("Not a number in num attribute in string-array"); + } + parser.next(); + + String[] array = new String[num]; + int i = 0; + + int eventType = parser.getEventType(); + do { + if (eventType == parser.START_TAG) { + if (parser.getName().equals("item")) { + try { + array[i] = parser.getAttributeValue(null, "value"); + } catch (NullPointerException e) { + throw new XmlPullParserException("Need value attribute in item"); + } catch (NumberFormatException e) { + throw new XmlPullParserException("Not a number in value attribute in item"); + } + } else { + throw new XmlPullParserException("Expected item tag at: " + parser.getName()); + } + } else if (eventType == parser.END_TAG) { + if (parser.getName().equals(endTag)) { + return array; + } else if (parser.getName().equals("item")) { + i++; + } else { + throw new XmlPullParserException("Expected " + endTag + " end tag at: " + + parser.getName()); + } + } + eventType = parser.next(); + } while (eventType != parser.END_DOCUMENT); + + throw new XmlPullParserException("Document ended before " + endTag + " end tag"); + } + + /** * Read a flattened object from an XmlPullParser. The XML data could * previously have been written with writeMapXml(), writeListXml(), or * writeValueXml(). The XmlPullParser must be positioned <em>at</em> the @@ -743,7 +1184,7 @@ public class XmlUtils { int eventType = parser.getEventType(); do { if (eventType == parser.START_TAG) { - return readThisValueXml(parser, name); + return readThisValueXml(parser, name, null); } else if (eventType == parser.END_TAG) { throw new XmlPullParserException( "Unexpected end tag at: " + parser.getName()); @@ -758,9 +1199,8 @@ public class XmlUtils { "Unexpected end of document"); } - private static final Object readThisValueXml(XmlPullParser parser, String[] name) - throws XmlPullParserException, java.io.IOException - { + private static final Object readThisValueXml(XmlPullParser parser, String[] name, + ReadMapCallback callback) throws XmlPullParserException, java.io.IOException { final String valueName = parser.getAttributeValue(null, "name"); final String tagName = parser.getName(); @@ -794,11 +1234,25 @@ public class XmlUtils { } else if ((res = readThisPrimitiveValueXml(parser, tagName)) != null) { // all work already done by readThisPrimitiveValueXml } else if (tagName.equals("int-array")) { - parser.next(); res = readThisIntArrayXml(parser, "int-array", name); name[0] = valueName; //System.out.println("Returning value for " + valueName + ": " + res); return res; + } else if (tagName.equals("long-array")) { + res = readThisLongArrayXml(parser, "long-array", name); + name[0] = valueName; + //System.out.println("Returning value for " + valueName + ": " + res); + return res; + } else if (tagName.equals("double-array")) { + res = readThisDoubleArrayXml(parser, "double-array", name); + name[0] = valueName; + //System.out.println("Returning value for " + valueName + ": " + res); + return res; + } else if (tagName.equals("string-array")) { + res = readThisStringArrayXml(parser, "string-array", name); + name[0] = valueName; + //System.out.println("Returning value for " + valueName + ": " + res); + return res; } else if (tagName.equals("map")) { parser.next(); res = readThisMapXml(parser, "map", name); @@ -817,9 +1271,12 @@ public class XmlUtils { name[0] = valueName; //System.out.println("Returning value for " + valueName + ": " + res); return res; + } else if (callback != null) { + res = callback.readThisUnknownObjectXml(parser, tagName); + name[0] = valueName; + return res; } else { - throw new XmlPullParserException( - "Unknown tag: " + tagName); + throw new XmlPullParserException("Unknown tag: " + tagName); } // Skip through to end tag. @@ -967,4 +1424,39 @@ public class XmlUtils { throws IOException { out.attribute(null, name, Boolean.toString(value)); } + + /** @hide */ + public interface WriteMapCallback { + /** + * Called from writeMapXml when an Object type is not recognized. The implementer + * must write out the entire element including start and end tags. + * + * @param v The object to be written out + * @param name The mapping key for v. Must be written into the "name" attribute of the + * start tag. + * @param out The XML output stream. + * @throws XmlPullParserException on unrecognized Object type. + * @throws IOException on XmlSerializer serialization errors. + * @hide + */ + public void writeUnknownObject(Object v, String name, XmlSerializer out) + throws XmlPullParserException, IOException; + } + + /** @hide */ + public interface ReadMapCallback { + /** + * Called from readThisMapXml when a START_TAG is not recognized. The input stream + * is positioned within the start tag so that attributes can be read using in.getAttribute. + * + * @param in the XML input stream + * @param tag the START_TAG that was not recognized. + * @return the Object parsed from the stream which will be put into the map. + * @throws XmlPullParserException if the START_TAG is not recognized. + * @throws IOException on XmlPullParser serialization errors. + * @hide + */ + public Object readThisUnknownObjectXml(XmlPullParser in, String tag) + throws XmlPullParserException, IOException; + } } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 835a648..a159715 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -138,6 +138,7 @@ LOCAL_SRC_FILES:= \ android_hardware_Camera.cpp \ android_hardware_camera2_CameraMetadata.cpp \ android_hardware_camera2_legacy_LegacyCameraDevice.cpp \ + android_hardware_camera2_DngCreator.cpp \ android_hardware_SensorManager.cpp \ android_hardware_SerialPort.cpp \ android_hardware_UsbDevice.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 2d350e0..0c7eefa 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -80,6 +80,7 @@ extern int register_android_opengl_jni_GLES31Ext(JNIEnv* env); extern int register_android_hardware_Camera(JNIEnv *env); extern int register_android_hardware_camera2_CameraMetadata(JNIEnv *env); extern int register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv *env); +extern int register_android_hardware_camera2_DngCreator(JNIEnv *env); extern int register_android_hardware_SensorManager(JNIEnv *env); extern int register_android_hardware_SerialPort(JNIEnv *env); extern int register_android_hardware_UsbDevice(JNIEnv *env); @@ -1286,6 +1287,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_hardware_Camera), REG_JNI(register_android_hardware_camera2_CameraMetadata), REG_JNI(register_android_hardware_camera2_legacy_LegacyCameraDevice), + REG_JNI(register_android_hardware_camera2_DngCreator), REG_JNI(register_android_hardware_SensorManager), REG_JNI(register_android_hardware_SerialPort), REG_JNI(register_android_hardware_UsbDevice), diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp index b389d9e..0cfcaef 100644 --- a/core/jni/android/graphics/Shader.cpp +++ b/core/jni/android/graphics/Shader.cpp @@ -50,26 +50,16 @@ static jint Color_HSVToColor(JNIEnv* env, jobject, jint alpha, jfloatArray hsvAr /////////////////////////////////////////////////////////////////////////////////////////////// -static void Shader_destructor(JNIEnv* env, jobject o, jlong shaderHandle, jlong skiaShaderHandle) +static void Shader_destructor(JNIEnv* env, jobject o, jlong shaderHandle) { SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - SkiaShader* skiaShader = reinterpret_cast<SkiaShader*>(skiaShaderHandle); SkSafeUnref(shader); - // skiaShader == NULL when not !USE_OPENGL_RENDERER, so no need to delete it outside the ifdef -#ifdef USE_OPENGL_RENDERER - if (android::uirenderer::Caches::hasInstance()) { - android::uirenderer::Caches::getInstance().resourceCache.destructor(skiaShader); - } else { - delete skiaShader; - } -#endif } static void Shader_setLocalMatrix(JNIEnv* env, jobject o, jlong shaderHandle, - jlong skiaShaderHandle, jlong matrixHandle) + jlong matrixHandle) { SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - SkiaShader* skiaShader = reinterpret_cast<SkiaShader*>(skiaShaderHandle); const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); if (shader) { if (NULL == matrix) { @@ -78,9 +68,6 @@ static void Shader_setLocalMatrix(JNIEnv* env, jobject o, jlong shaderHandle, else { shader->setLocalMatrix(*matrix); } -#ifdef USE_OPENGL_RENDERER - skiaShader->setMatrix(const_cast<SkMatrix*>(matrix)); -#endif } } @@ -98,20 +85,6 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong bitmapHandle return reinterpret_cast<jlong>(s); } -static jlong BitmapShader_postConstructor(JNIEnv* env, jobject o, jlong shaderHandle, - jlong bitmapHandle, jint tileModeX, jint tileModeY) { - SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); -#ifdef USE_OPENGL_RENDERER - SkiaShader* skiaShader = new SkiaBitmapShader(bitmap, shader, - static_cast<SkShader::TileMode>(tileModeX), static_cast<SkShader::TileMode>(tileModeY), - NULL, !shader->isOpaque()); - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - /////////////////////////////////////////////////////////////////////////////////////////////// static jlong LinearGradient_create1(JNIEnv* env, jobject o, @@ -141,105 +114,6 @@ static jlong LinearGradient_create1(JNIEnv* env, jobject o, return reinterpret_cast<jlong>(shader); } -static jlong LinearGradient_postCreate1(JNIEnv* env, jobject o, jlong shaderHandle, - jfloat x0, jfloat y0, jfloat x1, jfloat y1, jintArray colorArray, - jfloatArray posArray, jint tileMode) { -#ifdef USE_OPENGL_RENDERER - SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - size_t count = env->GetArrayLength(colorArray); - const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); - - jfloat* storedBounds = new jfloat[4]; - storedBounds[0] = x0; storedBounds[1] = y0; - storedBounds[2] = x1; storedBounds[3] = y1; - - bool missFirst = false; - bool missLast = false; - size_t stopCount = count; - - jfloat* storedPositions = NULL; - if (posArray) { - AutoJavaFloatArray autoPos(env, posArray, count); - const float* posValues = autoPos.ptr(); - - missFirst = posValues[0] != 0.0f; - missLast = posValues[count - 1] != 1.0f; - - stopCount += missFirst + missLast; - storedPositions = new jfloat[stopCount]; - - if (missFirst) { - storedPositions[0] = 0.0f; - } - - for (size_t i = missFirst; i < count + missFirst; i++) { - storedPositions[i] = posValues[i - missFirst]; - } - - if (missLast) { - storedPositions[stopCount - 1] = 1.0f; - } - } else { - storedPositions = new jfloat[count]; - storedPositions[0] = 0.0f; - const jfloat step = 1.0f / (count - 1); - for (size_t i = 1; i < count - 1; i++) { - storedPositions[i] = step * i; - } - storedPositions[count - 1] = 1.0f; - } - - uint32_t* storedColors = new uint32_t[stopCount]; - - if (missFirst) { - storedColors[0] = static_cast<uint32_t>(colorValues[0]); - } - - for (size_t i = missFirst; i < count + missFirst; i++) { - storedColors[i] = static_cast<uint32_t>(colorValues[i - missFirst]); - } - - if (missLast) { - storedColors[stopCount - 1] = static_cast<uint32_t>(colorValues[count - 1]); - } - - SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors, - storedPositions, stopCount, shader, static_cast<SkShader::TileMode>(tileMode), NULL, - !shader->isOpaque()); - - env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT); - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - -static jlong LinearGradient_postCreate2(JNIEnv* env, jobject o, jlong shaderHandle, - jfloat x0, jfloat y0, jfloat x1, jfloat y1, jint color0, jint color1, jint tileMode) { -#ifdef USE_OPENGL_RENDERER - SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - float* storedBounds = new float[4]; - storedBounds[0] = x0; storedBounds[1] = y0; - storedBounds[2] = x1; storedBounds[3] = y1; - - float* storedPositions = new float[2]; - storedPositions[0] = 0.0f; - storedPositions[1] = 1.0f; - - uint32_t* storedColors = new uint32_t[2]; - storedColors[0] = static_cast<uint32_t>(color0); - storedColors[1] = static_cast<uint32_t>(color1); - - SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors, - storedPositions, 2, shader, static_cast<SkShader::TileMode>(tileMode), NULL, - !shader->isOpaque()); - - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - static jlong LinearGradient_create2(JNIEnv* env, jobject o, jfloat x0, jfloat y0, jfloat x1, jfloat y1, jint color0, jint color1, jint tileMode) @@ -300,67 +174,6 @@ static jlong RadialGradient_create2(JNIEnv* env, jobject, jfloat x, jfloat y, jf return reinterpret_cast<jlong>(s); } -static jlong RadialGradient_postCreate1(JNIEnv* env, jobject o, jlong shaderHandle, - jfloat x, jfloat y, jfloat radius, jintArray colorArray, jfloatArray posArray, jint tileMode) { -#ifdef USE_OPENGL_RENDERER - SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - size_t count = env->GetArrayLength(colorArray); - const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); - - jfloat* storedPositions = new jfloat[count]; - uint32_t* storedColors = new uint32_t[count]; - for (size_t i = 0; i < count; i++) { - storedColors[i] = static_cast<uint32_t>(colorValues[i]); - } - - if (posArray) { - AutoJavaFloatArray autoPos(env, posArray, count); - const float* posValues = autoPos.ptr(); - for (size_t i = 0; i < count; i++) { - storedPositions[i] = posValues[i]; - } - } else { - storedPositions[0] = 0.0f; - const jfloat step = 1.0f / (count - 1); - for (size_t i = 1; i < count - 1; i++) { - storedPositions[i] = step * i; - } - storedPositions[count - 1] = 1.0f; - } - - SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors, - storedPositions, count, shader, (SkShader::TileMode) tileMode, NULL, - !shader->isOpaque()); - - env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT); - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - -static jlong RadialGradient_postCreate2(JNIEnv* env, jobject o, jlong shaderHandle, - jfloat x, jfloat y, jfloat radius, jint color0, jint color1, jint tileMode) { -#ifdef USE_OPENGL_RENDERER - SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - float* storedPositions = new float[2]; - storedPositions[0] = 0.0f; - storedPositions[1] = 1.0f; - - uint32_t* storedColors = new uint32_t[2]; - storedColors[0] = static_cast<uint32_t>(color0); - storedColors[1] = static_cast<uint32_t>(color1); - - SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors, - storedPositions, 2, shader, (SkShader::TileMode) tileMode, NULL, - !shader->isOpaque()); - - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - /////////////////////////////////////////////////////////////////////////////// static jlong SweepGradient_create1(JNIEnv* env, jobject, jfloat x, jfloat y, @@ -393,65 +206,6 @@ static jlong SweepGradient_create2(JNIEnv* env, jobject, jfloat x, jfloat y, return reinterpret_cast<jlong>(s); } -static jlong SweepGradient_postCreate1(JNIEnv* env, jobject o, jlong shaderHandle, - jfloat x, jfloat y, jintArray colorArray, jfloatArray posArray) { -#ifdef USE_OPENGL_RENDERER - SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - size_t count = env->GetArrayLength(colorArray); - const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); - - jfloat* storedPositions = new jfloat[count]; - uint32_t* storedColors = new uint32_t[count]; - for (size_t i = 0; i < count; i++) { - storedColors[i] = static_cast<uint32_t>(colorValues[i]); - } - - if (posArray) { - AutoJavaFloatArray autoPos(env, posArray, count); - const float* posValues = autoPos.ptr(); - for (size_t i = 0; i < count; i++) { - storedPositions[i] = posValues[i]; - } - } else { - storedPositions[0] = 0.0f; - const jfloat step = 1.0f / (count - 1); - for (size_t i = 1; i < count - 1; i++) { - storedPositions[i] = step * i; - } - storedPositions[count - 1] = 1.0f; - } - - SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, count, - shader, NULL, !shader->isOpaque()); - - env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT); - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - -static jlong SweepGradient_postCreate2(JNIEnv* env, jobject o, jlong shaderHandle, - jfloat x, jfloat y, jint color0, jint color1) { -#ifdef USE_OPENGL_RENDERER - SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle); - float* storedPositions = new float[2]; - storedPositions[0] = 0.0f; - storedPositions[1] = 1.0f; - - uint32_t* storedColors = new uint32_t[2]; - storedColors[0] = static_cast<uint32_t>(color0); - storedColors[1] = static_cast<uint32_t>(color1); - - SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, 2, - shader, NULL, !shader->isOpaque()); - - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - /////////////////////////////////////////////////////////////////////////////////////////////// static jlong ComposeShader_create1(JNIEnv* env, jobject o, @@ -476,40 +230,6 @@ static jlong ComposeShader_create2(JNIEnv* env, jobject o, return reinterpret_cast<jlong>(shader); } -static jlong ComposeShader_postCreate2(JNIEnv* env, jobject o, jlong shaderHandle, - jlong shaderAHandle, jlong shaderBHandle, jint porterDuffModeHandle) { -#ifdef USE_OPENGL_RENDERER - SkShader* shader = reinterpret_cast<SkShader *>(shaderHandle); - SkiaShader* shaderA = reinterpret_cast<SkiaShader *>(shaderAHandle); - SkiaShader* shaderB = reinterpret_cast<SkiaShader *>(shaderBHandle); - SkPorterDuff::Mode porterDuffMode = static_cast<SkPorterDuff::Mode>(porterDuffModeHandle); - SkXfermode::Mode mode = SkPorterDuff::ToXfermodeMode(porterDuffMode); - SkiaShader* skiaShader = new SkiaComposeShader(shaderA, shaderB, mode, shader); - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - -static jlong ComposeShader_postCreate1(JNIEnv* env, jobject o, jlong shaderHandle, - jlong shaderAHandle, jlong shaderBHandle, jlong modeHandle) { -#ifdef USE_OPENGL_RENDERER - SkShader* shader = reinterpret_cast<SkShader *>(shaderHandle); - SkiaShader* shaderA = reinterpret_cast<SkiaShader *>(shaderAHandle); - SkiaShader* shaderB = reinterpret_cast<SkiaShader *>(shaderBHandle); - SkXfermode* mode = reinterpret_cast<SkXfermode *>(modeHandle); - SkXfermode::Mode skiaMode; - if (!SkXfermode::AsMode(mode, &skiaMode)) { - // TODO: Support other modes - skiaMode = SkXfermode::kSrcOver_Mode; - } - SkiaShader* skiaShader = new SkiaComposeShader(shaderA, shaderB, skiaMode, shader); - return reinterpret_cast<jlong>(skiaShader); -#else - return NULL; -#endif -} - /////////////////////////////////////////////////////////////////////////////////////////////// static JNINativeMethod gColorMethods[] = { @@ -518,41 +238,32 @@ static JNINativeMethod gColorMethods[] = { }; static JNINativeMethod gShaderMethods[] = { - { "nativeDestructor", "(JJ)V", (void*)Shader_destructor }, - { "nativeSetLocalMatrix", "(JJJ)V", (void*)Shader_setLocalMatrix } + { "nativeDestructor", "(J)V", (void*)Shader_destructor }, + { "nativeSetLocalMatrix", "(JJ)V", (void*)Shader_setLocalMatrix } }; static JNINativeMethod gBitmapShaderMethods[] = { { "nativeCreate", "(JII)J", (void*)BitmapShader_constructor }, - { "nativePostCreate", "(JJII)J", (void*)BitmapShader_postConstructor } }; static JNINativeMethod gLinearGradientMethods[] = { { "nativeCreate1", "(FFFF[I[FI)J", (void*)LinearGradient_create1 }, { "nativeCreate2", "(FFFFIII)J", (void*)LinearGradient_create2 }, - { "nativePostCreate1", "(JFFFF[I[FI)J", (void*)LinearGradient_postCreate1 }, - { "nativePostCreate2", "(JFFFFIII)J", (void*)LinearGradient_postCreate2 } }; static JNINativeMethod gRadialGradientMethods[] = { { "nativeCreate1", "(FFF[I[FI)J", (void*)RadialGradient_create1 }, { "nativeCreate2", "(FFFIII)J", (void*)RadialGradient_create2 }, - { "nativePostCreate1", "(JFFF[I[FI)J", (void*)RadialGradient_postCreate1 }, - { "nativePostCreate2", "(JFFFIII)J", (void*)RadialGradient_postCreate2 } }; static JNINativeMethod gSweepGradientMethods[] = { { "nativeCreate1", "(FF[I[F)J", (void*)SweepGradient_create1 }, { "nativeCreate2", "(FFII)J", (void*)SweepGradient_create2 }, - { "nativePostCreate1", "(JFF[I[F)J", (void*)SweepGradient_postCreate1 }, - { "nativePostCreate2", "(JFFII)J", (void*)SweepGradient_postCreate2 } }; static JNINativeMethod gComposeShaderMethods[] = { { "nativeCreate1", "(JJJ)J", (void*)ComposeShader_create1 }, { "nativeCreate2", "(JJI)J", (void*)ComposeShader_create2 }, - { "nativePostCreate1", "(JJJJ)J", (void*)ComposeShader_postCreate1 }, - { "nativePostCreate2", "(JJJI)J", (void*)ComposeShader_postCreate2 } }; #include <android_runtime/AndroidRuntime.h> diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp index 0d2df80..7935329 100644 --- a/core/jni/android_hardware_camera2_CameraMetadata.cpp +++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp @@ -39,6 +39,9 @@ #include <nativehelper/ScopedUtfChars.h> #include <nativehelper/ScopedPrimitiveArray.h> +#include <sys/types.h> // for socketpair +#include <sys/socket.h> // for socketpair + #if defined(LOG_NNDEBUG) #if !LOG_NNDEBUG #define ALOGVV ALOGV @@ -351,6 +354,119 @@ static void CameraMetadata_writeValues(JNIEnv *env, jobject thiz, jint tag, jbyt } } +struct DumpMetadataParams { + int writeFd; + const CameraMetadata* metadata; +}; + +static void* CameraMetadata_writeMetadataThread(void* arg) { + DumpMetadataParams* p = static_cast<DumpMetadataParams*>(arg); + + /* + * Write the dumped data, and close the writing side FD. + */ + p->metadata->dump(p->writeFd, /*verbosity*/2); + + if (close(p->writeFd) < 0) { + ALOGE("%s: Failed to close writeFd (errno = %#x, message = '%s')", + __FUNCTION__, errno, strerror(errno)); + } + + return NULL; +} + +static void CameraMetadata_dump(JNIEnv *env, jobject thiz) { + ALOGV("%s", __FUNCTION__); + CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); + if (metadata == NULL) { + return; + } + + /* + * Create a socket pair for local streaming read/writes. + * + * The metadata will be dumped into the write side, + * and then read back out (and logged) via the read side. + */ + + int writeFd, readFd; + { + + int sv[2]; + if (socketpair(AF_LOCAL, SOCK_STREAM, /*protocol*/0, &sv[0]) < 0) { + jniThrowExceptionFmt(env, "java/io/IOException", + "Failed to create socketpair (errno = %#x, message = '%s')", + errno, strerror(errno)); + return; + } + writeFd = sv[0]; + readFd = sv[1]; + } + + /* + * Create a thread for doing the writing. + * + * The reading and writing must be concurrent, otherwise + * the write will block forever once it exhausts the capped + * buffer size (from getsockopt). + */ + pthread_t writeThread; + DumpMetadataParams params = { + writeFd, + metadata + }; + + { + int threadRet = pthread_create(&writeThread, /*attr*/NULL, + CameraMetadata_writeMetadataThread, (void*)¶ms); + + if (threadRet != 0) { + close(writeFd); + + jniThrowExceptionFmt(env, "java/io/IOException", + "Failed to create thread for writing (errno = %#x, message = '%s')", + threadRet, strerror(threadRet)); + } + } + + /* + * Read out a byte until stream is complete. Write completed lines + * to ALOG. + */ + { + char out[] = {'\0', '\0'}; // large enough to append as a string + String8 logLine; + + // Read one byte at a time! Very slow but avoids complicated \n scanning. + ssize_t res; + while ((res = TEMP_FAILURE_RETRY(read(readFd, &out[0], /*count*/1))) > 0) { + if (out[0] == '\n') { + ALOGD("%s", logLine.string()); + logLine.clear(); + } else { + logLine.append(out); + } + } + + if (res < 0) { + jniThrowExceptionFmt(env, "java/io/IOException", + "Failed to read from fd (errno = %#x, message = '%s')", + errno, strerror(errno)); + //return; + } else if (!logLine.isEmpty()) { + ALOGD("%s", logLine.string()); + } + } + + int res; + + // Join until thread finishes. Ensures params/metadata is valid until then. + if ((res = pthread_join(writeThread, /*retval*/NULL)) != 0) { + ALOGE("%s: Failed to join thread (errno = %#x, message = '%s')", + __FUNCTION__, res, strerror(res)); + } +} + static void CameraMetadata_readFromParcel(JNIEnv *env, jobject thiz, jobject parcel) { ALOGV("%s", __FUNCTION__); CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz); @@ -436,6 +552,9 @@ static JNINativeMethod gCameraMetadataMethods[] = { { "nativeWriteValues", "(I[B)V", (void *)CameraMetadata_writeValues }, + { "nativeDump", + "()V", + (void *)CameraMetadata_dump }, // Parcelable interface { "nativeReadFromParcel", "(Landroid/os/Parcel;)V", diff --git a/media/jni/android_media_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp index 860d896..7b686e7 100644 --- a/media/jni/android_media_DngCreator.cpp +++ b/core/jni/android_hardware_camera2_DngCreator.cpp @@ -54,7 +54,7 @@ using namespace img_utils; return; \ } -#define ANDROID_MEDIA_DNGCREATOR_CTX_JNI_ID "mNativeContext" +#define ANDROID_DNGCREATOR_CTX_JNI_ID "mNativeContext" static struct { jfieldID mNativeContext; @@ -163,9 +163,10 @@ static void DngCreator_nativeClassInit(JNIEnv* env, jclass clazz) { ALOGV("%s:", __FUNCTION__); gDngCreatorClassInfo.mNativeContext = env->GetFieldID(clazz, - ANDROID_MEDIA_DNGCREATOR_CTX_JNI_ID, "J"); + ANDROID_DNGCREATOR_CTX_JNI_ID, "J"); LOG_ALWAYS_FATAL_IF(gDngCreatorClassInfo.mNativeContext == NULL, - "can't find android/media/DngCreator.%s", ANDROID_MEDIA_DNGCREATOR_CTX_JNI_ID); + "can't find android/hardware/camera2/DngCreator.%s", + ANDROID_DNGCREATOR_CTX_JNI_ID); jclass outputStreamClazz = env->FindClass("java/io/OutputStream"); LOG_ALWAYS_FATAL_IF(outputStreamClazz == NULL, "Can't find java/io/OutputStream class"); @@ -766,7 +767,8 @@ static JNINativeMethod gDngCreatorMethods[] = { (void*) DngCreator_nativeWriteInputStream}, }; -int register_android_media_DngCreator(JNIEnv *env) { +int register_android_hardware_camera2_DngCreator(JNIEnv *env) { return AndroidRuntime::registerNativeMethods(env, - "android/media/DngCreator", gDngCreatorMethods, NELEM(gDngCreatorMethods)); + "android/hardware/camera2/DngCreator", gDngCreatorMethods, + NELEM(gDngCreatorMethods)); } diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 27d3f39..c5dd06f 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -45,7 +45,6 @@ #include <DisplayListRenderer.h> #include <LayerRenderer.h> #include <OpenGLRenderer.h> -#include <SkiaShader.h> #include <Stencil.h> #include <Rect.h> #include <RenderNode.h> @@ -85,8 +84,6 @@ using namespace uirenderer; #define RENDERER_LOGD(...) #endif -#define MODIFIER_SHADER 2 - // ---------------------------------------------------------------------------- static struct { @@ -616,24 +613,6 @@ static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz, } // ---------------------------------------------------------------------------- -// Shaders and color filters -// ---------------------------------------------------------------------------- - -static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject clazz, - jlong rendererPtr, jint modifiers) { - OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); - if (modifiers & MODIFIER_SHADER) renderer->resetShader(); -} - -static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject clazz, - jlong rendererPtr, jlong shaderPtr) { - OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); - SkiaShader* shader = reinterpret_cast<SkiaShader*>(shaderPtr); - renderer->setupShader(shader); -} - - -// ---------------------------------------------------------------------------- // Draw filters // ---------------------------------------------------------------------------- @@ -1091,9 +1070,6 @@ static JNINativeMethod gMethods[] = { { "nDrawPath", "(JJJ)V", (void*) android_view_GLES20Canvas_drawPath }, { "nDrawLines", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawLines }, - { "nResetModifiers", "(JI)V", (void*) android_view_GLES20Canvas_resetModifiers }, - { "nSetupShader", "(JJ)V", (void*) android_view_GLES20Canvas_setupShader }, - { "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter }, { "nResetPaintFilter", "(J)V", (void*) android_view_GLES20Canvas_resetPaintFilter }, diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 48fb729..5bc0f62 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -299,6 +299,12 @@ static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz, proxy->fence(); } +static void android_view_ThreadedRenderer_notifyFramePending(JNIEnv* env, jobject clazz, + jlong proxyPtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); + proxy->notifyFramePending(); +} + #endif // ---------------------------------------------------------------------------- @@ -329,6 +335,7 @@ static JNINativeMethod gMethods[] = { { "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto }, { "nDestroyLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_destroyLayer }, { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence }, + { "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending }, #endif }; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 1874fd8..14141d7 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1014,6 +1014,13 @@ android:description="@string/permdesc_sim_communication" android:protectionLevel="dangerous" /> + <!-- Allows TvInputService to access underlying TV input hardware such as + built-in tuners and HDMI-in's. + @hide This should only be used by OEM's TvInputService's. + --> + <permission android:name="android.permission.TV_INPUT_HARDWARE" + android:protectionLevel="signatureOrSystem" /> + <!-- =========================================== --> <!-- Permissions associated with audio capture --> <!-- =========================================== --> diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00000_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00000_qntm_alpha.png Binary files differdeleted file mode 100644 index 1880a15..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00000_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00001_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00001_qntm_alpha.png Binary files differdeleted file mode 100644 index aecb4d2..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00001_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00002_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00002_qntm_alpha.png Binary files differdeleted file mode 100644 index 8401f91..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00002_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00003_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00003_qntm_alpha.png Binary files differdeleted file mode 100644 index 5832865..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00003_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00004_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00004_qntm_alpha.png Binary files differdeleted file mode 100644 index 6d14962..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00004_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00005_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00005_qntm_alpha.png Binary files differdeleted file mode 100644 index aee057c..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00005_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00006_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00006_qntm_alpha.png Binary files differdeleted file mode 100644 index fb5801e..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00006_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00007_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00007_qntm_alpha.png Binary files differdeleted file mode 100644 index fdb5271..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00007_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00008_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00008_qntm_alpha.png Binary files differdeleted file mode 100644 index b8c7397..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00008_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00009_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00009_qntm_alpha.png Binary files differdeleted file mode 100644 index d0395a8..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00009_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00010_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00010_qntm_alpha.png Binary files differdeleted file mode 100644 index 59bb437..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00010_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00011_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00011_qntm_alpha.png Binary files differdeleted file mode 100644 index c053b90..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00011_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00012_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00012_qntm_alpha.png Binary files differdeleted file mode 100644 index eb30a79..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00012_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00013_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00013_qntm_alpha.png Binary files differdeleted file mode 100644 index 1af0bff..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00013_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00014_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00014_qntm_alpha.png Binary files differdeleted file mode 100644 index 3b36e7d..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00014_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_anim_00015_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_anim_00015_qntm_alpha.png Binary files differdeleted file mode 100644 index c12d20a..0000000 --- a/core/res/res/drawable-hdpi/btn_check_anim_00015_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_off_qntm_alpha.png Binary files differdeleted file mode 100644 index 5bc1d90..0000000 --- a/core/res/res/drawable-hdpi/btn_check_off_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_on_qntm_alpha.png Binary files differdeleted file mode 100644 index e5de2c1..0000000 --- a/core/res/res/drawable-hdpi/btn_check_on_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..3cb4073 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_000.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..8fd1480 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_001.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..d35b579 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_002.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..543c6bc --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_003.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..4fc3c40 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_004.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..c184535 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_005.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..9f9dd43 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_006.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..8c629ce --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_007.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..81134b5 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_008.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..baa5860 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_009.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..d7e28366 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_010.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..6f24795 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_011.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..22f997d --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_012.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..85f4471 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_013.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..ad483c9 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_014.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..f24c2fb --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_off_qntm_015.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..7a9e9bd --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_000.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..af04902 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_001.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..32a6e94 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_002.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..c1b4b37 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_003.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..34d3ade --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_004.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..3d5db53 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_005.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..ea35437 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_006.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..48744f8 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_007.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..f654517 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_008.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..16f959a --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_009.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..98c754b --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_010.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..5827dc2 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_011.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..9850d74 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_012.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..03ab06b --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_013.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..11cdd88 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_014.png diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..874edbf --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_check_to_on_qntm_015.png diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00000_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00000_qntm_alpha.png Binary files differdeleted file mode 100644 index 882365b..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00000_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00001_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00001_qntm_alpha.png Binary files differdeleted file mode 100644 index f6c7094..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00001_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00002_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00002_qntm_alpha.png Binary files differdeleted file mode 100644 index 0e326c9..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00002_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00003_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00003_qntm_alpha.png Binary files differdeleted file mode 100644 index 8bf1170..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00003_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00004_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00004_qntm_alpha.png Binary files differdeleted file mode 100644 index cedb66e..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00004_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00005_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00005_qntm_alpha.png Binary files differdeleted file mode 100644 index 257d7ba..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00005_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00006_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00006_qntm_alpha.png Binary files differdeleted file mode 100644 index e07b36e..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00006_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00007_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00007_qntm_alpha.png Binary files differdeleted file mode 100644 index ef94200..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00007_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00008_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00008_qntm_alpha.png Binary files differdeleted file mode 100644 index ad67004..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00008_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00009_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00009_qntm_alpha.png Binary files differdeleted file mode 100644 index 50796e2..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00009_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00010_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00010_qntm_alpha.png Binary files differdeleted file mode 100644 index ba7be9e..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00010_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00011_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00011_qntm_alpha.png Binary files differdeleted file mode 100644 index bdbfe78..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00011_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00012_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00012_qntm_alpha.png Binary files differdeleted file mode 100644 index fe89951..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00012_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00013_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00013_qntm_alpha.png Binary files differdeleted file mode 100644 index 840c88f..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00013_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00014_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00014_qntm_alpha.png Binary files differdeleted file mode 100644 index 621d1d2..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00014_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_anim_00015_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_anim_00015_qntm_alpha.png Binary files differdeleted file mode 100644 index fd8be89..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_anim_00015_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_off_pressed_qntm_alpha.png Binary files differdeleted file mode 100644 index 7bef530..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_off_pressed_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_off_qntm_alpha.png Binary files differdeleted file mode 100644 index ae50dd5..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_off_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_on_pressed_qntm_alpha.png Binary files differdeleted file mode 100644 index 0678dbb..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_on_pressed_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_on_qntm_alpha.png Binary files differdeleted file mode 100644 index f332925..0000000 --- a/core/res/res/drawable-hdpi/btn_radio_on_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..da88e98 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_000.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..907d92d --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_001.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..9d24dc1 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_002.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..8aa2605 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_003.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..b4cdf02 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_004.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..0724ed7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_005.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..c9bd4e3 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_006.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..5630ec3 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_007.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..4bf666c --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_008.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..dffaa07 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_009.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..5f86e18 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_010.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..9b50aef --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_011.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..1cf5e7f --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_012.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..2bb641a --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_013.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..08e7485 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_014.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..519b5a3 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_off_qntm_015.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..0d3e1e7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_000.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..88c4a9e --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_001.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..8fa2e88 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_002.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..53dd9d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_003.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..e235195 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_004.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..1721284 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_005.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..31819fa --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_006.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..5de44b9 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_007.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..aa20f65 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_008.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..c379ba7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_009.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..e23b410 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_010.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..a9543dc --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_011.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..2473b78 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_012.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..b4acc9c --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_013.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..c9cf344 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_014.png diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..a8c390e --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_radio_to_on_qntm_015.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..c54f8d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_000.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..e062f61 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_001.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..7737646 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_002.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..65ff45e --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_003.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..11aaec0 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_004.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..9e1b60f --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_005.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..1e45687 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_006.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..1e45687 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_007.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..6c48456 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_008.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..a4d084b --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_009.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..1e1a1b0 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_010.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..1e1a1b0 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_011.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..1e1a1b0 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_012.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..1e1a1b0 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_013.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..1e1a1b0 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_off_qntm_014.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..cf09f97 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_000.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..3218e66 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_001.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..0acff03 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_002.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..c93adf4 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_003.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..5d8ddc96 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_004.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..47206a4 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_005.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..7d6a91f --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_006.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..e062f61 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_007.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..b0f0dde --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_008.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..c54f8d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_009.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..c54f8d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_010.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..c54f8d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_011.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..c54f8d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_012.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..c54f8d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_013.png diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..c54f8d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_switch_to_on_qntm_014.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-hdpi/btn_toggle_indicator_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..68e17ad --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_toggle_indicator_qntm_alpha.9.png diff --git a/core/res/res/drawable-hdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-hdpi/btn_toggle_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..879d9c2 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_toggle_qntm_alpha.9.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..281923e --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_000.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..e91d4fb --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_001.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..15baded --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_002.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..3d5899f --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_003.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..e2277bd --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_004.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..b502e22 --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_from_pressed_qntm_005.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..a70be2c --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_000.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..9442316 --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_001.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..33db4a88 --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_002.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..4e1cd16 --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_003.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..d5254f4 --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_004.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..7aa0a3e --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_to_pressed_qntm_005.png diff --git a/core/res/res/drawable-hdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-hdpi/switch_off_qntm_alpha.9.png Binary files differdeleted file mode 100644 index 73e8f1c..0000000 --- a/core/res/res/drawable-hdpi/switch_off_qntm_alpha.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-hdpi/switch_on_qntm_alpha.9.png Binary files differdeleted file mode 100644 index ff6affe..0000000 --- a/core/res/res/drawable-hdpi/switch_on_qntm_alpha.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png Binary files differindex b11de9e..ac1fc23 100644 --- a/core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png +++ b/core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png diff --git a/core/res/res/drawable-hdpi/text_select_handle_left_qntm_alpha.png b/core/res/res/drawable-hdpi/text_select_handle_left_qntm_alpha.png Binary files differindex 598b98c..9cdc25b 100644 --- a/core/res/res/drawable-hdpi/text_select_handle_left_qntm_alpha.png +++ b/core/res/res/drawable-hdpi/text_select_handle_left_qntm_alpha.png diff --git a/core/res/res/drawable-hdpi/text_select_handle_right_qntm_alpha.png b/core/res/res/drawable-hdpi/text_select_handle_right_qntm_alpha.png Binary files differindex 79fe7c5..276d480 100644 --- a/core/res/res/drawable-hdpi/text_select_handle_right_qntm_alpha.png +++ b/core/res/res/drawable-hdpi/text_select_handle_right_qntm_alpha.png diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00000_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00000_qntm_alpha.png Binary files differdeleted file mode 100644 index 0f44ff9..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00000_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00001_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00001_qntm_alpha.png Binary files differdeleted file mode 100644 index 9d5dda0..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00001_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00002_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00002_qntm_alpha.png Binary files differdeleted file mode 100644 index e4ce802..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00002_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00003_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00003_qntm_alpha.png Binary files differdeleted file mode 100644 index d1806ac..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00003_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00004_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00004_qntm_alpha.png Binary files differdeleted file mode 100644 index ab9315b..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00004_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00005_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00005_qntm_alpha.png Binary files differdeleted file mode 100644 index 46e90e6..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00005_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00006_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00006_qntm_alpha.png Binary files differdeleted file mode 100644 index e8c56ff..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00006_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00007_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00007_qntm_alpha.png Binary files differdeleted file mode 100644 index 59dcb7e..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00007_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00008_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00008_qntm_alpha.png Binary files differdeleted file mode 100644 index e9bd4a2..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00008_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00009_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00009_qntm_alpha.png Binary files differdeleted file mode 100644 index 1d05037..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00009_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00010_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00010_qntm_alpha.png Binary files differdeleted file mode 100644 index 91b40de..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00010_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00011_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00011_qntm_alpha.png Binary files differdeleted file mode 100644 index c531cab..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00011_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00012_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00012_qntm_alpha.png Binary files differdeleted file mode 100644 index 11bb387..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00012_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00013_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00013_qntm_alpha.png Binary files differdeleted file mode 100644 index 8843210..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00013_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00014_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00014_qntm_alpha.png Binary files differdeleted file mode 100644 index 6ff2f3d..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00014_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_anim_00015_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_anim_00015_qntm_alpha.png Binary files differdeleted file mode 100644 index a03c1e2..0000000 --- a/core/res/res/drawable-mdpi/btn_check_anim_00015_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_off_qntm_alpha.png Binary files differdeleted file mode 100644 index 2ab6b7f..0000000 --- a/core/res/res/drawable-mdpi/btn_check_off_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_on_qntm_alpha.png Binary files differdeleted file mode 100644 index 2211d83..0000000 --- a/core/res/res/drawable-mdpi/btn_check_on_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..9759818 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_000.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..4eb2c4f --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_001.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..e6d6b42 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_002.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..03cb23a --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_003.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..bfe3c3d --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_004.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..65bdf42 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_005.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..44f9614b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_006.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..cf8ec38 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_007.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..4d624b3 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_008.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..7c4eb7f --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_009.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..e90dd31 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_010.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..831c0e8 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_011.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..7355dfd --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_012.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..be71a69 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_013.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..a4a185b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_014.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..8d0386f --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_off_qntm_015.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..70793c4 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_000.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..632082b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_001.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..e7fc5fb --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_002.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..91a0a33 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_003.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..3bd90d6 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_004.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..5ac39ec --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_005.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..4181983 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_006.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..c8b04df --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_007.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..b7b3a9f --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_008.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..62bc4ed --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_009.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..ac463ad --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_010.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..12b605d --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_011.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..63a3c6a --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_012.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..17660c4 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_013.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..7d9de3d --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_014.png diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..8aa1be2 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_check_to_on_qntm_015.png diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00000_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00000_qntm_alpha.png Binary files differdeleted file mode 100644 index 0a22e1a..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00000_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00001_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00001_qntm_alpha.png Binary files differdeleted file mode 100644 index 2e2469c..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00001_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00002_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00002_qntm_alpha.png Binary files differdeleted file mode 100644 index c1054d9..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00002_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00003_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00003_qntm_alpha.png Binary files differdeleted file mode 100644 index cf8d80a..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00003_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00004_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00004_qntm_alpha.png Binary files differdeleted file mode 100644 index 9d9e870..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00004_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00005_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00005_qntm_alpha.png Binary files differdeleted file mode 100644 index 1bad701..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00005_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00006_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00006_qntm_alpha.png Binary files differdeleted file mode 100644 index a84a54f..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00006_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00007_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00007_qntm_alpha.png Binary files differdeleted file mode 100644 index 4d8050b..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00007_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00008_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00008_qntm_alpha.png Binary files differdeleted file mode 100644 index 374172c..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00008_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00009_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00009_qntm_alpha.png Binary files differdeleted file mode 100644 index 233036e..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00009_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00010_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00010_qntm_alpha.png Binary files differdeleted file mode 100644 index 61d9b58..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00010_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00011_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00011_qntm_alpha.png Binary files differdeleted file mode 100644 index 274e983..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00011_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00012_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00012_qntm_alpha.png Binary files differdeleted file mode 100644 index acf16e5..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00012_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00013_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00013_qntm_alpha.png Binary files differdeleted file mode 100644 index ee48241..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00013_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00014_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00014_qntm_alpha.png Binary files differdeleted file mode 100644 index dbbb736..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00014_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_anim_00015_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_anim_00015_qntm_alpha.png Binary files differdeleted file mode 100644 index bcabd0d..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_anim_00015_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_off_pressed_qntm_alpha.png Binary files differdeleted file mode 100644 index 713fee8..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_off_pressed_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_off_qntm_alpha.png Binary files differdeleted file mode 100644 index dcb90d0..0000000 --- a/core/res/res/drawable-mdpi/btn_radio_off_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..a2b7fce --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_000.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..fe0d3b1 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_001.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..d66d00d --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_002.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..2f2f5cd --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_003.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..72c9495 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_004.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..7d9090f --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_005.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..c5442e8 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_006.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..ca80cdb --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_007.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..d41a10b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_008.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..262c838 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_009.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..7f6ea8b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_010.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..8d50a81 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_011.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..0725a68 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_012.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..6191a4b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_013.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..1904d74 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_014.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..bec8dda --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_off_qntm_015.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..54ef480 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_000.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..55c5163 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_001.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..0fe2a89 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_002.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..86efab7 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_003.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..c0a5ca5 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_004.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..ec55175 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_005.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..3e4a690 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_006.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..da49734 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_007.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..471cda1 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_008.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..d560262 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_009.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..f6096b4 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_010.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..9e2500b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_011.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..efbac99 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_012.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..676f0ca --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_013.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..4803157 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_014.png diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..4f8a162 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_radio_to_on_qntm_015.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..8c3f26c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_000.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..3617168 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_001.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..e4366f4 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_002.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..ea4533b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_003.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..94aedbb --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_004.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..ef84578 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_005.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..4de2321 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_006.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..4de2321 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_007.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..d62fbd5 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_008.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..3d87c4e --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_009.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..536ed46 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_010.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..536ed46 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_011.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..536ed46 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_012.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..536ed46 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_013.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..536ed46 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_off_qntm_014.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..f5b660d --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_000.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..9e4db6c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_001.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..7de2128 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_002.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..1980c2c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_003.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..6e73ef0 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_004.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..f897392 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_005.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..74a6ebd --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_006.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..3617168 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_007.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..884eb66 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_008.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..8c3f26c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_009.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..8c3f26c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_010.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..8c3f26c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_011.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..8c3f26c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_012.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..8c3f26c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_013.png diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..8c3f26c --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_switch_to_on_qntm_014.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-mdpi/btn_toggle_indicator_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..e5bface --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_toggle_indicator_qntm_alpha.9.png diff --git a/core/res/res/drawable-mdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-mdpi/btn_toggle_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..dca86ea --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_toggle_qntm_alpha.9.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..377a6b4 --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_000.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..0859f62 --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_001.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..bf5cdcd --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_002.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..4cd177d --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_003.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..dfe39ca --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_004.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..5d3ab99 --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_from_pressed_qntm_005.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..80922eb --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_000.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..aa77044 --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_001.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..7b099db --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_002.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..088c86a --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_003.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..3c6b9bc --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_004.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..adf5100 --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_to_pressed_qntm_005.png diff --git a/core/res/res/drawable-mdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-mdpi/switch_off_qntm_alpha.9.png Binary files differdeleted file mode 100644 index 8949b52..0000000 --- a/core/res/res/drawable-mdpi/switch_off_qntm_alpha.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-mdpi/switch_on_qntm_alpha.9.png Binary files differdeleted file mode 100644 index d727683..0000000 --- a/core/res/res/drawable-mdpi/switch_on_qntm_alpha.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png Binary files differindex 8991421..b6538e4 100644 --- a/core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png +++ b/core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png diff --git a/core/res/res/drawable-mdpi/text_select_handle_left_qntm_alpha.png b/core/res/res/drawable-mdpi/text_select_handle_left_qntm_alpha.png Binary files differindex 506a186..95c0168 100644 --- a/core/res/res/drawable-mdpi/text_select_handle_left_qntm_alpha.png +++ b/core/res/res/drawable-mdpi/text_select_handle_left_qntm_alpha.png diff --git a/core/res/res/drawable-mdpi/text_select_handle_right_qntm_alpha.png b/core/res/res/drawable-mdpi/text_select_handle_right_qntm_alpha.png Binary files differindex fb0e926..569332a 100644 --- a/core/res/res/drawable-mdpi/text_select_handle_right_qntm_alpha.png +++ b/core/res/res/drawable-mdpi/text_select_handle_right_qntm_alpha.png diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00000_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00000_qntm_alpha.png Binary files differdeleted file mode 100644 index 25500e8..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00000_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00001_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00001_qntm_alpha.png Binary files differdeleted file mode 100644 index b136e25..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00001_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00002_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00002_qntm_alpha.png Binary files differdeleted file mode 100644 index 6a94e30..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00002_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00003_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00003_qntm_alpha.png Binary files differdeleted file mode 100644 index d386421..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00003_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00004_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00004_qntm_alpha.png Binary files differdeleted file mode 100644 index c811385..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00004_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00005_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00005_qntm_alpha.png Binary files differdeleted file mode 100644 index 58b3267..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00005_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00006_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00006_qntm_alpha.png Binary files differdeleted file mode 100644 index 0659e72..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00006_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00007_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00007_qntm_alpha.png Binary files differdeleted file mode 100644 index b4227d1..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00007_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00008_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00008_qntm_alpha.png Binary files differdeleted file mode 100644 index 714ef00..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00008_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00009_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00009_qntm_alpha.png Binary files differdeleted file mode 100644 index 139595b..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00009_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00010_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00010_qntm_alpha.png Binary files differdeleted file mode 100644 index 4491107..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00010_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00011_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00011_qntm_alpha.png Binary files differdeleted file mode 100644 index 20eb752..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00011_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00012_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00012_qntm_alpha.png Binary files differdeleted file mode 100644 index 532c9f2..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00012_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00013_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00013_qntm_alpha.png Binary files differdeleted file mode 100644 index 0d78a32..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00013_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00014_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00014_qntm_alpha.png Binary files differdeleted file mode 100644 index af29678..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00014_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_anim_00015_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_anim_00015_qntm_alpha.png Binary files differdeleted file mode 100644 index 23eb9e3..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_anim_00015_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_off_qntm_alpha.png Binary files differdeleted file mode 100644 index 5d820ae..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_off_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_on_qntm_alpha.png Binary files differdeleted file mode 100644 index 019c92e..0000000 --- a/core/res/res/drawable-xhdpi/btn_check_on_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..2347643 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_000.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..70aaa01 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_001.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..01e498a --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_002.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..71d1cf7 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_003.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..d1e7b1d --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_004.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..7db7d06 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_005.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..dadb62e --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_006.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..f87f744 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_007.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..be99d87 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_008.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..f83bc05 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_009.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..870071d --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_010.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..3a18414 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_011.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..f3d1187 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_012.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..4078cca --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_013.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..d4849b5 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_014.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..6e2af72 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_off_qntm_015.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..9244174 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_000.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..8c7fe95 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_001.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..71eb1d0 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_002.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..613f38a --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_003.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..2d20ccc --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_004.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..407f78d --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_005.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..1bf24b0 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_006.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..a450bd0 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_007.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..63ba593 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_008.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..6d05e5a --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_009.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..1c8cd8f --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_010.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..b8bc564 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_011.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..3d80128 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_012.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..c21dfba --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_013.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..2dfe90d --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_014.png diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..5f40d73 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_check_to_on_qntm_015.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00000_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00000_qntm_alpha.png Binary files differdeleted file mode 100644 index cd11e14..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00000_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00001_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00001_qntm_alpha.png Binary files differdeleted file mode 100644 index b10db83..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00001_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00002_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00002_qntm_alpha.png Binary files differdeleted file mode 100644 index efeb6fb..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00002_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00003_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00003_qntm_alpha.png Binary files differdeleted file mode 100644 index 83080af..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00003_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00004_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00004_qntm_alpha.png Binary files differdeleted file mode 100644 index b9cc322..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00004_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00005_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00005_qntm_alpha.png Binary files differdeleted file mode 100644 index 3b5f9c4..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00005_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00006_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00006_qntm_alpha.png Binary files differdeleted file mode 100644 index 58c93db..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00006_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00007_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00007_qntm_alpha.png Binary files differdeleted file mode 100644 index 0f1d010..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00007_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00008_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00008_qntm_alpha.png Binary files differdeleted file mode 100644 index 05a7a0f..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00008_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00009_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00009_qntm_alpha.png Binary files differdeleted file mode 100644 index 9345035..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00009_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00010_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00010_qntm_alpha.png Binary files differdeleted file mode 100644 index 5f149b7..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00010_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00011_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00011_qntm_alpha.png Binary files differdeleted file mode 100644 index 191f369..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00011_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00012_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00012_qntm_alpha.png Binary files differdeleted file mode 100644 index 44e08e6..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00012_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00013_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00013_qntm_alpha.png Binary files differdeleted file mode 100644 index 5a9dfa0..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00013_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00014_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00014_qntm_alpha.png Binary files differdeleted file mode 100644 index ee921c6..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00014_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_anim_00015_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_anim_00015_qntm_alpha.png Binary files differdeleted file mode 100644 index 567bb0c..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_anim_00015_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_off_pressed_qntm_alpha.png Binary files differdeleted file mode 100644 index 2fd964e..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_off_pressed_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_off_qntm_alpha.png Binary files differdeleted file mode 100644 index 8873cd6..0000000 --- a/core/res/res/drawable-xhdpi/btn_radio_off_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..b54c6ff --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_000.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..fff7056 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_001.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..026462d --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_002.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..26cc8de --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_003.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..c055fff --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_004.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..a22e780 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_005.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..357374c --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_006.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..71d4667 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_007.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..2ed175e --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_008.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..e0f7d8e --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_009.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..62b0578 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_010.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..4d6ef4a --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_011.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..37cee2d --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_012.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..a8bc25f --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_013.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..cf68d93 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_014.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..96834bc --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_off_qntm_015.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..d068dbe --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_000.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..4aabb1e --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_001.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..bbac8e4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_002.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..2fc7459 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_003.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..83c6d0e --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_004.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..45c08d7 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_005.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..05b7dfb --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_006.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..baf9964 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_007.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..d6e0369 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_008.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..3f35270 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_009.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..a5b34dc --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_010.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..361967b --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_011.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..c478bb7 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_012.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..075fa0c --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_013.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..d9e364b --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_014.png diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..9924496 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_radio_to_on_qntm_015.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..2494fd4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_000.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..7bd99fe --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_001.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..2ef623b --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_002.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..19db3e0 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_003.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..984c3c5 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_004.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..6454190 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_005.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..cee9393 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_006.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..cee9393 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_007.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..437ffdd --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_008.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..d2e14ad --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_009.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..4e2f5bc --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_010.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..4e2f5bc --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_011.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..4e2f5bc --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_012.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..4e2f5bc --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_013.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..4e2f5bc --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_qntm_014.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..f1bcfa3 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_000.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..ede2fec --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_001.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..94ce017 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_002.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..647cfe3 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_003.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..b3bf923 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_004.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..ae95b2b --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_005.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..b8e4bd6 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_006.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..ec6d6d7 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_007.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..c0e493f --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_008.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..2494fd4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_009.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..2494fd4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_010.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..2494fd4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_011.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..2494fd4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_012.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..2494fd4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_013.png diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..2494fd4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_qntm_014.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/btn_toggle_indicator_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..dff391f --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_toggle_indicator_qntm_alpha.9.png diff --git a/core/res/res/drawable-xhdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/btn_toggle_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..b135338 --- /dev/null +++ b/core/res/res/drawable-xhdpi/btn_toggle_qntm_alpha.9.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..ea09a31 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_000.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..f9a4391 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_001.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..d9606e1 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_002.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..df2d9d0 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_003.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..625a322 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_004.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..79e8dde --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_from_pressed_qntm_005.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..e99c266 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_000.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..f0329a4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_001.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..42c40b7 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_002.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..807491f --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_003.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..dfec9cc --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_004.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..0ed59ea --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_to_pressed_qntm_005.png diff --git a/core/res/res/drawable-xhdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/switch_off_qntm_alpha.9.png Binary files differdeleted file mode 100644 index a7a972c..0000000 --- a/core/res/res/drawable-xhdpi/switch_off_qntm_alpha.9.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/switch_on_qntm_alpha.9.png Binary files differdeleted file mode 100644 index dd8910b..0000000 --- a/core/res/res/drawable-xhdpi/switch_on_qntm_alpha.9.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png Binary files differindex 4970f56..d6a0ab2 100644 --- a/core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png +++ b/core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png diff --git a/core/res/res/drawable-xhdpi/text_select_handle_left_qntm_alpha.png b/core/res/res/drawable-xhdpi/text_select_handle_left_qntm_alpha.png Binary files differindex 38b8e8b..a01ac10 100644 --- a/core/res/res/drawable-xhdpi/text_select_handle_left_qntm_alpha.png +++ b/core/res/res/drawable-xhdpi/text_select_handle_left_qntm_alpha.png diff --git a/core/res/res/drawable-xhdpi/text_select_handle_right_qntm_alpha.png b/core/res/res/drawable-xhdpi/text_select_handle_right_qntm_alpha.png Binary files differindex d6002a7..d3602d9 100644 --- a/core/res/res/drawable-xhdpi/text_select_handle_right_qntm_alpha.png +++ b/core/res/res/drawable-xhdpi/text_select_handle_right_qntm_alpha.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00000_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00000_qntm_alpha.png Binary files differdeleted file mode 100644 index 1881f54..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00000_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00001_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00001_qntm_alpha.png Binary files differdeleted file mode 100644 index 6f8ec2d..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00001_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00002_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00002_qntm_alpha.png Binary files differdeleted file mode 100644 index c954ed9..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00002_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00003_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00003_qntm_alpha.png Binary files differdeleted file mode 100644 index 9d1a47e..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00003_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00004_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00004_qntm_alpha.png Binary files differdeleted file mode 100644 index ce63631..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00004_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00005_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00005_qntm_alpha.png Binary files differdeleted file mode 100644 index 430c134..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00005_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00006_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00006_qntm_alpha.png Binary files differdeleted file mode 100644 index cdebf83..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00006_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00007_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00007_qntm_alpha.png Binary files differdeleted file mode 100644 index 40ceadb..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00007_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00008_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00008_qntm_alpha.png Binary files differdeleted file mode 100644 index fb13eb2..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00008_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00009_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00009_qntm_alpha.png Binary files differdeleted file mode 100644 index d716fba..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00009_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00010_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00010_qntm_alpha.png Binary files differdeleted file mode 100644 index b8be041..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00010_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00011_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00011_qntm_alpha.png Binary files differdeleted file mode 100644 index bad0c3c..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00011_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00012_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00012_qntm_alpha.png Binary files differdeleted file mode 100644 index a6368fb..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00012_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00013_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00013_qntm_alpha.png Binary files differdeleted file mode 100644 index 234e5d1..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00013_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00014_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00014_qntm_alpha.png Binary files differdeleted file mode 100644 index 3e7796d..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00014_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_anim_00015_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_anim_00015_qntm_alpha.png Binary files differdeleted file mode 100644 index 0673999..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_anim_00015_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png Binary files differdeleted file mode 100644 index 2a17861..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png Binary files differdeleted file mode 100644 index 61067ac..0000000 --- a/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..b754381 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_000.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..517d7a7 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_001.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..2c1d5b6 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_002.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..0c6ff7e --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_003.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..0796601 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_004.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..9b4e0f8 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_005.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..25767eb --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_006.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..cd0951f --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_007.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..9ae8165 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_008.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..efd9bc6 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_009.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..fccbc9d --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_010.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..dddafca --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_011.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..7e37433 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_012.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..9bc22de --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_013.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..507ed10 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_014.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..6a21c7f --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_off_qntm_015.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..0d544d9 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_000.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..39da0ac --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_001.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..d5ada12 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_002.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..d4e096c --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_003.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..468a9b4 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_004.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..ea3cd2e --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_005.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..0652cb0 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_006.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..768d2b0 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_007.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..1d06a90 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_008.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..8a70a80 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_009.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..bf9ec7f --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_010.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..cff07b9 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_011.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..40f997e --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_012.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..6ba84ec --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_013.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..766610e --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_014.png diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..810a029 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_check_to_on_qntm_015.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png Binary files differdeleted file mode 100644 index fdbbbce..0000000 --- a/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png Binary files differdeleted file mode 100644 index 0ec2ee6..0000000 --- a/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png Binary files differdeleted file mode 100644 index b46ee1c..0000000 --- a/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png Binary files differdeleted file mode 100644 index 8737156..0000000 --- a/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..cbc3833 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_000.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..4243895 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_001.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..b522d37 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_002.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..647b965 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_003.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..a317497 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_004.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..0e4b25f --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_005.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..6e279d9 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_006.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..f0840cc --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_007.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..140e9e8 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_008.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..5cf8ec5 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_009.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..f9624d8 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_010.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..899df8c --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_011.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..6543e1c --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_012.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..cd758dd --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_013.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..72d950c --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_014.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..07bdbc9 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_off_qntm_015.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..c9af24b --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_000.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..01de3f5 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_001.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..f428bc5 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_002.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..ab5c008 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_003.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..5b157cf --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_004.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..1210be2 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_005.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..e6b4140 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_006.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..b678e08 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_007.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..6ca2a69 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_008.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..7de608e --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_009.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..b2bbcce --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_010.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..6950db3 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_011.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..c790756 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_012.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..ed5d888 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_013.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..81a4a63 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_014.png diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..db1d93a --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_radio_to_on_qntm_015.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..198ac07 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_000.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..eff3dd0 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_001.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..000a23a --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_002.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..394d661 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_003.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..4e7311d --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_004.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..d9dcf91 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_005.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..674142e --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_006.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..674142e --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_007.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..9d4026a --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_008.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..bb4b426 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_009.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..a37076d --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_010.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..a37076d --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_011.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..a37076d --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_012.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..a37076d --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_013.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..a37076d --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_qntm_014.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..22e9951 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_000.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..14e6b39 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_001.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..86b2c01 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_002.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..1c565df --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_003.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..b825449 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_004.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..170c234 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_005.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..5477007 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_006.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..eff3dd0 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_007.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..e3fd96a --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_008.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..198ac07 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_009.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..198ac07 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_010.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..198ac07 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_011.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..198ac07 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_012.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..198ac07 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_013.png diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..198ac07 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_qntm_014.png diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_indicator_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..0d6a39a --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_toggle_indicator_qntm_alpha.9.png diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..f235aed --- /dev/null +++ b/core/res/res/drawable-xxhdpi/btn_toggle_qntm_alpha.9.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..46aa533 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_000.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..a749469 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_001.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..ef43f00 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_002.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..eebddc3 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_003.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..44b654d --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_004.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..6e768c1 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_from_pressed_qntm_005.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..2ac6dae --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_000.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..91c49ce --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_001.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..4b4bd1f --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_002.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..637e596 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_003.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..42d4d2a --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_004.png diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..995d1b2 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/scrubber_control_to_pressed_qntm_005.png diff --git a/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png Binary files differdeleted file mode 100644 index 8d79a13..0000000 --- a/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png Binary files differdeleted file mode 100644 index e0e4ef9..0000000 --- a/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png Binary files differindex 74a259b..a8067cb 100644 --- a/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png +++ b/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_left_qntm_alpha.png b/core/res/res/drawable-xxhdpi/text_select_handle_left_qntm_alpha.png Binary files differindex 93469a2..75085ce 100644 --- a/core/res/res/drawable-xxhdpi/text_select_handle_left_qntm_alpha.png +++ b/core/res/res/drawable-xxhdpi/text_select_handle_left_qntm_alpha.png diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_right_qntm_alpha.png b/core/res/res/drawable-xxhdpi/text_select_handle_right_qntm_alpha.png Binary files differindex b3493e7..e2eb5be 100644 --- a/core/res/res/drawable-xxhdpi/text_select_handle_right_qntm_alpha.png +++ b/core/res/res/drawable-xxhdpi/text_select_handle_right_qntm_alpha.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..f0ff1a7 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_000.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..b382df3 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_001.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..8cb4ce2 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_002.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..4db2b01 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_003.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..8c4709b --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_004.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..1ad960a --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_005.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..e47cc20 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_006.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..c4d0d51 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_007.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..915d56a --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_008.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..85795cb --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_009.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..157fd91 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_010.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..9d446de --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_011.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..dfac1f0 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_012.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..aed6c08 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_013.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..1b8bd6b --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_014.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_015.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..5dd0e5b --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_off_qntm_015.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..5dd0e5b --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_000.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..1a31ad9 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_001.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..63c7f12 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_002.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..847dd08 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_003.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..b93f3cc --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_004.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..1e3dea7 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_005.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..5a85238 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_006.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..35960ca --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_007.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..6db5555 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_008.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..a9c5851 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_009.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..38465bd --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_010.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..15942dc --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_011.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..67d0d64 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_012.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..69b5c1b --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_013.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..0e5d331 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_014.png diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_015.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..f0ff1a7 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_check_to_on_qntm_015.png diff --git a/core/res/res/drawable-xxxhdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/btn_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..01eeefe --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_qntm_alpha.9.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..44028af --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_000.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..ec13a86 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_001.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..43754eb --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_002.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..39d1d64 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_003.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..f36f883 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_004.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..7a4cc5c --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_005.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..80a21ec --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_006.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..2141104 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_007.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..203bd51 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_008.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..5df6fc5 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_009.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..6d0fced --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_010.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..8c0c372 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_011.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..4fa6f53 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_012.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..d3dbf7d --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_013.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..4ccf8de --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_014.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_015.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_015.png Binary files differnew file mode 100644 index 0000000..adef871 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_qntm_015.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..adef871 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_000.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..9fc3556 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_001.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..7f00609 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_002.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..e4aa58d --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_003.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..fe4e4b7 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_004.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..86666ca --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_005.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..608faaf --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_006.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..ec95422 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_007.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..76e2754 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_008.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..3853eac --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_009.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..621aff1 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_010.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..d24be2a --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_011.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..df33892 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_012.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..ff4b818 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_013.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..d9793ae --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_014.png diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_015.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_015.png Binary files differnew file mode 100644 index 0000000..44028af --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_qntm_015.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_000.png Binary files differnew file mode 100644 index 0000000..8b202c6 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_000.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_001.png Binary files differnew file mode 100644 index 0000000..3b497f3 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_001.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_002.png Binary files differnew file mode 100644 index 0000000..532b6de --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_002.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_003.png Binary files differnew file mode 100644 index 0000000..403b2fe --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_003.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_004.png Binary files differnew file mode 100644 index 0000000..8c5086c --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_004.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_005.png Binary files differnew file mode 100644 index 0000000..d4870f8 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_005.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_006.png Binary files differnew file mode 100644 index 0000000..c05adf5 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_006.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_007.png Binary files differnew file mode 100644 index 0000000..99b2056 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_007.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_008.png Binary files differnew file mode 100644 index 0000000..d839358 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_008.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_009.png Binary files differnew file mode 100644 index 0000000..913f94d --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_009.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_010.png Binary files differnew file mode 100644 index 0000000..7f325b3 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_010.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_011.png Binary files differnew file mode 100644 index 0000000..149a9aa --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_011.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_012.png Binary files differnew file mode 100644 index 0000000..95c219e --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_012.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_013.png Binary files differnew file mode 100644 index 0000000..462a128 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_013.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_014.png Binary files differnew file mode 100644 index 0000000..5911d16 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_qntm_014.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_000.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_000.png Binary files differnew file mode 100644 index 0000000..e0c6d85 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_000.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_001.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_001.png Binary files differnew file mode 100644 index 0000000..5679943 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_001.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_002.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_002.png Binary files differnew file mode 100644 index 0000000..54b636d --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_002.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_003.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_003.png Binary files differnew file mode 100644 index 0000000..bf9fac0 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_003.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_004.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_004.png Binary files differnew file mode 100644 index 0000000..25d5319 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_004.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_005.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_005.png Binary files differnew file mode 100644 index 0000000..d2df595 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_005.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_006.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_006.png Binary files differnew file mode 100644 index 0000000..7700bde --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_006.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_007.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_007.png Binary files differnew file mode 100644 index 0000000..883f98b --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_007.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_008.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_008.png Binary files differnew file mode 100644 index 0000000..b3b2108 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_008.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_009.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_009.png Binary files differnew file mode 100644 index 0000000..3aad596 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_009.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_010.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_010.png Binary files differnew file mode 100644 index 0000000..2017e17 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_010.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_011.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_011.png Binary files differnew file mode 100644 index 0000000..1fc2700 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_011.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_012.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_012.png Binary files differnew file mode 100644 index 0000000..bb8b0f2 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_012.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_013.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_013.png Binary files differnew file mode 100644 index 0000000..66ab8f6 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_013.png diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_014.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_014.png Binary files differnew file mode 100644 index 0000000..e3424db --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_qntm_014.png diff --git a/core/res/res/drawable-xxxhdpi/btn_toggle_indicator_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/btn_toggle_indicator_qntm_alpha.9.png Binary files differnew file mode 100755 index 0000000..c06740b --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_toggle_indicator_qntm_alpha.9.png diff --git a/core/res/res/drawable-xxxhdpi/btn_toggle_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/btn_toggle_qntm_alpha.9.png Binary files differnew file mode 100755 index 0000000..7556167 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/btn_toggle_qntm_alpha.9.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_000.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..0c8f746 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_000.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_001.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..5db9deb --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_001.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_002.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..3aca6d3 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_002.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_003.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..746c74f --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_003.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_004.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..454a5b2 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_004.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_005.png b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..80ad8cc --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_from_pressed_qntm_005.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_000.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_000.png Binary files differnew file mode 100644 index 0000000..cfd0db4 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_000.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_001.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_001.png Binary files differnew file mode 100644 index 0000000..845092f --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_001.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_002.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_002.png Binary files differnew file mode 100644 index 0000000..0042db4 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_002.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_003.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_003.png Binary files differnew file mode 100644 index 0000000..77b2901 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_003.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_004.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_004.png Binary files differnew file mode 100644 index 0000000..fb3c238 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_004.png diff --git a/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_005.png b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_005.png Binary files differnew file mode 100644 index 0000000..0d28c45 --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/scrubber_control_to_pressed_qntm_005.png diff --git a/core/res/res/drawable-xxxhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/switch_track_qntm_alpha.9.png Binary files differnew file mode 100644 index 0000000..fb07f2a --- /dev/null +++ b/core/res/res/drawable-xxxhdpi/switch_track_qntm_alpha.9.png diff --git a/core/res/res/drawable/btn_borderless_quantum.xml b/core/res/res/drawable/btn_borderless_quantum.xml index a8def44..2cd7ed6 100644 --- a/core/res/res/drawable/btn_borderless_quantum.xml +++ b/core/res/res/drawable/btn_borderless_quantum.xml @@ -16,21 +16,6 @@ <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:tint="?attr/colorControlHighlight"> - <item android:id="@id/mask"> - <inset - android:insetLeft="4dp" - android:insetTop="4dp" - android:insetBottom="4dp" - android:insetRight="4dp"> - <shape android:shape="rectangle"> - <solid android:color="@color/white" /> - <corners android:radius="2dp" /> - <padding - android:left="4dp" - android:top="4dp" - android:bottom="4dp" - android:right="4dp" /> - </shape> - </inset> - </item> + <item android:id="@id/mask" + android:drawable="@drawable/btn_qntm_alpha" /> </ripple> diff --git a/core/res/res/drawable/btn_check_quantum.xml b/core/res/res/drawable/btn_check_quantum.xml deleted file mode 100644 index 6ceba60..0000000 --- a/core/res/res/drawable/btn_check_quantum.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_checked="true" android:state_pressed="true"> - <bitmap android:src="@drawable/btn_check_on_qntm_alpha" - android:tint="?attr/colorControlActivated" /> - </item> - <item android:state_checked="true"> - <bitmap android:src="@drawable/btn_check_on_qntm_alpha" - android:tint="?attr/colorControlActivated" /> - </item> - <item android:state_pressed="true"> - <bitmap android:src="@drawable/btn_check_off_qntm_alpha" - android:tint="?attr/colorControlActivated" /> - </item> - <item> - <bitmap android:src="@drawable/btn_check_off_qntm_alpha" - android:tint="?attr/colorControlNormal" /> - </item> -</selector> diff --git a/core/res/res/drawable/btn_check_quantum_anim.xml b/core/res/res/drawable/btn_check_quantum_anim.xml index 96715a4..b16875e 100644 --- a/core/res/res/drawable/btn_check_quantum_anim.xml +++ b/core/res/res/drawable/btn_check_quantum_anim.xml @@ -16,88 +16,118 @@ <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:state_checked="true"> - <bitmap android:src="@drawable/btn_check_anim_00015_qntm_alpha" - android:tint="?attr/colorControlActivated" - android:alpha="?attr/disabledAlpha" /> + <bitmap android:src="@drawable/btn_check_to_on_qntm_015" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" /> </item> <item android:state_enabled="false"> - <bitmap android:src="@drawable/btn_check_anim_00000_qntm_alpha" - android:tint="?attr/colorControlNormal" - android:alpha="?attr/disabledAlpha" /> + <bitmap android:src="@drawable/btn_check_to_on_qntm_000" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" /> </item> <item android:state_checked="true" android:id="@+id/on"> - <bitmap android:src="@drawable/btn_check_anim_00015_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <bitmap android:src="@drawable/btn_check_to_on_qntm_015" android:tint="?attr/colorControlActivated" /> </item> <item android:id="@+id/off"> - <bitmap android:src="@drawable/btn_check_anim_00000_qntm_alpha" - android:tint="?attr/colorControlNormal" /> + <bitmap android:src="@drawable/btn_check_to_on_qntm_000" android:tint="?attr/colorControlNormal" /> </item> - <transition android:fromId="@+id/off" android:toId="@+id/on" android:reversible="true"> + <transition android:fromId="@+id/off" android:toId="@+id/on"> <animation-list> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00000_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_000" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00001_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_001" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00002_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_002" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00003_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_003" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00004_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_004" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00005_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_005" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00006_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_006" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00007_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_007" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00008_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_008" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00009_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_009" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00010_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_010" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00011_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_011" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00012_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_012" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00013_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_013" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00014_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_014" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_check_anim_00015_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_on_qntm_015" android:tint="?attr/colorControlActivated" /> + </item> + </animation-list> + </transition> + <transition android:fromId="@+id/on" android:toId="@+id/off"> + <animation-list> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_000" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_001" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_002" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_003" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_004" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_005" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_006" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_007" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_008" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_009" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_010" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_011" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_012" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_013" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_014" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_check_to_off_qntm_015" android:tint="?attr/colorControlActivated" /> </item> </animation-list> </transition> diff --git a/core/res/res/drawable/btn_default_quantum.xml b/core/res/res/drawable/btn_default_quantum.xml index 63473a4..61193fe 100644 --- a/core/res/res/drawable/btn_default_quantum.xml +++ b/core/res/res/drawable/btn_default_quantum.xml @@ -17,20 +17,7 @@ <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:tint="?attr/colorControlHighlight"> <item> - <inset - android:insetLeft="4dp" - android:insetTop="4dp" - android:insetBottom="4dp" - android:insetRight="4dp"> - <shape android:shape="rectangle"> - <solid android:color="?attr/colorButtonNormal" /> - <corners android:radius="2dp" /> - <padding - android:left="4dp" - android:top="4dp" - android:bottom="4dp" - android:right="4dp" /> - </shape> - </inset> + <nine-patch android:src="@drawable/btn_qntm_alpha" + android:tint="?attr/colorButtonNormal" /> </item> </ripple> diff --git a/core/res/res/drawable/btn_radio_quantum.xml b/core/res/res/drawable/btn_radio_quantum.xml deleted file mode 100644 index 0f9ebce..0000000 --- a/core/res/res/drawable/btn_radio_quantum.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_enabled="false" android:state_checked="true"> - <bitmap android:src="@drawable/btn_radio_on_qntm_alpha" - android:tint="?attr/colorControlNormal" - android:alpha="?attr/disabledAlpha" /> - </item> - <item android:state_enabled="false"> - <bitmap android:src="@drawable/btn_radio_off_qntm_alpha" - android:tint="?attr/colorControlNormal" - android:alpha="?attr/disabledAlpha" /> - </item> - <item android:state_checked="true"> - <bitmap android:src="@drawable/btn_radio_on_qntm_alpha" - android:tint="?attr/colorControlActivated" /> - </item> - <item> - <bitmap android:src="@drawable/btn_radio_off_qntm_alpha" - android:tint="?attr/colorControlNormal" /> - </item> -</selector> diff --git a/core/res/res/drawable/btn_radio_quantum_anim.xml b/core/res/res/drawable/btn_radio_quantum_anim.xml index 5068b7a..cd9b518 100644 --- a/core/res/res/drawable/btn_radio_quantum_anim.xml +++ b/core/res/res/drawable/btn_radio_quantum_anim.xml @@ -16,88 +16,118 @@ <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:state_checked="true"> - <bitmap android:src="@drawable/btn_radio_anim_00015_qntm_alpha" - android:tint="?attr/colorControlActivated" - android:alpha="?attr/disabledAlpha" /> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_015" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" /> </item> <item android:state_enabled="false"> - <bitmap android:src="@drawable/btn_radio_anim_00000_qntm_alpha" - android:tint="?attr/colorControlNormal" - android:alpha="?attr/disabledAlpha" /> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_000" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" /> </item> <item android:state_checked="true" android:id="@+id/on"> - <bitmap android:src="@drawable/btn_radio_anim_00015_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_015" android:tint="?attr/colorControlActivated" /> </item> <item android:id="@+id/off"> - <bitmap android:src="@drawable/btn_radio_anim_00000_qntm_alpha" - android:tint="?attr/colorControlNormal" /> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_000" android:tint="?attr/colorControlNormal" /> </item> - <transition android:fromId="@+id/off" android:toId="@+id/on" android:reversible="true"> + <transition android:fromId="@+id/off" android:toId="@+id/on"> <animation-list> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00000_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_000" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00001_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_001" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00002_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_002" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00003_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_003" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00004_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_004" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00005_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_005" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00006_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_006" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00007_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_007" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00008_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_008" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00009_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_009" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00010_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_010" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00011_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_011" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00012_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_012" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00013_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_013" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00014_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_014" android:tint="?attr/colorControlActivated" /> </item> - <item android:duration="33"> - <bitmap android:src="@drawable/btn_radio_anim_00015_qntm_alpha" - android:tint="?attr/colorControlActivated" /> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_on_qntm_015" android:tint="?attr/colorControlActivated" /> + </item> + </animation-list> + </transition> + <transition android:fromId="@+id/on" android:toId="@+id/off"> + <animation-list> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_000" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_001" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_002" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_003" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_004" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_005" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_006" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_007" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_008" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_009" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_010" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_011" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_012" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_013" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_014" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_radio_to_off_qntm_015" android:tint="?attr/colorControlActivated" /> </item> </animation-list> </transition> diff --git a/core/res/res/drawable/btn_toggle_quantum.xml b/core/res/res/drawable/btn_toggle_quantum.xml new file mode 100644 index 0000000..e235598 --- /dev/null +++ b/core/res/res/drawable/btn_toggle_quantum.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<inset xmlns:android="http://schemas.android.com/apk/res/android" + android:insetLeft="4dp" + android:insetTop="4dp" + android:insetBottom="4dp" + android:insetRight="4dp"> + <layer-list android:paddingMode="stack"> + <item> + <ripple android:tint="?attr/colorControlHighlight"> + <item> + <nine-patch android:src="@drawable/btn_toggle_qntm_alpha" + android:tint="?attr/colorButtonNormal" /> + </item> + </ripple> + </item> + <item> + <selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_checked="false"> + <nine-patch android:src="@drawable/btn_toggle_indicator_qntm_alpha" + android:tint="?attr/colorControlNormal" /> + </item> + <item android:state_checked="true"> + <nine-patch android:src="@drawable/btn_toggle_indicator_qntm_alpha" + android:tint="?attr/colorControlActivated" /> + </item> + </selector> + </item> + </layer-list> +</inset> diff --git a/core/res/res/drawable/ic_audio_ring_notif.xml b/core/res/res/drawable/ic_audio_ring_notif.xml index 247d1b4..b52db5c 100644 --- a/core/res/res/drawable/ic_audio_ring_notif.xml +++ b/core/res/res/drawable/ic_audio_ring_notif.xml @@ -1,23 +1,28 @@ -<?xml version="1.0" encoding="utf-8"?> <!-- -/* - * Copyright 2013, 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. - */ +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" > + <size + android:width="32dp" + android:height="32dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> -<bitmap xmlns:android="http://schemas.android.com/apk/res/android" - android:src="@drawable/ic_audio_ring_notif_am_alpha" - android:autoMirrored="true" - android:tint="?attr/colorControlNormal" /> + <path + android:fill="#8A000000" + android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/> +</vector> diff --git a/core/res/res/drawable/ic_audio_ring_notif_mute.xml b/core/res/res/drawable/ic_audio_ring_notif_mute.xml index 72aaa9d..8d7d6cb 100644 --- a/core/res/res/drawable/ic_audio_ring_notif_mute.xml +++ b/core/res/res/drawable/ic_audio_ring_notif_mute.xml @@ -1,23 +1,28 @@ -<?xml version="1.0" encoding="utf-8"?> <!-- -/* - * Copyright 2013, 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. - */ +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" > + <size + android:width="32dp" + android:height="32dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> -<bitmap xmlns:android="http://schemas.android.com/apk/res/android" - android:src="@drawable/ic_audio_ring_notif_mute_am_alpha" - android:autoMirrored="true" - android:tint="?attr/colorControlNormal" /> + <path + android:fill="#8A000000" + android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7C9.5,4.3 9.0,4.5 8.6,4.7l9.4,9.4L18.0,10.5zM17.7,19.0l2.0,2.0l1.3,-1.3L4.3,3.0L3.0,4.3l2.9,2.9C5.3,8.2 5.0,9.3 5.0,10.5L5.0,16.0l-2.0,2.0l0.0,1.0L17.7,19.0z" /> +</vector> diff --git a/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml b/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml index 9e31aba..2f1d940 100644 --- a/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml +++ b/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml @@ -1,23 +1,28 @@ -<?xml version="1.0" encoding="utf-8"?> <!-- -/* - * Copyright 2013, 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. - */ +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" > + <size + android:width="32dp" + android:height="32dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> -<bitmap xmlns:android="http://schemas.android.com/apk/res/android" - android:src="@drawable/ic_audio_ring_notif_vibrate_am_alpha" - android:autoMirrored="true" - android:tint="?attr/colorControlNormal" /> + <path + android:fill="#8A000000" + android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/> +</vector> diff --git a/core/res/res/drawable/scrubber_control_quantum_anim.xml b/core/res/res/drawable/scrubber_control_quantum_anim.xml new file mode 100644 index 0000000..87d3ae9 --- /dev/null +++ b/core/res/res/drawable/scrubber_control_quantum_anim.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<animated-selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true"> + <item android:state_enabled="false" android:state_pressed="true"> + <bitmap android:src="@drawable/scrubber_control_off_qntm_alpha" android:gravity="center" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" /> + </item> + <item android:state_enabled="false"> + <bitmap android:src="@drawable/scrubber_control_off_qntm_alpha" android:gravity="center" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" /> + </item> + <item android:state_pressed="true" android:id="@+id/pressed"> + <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:id="@+id/not_pressed"> + <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <transition android:fromId="@+id/not_pressed" android:toId="@+id/pressed"> + <animation-list> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_001" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_002" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_003" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_004" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_to_pressed_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + </animation-list> + </transition> + <transition android:fromId="@+id/pressed" android:toId="@+id/not_pressed"> + <animation-list> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_001" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_002" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_003" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_004" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/scrubber_control_from_pressed_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + </animation-list> + </transition> +</animated-selector> diff --git a/core/res/res/drawable/switch_inner_quantum.xml b/core/res/res/drawable/switch_inner_quantum.xml deleted file mode 100644 index 856895e..0000000 --- a/core/res/res/drawable/switch_inner_quantum.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_enabled="false" android:state_checked="true"> - <nine-patch android:src="@drawable/switch_on_qntm_alpha" - android:tint="?attr/colorControlNormal" - android:alpha="?attr/disabledAlpha" /> - </item> - <item android:state_enabled="false"> - <nine-patch android:src="@drawable/switch_off_qntm_alpha" - android:tint="?attr/colorControlNormal" - android:alpha="?attr/disabledAlpha" /> - </item> - <item android:state_checked="true"> - <nine-patch android:src="@drawable/switch_on_qntm_alpha" - android:tint="?attr/colorControlActivated" /> - </item> - <item> - <nine-patch android:src="@drawable/switch_off_qntm_alpha" - android:tint="?attr/colorControlNormal" /> - </item> -</selector> diff --git a/core/res/res/drawable/switch_thumb_quantum_anim.xml b/core/res/res/drawable/switch_thumb_quantum_anim.xml new file mode 100644 index 0000000..1984d47 --- /dev/null +++ b/core/res/res/drawable/switch_thumb_quantum_anim.xml @@ -0,0 +1,128 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<animated-selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true"> + <item android:state_enabled="false" android:state_checked="true"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_014" android:gravity="center" android:tint="?attr/colorControlActivated" android:alpha="?attr/disabledAlpha" /> + </item> + <item android:state_enabled="false"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_000" android:gravity="center" android:tint="?attr/colorControlNormal" android:alpha="?attr/disabledAlpha" /> + </item> + <item android:state_checked="true" android:id="@+id/on"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_014" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:id="@+id/off"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_000" android:gravity="center" android:tint="?attr/colorControlNormal" /> + </item> + <transition android:fromId="@+id/off" android:toId="@+id/on"> + <animation-list> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_001" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_002" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_003" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_004" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_006" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_007" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_008" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_009" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_010" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_011" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_012" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_013" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_on_qntm_014" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + </animation-list> + </transition> + <transition android:fromId="@+id/on" android:toId="@+id/off"> + <animation-list> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_000" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_001" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_002" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_003" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_004" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_005" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_006" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_007" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_008" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_009" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_010" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_011" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_012" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_013" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + <item android:duration="15"> + <bitmap android:src="@drawable/btn_switch_to_off_qntm_014" android:gravity="center" android:tint="?attr/colorControlActivated" /> + </item> + </animation-list> + </transition> +</animated-selector> diff --git a/core/res/res/drawable/switch_track_quantum.xml b/core/res/res/drawable/switch_track_quantum.xml index 8c4e6b71..3651a0a 100644 --- a/core/res/res/drawable/switch_track_quantum.xml +++ b/core/res/res/drawable/switch_track_quantum.xml @@ -15,6 +15,16 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="false" android:state_checked="true"> + <nine-patch android:src="@drawable/switch_track_qntm_alpha" + android:tint="?attr/colorControlActivated" + android:alpha="?attr/disabledAlpha" /> + </item> + <item android:state_enabled="false"> + <nine-patch android:src="@drawable/switch_track_qntm_alpha" + android:tint="?attr/colorControlNormal" + android:alpha="?attr/disabledAlpha" /> + </item> <item android:state_checked="true"> <nine-patch android:src="@drawable/switch_track_qntm_alpha" android:tint="?attr/colorControlActivated" /> diff --git a/core/res/res/layout/global_actions_silent_mode.xml b/core/res/res/layout/global_actions_silent_mode.xml index 79401af..a358623 100644 --- a/core/res/res/layout/global_actions_silent_mode.xml +++ b/core/res/res/layout/global_actions_silent_mode.xml @@ -37,7 +37,7 @@ android:layout_marginEnd="8dp" android:layout_marginTop="6dp" android:layout_marginBottom="6dp" - android:src="@drawable/ic_audio_vol_mute" + android:src="@drawable/ic_audio_ring_notif_mute" android:scaleType="center" android:duplicateParentState="true" android:background="@drawable/silent_mode_indicator" @@ -94,7 +94,7 @@ android:layout_marginEnd="8dp" android:layout_marginTop="6dp" android:layout_marginBottom="6dp" - android:src="@drawable/ic_audio_vol" + android:src="@drawable/ic_audio_ring_notif" android:scaleType="center" android:duplicateParentState="true" android:background="@drawable/silent_mode_indicator" diff --git a/core/res/res/layout/volume_adjust.xml b/core/res/res/layout/volume_adjust.xml deleted file mode 100644 index 3ad1f23..0000000 --- a/core/res/res/layout/volume_adjust.xml +++ /dev/null @@ -1,51 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 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. ---> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/visible_panel" - android:orientation="horizontal" - android:layout_width="300dp" - android:layout_height="wrap_content"> - - <LinearLayout - android:id="@+id/slider_group" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:orientation="vertical"> - <!-- Sliders go here --> - </LinearLayout> - - <ImageView - android:id="@+id/expand_button_divider" - android:src="?attr/dividerVertical" - android:layout_width="wrap_content" - android:layout_height="32dip" - android:scaleType="fitXY" - android:layout_gravity="top" - android:layout_marginTop="16dip" - android:layout_marginBottom="16dip" /> - - <ImageView - android:id="@+id/expand_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="top" - android:padding="16dip" - android:background="?attr/selectableItemBackground" - android:src="@drawable/ic_sysbar_quicksettings" /> - -</LinearLayout> diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml index 8f83ab2..3180e58 100644 --- a/core/res/res/values-sw600dp/dimens.xml +++ b/core/res/res/values-sw600dp/dimens.xml @@ -19,13 +19,9 @@ --> <resources> <!-- The width that is used when creating thumbnails of applications. --> - <dimen name="thumbnail_width">200dp</dimen> + <dimen name="thumbnail_width">512dp</dimen> <!-- The height that is used when creating thumbnails of applications. --> - <dimen name="thumbnail_height">177dp</dimen> - <!-- The width that is used when creating thumbnails of applications. --> - <dimen name="recents_thumbnail_width">512dp</dimen> - <!-- The height that is used when creating thumbnails of applications. --> - <dimen name="recents_thumbnail_height">512dp</dimen> + <dimen name="thumbnail_height">512dp</dimen> <!-- The maximum number of action buttons that should be permitted within an action bar/action mode. This will be used to determine how many showAsAction="ifRoom" items can fit. "always" items can override this. --> diff --git a/core/res/res/values-sw720dp/dimens.xml b/core/res/res/values-sw720dp/dimens.xml index 040bb5b..21235ec 100644 --- a/core/res/res/values-sw720dp/dimens.xml +++ b/core/res/res/values-sw720dp/dimens.xml @@ -35,13 +35,9 @@ <item type="dimen" name="dialog_fixed_height_minor">90%</item> <!-- The width that is used when creating thumbnails of applications. --> - <dimen name="thumbnail_width">230dp</dimen> + <dimen name="thumbnail_width">640dp</dimen> <!-- The height that is used when creating thumbnails of applications. --> - <dimen name="thumbnail_height">135dp</dimen> - <!-- The width that is used when creating thumbnails of applications. --> - <dimen name="recents_thumbnail_width">512dp</dimen> - <!-- The height that is used when creating thumbnails of applications. --> - <dimen name="recents_thumbnail_height">512dp</dimen> + <dimen name="thumbnail_height">640dp</dimen> <!-- Preference activity, vertical padding for the header list --> <dimen name="preference_screen_header_vertical_padding">32dp</dimen> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index b1f256e..acfbe2d 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -885,41 +885,57 @@ be passed a persistable Bundle in their Intent.extras. --> <attr name="persistable" format="boolean" /> - <!-- Specify whether this activity should always be launched in doc-centric mode. For - values other than <code>none</code> the activity must be defined with + <!-- This attribute specifies that an activity shall become the root activity of a + new task each time it is launched. Using this attribute permits the user to + have multiple documents from the same applications appear in the recent tasks list. + + <p>Such a document is any kind of item for which an application may want to + maintain multiple simultaneous instances. Examples might be text files, web + pages, spreadsheets, or emails. Each such document will be in a separate + task in the recent taskss list. + + <p>This attribute is equivalent to adding the flag {@link + android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} to every Intent used to launch + the activity. + + <p>The documentLaunchMode attribute may be assigned one of three values, "none", + "intoExisting" and "always", described in detail below. For values other than + <code>none</code> the activity must be defined with {@link android.R.attr#launchMode} <code>standard</code> or <code>singleTop</code>. - This attribute can be overridden by {@link - android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}. - - <p>If this attribute is not specified, <code>none</code> will be used. - Note that this launch behavior can be changed in some ways at runtime - through the {@link android.content.Intent} flags - {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}. --> + If this attribute is not specified, <code>none</code> will be used. + Note that <code>none</code> can be overridden at run time if the Intent used + to launch it contains the flag {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}. + Similarly <code>intoExisting</code> will be overridden by the flag + {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} combined with + {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}. --> <attr name="documentLaunchMode"> <!-- The default mode, which will create a new task only when {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK} is set. --> <enum name="none" value="0" /> - <!-- All tasks will be searched for a matching Intent. If one is found - That task will cleared and restarted with the root activity receiving a call + <!-- All tasks will be searched for one whose base Intent's ComponentName and + data URI match those of the launching Intent. If such a task is found + that task will be cleared and restarted with the root activity receiving a call to {@link android.app.Activity#onNewIntent Activity.onNewIntent}. If no such task is found a new task will be created. - This is the equivalent of with {@link + <p>This is the equivalent of launching an activity with {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT Intent.FLAG_ACTIVITY_NEW_DOCUMENT} - without {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK - Intent.FLAG_ACTIVITY_MULTIPLE_TASK}. --> + set and without {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK + Intent.FLAG_ACTIVITY_MULTIPLE_TASK} set. --> <enum name="intoExisting" value="1" /> - <!-- A new task rooted at this activity will be created. - This is the equivalent of with {@link + <!-- A new task rooted at this activity will be created. This will happen whether or + not there is an existing task whose ComponentName and data URI match + that of the launcing intent This is the equivalent of launching an activity + with {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT Intent.FLAG_ACTIVITY_NEW_DOCUMENT} - paired with {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK - Intent.FLAG_ACTIVITY_MULTIPLE_TASK}. --> + and {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK + Intent.FLAG_ACTIVITY_MULTIPLE_TASK} both set. --> <enum name="always" value="2" /> </attr> - <!-- Tasks launched by activities with this attribute will remain in the recent task + <!-- Tasks launched by activities with this attribute will remain in the recent tasks list until the last activity in the task is completed. When that happens the task - will be automatically removed from the recent task list. + will be automatically removed from the recent tasks list. This attribute is the equivalent of {@link android.content.Intent#FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 5375c14..e9d8ccc 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1538,9 +1538,6 @@ --> <string-array translatable="false" name="config_globalActionsList"> <item>power</item> - <item>airplane</item> - <item>bugreport</item> - <item>silent</item> <item>users</item> </string-array> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 52b021f..657f614 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -19,13 +19,9 @@ --> <resources> <!-- The width that is used when creating thumbnails of applications. --> - <dimen name="thumbnail_width">164dp</dimen> + <dimen name="thumbnail_width">256dp</dimen> <!-- The height that is used when creating thumbnails of applications. --> - <dimen name="thumbnail_height">145dp</dimen> - <!-- The width that is used when creating thumbnails of applications. --> - <dimen name="recents_thumbnail_width">256dp</dimen> - <!-- The height that is used when creating thumbnails of applications. --> - <dimen name="recents_thumbnail_height">256dp</dimen> + <dimen name="thumbnail_height">256dp</dimen> <!-- The standard size (both width and height) of an application icon that will be displayed in the app launcher and elsewhere. --> <dimen name="app_icon_size">48dip</dimen> @@ -206,9 +202,6 @@ <!-- Default width for a textview error popup --> <dimen name="textview_error_popup_default_width">240dip</dimen> - <!-- Volume panel y offset --> - <dimen name="volume_panel_top">16dp</dimen> - <!-- Default padding to apply to AppWidgetHostViews containing widgets targeting API level 14 and up. --> <dimen name="default_app_widget_padding_left">8dp</dimen> <dimen name="default_app_widget_padding_top">8dp</dimen> diff --git a/core/res/res/values/dimens_quantum.xml b/core/res/res/values/dimens_quantum.xml index 53e97fd..2defee2 100644 --- a/core/res/res/values/dimens_quantum.xml +++ b/core/res/res/values/dimens_quantum.xml @@ -47,6 +47,10 @@ <dimen name="text_size_menu_quantum">14sp</dimen> <dimen name="text_size_button_quantum">14sp</dimen> + <dimen name="text_size_large_quantum">22sp</dimen> + <dimen name="text_size_medium_quantum">18sp</dimen> + <dimen name="text_size_small_quantum">14sp</dimen> + <dimen name="floating_window_z">16dp</dimen> <dimen name="floating_window_margin">32dp</dimen> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index ce0d2d5..7dc967c 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2181,9 +2181,6 @@ <public-padding type="dimen" name="l_resource_pad" end="0x01050010" /> - <public type="dimen" name="recents_thumbnail_height" /> - <public type="dimen" name="recents_thumbnail_width" /> - <public-padding type="id" name="l_resource_pad" end="0x01020040" /> <public type="id" name="mask" /> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 4a27ebe..f6cd9e8 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -277,37 +277,6 @@ please see styles_device_defaults.xml. <item name="android:textColor">#CCCCCC</item> </style> - <style name="TextAppearance.StatusBar.Quantum"> - </style> - <style name="TextAppearance.StatusBar.Quantum.EventContent"> - <item name="android:textColor">#90000000</item> - <item name="android:textSize">@dimen/notification_text_size</item> - </style> - <style name="TextAppearance.StatusBar.Quantum.EventContent.Title"> - <item name="android:textColor">#DD000000</item> - <item name="android:textSize">@dimen/notification_title_text_size</item> - </style> - <style name="TextAppearance.StatusBar.Quantum.EventContent.Line2"> - <item name="android:textSize">@dimen/notification_subtext_size</item> - </style> - <style name="TextAppearance.StatusBar.Quantum.EventContent.Info"> - <item name="android:textSize">@dimen/notification_subtext_size</item> - </style> - <style name="TextAppearance.StatusBar.Quantum.EventContent.Time"> - <item name="android:textSize">@dimen/notification_subtext_size</item> - </style> - <style name="TextAppearance.StatusBar.Quantum.EventContent.Emphasis"> - <item name="android:textColor">#66000000</item> - </style> - <style name="Widget.StatusBar.Quantum.ProgressBar" - parent="Widget.Quantum.Light.ProgressBar.Horizontal"> - <item name="android:progressDrawable">@drawable/notification_quantum_media_progress</item> - </style> - - <style name="Widget.StatusBar.Quantum.ProgressBar" - parent="Widget.Quantum.Light.ProgressBar.Horizontal"> - </style> - <style name="TextAppearance.Small.CalendarViewWeekDayView"> <item name="android:textStyle">bold</item> </style> diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml index e528278..2e7a5b1 100644 --- a/core/res/res/values/styles_quantum.xml +++ b/core/res/res/values/styles_quantum.xml @@ -182,7 +182,10 @@ please see styles_device_defaults.xml. <item name="textColorLink">?attr/textColorLinkInverse</item> </style> - <style name="TextAppearance.Quantum.Large" parent="TextAppearance.Quantum.Headline" /> + <style name="TextAppearance.Quantum.Large"> + <item name="textSize">@dimen/text_size_large_quantum</item> + <item name="textColor">?attr/textColorPrimary</item> + </style> <style name="TextAppearance.Quantum.Large.Inverse"> <item name="textColor">?attr/textColorPrimaryInverse</item> @@ -191,7 +194,10 @@ please see styles_device_defaults.xml. <item name="textColorLink">?attr/textColorLinkInverse</item> </style> - <style name="TextAppearance.Quantum.Medium" parent="TextAppearance.Quantum.Body1" /> + <style name="TextAppearance.Quantum.Medium"> + <item name="textSize">@dimen/text_size_medium_quantum</item> + <item name="textColor">?attr/textColorSecondary</item> + </style> <style name="TextAppearance.Quantum.Medium.Inverse"> <item name="textColor">?attr/textColorSecondaryInverse</item> @@ -200,7 +206,10 @@ please see styles_device_defaults.xml. <item name="textColorLink">?attr/textColorLinkInverse</item> </style> - <style name="TextAppearance.Quantum.Small" parent="TextAppearance.Quantum.Caption" /> + <style name="TextAppearance.Quantum.Small"> + <item name="textSize">@dimen/text_size_small_quantum</item> + <item name="textColor">?attr/textColorTertiary</item> + </style> <style name="TextAppearance.Quantum.Small.Inverse"> <item name="textColor">?attr/textColorTertiaryInverse</item> @@ -351,6 +360,38 @@ please see styles_device_defaults.xml. <item name="textStyle">bold</item> </style> + <style name="TextAppearance.StatusBar.Quantum" /> + + <style name="TextAppearance.StatusBar.Quantum.EventContent"> + <item name="android:textColor">#90000000</item> + <item name="android:textSize">@dimen/notification_text_size</item> + </style> + + <style name="TextAppearance.StatusBar.Quantum.EventContent.Title"> + <item name="android:textColor">#DD000000</item> + <item name="android:textSize">@dimen/notification_title_text_size</item> + </style> + + <style name="TextAppearance.StatusBar.Quantum.EventContent.Line2"> + <item name="android:textSize">@dimen/notification_subtext_size</item> + </style> + + <style name="TextAppearance.StatusBar.Quantum.EventContent.Info"> + <item name="android:textSize">@dimen/notification_subtext_size</item> + </style> + + <style name="TextAppearance.StatusBar.Quantum.EventContent.Time"> + <item name="android:textSize">@dimen/notification_subtext_size</item> + </style> + + <style name="TextAppearance.StatusBar.Quantum.EventContent.Emphasis"> + <item name="android:textColor">#66000000</item> + </style> + + <style name="Widget.StatusBar.Quantum.ProgressBar" parent="Widget.Quantum.Light.ProgressBar.Horizontal"> + <item name="android:progressDrawable">@drawable/notification_quantum_media_progress</item> + </style> + <!-- Widget Styles --> <style name="Quantum"/> @@ -390,7 +431,7 @@ please see styles_device_defaults.xml. </style> <style name="Widget.Quantum.Button.Toggle"> - <item name="background">@drawable/btn_toggle_holo_dark</item> + <item name="background">@drawable/btn_toggle_quantum</item> <item name="textOn">@string/capital_on</item> <item name="textOff">@string/capital_off</item> <item name="textAppearance">?attr/textAppearanceSmall</item> @@ -459,13 +500,13 @@ please see styles_device_defaults.xml. <style name="Widget.Quantum.CompoundButton.Switch"> <item name="track">@drawable/switch_track_quantum</item> - <item name="thumb">@drawable/switch_inner_quantum</item> + <item name="thumb">@drawable/switch_thumb_quantum_anim</item> <item name="splitTrack">true</item> <item name="switchTextAppearance">@style/TextAppearance.Quantum.Widget.Switch</item> <item name="textOn"></item> <item name="textOff"></item> - <item name="switchMinWidth">72dip</item> - <item name="switchPadding">16dip</item> + <item name="switchMinWidth">4dip</item> + <item name="switchPadding">4dip</item> <item name="background">?attr/selectableItemBackground</item> </style> @@ -579,7 +620,7 @@ please see styles_device_defaults.xml. <item name="indeterminateOnly">false</item> <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum</item> <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum</item> - <item name="thumb">@drawable/scrubber_control_selector_quantum</item> + <item name="thumb">@drawable/scrubber_control_quantum_anim</item> <item name="splitTrack">true</item> <item name="focusable">true</item> <item name="paddingStart">16dip</item> @@ -784,15 +825,7 @@ please see styles_device_defaults.xml. <style name="Widget.Quantum.Light.Button.Borderless" parent="Widget.Quantum.Button.Borderless"/> <style name="Widget.Quantum.Light.Button.Borderless.Small" parent="Widget.Quantum.Button.Borderless.Small"/> <style name="Widget.Quantum.Light.Button.Inset" parent="Widget.Quantum.Button.Inset"/> - - <style name="Widget.Quantum.Light.Button.Toggle"> - <item name="background">@drawable/btn_toggle_holo_light</item> - <item name="textOn">@string/capital_on</item> - <item name="textOff">@string/capital_off</item> - <item name="textAppearance">?attr/textAppearanceSmall</item> - <item name="minHeight">48dip</item> - </style> - + <style name="Widget.Quantum.Light.Button.Toggle" parent="Widget.Quantum.Button.Toggle" /> <style name="Widget.Quantum.Light.ButtonBar" parent="Widget.Quantum.ButtonBar"/> <style name="Widget.Quantum.Light.ButtonBar.AlertDialog" parent="Widget.Quantum.ButtonBar.AlertDialog"/> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index dcff978..69f73e5 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -69,8 +69,6 @@ <java-symbol type="id" name="edittext_container" /> <java-symbol type="id" name="enter_pin_section" /> <java-symbol type="id" name="expand_activities_button" /> - <java-symbol type="id" name="expand_button" /> - <java-symbol type="id" name="expand_button_divider" /> <java-symbol type="id" name="expires_on" /> <java-symbol type="id" name="find_next" /> <java-symbol type="id" name="find_prev" /> @@ -161,9 +159,7 @@ <java-symbol type="id" name="share" /> <java-symbol type="id" name="shortcut" /> <java-symbol type="id" name="skip_button" /> - <java-symbol type="id" name="slider_group" /> <java-symbol type="id" name="split_action_bar" /> - <java-symbol type="id" name="stream_icon" /> <java-symbol type="id" name="submit_area" /> <java-symbol type="id" name="switch_new" /> <java-symbol type="id" name="switch_old" /> @@ -181,7 +177,6 @@ <java-symbol type="id" name="topPanel" /> <java-symbol type="id" name="up" /> <java-symbol type="id" name="value" /> - <java-symbol type="id" name="visible_panel" /> <java-symbol type="id" name="websearch" /> <java-symbol type="id" name="wifi_p2p_wps_pin" /> <java-symbol type="id" name="year" /> @@ -343,7 +338,6 @@ <java-symbol type="dimen" name="search_view_preferred_width" /> <java-symbol type="dimen" name="textview_error_popup_default_width" /> <java-symbol type="dimen" name="toast_y_offset" /> - <java-symbol type="dimen" name="volume_panel_top" /> <java-symbol type="dimen" name="action_bar_stacked_max_height" /> <java-symbol type="dimen" name="action_bar_stacked_tab_max_width" /> <java-symbol type="dimen" name="notification_text_size" /> @@ -1199,8 +1193,6 @@ <java-symbol type="layout" name="time_picker_legacy" /> <java-symbol type="layout" name="time_picker_dialog" /> <java-symbol type="layout" name="transient_notification" /> - <java-symbol type="layout" name="volume_adjust" /> - <java-symbol type="layout" name="volume_adjust_item" /> <java-symbol type="layout" name="voice_interaction_session" /> <java-symbol type="layout" name="web_text_view_dropdown" /> <java-symbol type="layout" name="webview_find" /> diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk index 452c575..c6bccfe 100644 --- a/data/fonts/Android.mk +++ b/data/fonts/Android.mk @@ -105,8 +105,11 @@ font_src_files := \ ifeq ($(MINIMAL_FONT_FOOTPRINT),true) +$(eval $(call create-font-symlink,Roboto-Black.ttf,Roboto-Bold.ttf)) $(eval $(call create-font-symlink,Roboto-Light.ttf,Roboto-Regular.ttf)) $(eval $(call create-font-symlink,Roboto-LightItalic.ttf,Roboto-Italic.ttf)) +$(eval $(call create-font-symlink,Roboto-Medium.ttf,Roboto-Regular.ttf)) +$(eval $(call create-font-symlink,Roboto-MediumItalic.ttf,Roboto-Italic.ttf)) $(eval $(call create-font-symlink,Roboto-Thin.ttf,Roboto-Regular.ttf)) $(eval $(call create-font-symlink,Roboto-ThinItalic.ttf,Roboto-Italic.ttf)) $(eval $(call create-font-symlink,RobotoCondensed-Regular.ttf,Roboto-Regular.ttf)) @@ -116,8 +119,11 @@ $(eval $(call create-font-symlink,RobotoCondensed-BoldItalic.ttf,Roboto-BoldItal else # !MINIMAL_FONT font_src_files += \ + Roboto-Black.ttf \ Roboto-Light.ttf \ Roboto-LightItalic.ttf \ + Roboto-Medium.ttf \ + Roboto-MediumItalic.ttf \ Roboto-Thin.ttf \ Roboto-ThinItalic.ttf \ RobotoCondensed-Regular.ttf \ diff --git a/data/fonts/Roboto-Black.ttf b/data/fonts/Roboto-Black.ttf Binary files differnew file mode 100644 index 0000000..2cdbe43 --- /dev/null +++ b/data/fonts/Roboto-Black.ttf diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf Binary files differindex c5b9c67..15c9b4e 100644 --- a/data/fonts/Roboto-Bold.ttf +++ b/data/fonts/Roboto-Bold.ttf diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf Binary files differindex 0320214..a0abf30 100644 --- a/data/fonts/Roboto-BoldItalic.ttf +++ b/data/fonts/Roboto-BoldItalic.ttf diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf Binary files differindex 38ba570..67b5394 100644 --- a/data/fonts/Roboto-Italic.ttf +++ b/data/fonts/Roboto-Italic.ttf diff --git a/data/fonts/Roboto-Light.ttf b/data/fonts/Roboto-Light.ttf Binary files differindex 271606b..d9fb64a 100644 --- a/data/fonts/Roboto-Light.ttf +++ b/data/fonts/Roboto-Light.ttf diff --git a/data/fonts/Roboto-LightItalic.ttf b/data/fonts/Roboto-LightItalic.ttf Binary files differindex 17ef355..1fd1d31 100644 --- a/data/fonts/Roboto-LightItalic.ttf +++ b/data/fonts/Roboto-LightItalic.ttf diff --git a/data/fonts/Roboto-Medium.ttf b/data/fonts/Roboto-Medium.ttf Binary files differnew file mode 100644 index 0000000..c63c115 --- /dev/null +++ b/data/fonts/Roboto-Medium.ttf diff --git a/data/fonts/Roboto-MediumItalic.ttf b/data/fonts/Roboto-MediumItalic.ttf Binary files differnew file mode 100644 index 0000000..cd7c835 --- /dev/null +++ b/data/fonts/Roboto-MediumItalic.ttf diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf Binary files differindex 7469063..9cb4a5a 100644 --- a/data/fonts/Roboto-Regular.ttf +++ b/data/fonts/Roboto-Regular.ttf diff --git a/data/fonts/Roboto-Thin.ttf b/data/fonts/Roboto-Thin.ttf Binary files differindex 74efe4d..f02f100 100644 --- a/data/fonts/Roboto-Thin.ttf +++ b/data/fonts/Roboto-Thin.ttf diff --git a/data/fonts/Roboto-ThinItalic.ttf b/data/fonts/Roboto-ThinItalic.ttf Binary files differindex f08ea51..12a2ce0 100644 --- a/data/fonts/Roboto-ThinItalic.ttf +++ b/data/fonts/Roboto-ThinItalic.ttf diff --git a/data/fonts/RobotoCondensed-Bold.ttf b/data/fonts/RobotoCondensed-Bold.ttf Binary files differindex 1252d00..1079af6 100644 --- a/data/fonts/RobotoCondensed-Bold.ttf +++ b/data/fonts/RobotoCondensed-Bold.ttf diff --git a/data/fonts/RobotoCondensed-BoldItalic.ttf b/data/fonts/RobotoCondensed-BoldItalic.ttf Binary files differindex e914a07..e7f13c2 100644 --- a/data/fonts/RobotoCondensed-BoldItalic.ttf +++ b/data/fonts/RobotoCondensed-BoldItalic.ttf diff --git a/data/fonts/RobotoCondensed-Italic.ttf b/data/fonts/RobotoCondensed-Italic.ttf Binary files differindex 8a570cf..7fa0448 100644 --- a/data/fonts/RobotoCondensed-Italic.ttf +++ b/data/fonts/RobotoCondensed-Italic.ttf diff --git a/data/fonts/RobotoCondensed-Light.ttf b/data/fonts/RobotoCondensed-Light.ttf Binary files differindex 41d212a..96b75dd 100644 --- a/data/fonts/RobotoCondensed-Light.ttf +++ b/data/fonts/RobotoCondensed-Light.ttf diff --git a/data/fonts/RobotoCondensed-LightItalic.ttf b/data/fonts/RobotoCondensed-LightItalic.ttf Binary files differindex dd54971..7a2c164 100755..100644 --- a/data/fonts/RobotoCondensed-LightItalic.ttf +++ b/data/fonts/RobotoCondensed-LightItalic.ttf diff --git a/data/fonts/RobotoCondensed-Regular.ttf b/data/fonts/RobotoCondensed-Regular.ttf Binary files differindex a16b9cb..734cc40 100644 --- a/data/fonts/RobotoCondensed-Regular.ttf +++ b/data/fonts/RobotoCondensed-Regular.ttf diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk index 2312a04..e5573bb 100644 --- a/data/fonts/fonts.mk +++ b/data/fonts/fonts.mk @@ -24,8 +24,11 @@ PRODUCT_PACKAGES := \ Roboto-Bold.ttf \ Roboto-Italic.ttf \ Roboto-BoldItalic.ttf \ + Roboto-Black.ttf \ Roboto-Light.ttf \ Roboto-LightItalic.ttf \ + Roboto-Medium.ttf \ + Roboto-MediumItalic.ttf \ Roboto-Thin.ttf \ Roboto-ThinItalic.ttf \ RobotoCondensed-Regular.ttf \ diff --git a/data/fonts/system_fonts.xml b/data/fonts/system_fonts.xml index 97b7fd8..646b33b 100644 --- a/data/fonts/system_fonts.xml +++ b/data/fonts/system_fonts.xml @@ -68,6 +68,25 @@ <family> <nameset> + <name>sans-serif-medium</name> + </nameset> + <fileset> + <file>Roboto-Medium.ttf</file> + <file>Roboto-MediumItalic.ttf</file> + </fileset> + </family> + + <family> + <nameset> + <name>sans-serif-black</name> + </nameset> + <fileset> + <file>Roboto-Black.ttf</file> + </fileset> + </family> + + <family> + <nameset> <name>sans-serif-condensed-light</name> </nameset> <fileset> diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java index b7673d8..3ab57c1 100644 --- a/graphics/java/android/graphics/BitmapShader.java +++ b/graphics/java/android/graphics/BitmapShader.java @@ -44,7 +44,6 @@ public class BitmapShader extends Shader { mTileY = tileY; final long b = bitmap.ni(); native_instance = nativeCreate(b, tileX.nativeInt, tileY.nativeInt); - native_shader = nativePostCreate(native_instance, b, tileX.nativeInt, tileY.nativeInt); } /** @@ -59,6 +58,4 @@ public class BitmapShader extends Shader { private static native long nativeCreate(long native_bitmap, int shaderTileModeX, int shaderTileModeY); - private static native long nativePostCreate(long native_shader, long native_bitmap, - int shaderTileModeX, int shaderTileModeY); } diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java index 5109ffd..d7b2071 100644 --- a/graphics/java/android/graphics/ComposeShader.java +++ b/graphics/java/android/graphics/ComposeShader.java @@ -55,14 +55,6 @@ public class ComposeShader extends Shader { mXferMode = mode; native_instance = nativeCreate1(shaderA.native_instance, shaderB.native_instance, (mode != null) ? mode.native_instance : 0); - if (mode instanceof PorterDuffXfermode) { - PorterDuff.Mode pdMode = ((PorterDuffXfermode) mode).mode; - native_shader = nativePostCreate2(native_instance, shaderA.native_shader, - shaderB.native_shader, pdMode != null ? pdMode.nativeInt : 0); - } else { - native_shader = nativePostCreate1(native_instance, shaderA.native_shader, - shaderB.native_shader, mode != null ? mode.native_instance : 0); - } } /** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode. @@ -79,8 +71,6 @@ public class ComposeShader extends Shader { mPorterDuffMode = mode; native_instance = nativeCreate2(shaderA.native_instance, shaderB.native_instance, mode.nativeInt); - native_shader = nativePostCreate2(native_instance, shaderA.native_shader, - shaderB.native_shader, mode.nativeInt); } /** @@ -108,8 +98,4 @@ public class ComposeShader extends Shader { long native_mode); private static native long nativeCreate2(long native_shaderA, long native_shaderB, int porterDuffMode); - private static native long nativePostCreate1(long native_shader, long native_skiaShaderA, - long native_skiaShaderB, long native_mode); - private static native long nativePostCreate2(long native_shader, long native_skiaShaderA, - long native_skiaShaderB, int porterDuffMode); } diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java index 0eae67c..90cb217 100644 --- a/graphics/java/android/graphics/LinearGradient.java +++ b/graphics/java/android/graphics/LinearGradient.java @@ -66,8 +66,6 @@ public class LinearGradient extends Shader { mPositions = positions; mTileMode = tile; native_instance = nativeCreate1(x0, y0, x1, y1, colors, positions, tile.nativeInt); - native_shader = nativePostCreate1(native_instance, x0, y0, x1, y1, colors, positions, - tile.nativeInt); } /** Create a shader that draws a linear gradient along a line. @@ -90,8 +88,6 @@ public class LinearGradient extends Shader { mColor1 = color1; mTileMode = tile; native_instance = nativeCreate2(x0, y0, x1, y1, color0, color1, tile.nativeInt); - native_shader = nativePostCreate2(native_instance, x0, y0, x1, y1, color0, color1, - tile.nativeInt); } /** @@ -120,8 +116,4 @@ public class LinearGradient extends Shader { int colors[], float positions[], int tileMode); private native long nativeCreate2(float x0, float y0, float x1, float y1, int color0, int color1, int tileMode); - private native long nativePostCreate1(long native_shader, float x0, float y0, float x1, float y1, - int colors[], float positions[], int tileMode); - private native long nativePostCreate2(long native_shader, float x0, float y0, float x1, float y1, - int color0, int color1, int tileMode); } diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java index c00c612..75c951a 100644 --- a/graphics/java/android/graphics/RadialGradient.java +++ b/graphics/java/android/graphics/RadialGradient.java @@ -66,8 +66,6 @@ public class RadialGradient extends Shader { mPositions = positions; mTileMode = tile; native_instance = nativeCreate1(x, y, radius, colors, positions, tile.nativeInt); - native_shader = nativePostCreate1(native_instance, x, y, radius, colors, positions, - tile.nativeInt); } /** Create a shader that draws a radial gradient given the center and radius. @@ -91,8 +89,6 @@ public class RadialGradient extends Shader { mColor1 = color1; mTileMode = tile; native_instance = nativeCreate2(x, y, radius, color0, color1, tile.nativeInt); - native_shader = nativePostCreate2(native_instance, x, y, radius, color0, color1, - tile.nativeInt); } /** @@ -121,10 +117,5 @@ public class RadialGradient extends Shader { int colors[], float positions[], int tileMode); private static native long nativeCreate2(float x, float y, float radius, int color0, int color1, int tileMode); - - private static native long nativePostCreate1(long native_shader, float x, float y, float radius, - int colors[], float positions[], int tileMode); - private static native long nativePostCreate2(long native_shader, float x, float y, float radius, - int color0, int color1, int tileMode); } diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java index 94b4c4a..6870ab4 100644 --- a/graphics/java/android/graphics/Shader.java +++ b/graphics/java/android/graphics/Shader.java @@ -29,10 +29,6 @@ public class Shader { * @hide */ public long native_instance; - /** - * @hide - */ - public long native_shader; private Matrix mLocalMatrix; @@ -78,7 +74,7 @@ public class Shader { */ public void setLocalMatrix(Matrix localM) { mLocalMatrix = localM; - nativeSetLocalMatrix(native_instance, native_shader, + nativeSetLocalMatrix(native_instance, localM == null ? 0 : localM.native_instance); } @@ -86,7 +82,7 @@ public class Shader { try { super.finalize(); } finally { - nativeDestructor(native_instance, native_shader); + nativeDestructor(native_instance); } } @@ -112,7 +108,7 @@ public class Shader { } } - private static native void nativeDestructor(long native_shader, long native_skiaShader); + private static native void nativeDestructor(long native_shader); private static native void nativeSetLocalMatrix(long native_shader, - long native_skiaShader, long matrix_instance); + long matrix_instance); } diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java index 21239f7..18a748f 100644 --- a/graphics/java/android/graphics/SweepGradient.java +++ b/graphics/java/android/graphics/SweepGradient.java @@ -63,7 +63,6 @@ public class SweepGradient extends Shader { mColors = colors; mPositions = positions; native_instance = nativeCreate1(cx, cy, colors, positions); - native_shader = nativePostCreate1(native_instance, cx, cy, colors, positions); } /** @@ -81,7 +80,6 @@ public class SweepGradient extends Shader { mColor0 = color0; mColor1 = color1; native_instance = nativeCreate2(cx, cy, color0, color1); - native_shader = nativePostCreate2(native_instance, cx, cy, color0, color1); } /** @@ -108,10 +106,5 @@ public class SweepGradient extends Shader { private static native long nativeCreate1(float x, float y, int colors[], float positions[]); private static native long nativeCreate2(float x, float y, int color0, int color1); - - private static native long nativePostCreate1(long native_shader, float cx, float cy, - int[] colors, float[] positions); - private static native long nativePostCreate2(long native_shader, float cx, float cy, - int color0, int color1); } diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index 46e3401..42872e9 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -80,6 +80,22 @@ public class AnimatedStateListDrawable extends StateListDrawable { this(null, null); } + @Override + public boolean setVisible(boolean visible, boolean restart) { + final boolean changed = super.setVisible(visible, restart); + if (mAnim != null) { + if (visible) { + if (changed || restart) { + // TODO: Should this support restart? + mAnim.end(); + } + } else { + mAnim.end(); + } + } + return changed; + } + /** * Add a new drawable to the set of keyframes. * diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index f3fcf2c..c95ac82 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -25,6 +25,7 @@ import android.graphics.BitmapFactory; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.ColorFilter; +import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; @@ -92,6 +93,9 @@ public class BitmapDrawable extends Drawable { private int mBitmapWidth; private int mBitmapHeight; + /** Optical insets due to gravity. */ + private Insets mOpticalInsets = null; + // Mirroring matrix for using with Shaders private Matrix mMirrorMatrix; @@ -456,9 +460,9 @@ public class BitmapDrawable extends Drawable { @Override protected void onBoundsChange(Rect bounds) { - super.onBoundsChange(bounds); mApplyGravity = true; - Shader shader = mBitmapState.mPaint.getShader(); + + final Shader shader = mBitmapState.mPaint.getShader(); if (shader != null) { if (needMirroring()) { updateMirrorMatrix(bounds.right - bounds.left); @@ -517,9 +521,7 @@ public class BitmapDrawable extends Drawable { final boolean needMirroring = needMirroring(); if (shader == null) { if (mApplyGravity) { - final int layoutDirection = getLayoutDirection(); - Gravity.apply(state.mGravity, mBitmapWidth, mBitmapHeight, - getBounds(), mDstRect, layoutDirection); + applyGravity(); mApplyGravity = false; } @@ -564,6 +566,31 @@ public class BitmapDrawable extends Drawable { } } + /** + * @hide + */ + @Override + public Insets getOpticalInsets() { + if (mApplyGravity && mBitmapState.mPaint.getShader() == null) { + applyGravity(); + mApplyGravity = false; + } + return mOpticalInsets == null ? Insets.NONE : mOpticalInsets; + } + + private void applyGravity() { + final Rect bounds = getBounds(); + final int layoutDirection = getLayoutDirection(); + Gravity.apply(mBitmapState.mGravity, mBitmapWidth, mBitmapHeight, + bounds, mDstRect, layoutDirection); + + final int left = mDstRect.left - bounds.left; + final int top = mDstRect.top - bounds.top; + final int right = bounds.right - mDstRect.right; + final int bottom = bounds.bottom - mDstRect.bottom; + mOpticalInsets = Insets.of(left, top, right, bottom); + } + @Override public void setAlpha(int alpha) { final int oldAlpha = mBitmapState.mPaint.getAlpha(); diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 04373d4..2aef39f 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -187,6 +187,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } if (mCurrDrawable != null) { mCurrDrawable.setBounds(bounds); + + // Must obtain optical insets after setting bounds. + mInsets = mCurrDrawable.getOpticalInsets(); } } @@ -385,7 +388,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { mCurrDrawable = d; mCurIndex = idx; if (d != null) { - mInsets = d.getOpticalInsets(); d.mutate(); if (mDrawableContainerState.mEnterFadeDuration > 0) { mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration; @@ -402,6 +404,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { d.setBounds(getBounds()); d.setLayoutDirection(getLayoutDirection()); d.setAutoMirrored(mDrawableContainerState.mAutoMirrored); + + // Must obtain optical insets after setting bounds. + mInsets = d.getOpticalInsets(); } else { mInsets = Insets.NONE; } diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index e3ed75e..9a63fa3 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -101,6 +101,7 @@ import java.util.HashMap; * <dd>Sets the Miter limit for a stroked path</dd></dt> * </dl> * </dd> + * @hide */ public class VectorDrawable extends Drawable { private static final String LOGTAG = VectorDrawable.class.getSimpleName(); @@ -159,7 +160,8 @@ public class VectorDrawable extends Drawable { @Override public void setColorFilter(ColorFilter colorFilter) { - // TODO: support color filter + mVectorState.mVPathRenderer.setColorFilter(colorFilter); + invalidateSelf(); } @Override @@ -365,14 +367,15 @@ public class VectorDrawable extends Drawable { private VPath[] mCurrentPaths; private Paint mStrokePaint; private Paint mFillPaint; + private ColorFilter mColorFilter; private PathMeasure mPathMeasure; private VGroup mCurrentGroup = new VGroup(); - float mBaseWidth = 1; - float mBaseHeight = 1; - float mViewportWidth; - float mViewportHeight; + float mBaseWidth = 0; + float mBaseHeight = 0; + float mViewportWidth = 0; + float mViewportHeight = 0; public VPathRenderer() { } @@ -413,6 +416,18 @@ public class VectorDrawable extends Drawable { } } + public void setColorFilter(ColorFilter colorFilter) { + mColorFilter = colorFilter; + + if (mFillPaint != null) { + mFillPaint.setColorFilter(colorFilter); + } + + if (mStrokePaint != null) { + mStrokePaint.setColorFilter(colorFilter); + } + } + public void draw(Canvas canvas, int w, int h) { if (mCurrentPaths == null) { Log.e(LOGTAG,"mCurrentPaths == null"); @@ -470,6 +485,7 @@ public class VectorDrawable extends Drawable { if (vPath.mFillColor != 0) { if (mFillPaint == null) { mFillPaint = new Paint(); + mFillPaint.setColorFilter(mColorFilter); mFillPaint.setStyle(Paint.Style.FILL); mFillPaint.setAntiAlias(true); } @@ -481,6 +497,7 @@ public class VectorDrawable extends Drawable { if (vPath.mStrokeColor != 0) { if (mStrokePaint == null) { mStrokePaint = new Paint(); + mStrokePaint.setColorFilter(mColorFilter); mStrokePaint.setStyle(Paint.Style.STROKE); mStrokePaint.setAntiAlias(true); } @@ -516,24 +533,34 @@ public class VectorDrawable extends Drawable { private void parseViewport(Resources r, AttributeSet attrs) throws XmlPullParserException { final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableViewport); - mViewportWidth = a.getFloat(R.styleable.VectorDrawableViewport_viewportWidth, 0); - mViewportHeight = a.getFloat(R.styleable.VectorDrawableViewport_viewportHeight, 0); - if (mViewportWidth == 0 || mViewportHeight == 0) { - throw new XmlPullParserException(a.getPositionDescription()+ - "<viewport> tag requires viewportWidth & viewportHeight to be set"); + mViewportWidth = a.getFloat(R.styleable.VectorDrawableViewport_viewportWidth, mViewportWidth); + mViewportHeight = a.getFloat(R.styleable.VectorDrawableViewport_viewportHeight, mViewportHeight); + + if (mViewportWidth <= 0) { + throw new XmlPullParserException(a.getPositionDescription() + + "<viewport> tag requires viewportWidth > 0"); + } else if (mViewportHeight <= 0) { + throw new XmlPullParserException(a.getPositionDescription() + + "<viewport> tag requires viewportHeight > 0"); } + a.recycle(); } private void parseSize(Resources r, AttributeSet attrs) throws XmlPullParserException { final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize); - mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, 0); - mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, 0); - if (mBaseWidth == 0 || mBaseHeight == 0) { - throw new XmlPullParserException(a.getPositionDescription()+ - "<size> tag requires width & height to be set"); + mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, mBaseWidth); + mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, mBaseHeight); + + if (mBaseWidth <= 0) { + throw new XmlPullParserException(a.getPositionDescription() + + "<size> tag requires width > 0"); + } else if (mBaseHeight <= 0) { + throw new XmlPullParserException(a.getPositionDescription() + + "<size> tag requires height > 0"); } + a.recycle(); } diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 2e2ee15..5367663 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -33,6 +33,7 @@ #include "thread/TaskManager.h" #include "AssetAtlas.h" +#include "Extensions.h" #include "FontRenderer.h" #include "GammaFontRenderer.h" #include "TextureCache.h" diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp index 3016814..937bf8d 100644 --- a/libs/hwui/DeferredDisplayList.cpp +++ b/libs/hwui/DeferredDisplayList.cpp @@ -230,6 +230,11 @@ public: return false; } + if (op->mPaint && mOps[0].op->mPaint && + op->mPaint->getShader() != mOps[0].op->mPaint->getShader()) { + return false; + } + /* Draw Modifiers compatibility check * * Shadows are ignored, as only text uses them, and in that case they are drawn @@ -244,7 +249,6 @@ public: */ const DrawModifiers& lhsMod = lhs->mDrawModifiers; const DrawModifiers& rhsMod = rhs->mDrawModifiers; - if (lhsMod.mShader != rhsMod.mShader) return false; // Draw filter testing expects bit fields to be clear if filter not set. if (lhsMod.mHasDrawFilter != rhsMod.mHasDrawFilter) return false; diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index dac86cb..96c6292 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -58,11 +58,6 @@ void DisplayListData::cleanupResources() { caches.resourceCache.decrementRefcountLocked(patchResources.itemAt(i)); } - for (size_t i = 0; i < shaders.size(); i++) { - caches.resourceCache.decrementRefcountLocked(shaders.itemAt(i)); - caches.resourceCache.destructorLocked(shaders.itemAt(i)); - } - for (size_t i = 0; i < sourcePaths.size(); i++) { caches.resourceCache.decrementRefcountLocked(sourcePaths.itemAt(i)); } @@ -92,7 +87,6 @@ void DisplayListData::cleanupResources() { bitmapResources.clear(); ownedBitmapResources.clear(); patchResources.clear(); - shaders.clear(); sourcePaths.clear(); paints.clear(); regions.clear(); diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index b2ead5b..11e78b0 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -56,7 +56,6 @@ class DisplayListRenderer; class OpenGLRenderer; class Rect; class Layer; -class SkiaShader; class ClipRectOp; class SaveLayerOp; @@ -127,7 +126,6 @@ public: SortedVector<const SkPath*> sourcePaths; Vector<const SkRegion*> regions; Vector<const SkMatrix*> matrices; - Vector<SkiaShader*> shaders; Vector<Layer*> layers; uint32_t functorCount; bool hasDrawOps; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index e4867220..ea3e7a8 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -208,9 +208,16 @@ protected: if (!state.mMatrix.isSimple()) return false; // check state/paint for transparency - if (state.mDrawModifiers.mShader || - state.mAlpha != 1.0f || - (mPaint && mPaint->getAlpha() != 0xFF)) return false; + if (mPaint) { + if (mPaint->getShader() && !mPaint->getShader()->isOpaque()) { + return false; + } + if (mPaint->getAlpha() != 0xFF) { + return false; + } + } + + if (state.mAlpha != 1.0f) return false; SkXfermode::Mode mode = OpenGLRenderer::getXfermodeDirect(mPaint); return (mode == SkXfermode::kSrcOver_Mode || @@ -592,37 +599,6 @@ private: const SkRegion* mRegion; }; -class ResetShaderOp : public StateOp { -public: - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.resetShader(); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOGS("ResetShader"); - } - - virtual const char* name() { return "ResetShader"; } -}; - -class SetupShaderOp : public StateOp { -public: - SetupShaderOp(SkiaShader* shader) - : mShader(shader) {} - virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { - renderer.setupShader(mShader); - } - - virtual void output(int level, uint32_t logFlags) const { - OP_LOG("SetupShader, shader %p", mShader); - } - - virtual const char* name() { return "SetupShader"; } - -private: - SkiaShader* mShader; -}; - class ResetPaintFilterOp : public StateOp { public: virtual void applyState(OpenGLRenderer& renderer, int saveCount) const { diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 606c67e..229afdf 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -47,7 +47,6 @@ DisplayListRenderer::~DisplayListRenderer() { /////////////////////////////////////////////////////////////////////////////// DisplayListData* DisplayListRenderer::finishRecording() { - mShaderMap.clear(); mPaintMap.clear(); mRegionMap.clear(); mPathMap.clear(); @@ -394,15 +393,6 @@ status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkP return DrawGlInfo::kStatusDone; } -void DisplayListRenderer::resetShader() { - addStateOp(new (alloc()) ResetShaderOp()); -} - -void DisplayListRenderer::setupShader(SkiaShader* shader) { - shader = refShader(shader); - addStateOp(new (alloc()) SetupShaderOp(shader)); -} - void DisplayListRenderer::resetPaintFilter() { addStateOp(new (alloc()) ResetPaintFilterOp()); } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index d814111..f0ae00f 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -95,9 +95,6 @@ public: virtual bool clipRegion(const SkRegion* region, SkRegion::Op op); // Misc - should be implemented with SkPaint inspection - virtual void resetShader(); - virtual void setupShader(SkiaShader* shader); - virtual void resetPaintFilter(); virtual void setupPaintFilter(int clearBits, int setBits); @@ -269,21 +266,6 @@ private: return bitmap; } - inline SkiaShader* refShader(SkiaShader* shader) { - if (!shader) return NULL; - - SkiaShader* shaderCopy = mShaderMap.valueFor(shader); - // TODO: We also need to handle generation ID changes in compose shaders - if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { - shaderCopy = shader->copy(); - // replaceValueFor() performs an add if the entry doesn't exist - mShaderMap.replaceValueFor(shader, shaderCopy); - mDisplayListData->shaders.add(shaderCopy); - mCaches.resourceCache.incrementRefcount(shaderCopy); - } - return shaderCopy; - } - inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) { mDisplayListData->patchResources.add(patch); mCaches.resourceCache.incrementRefcount(patch); @@ -293,7 +275,6 @@ private: DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap; DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap; DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap; - DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; Caches& mCaches; DisplayListData* mDisplayListData; diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 647c281..4407ab0 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -73,7 +73,7 @@ status_t TextSetupFunctor::operator ()(int what, void* data) { } } renderer->setupDrawColorFilter(paint->getColorFilter()); - renderer->setupDrawShader(); + renderer->setupDrawShader(paint->getShader()); renderer->setupDrawBlending(paint); renderer->setupDrawProgram(); renderer->setupDrawModelView(kModelViewMode_Translate, false, @@ -85,7 +85,7 @@ status_t TextSetupFunctor::operator ()(int what, void* data) { renderer->setupDrawTexture(0); renderer->setupDrawPureColorUniforms(); renderer->setupDrawColorFilterUniforms(paint->getColorFilter()); - renderer->setupDrawShaderUniforms(pureTranslate); + renderer->setupDrawShaderUniforms(paint->getShader(), pureTranslate); renderer->setupDrawTextGammaUniforms(); return NO_ERROR; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 691f1c9..71836dd 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -21,6 +21,7 @@ #include <sys/types.h> #include <SkCanvas.h> +#include <SkShader.h> #include <SkTypeface.h> #include <utils/Log.h> @@ -37,6 +38,7 @@ #include "PathTessellator.h" #include "Properties.h" #include "ShadowTessellator.h" +#include "SkiaShader.h" #include "utils/GLUtils.h" #include "Vector.h" #include "VertexBuffer.h" @@ -1053,6 +1055,45 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) #define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND) +// This class is purely for inspection. It inherits from SkShader, but Skia does not know how to +// use it. The OpenGLRenderer will look at it to find its Layer and whether it is opaque. +class LayerShader : public SkShader { +public: + LayerShader(Layer* layer, const SkMatrix* localMatrix) + : INHERITED(localMatrix) + , mLayer(layer) { + } + + virtual bool asACustomShader(void** data) const { + if (data) { + *data = static_cast<void*>(mLayer); + } + return true; + } + + virtual bool isOpaque() const { + return !mLayer->isBlend(); + } + +protected: + virtual void shadeSpan(int x, int y, SkPMColor[], int count) { + LOG_ALWAYS_FATAL("LayerShader should never be drawn with raster backend."); + } + + virtual void flatten(SkWriteBuffer&) const { + LOG_ALWAYS_FATAL("LayerShader should never be flattened."); + } + + virtual Factory getFactory() const { + LOG_ALWAYS_FATAL("LayerShader should never be created from a stream."); + return NULL; + } +private: + // Unowned. + Layer* mLayer; + typedef SkShader INHERITED; +}; + void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { if (CC_UNLIKELY(layer->region.isEmpty())) return; // nothing to draw @@ -1066,21 +1107,19 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { paint.setAntiAlias(true); paint.setColor(SkColorSetARGB(int(getLayerAlpha(layer) * 255), 0, 0, 0)); - SkiaShader* oldShader = mDrawModifiers.mShader; - // create LayerShader to map SaveLayer content into subsequent draw SkMatrix shaderMatrix; shaderMatrix.setTranslate(rect.left, rect.bottom); shaderMatrix.preScale(1, -1); - SkiaLayerShader layerShader(layer, &shaderMatrix); - mDrawModifiers.mShader = &layerShader; + LayerShader layerShader(layer, &shaderMatrix); + paint.setShader(&layerShader); // Since the drawing primitive is defined in local drawing space, // we don't need to modify the draw matrix const SkPath* maskPath = layer->getConvexMask(); DRAW_DOUBLE_STENCIL(drawConvexPath(*maskPath, &paint)); - mDrawModifiers.mShader = oldShader; + paint.setShader(NULL); restore(); return; @@ -1627,9 +1666,9 @@ void OpenGLRenderer::setupDrawColor(float r, float g, float b, float a) { mSetShaderColor = mDescription.setColorModulate(a); } -void OpenGLRenderer::setupDrawShader() { - if (mDrawModifiers.mShader) { - mDrawModifiers.mShader->describe(mDescription, mExtensions); +void OpenGLRenderer::setupDrawShader(const SkShader* shader) { + if (shader != NULL) { + SkiaShader::describe(&mCaches, mDescription, mExtensions, *shader); } } @@ -1655,15 +1694,21 @@ void OpenGLRenderer::accountForClear(SkXfermode::Mode mode) { } } +static bool isBlendedColorFilter(const SkColorFilter* filter) { + if (filter == NULL) { + return false; + } + return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0; +} + void OpenGLRenderer::setupDrawBlending(const Layer* layer, bool swapSrcDst) { SkXfermode::Mode mode = layer->getMode(); // When the blending mode is kClear_Mode, we need to use a modulate color // argb=1,0,0,0 accountForClear(mode); + // TODO: check shader blending, once we have shader drawing support for layers. bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f || - (mColorSet && mColorA < 1.0f) || - (mDrawModifiers.mShader && mDrawModifiers.mShader->blend()) || - layer->getColorFilter(); + (mColorSet && mColorA < 1.0f) || isBlendedColorFilter(layer->getColorFilter()); chooseBlending(blend, mode, mDescription, swapSrcDst); } @@ -1673,8 +1718,8 @@ void OpenGLRenderer::setupDrawBlending(const SkPaint* paint, bool blend, bool sw // argb=1,0,0,0 accountForClear(mode); blend |= (mColorSet && mColorA < 1.0f) || - (mDrawModifiers.mShader && mDrawModifiers.mShader->blend()) || - (paint && paint->getColorFilter()); + (getShader(paint) && !getShader(paint)->isOpaque()) || + isBlendedColorFilter(getColorFilter(paint)); chooseBlending(blend, mode, mDescription, swapSrcDst); } @@ -1717,8 +1762,8 @@ void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset, } } -void OpenGLRenderer::setupDrawColorUniforms() { - if ((mColorSet && !mDrawModifiers.mShader) || (mDrawModifiers.mShader && mSetShaderColor)) { +void OpenGLRenderer::setupDrawColorUniforms(bool hasShader) { + if ((mColorSet && !hasShader) || (hasShader && mSetShaderColor)) { mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA); } } @@ -1729,20 +1774,22 @@ void OpenGLRenderer::setupDrawPureColorUniforms() { } } -void OpenGLRenderer::setupDrawShaderUniforms(bool ignoreTransform) { - if (mDrawModifiers.mShader) { - if (ignoreTransform) { - // if ignoreTransform=true was passed to setupDrawModelView, undo currentTransform() - // because it was built into modelView / the geometry, and the SkiaShader needs to - // compensate. - mat4 modelViewWithoutTransform; - modelViewWithoutTransform.loadInverse(*currentTransform()); - modelViewWithoutTransform.multiply(mModelViewMatrix); - mModelViewMatrix.load(modelViewWithoutTransform); - } - mDrawModifiers.mShader->setupProgram(mCaches.currentProgram, - mModelViewMatrix, *mSnapshot, &mTextureUnit); +void OpenGLRenderer::setupDrawShaderUniforms(const SkShader* shader, bool ignoreTransform) { + if (shader == NULL) { + return; + } + + if (ignoreTransform) { + // if ignoreTransform=true was passed to setupDrawModelView, undo currentTransform() + // because it was built into modelView / the geometry, and the description needs to + // compensate. + mat4 modelViewWithoutTransform; + modelViewWithoutTransform.loadInverse(*currentTransform()); + modelViewWithoutTransform.multiply(mModelViewMatrix); + mModelViewMatrix.load(modelViewWithoutTransform); } + + SkiaShader::setupProgram(&mCaches, mModelViewMatrix, &mTextureUnit, mExtensions, *shader); } void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) { @@ -2201,7 +2248,7 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, // Apply a scale transform on the canvas only when a shader is in use // Skia handles the ratio between the dst and src rects as a scale factor // when a shader is set - bool useScaleTransform = mDrawModifiers.mShader && scaled; + bool useScaleTransform = getShader(paint) && scaled; bool ignoreTransform = false; if (CC_LIKELY(currentTransform()->isPureTranslate() && !useScaleTransform)) { @@ -2359,13 +2406,13 @@ status_t OpenGLRenderer::drawVertexBuffer(VertexBufferMode mode, if (isAA) setupDrawAA(); setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha); setupDrawColorFilter(getColorFilter(paint)); - setupDrawShader(); + setupDrawShader(getShader(paint)); setupDrawBlending(paint, isAA); setupDrawProgram(); setupDrawModelView(kModelViewMode_Translate, useOffset, 0, 0, 0, 0); - setupDrawColorUniforms(); + setupDrawColorUniforms(getShader(paint)); setupDrawColorFilterUniforms(getColorFilter(paint)); - setupDrawShaderUniforms(); + setupDrawShaderUniforms(getShader(paint)); const void* vertices = vertexBuffer.getBuffer(); bool force = mCaches.unbindMeshBuffer(); @@ -2670,7 +2717,7 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, const float sy = y - shadow->top + textShadow.dy; const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * mSnapshot->alpha; - if (mDrawModifiers.mShader) { + if (getShader(paint)) { textShadow.color = SK_ColorWHITE; } @@ -2678,7 +2725,7 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, setupDrawWithTexture(true); setupDrawAlpha8Color(textShadow.color, shadowAlpha < 255 ? shadowAlpha : alpha); setupDrawColorFilter(getColorFilter(paint)); - setupDrawShader(); + setupDrawShader(getShader(paint)); setupDrawBlending(paint, true); setupDrawProgram(); setupDrawModelView(kModelViewMode_TranslateAndScale, false, @@ -2686,7 +2733,7 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, setupDrawTexture(shadow->id); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); - setupDrawShaderUniforms(); + setupDrawShaderUniforms(getShader(paint)); setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); @@ -3008,21 +3055,6 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { } /////////////////////////////////////////////////////////////////////////////// -// Shaders -/////////////////////////////////////////////////////////////////////////////// - -void OpenGLRenderer::resetShader() { - mDrawModifiers.mShader = NULL; -} - -void OpenGLRenderer::setupShader(SkiaShader* shader) { - mDrawModifiers.mShader = shader; - if (mDrawModifiers.mShader) { - mDrawModifiers.mShader->setCaches(mCaches); - } -} - -/////////////////////////////////////////////////////////////////////////////// // Draw filters /////////////////////////////////////////////////////////////////////////////// @@ -3080,7 +3112,7 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture, setupDrawWithTexture(true); setupDrawAlpha8Color(paint->getColor(), alpha); setupDrawColorFilter(getColorFilter(paint)); - setupDrawShader(); + setupDrawShader(getShader(paint)); setupDrawBlending(paint, true); setupDrawProgram(); setupDrawModelView(kModelViewMode_TranslateAndScale, false, @@ -3088,7 +3120,7 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture, setupDrawTexture(texture->id); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); - setupDrawShaderUniforms(); + setupDrawShaderUniforms(getShader(paint)); setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); @@ -3254,7 +3286,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkP int color = paint->getColor(); // If a shader is set, preserve only the alpha - if (mDrawModifiers.mShader) { + if (getShader(paint)) { color |= 0x00ffffff; } @@ -3290,15 +3322,15 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkP setupDraw(); setupDrawNoTexture(); setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha); - setupDrawShader(); + setupDrawShader(getShader(paint)); setupDrawColorFilter(getColorFilter(paint)); setupDrawBlending(paint); setupDrawProgram(); setupDrawDirtyRegionsDisabled(); setupDrawModelView(kModelViewMode_Translate, false, 0.0f, 0.0f, 0.0f, 0.0f, ignoreTransform); - setupDrawColorUniforms(); - setupDrawShaderUniforms(); + setupDrawColorUniforms(getShader(paint)); + setupDrawShaderUniforms(getShader(paint)); setupDrawColorFilterUniforms(getColorFilter(paint)); if (dirty && hasLayer()) { @@ -3314,21 +3346,21 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot const SkPaint* paint, bool ignoreTransform) { int color = paint->getColor(); // If a shader is set, preserve only the alpha - if (mDrawModifiers.mShader) { + if (getShader(paint)) { color |= 0x00ffffff; } setupDraw(); setupDrawNoTexture(); setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha); - setupDrawShader(); + setupDrawShader(getShader(paint)); setupDrawColorFilter(getColorFilter(paint)); setupDrawBlending(paint); setupDrawProgram(); setupDrawModelView(kModelViewMode_TranslateAndScale, false, left, top, right, bottom, ignoreTransform); - setupDrawColorUniforms(); - setupDrawShaderUniforms(ignoreTransform); + setupDrawColorUniforms(getShader(paint)); + setupDrawShaderUniforms(getShader(paint), ignoreTransform); setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawSimpleMesh(); @@ -3441,7 +3473,7 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f setupDrawAlpha8Color(color, alpha); } setupDrawColorFilter(getColorFilter(paint)); - setupDrawShader(); + setupDrawShader(getShader(paint)); setupDrawBlending(paint, true); setupDrawProgram(); if (!dirty) setupDrawDirtyRegionsDisabled(); @@ -3449,7 +3481,7 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f setupDrawTexture(texture); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); - setupDrawShaderUniforms(ignoreTransform); + setupDrawShaderUniforms(getShader(paint), ignoreTransform); setupDrawMesh(vertices, texCoords); glDrawArrays(drawMode, 0, elementsCount); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index c6d9071..fc27947 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -26,7 +26,6 @@ #include <SkMatrix.h> #include <SkPaint.h> #include <SkRegion.h> -#include <SkShader.h> #include <SkXfermode.h> #include <utils/Blur.h> @@ -45,13 +44,15 @@ #include "Program.h" #include "Rect.h" #include "Renderer.h" -#include "StatefulBaseRenderer.h" #include "Snapshot.h" +#include "StatefulBaseRenderer.h" #include "UvMapper.h" #include "Vertex.h" #include "Caches.h" #include "CanvasProperty.h" +class SkShader; + namespace android { namespace uirenderer { @@ -59,7 +60,6 @@ class DeferredDisplayState; class RenderNode; class TextSetupFunctor; class VertexBuffer; -class SkiaShader; struct DrawModifiers { DrawModifiers() { @@ -70,7 +70,6 @@ struct DrawModifiers { memset(this, 0, sizeof(DrawModifiers)); } - SkiaShader* mShader; float mOverrideLayerAlpha; // Draw filters @@ -217,9 +216,6 @@ public: status_t drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ, float casterAlpha, bool casterUnclipped, const SkPath* casterPerimeter); - virtual void resetShader(); - virtual void setupShader(SkiaShader* shader); - virtual void resetPaintFilter(); virtual void setupPaintFilter(int clearBits, int setBits); @@ -467,6 +463,14 @@ protected: } /** + * Safely retrieves the Shader from the given Paint. If the paint is + * null then null is returned. + */ + static inline const SkShader* getShader(const SkPaint* paint) { + return paint ? paint->getShader() : NULL; + } + + /** * Set to true to suppress error checks at the end of a frame. */ virtual bool suppressErrorChecks() const { @@ -838,7 +842,7 @@ private: void setupDrawColor(float r, float g, float b, float a); void setupDrawAlpha8Color(int color, int alpha); void setupDrawTextGamma(const SkPaint* paint); - void setupDrawShader(); + void setupDrawShader(const SkShader* shader); void setupDrawColorFilter(const SkColorFilter* filter); void setupDrawBlending(const Layer* layer, bool swapSrcDst = false); void setupDrawBlending(const SkPaint* paint, bool blend = true, bool swapSrcDst = false); @@ -862,9 +866,17 @@ private: */ void setupDrawModelView(ModelViewMode mode, bool offset, float left, float top, float right, float bottom, bool ignoreTransform = false); - void setupDrawColorUniforms(); + void setupDrawColorUniforms(bool hasShader); void setupDrawPureColorUniforms(); - void setupDrawShaderUniforms(bool ignoreTransform = false); + + /** + * Setup uniforms for the current shader. + * + * @param shader SkShader on the current paint. + * + * @param ignoreTransform Set to true to ignore the transform in shader. + */ + void setupDrawShaderUniforms(const SkShader* shader, bool ignoreTransform = false); void setupDrawColorFilterUniforms(const SkColorFilter* paint); void setupDrawSimpleMesh(); void setupDrawTexture(GLuint texture); diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h index e191a26..23cab0e 100644 --- a/libs/hwui/Renderer.h +++ b/libs/hwui/Renderer.h @@ -35,7 +35,6 @@ class RenderNode; class Layer; class Matrix4; class SkiaColorFilter; -class SkiaShader; class Patch; enum DrawOpMode { @@ -183,9 +182,6 @@ public: virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0; // Misc - should be implemented with SkPaint inspection - virtual void resetShader() = 0; - virtual void setupShader(SkiaShader* shader) = 0; - virtual void resetPaintFilter() = 0; virtual void setupPaintFilter(int clearBits, int setBits) = 0; diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index 13a3e8e..8b553d1 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -71,11 +71,6 @@ void ResourceCache::incrementRefcount(const SkPath* pathResource) { incrementRefcount((void*) pathResource, kPath); } -void ResourceCache::incrementRefcount(SkiaShader* shaderResource) { - SkSafeRef(shaderResource->getSkShader()); - incrementRefcount((void*) shaderResource, kShader); -} - void ResourceCache::incrementRefcount(const Res_png_9patch* patchResource) { incrementRefcount((void*) patchResource, kNinePatch); } @@ -104,11 +99,6 @@ void ResourceCache::incrementRefcountLocked(const SkPath* pathResource) { incrementRefcountLocked((void*) pathResource, kPath); } -void ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) { - SkSafeRef(shaderResource->getSkShader()); - incrementRefcountLocked((void*) shaderResource, kShader); -} - void ResourceCache::incrementRefcountLocked(const Res_png_9patch* patchResource) { incrementRefcountLocked((void*) patchResource, kNinePatch); } @@ -132,11 +122,6 @@ void ResourceCache::decrementRefcount(const SkPath* pathResource) { decrementRefcount((void*) pathResource); } -void ResourceCache::decrementRefcount(SkiaShader* shaderResource) { - SkSafeUnref(shaderResource->getSkShader()); - decrementRefcount((void*) shaderResource); -} - void ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) { decrementRefcount((void*) patchResource); } @@ -168,11 +153,6 @@ void ResourceCache::decrementRefcountLocked(const SkPath* pathResource) { decrementRefcountLocked((void*) pathResource); } -void ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) { - SkSafeUnref(shaderResource->getSkShader()); - decrementRefcountLocked((void*) shaderResource); -} - void ResourceCache::decrementRefcountLocked(const Res_png_9patch* patchResource) { decrementRefcountLocked((void*) patchResource); } @@ -227,25 +207,6 @@ void ResourceCache::destructorLocked(const SkBitmap* resource) { } } -void ResourceCache::destructor(SkiaShader* resource) { - Mutex::Autolock _l(mLock); - destructorLocked(resource); -} - -void ResourceCache::destructorLocked(SkiaShader* resource) { - ssize_t index = mCache->indexOfKey(resource); - ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; - if (ref == NULL) { - // If we're not tracking this resource, just delete it - delete resource; - return; - } - ref->destroyed = true; - if (ref->refCount == 0) { - deleteResourceReferenceLocked(resource, ref); - } -} - void ResourceCache::destructor(Res_png_9patch* resource) { Mutex::Autolock _l(mLock); destructorLocked(resource); @@ -333,11 +294,6 @@ void ResourceCache::deleteResourceReferenceLocked(const void* resource, Resource } } break; - case kShader: { - SkiaShader* shader = (SkiaShader*) resource; - delete shader; - } - break; case kNinePatch: { if (Caches::hasInstance()) { Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource); diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h index 4097ba4..3864d4b 100644 --- a/libs/hwui/ResourceCache.h +++ b/libs/hwui/ResourceCache.h @@ -20,7 +20,6 @@ #include <cutils/compiler.h> #include <SkBitmap.h> -#include <SkiaShader.h> #include <utils/KeyedVector.h> @@ -36,7 +35,6 @@ namespace uirenderer { */ enum ResourceType { kBitmap, - kShader, kNinePatch, kPath, kLayer @@ -70,36 +68,30 @@ public: void incrementRefcount(const SkPath* resource); void incrementRefcount(const SkBitmap* resource); - void incrementRefcount(SkiaShader* resource); void incrementRefcount(const Res_png_9patch* resource); void incrementRefcount(Layer* resource); void incrementRefcountLocked(const SkPath* resource); void incrementRefcountLocked(const SkBitmap* resource); - void incrementRefcountLocked(SkiaShader* resource); void incrementRefcountLocked(const Res_png_9patch* resource); void incrementRefcountLocked(Layer* resource); void decrementRefcount(const SkBitmap* resource); void decrementRefcount(const SkPath* resource); - void decrementRefcount(SkiaShader* resource); void decrementRefcount(const Res_png_9patch* resource); void decrementRefcount(Layer* resource); void decrementRefcountLocked(const SkBitmap* resource); void decrementRefcountLocked(const SkPath* resource); - void decrementRefcountLocked(SkiaShader* resource); void decrementRefcountLocked(const Res_png_9patch* resource); void decrementRefcountLocked(Layer* resource); void destructor(SkPath* resource); void destructor(const SkBitmap* resource); - void destructor(SkiaShader* resource); void destructor(Res_png_9patch* resource); void destructorLocked(SkPath* resource); void destructorLocked(const SkBitmap* resource); - void destructorLocked(SkiaShader* resource); void destructorLocked(Res_png_9patch* resource); bool recycle(SkBitmap* resource); diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index 6a4a0c8..c672bc4 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -21,9 +21,10 @@ #include <SkMatrix.h> #include "Caches.h" +#include "Layer.h" +#include "Matrix.h" #include "SkiaShader.h" #include "Texture.h" -#include "Matrix.h" namespace android { namespace uirenderer { @@ -54,89 +55,142 @@ static inline void bindUniformColor(int slot, uint32_t color) { a); } -/////////////////////////////////////////////////////////////////////////////// -// Base shader -/////////////////////////////////////////////////////////////////////////////// - -void SkiaShader::copyFrom(const SkiaShader& shader) { - mType = shader.mType; - mKey = shader.mKey; - mTileX = shader.mTileX; - mTileY = shader.mTileY; - mBlend = shader.mBlend; - mUnitMatrix = shader.mUnitMatrix; - mShaderMatrix = shader.mShaderMatrix; - mGenerationId = shader.mGenerationId; +static inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) { + caches->bindTexture(texture->id); + texture->setWrapST(wrapS, wrapT); } -SkiaShader::SkiaShader(): mCaches(NULL) { -} +/** + * Compute the matrix to transform to screen space. + * @param screenSpace Output param for the computed matrix. + * @param unitMatrix The unit matrix for gradient shaders, as returned by SkShader::asAGradient, + * or identity. + * @param localMatrix Local matrix, as returned by SkShader::getLocalMatrix(). + * @param modelViewMatrix Model view matrix, as supplied by the OpenGLRenderer. + */ +static void computeScreenSpaceMatrix(mat4& screenSpace, const SkMatrix& unitMatrix, + const SkMatrix& localMatrix, const mat4& modelViewMatrix) { + mat4 shaderMatrix; + // uses implicit construction + shaderMatrix.loadInverse(localMatrix); + // again, uses implicit construction + screenSpace.loadMultiply(unitMatrix, shaderMatrix); + screenSpace.multiply(modelViewMatrix); +} + +// Returns true if one is a bitmap and the other is a gradient +static bool bitmapAndGradient(SkiaShaderType type1, SkiaShaderType type2) { + return (type1 == kBitmap_SkiaShaderType && type2 == kGradient_SkiaShaderType) + || (type2 == kBitmap_SkiaShaderType && type1 == kGradient_SkiaShaderType); +} + +SkiaShaderType SkiaShader::getType(const SkShader& shader) { + // First check for a gradient shader. + switch (shader.asAGradient(NULL)) { + case SkShader::kNone_GradientType: + // Not a gradient shader. Fall through to check for other types. + break; + case SkShader::kLinear_GradientType: + case SkShader::kRadial_GradientType: + case SkShader::kSweep_GradientType: + return kGradient_SkiaShaderType; + default: + // This is a Skia gradient that has no SkiaShader equivalent. Return None to skip. + return kNone_SkiaShaderType; + } -SkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, - SkShader::TileMode tileY, const SkMatrix* matrix, bool blend): - mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend), - mCaches(NULL) { - setMatrix(matrix); - mGenerationId = 0; -} + // The shader is not a gradient. Check for a bitmap shader. + if (shader.asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType) { + return kBitmap_SkiaShaderType; + } -SkiaShader::~SkiaShader() { -} + // Check for a ComposeShader. + SkShader::ComposeRec rec; + if (shader.asACompose(&rec)) { + const SkiaShaderType shaderAType = getType(*rec.fShaderA); + const SkiaShaderType shaderBType = getType(*rec.fShaderB); + + // Compose is only supported if one is a bitmap and the other is a + // gradient. Otherwise, return None to skip. + if (!bitmapAndGradient(shaderAType, shaderBType)) { + return kNone_SkiaShaderType; + } + return kCompose_SkiaShaderType; + } -void SkiaShader::describe(ProgramDescription& description, const Extensions& extensions) { -} + if (shader.asACustomShader(NULL)) { + return kLayer_SkiaShaderType; + } -void SkiaShader::setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, - GLuint* textureUnit) { + return kNone_SkiaShaderType; } -void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT) { - mCaches->bindTexture(texture->id); - texture->setWrapST(wrapS, wrapT); +typedef void (*describeProc)(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader); + +describeProc gDescribeProc[] = { + InvalidSkiaShader::describe, + SkiaBitmapShader::describe, + SkiaGradientShader::describe, + SkiaComposeShader::describe, + SkiaLayerShader::describe, +}; + +typedef void (*setupProgramProc)(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader); + +setupProgramProc gSetupProgramProc[] = { + InvalidSkiaShader::setupProgram, + SkiaBitmapShader::setupProgram, + SkiaGradientShader::setupProgram, + SkiaComposeShader::setupProgram, + SkiaLayerShader::setupProgram, +}; + +void SkiaShader::describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader) { + gDescribeProc[getType(shader)](caches, description, extensions, shader); } -void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) { - screenSpace.loadMultiply(mUnitMatrix, mShaderMatrix); - screenSpace.multiply(modelView); +void SkiaShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { + + gSetupProgramProc[getType(shader)](caches, modelViewMatrix, textureUnit, extensions, shader); } /////////////////////////////////////////////////////////////////////////////// // Layer shader /////////////////////////////////////////////////////////////////////////////// -SkiaLayerShader::SkiaLayerShader(Layer* layer, const SkMatrix* matrix): - SkiaShader(kBitmap, NULL, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, - matrix, layer->isBlend()), mLayer(layer) { - updateLocalMatrix(matrix); -} - -SkiaShader* SkiaLayerShader::copy() { - SkiaLayerShader* copy = new SkiaLayerShader(); - copy->copyFrom(*this); - copy->mLayer = mLayer; - return copy; -} - -void SkiaLayerShader::describe(ProgramDescription& description, const Extensions& extensions) { +void SkiaLayerShader::describe(Caches*, ProgramDescription& description, + const Extensions&, const SkShader& shader) { description.hasBitmap = true; } -void SkiaLayerShader::setupProgram(Program* program, const mat4& modelView, - const Snapshot& snapshot, GLuint* textureUnit) { +void SkiaLayerShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions&, const SkShader& shader) { + Layer* layer; + if (!shader.asACustomShader(reinterpret_cast<void**>(&layer))) { + LOG_ALWAYS_FATAL("SkiaLayerShader::setupProgram called on the wrong type of shader!"); + } + GLuint textureSlot = (*textureUnit)++; - Caches::getInstance().activeTexture(textureSlot); + caches->activeTexture(textureSlot); - const float width = mLayer->getWidth(); - const float height = mLayer->getHeight(); + const float width = layer->getWidth(); + const float height = layer->getHeight(); mat4 textureTransform; - computeScreenSpaceMatrix(textureTransform, modelView); + computeScreenSpaceMatrix(textureTransform, SkMatrix::I(), shader.getLocalMatrix(), + modelViewMatrix); + // Uniforms - mLayer->bindTexture(); - mLayer->setWrap(GL_CLAMP_TO_EDGE); - mLayer->setFilter(GL_LINEAR); + layer->bindTexture(); + layer->setWrap(GL_CLAMP_TO_EDGE); + layer->setFilter(GL_LINEAR); + Program* program = caches->currentProgram; glUniform1i(program->getUniform("bitmapSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("textureTransform"), 1, GL_FALSE, &textureTransform.data[0]); @@ -147,67 +201,99 @@ void SkiaLayerShader::setupProgram(Program* program, const mat4& modelView, // Bitmap shader /////////////////////////////////////////////////////////////////////////////// -SkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, - SkShader::TileMode tileY, SkMatrix* matrix, bool blend): - SkiaShader(kBitmap, key, tileX, tileY, matrix, blend), mBitmap(bitmap), mTexture(NULL) { - updateLocalMatrix(matrix); -} - -SkiaShader* SkiaBitmapShader::copy() { - SkiaBitmapShader* copy = new SkiaBitmapShader(); - copy->copyFrom(*this); - copy->mBitmap = mBitmap; - return copy; -} +struct BitmapShaderInfo { + float width; + float height; + GLenum wrapS; + GLenum wrapT; + Texture* texture; +}; -void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) { - Texture* texture = mCaches->textureCache.get(mBitmap); - if (!texture) return; - mTexture = texture; +static bool bitmapShaderHelper(Caches* caches, ProgramDescription* description, + BitmapShaderInfo* shaderInfo, + const Extensions& extensions, + const SkBitmap& bitmap, SkShader::TileMode tileModes[2]) { + Texture* texture = caches->textureCache.get(&bitmap); + if (!texture) return false; const float width = texture->width; const float height = texture->height; + GLenum wrapS, wrapT; - description.hasBitmap = true; + if (description) { + description->hasBitmap = true; + } // The driver does not support non-power of two mirrored/repeated // textures, so do it ourselves if (!extensions.hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) && - (mTileX != SkShader::kClamp_TileMode || mTileY != SkShader::kClamp_TileMode)) { - description.isBitmapNpot = true; - description.bitmapWrapS = gTileModes[mTileX]; - description.bitmapWrapT = gTileModes[mTileY]; - mWrapS = GL_CLAMP_TO_EDGE; - mWrapT = GL_CLAMP_TO_EDGE; + (tileModes[0] != SkShader::kClamp_TileMode || + tileModes[1] != SkShader::kClamp_TileMode)) { + if (description) { + description->isBitmapNpot = true; + description->bitmapWrapS = gTileModes[tileModes[0]]; + description->bitmapWrapT = gTileModes[tileModes[1]]; + } + wrapS = GL_CLAMP_TO_EDGE; + wrapT = GL_CLAMP_TO_EDGE; } else { - mWrapS = gTileModes[mTileX]; - mWrapT = gTileModes[mTileY]; + wrapS = gTileModes[tileModes[0]]; + wrapT = gTileModes[tileModes[1]]; + } + + if (shaderInfo) { + shaderInfo->width = width; + shaderInfo->height = height; + shaderInfo->wrapS = wrapS; + shaderInfo->wrapT = wrapT; + shaderInfo->texture = texture; } + return true; } -void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, - const Snapshot&, GLuint* textureUnit) { +void SkiaBitmapShader::describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader) { + SkBitmap bitmap; + SkShader::TileMode xy[2]; + if (shader.asABitmap(&bitmap, NULL, xy) != SkShader::kDefault_BitmapType) { + LOG_ALWAYS_FATAL("SkiaBitmapShader::describe called with a different kind of shader!"); + } + bitmapShaderHelper(caches, &description, NULL, extensions, bitmap, xy); +} + +void SkiaBitmapShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { + SkBitmap bitmap; + SkShader::TileMode xy[2]; + if (shader.asABitmap(&bitmap, NULL, xy) != SkShader::kDefault_BitmapType) { + LOG_ALWAYS_FATAL("SkiaBitmapShader::setupProgram called with a different kind of shader!"); + } + GLuint textureSlot = (*textureUnit)++; Caches::getInstance().activeTexture(textureSlot); - Texture* texture = mTexture; - mTexture = NULL; - if (!texture) return; - const AutoTexture autoCleanup(texture); + BitmapShaderInfo shaderInfo; + if (!bitmapShaderHelper(caches, NULL, &shaderInfo, extensions, bitmap, xy)) { + return; + } - const float width = texture->width; - const float height = texture->height; + Program* program = caches->currentProgram; + Texture* texture = shaderInfo.texture; + + const AutoTexture autoCleanup(texture); mat4 textureTransform; - computeScreenSpaceMatrix(textureTransform, modelView); + computeScreenSpaceMatrix(textureTransform, SkMatrix::I(), shader.getLocalMatrix(), + modelViewMatrix); // Uniforms - bindTexture(texture, mWrapS, mWrapT); + bindTexture(caches, texture, shaderInfo.wrapS, shaderInfo.wrapT); texture->setFilter(GL_LINEAR); glUniform1i(program->getUniform("bitmapSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("textureTransform"), 1, GL_FALSE, &textureTransform.data[0]); - glUniform2f(program->getUniform("textureDimension"), 1.0f / width, 1.0f / height); + glUniform2f(program->getUniform("textureDimension"), 1.0f / shaderInfo.width, + 1.0f / shaderInfo.height); } /////////////////////////////////////////////////////////////////////////////// @@ -225,74 +311,6 @@ static void toUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) { matrix->postScale(inv, inv); } -SkiaLinearGradientShader::SkiaLinearGradientShader(float* bounds, uint32_t* colors, - float* positions, int count, SkShader* key, SkShader::TileMode tileMode, - SkMatrix* matrix, bool blend): - SkiaShader(kLinearGradient, key, tileMode, tileMode, matrix, blend), - mBounds(bounds), mColors(colors), mPositions(positions), mCount(count) { - SkPoint points[2]; - points[0].set(bounds[0], bounds[1]); - points[1].set(bounds[2], bounds[3]); - - SkMatrix unitMatrix; - toUnitMatrix(points, &unitMatrix); - mUnitMatrix.load(unitMatrix); - - updateLocalMatrix(matrix); - - mIsSimple = count == 2 && tileMode == SkShader::kClamp_TileMode; -} - -SkiaLinearGradientShader::~SkiaLinearGradientShader() { - delete[] mBounds; - delete[] mColors; - delete[] mPositions; -} - -SkiaShader* SkiaLinearGradientShader::copy() { - SkiaLinearGradientShader* copy = new SkiaLinearGradientShader(); - copy->copyFrom(*this); - copy->mBounds = new float[4]; - memcpy(copy->mBounds, mBounds, sizeof(float) * 4); - copy->mColors = new uint32_t[mCount]; - memcpy(copy->mColors, mColors, sizeof(uint32_t) * mCount); - copy->mPositions = new float[mCount]; - memcpy(copy->mPositions, mPositions, sizeof(float) * mCount); - copy->mCount = mCount; - copy->mIsSimple = mIsSimple; - return copy; -} - -void SkiaLinearGradientShader::describe(ProgramDescription& description, - const Extensions& extensions) { - description.hasGradient = true; - description.gradientType = ProgramDescription::kGradientLinear; - description.isSimpleGradient = mIsSimple; -} - -void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView, - const Snapshot&, GLuint* textureUnit) { - if (CC_UNLIKELY(!mIsSimple)) { - GLuint textureSlot = (*textureUnit)++; - Caches::getInstance().activeTexture(textureSlot); - - Texture* texture = mCaches->gradientCache.get(mColors, mPositions, mCount); - - // Uniforms - bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]); - glUniform1i(program->getUniform("gradientSampler"), textureSlot); - } else { - bindUniformColor(program->getUniform("startColor"), mColors[0]); - bindUniformColor(program->getUniform("endColor"), mColors[1]); - } - - Caches::getInstance().dither.setupProgram(program, textureUnit); - - mat4 screenSpace; - computeScreenSpaceMatrix(screenSpace, modelView); - glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); -} - /////////////////////////////////////////////////////////////////////////////// // Circular gradient shader /////////////////////////////////////////////////////////////////////////////// @@ -304,37 +322,6 @@ static void toCircularUnitMatrix(const float x, const float y, const float radiu matrix->postScale(inv, inv); } -SkiaCircularGradientShader::SkiaCircularGradientShader(float x, float y, float radius, - uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode, - SkMatrix* matrix, bool blend): - SkiaSweepGradientShader(kCircularGradient, colors, positions, count, key, - tileMode, matrix, blend) { - SkMatrix unitMatrix; - toCircularUnitMatrix(x, y, radius, &unitMatrix); - mUnitMatrix.load(unitMatrix); - - updateLocalMatrix(matrix); -} - -SkiaShader* SkiaCircularGradientShader::copy() { - SkiaCircularGradientShader* copy = new SkiaCircularGradientShader(); - copy->copyFrom(*this); - copy->mColors = new uint32_t[mCount]; - memcpy(copy->mColors, mColors, sizeof(uint32_t) * mCount); - copy->mPositions = new float[mCount]; - memcpy(copy->mPositions, mPositions, sizeof(float) * mCount); - copy->mCount = mCount; - copy->mIsSimple = mIsSimple; - return copy; -} - -void SkiaCircularGradientShader::describe(ProgramDescription& description, - const Extensions& extensions) { - description.hasGradient = true; - description.gradientType = ProgramDescription::kGradientCircular; - description.isSimpleGradient = mIsSimple; -} - /////////////////////////////////////////////////////////////////////////////// // Sweep gradient shader /////////////////////////////////////////////////////////////////////////////// @@ -343,74 +330,103 @@ static void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) { matrix->setTranslate(-x, -y); } -SkiaSweepGradientShader::SkiaSweepGradientShader(float x, float y, uint32_t* colors, - float* positions, int count, SkShader* key, SkMatrix* matrix, bool blend): - SkiaShader(kSweepGradient, key, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode, matrix, blend), - mColors(colors), mPositions(positions), mCount(count) { - SkMatrix unitMatrix; - toSweepUnitMatrix(x, y, &unitMatrix); - mUnitMatrix.load(unitMatrix); - - updateLocalMatrix(matrix); - - mIsSimple = count == 2; -} - -SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, uint32_t* colors, - float* positions, int count, SkShader* key, SkShader::TileMode tileMode, - SkMatrix* matrix, bool blend): - SkiaShader(type, key, tileMode, tileMode, matrix, blend), - mColors(colors), mPositions(positions), mCount(count) { - // protected method, that doesn't setup mUnitMatrix - should be handled by subclass - - mIsSimple = count == 2 && tileMode == SkShader::kClamp_TileMode; -} - -SkiaSweepGradientShader::~SkiaSweepGradientShader() { - delete[] mColors; - delete[] mPositions; -} - -SkiaShader* SkiaSweepGradientShader::copy() { - SkiaSweepGradientShader* copy = new SkiaSweepGradientShader(); - copy->copyFrom(*this); - copy->mColors = new uint32_t[mCount]; - memcpy(copy->mColors, mColors, sizeof(uint32_t) * mCount); - copy->mPositions = new float[mCount]; - memcpy(copy->mPositions, mPositions, sizeof(float) * mCount); - copy->mCount = mCount; - copy->mIsSimple = mIsSimple; - return copy; -} +/////////////////////////////////////////////////////////////////////////////// +// Common gradient code +/////////////////////////////////////////////////////////////////////////////// -void SkiaSweepGradientShader::describe(ProgramDescription& description, - const Extensions& extensions) { +static bool isSimpleGradient(const SkShader::GradientInfo& gradInfo) { + return gradInfo.fColorCount == 2 && gradInfo.fTileMode == SkShader::kClamp_TileMode; +} + +void SkiaGradientShader::describe(Caches*, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader) { + SkShader::GradientInfo gradInfo; + gradInfo.fColorCount = 0; + gradInfo.fColors = NULL; + gradInfo.fColorOffsets = NULL; + + switch (shader.asAGradient(&gradInfo)) { + case SkShader::kLinear_GradientType: + description.gradientType = ProgramDescription::kGradientLinear; + break; + case SkShader::kRadial_GradientType: + description.gradientType = ProgramDescription::kGradientCircular; + break; + case SkShader::kSweep_GradientType: + description.gradientType = ProgramDescription::kGradientSweep; + break; + default: + // Do nothing. This shader is unsupported. + return; + } description.hasGradient = true; - description.gradientType = ProgramDescription::kGradientSweep; - description.isSimpleGradient = mIsSimple; -} - -void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelView, - const Snapshot& snapshot, GLuint* textureUnit) { - if (CC_UNLIKELY(!mIsSimple)) { + description.isSimpleGradient = isSimpleGradient(gradInfo); +} + +void SkiaGradientShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions&, const SkShader& shader) { + // SkShader::GradientInfo.fColorCount is an in/out parameter. As input, it tells asAGradient + // how much space has been allocated for fColors and fColorOffsets. 10 was chosen + // arbitrarily, but should be >= 2. + // As output, it tells the number of actual colors/offsets in the gradient. + const int COLOR_COUNT = 10; + SkAutoSTMalloc<COLOR_COUNT, SkColor> colorStorage(COLOR_COUNT); + SkAutoSTMalloc<COLOR_COUNT, SkScalar> positionStorage(COLOR_COUNT); + + SkShader::GradientInfo gradInfo; + gradInfo.fColorCount = COLOR_COUNT; + gradInfo.fColors = colorStorage.get(); + gradInfo.fColorOffsets = positionStorage.get(); + + SkShader::GradientType gradType = shader.asAGradient(&gradInfo); + + Program* program = caches->currentProgram; + if (CC_UNLIKELY(!isSimpleGradient(gradInfo))) { + if (gradInfo.fColorCount > COLOR_COUNT) { + // There was not enough room in our arrays for all the colors and offsets. Try again, + // now that we know the true number of colors. + gradInfo.fColors = colorStorage.reset(gradInfo.fColorCount); + gradInfo.fColorOffsets = positionStorage.reset(gradInfo.fColorCount); + + shader.asAGradient(&gradInfo); + } GLuint textureSlot = (*textureUnit)++; - Caches::getInstance().activeTexture(textureSlot); + caches->activeTexture(textureSlot); - Texture* texture = mCaches->gradientCache.get(mColors, mPositions, mCount); +#ifndef SK_SCALAR_IS_FLOAT + #error Need to convert gradInfo.fColorOffsets to float! +#endif + Texture* texture = caches->gradientCache.get(gradInfo.fColors, gradInfo.fColorOffsets, + gradInfo.fColorCount); // Uniforms - bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]); + bindTexture(caches, texture, gTileModes[gradInfo.fTileMode], gTileModes[gradInfo.fTileMode]); glUniform1i(program->getUniform("gradientSampler"), textureSlot); } else { - bindUniformColor(program->getUniform("startColor"), mColors[0]); - bindUniformColor(program->getUniform("endColor"), mColors[1]); + bindUniformColor(program->getUniform("startColor"), gradInfo.fColors[0]); + bindUniformColor(program->getUniform("endColor"), gradInfo.fColors[1]); } - mCaches->dither.setupProgram(program, textureUnit); + caches->dither.setupProgram(program, textureUnit); + + SkMatrix unitMatrix; + switch (gradType) { + case SkShader::kLinear_GradientType: + toUnitMatrix(gradInfo.fPoint, &unitMatrix); + break; + case SkShader::kRadial_GradientType: + toCircularUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, + gradInfo.fRadius[0], &unitMatrix); + break; + case SkShader::kSweep_GradientType: + toSweepUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, &unitMatrix); + break; + default: + LOG_ALWAYS_FATAL("Invalid SkShader gradient type %d", gradType); + } mat4 screenSpace; - computeScreenSpaceMatrix(screenSpace, modelView); + computeScreenSpaceMatrix(screenSpace, unitMatrix, shader.getLocalMatrix(), modelViewMatrix); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } @@ -418,49 +434,39 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi // Compose shader /////////////////////////////////////////////////////////////////////////////// -SkiaComposeShader::SkiaComposeShader(SkiaShader* first, SkiaShader* second, - SkXfermode::Mode mode, SkShader* key): - SkiaShader(kCompose, key, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, - NULL, first->blend() || second->blend()), - mFirst(first), mSecond(second), mMode(mode), mCleanup(false) { -} - -SkiaComposeShader::~SkiaComposeShader() { - if (mCleanup) { - delete mFirst; - delete mSecond; +void SkiaComposeShader::describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader) { + SkShader::ComposeRec rec; + if (!shader.asACompose(&rec)) { + LOG_ALWAYS_FATAL("SkiaComposeShader::describe called on the wrong shader type!"); } -} - -SkiaShader* SkiaComposeShader::copy() { - SkiaComposeShader* copy = new SkiaComposeShader(); - copy->copyFrom(*this); - copy->mFirst = mFirst->copy(); - copy->mSecond = mSecond->copy(); - copy->mMode = mMode; - copy->cleanup(); - return copy; -} - -void SkiaComposeShader::describe(ProgramDescription& description, const Extensions& extensions) { - mFirst->describe(description, extensions); - mSecond->describe(description, extensions); - if (mFirst->type() == kBitmap) { + SkiaShader::describe(caches, description, extensions, *rec.fShaderA); + SkiaShader::describe(caches, description, extensions, *rec.fShaderB); + if (SkiaShader::getType(*rec.fShaderA) == kBitmap_SkiaShaderType) { description.isBitmapFirst = true; } - description.shadersMode = mMode; + if (!SkXfermode::AsMode(rec.fMode, &description.shadersMode)) { + // TODO: Support other modes. + description.shadersMode = SkXfermode::kSrcOver_Mode; + } } -void SkiaComposeShader::setupProgram(Program* program, const mat4& modelView, - const Snapshot& snapshot, GLuint* textureUnit) { +void SkiaComposeShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { + SkShader::ComposeRec rec; + if (!shader.asACompose(&rec)) { + LOG_ALWAYS_FATAL("SkiaComposeShader::setupProgram called on the wrong shader type!"); + } + // Apply this compose shader's local transform and pass it down to // the child shaders. They will in turn apply their local transform // to this matrix. mat4 transform; - computeScreenSpaceMatrix(transform, modelView); + computeScreenSpaceMatrix(transform, SkMatrix::I(), shader.getLocalMatrix(), + modelViewMatrix); - mFirst->setupProgram(program, transform, snapshot, textureUnit); - mSecond->setupProgram(program, transform, snapshot, textureUnit); + SkiaShader::setupProgram(caches, transform, textureUnit, extensions, *rec.fShaderA); + SkiaShader::setupProgram(caches, transform, textureUnit, extensions, *rec.fShaderB); } }; // namespace uirenderer diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 9f30257..034c3f6 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -28,249 +28,90 @@ #include "ProgramCache.h" #include "TextureCache.h" #include "GradientCache.h" -#include "Snapshot.h" namespace android { namespace uirenderer { class Caches; - -/////////////////////////////////////////////////////////////////////////////// -// Base shader -/////////////////////////////////////////////////////////////////////////////// +class Layer; /** - * Represents a Skia shader. A shader will modify the GL context and active - * program to recreate the original effect. + * Type of Skia shader in use. */ +enum SkiaShaderType { + kNone_SkiaShaderType, + kBitmap_SkiaShaderType, + kGradient_SkiaShaderType, + kCompose_SkiaShaderType, + kLayer_SkiaShaderType +}; + class SkiaShader { public: - /** - * Type of Skia shader in use. - */ - enum Type { - kNone, - kBitmap, - kLinearGradient, - kCircularGradient, - kSweepGradient, - kCompose - }; - - ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, - SkShader::TileMode tileY, const SkMatrix* matrix, bool blend); - virtual ~SkiaShader(); - - virtual SkiaShader* copy() = 0; - void copyFrom(const SkiaShader& shader); - - virtual void describe(ProgramDescription& description, const Extensions& extensions); - virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, - GLuint* textureUnit); - - inline SkShader* getSkShader() { - return mKey; - } - - inline bool blend() const { - return mBlend; - } - - Type type() const { - return mType; - } - - virtual void setCaches(Caches& caches) { - mCaches = &caches; - } - - uint32_t getGenerationId() { - return mGenerationId; - } - - void setMatrix(const SkMatrix* matrix) { - updateLocalMatrix(matrix); - mGenerationId++; + static SkiaShaderType getType(const SkShader& shader); + static void describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader); + static void setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader); +}; + +class InvalidSkiaShader { +public: + static void describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader) { + // This shader is unsupported. Skip it. } - - void updateLocalMatrix(const SkMatrix* matrix) { - if (matrix) { - mat4 localMatrix(*matrix); - mShaderMatrix.loadInverse(localMatrix); - } else { - mShaderMatrix.loadIdentity(); - } + static void setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { + // This shader is unsupported. Skip it. } - void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); - -protected: - SkiaShader(); - - /** - * The appropriate texture unit must have been activated prior to invoking - * this method. - */ - inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT); - - Type mType; - SkShader* mKey; - SkShader::TileMode mTileX; - SkShader::TileMode mTileY; - bool mBlend; - - Caches* mCaches; - - mat4 mUnitMatrix; - mat4 mShaderMatrix; - -private: - uint32_t mGenerationId; -}; // struct SkiaShader - - -/////////////////////////////////////////////////////////////////////////////// -// Implementations -/////////////////////////////////////////////////////////////////////////////// - +}; /** * A shader that draws a layer. */ -struct SkiaLayerShader: public SkiaShader { - SkiaLayerShader(Layer* layer, const SkMatrix* matrix); - SkiaShader* copy(); - - void describe(ProgramDescription& description, const Extensions& extensions); - void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, - GLuint* textureUnit); - -private: - SkiaLayerShader() { - } - - Layer* mLayer; -}; // struct SkiaLayerShader +class SkiaLayerShader { +public: + static void describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader); + static void setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader); +}; // class SkiaLayerShader /** * A shader that draws a bitmap. */ -struct SkiaBitmapShader: public SkiaShader { - ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, - SkShader::TileMode tileY, SkMatrix* matrix, bool blend); - SkiaShader* copy(); - - void describe(ProgramDescription& description, const Extensions& extensions); - void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, - GLuint* textureUnit); - -private: - SkiaBitmapShader() : mBitmap(NULL), mTexture(NULL) { - } - - SkBitmap* mBitmap; - Texture* mTexture; - GLenum mWrapS; - GLenum mWrapT; -}; // struct SkiaBitmapShader - -/** - * A shader that draws a linear gradient. - */ -struct SkiaLinearGradientShader: public SkiaShader { - ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, - int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); - ~SkiaLinearGradientShader(); - SkiaShader* copy(); - - void describe(ProgramDescription& description, const Extensions& extensions); - void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, - GLuint* textureUnit); +class SkiaBitmapShader { +public: + static void describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader); + static void setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader); -private: - SkiaLinearGradientShader() { - } - bool mIsSimple; - float* mBounds; - uint32_t* mColors; - float* mPositions; - int mCount; -}; // struct SkiaLinearGradientShader +}; // class SkiaBitmapShader /** - * A shader that draws a sweep gradient. + * A shader that draws one of three types of gradient, depending on shader param. */ -struct SkiaSweepGradientShader: public SkiaShader { - ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, - int count, SkShader* key, SkMatrix* matrix, bool blend); - ~SkiaSweepGradientShader(); - SkiaShader* copy(); - - virtual void describe(ProgramDescription& description, const Extensions& extensions); - void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, - GLuint* textureUnit); - -protected: - SkiaSweepGradientShader(Type type, uint32_t* colors, float* positions, - int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); - SkiaSweepGradientShader() { - } - - bool mIsSimple; - uint32_t* mColors; - float* mPositions; - int mCount; -}; // struct SkiaSweepGradientShader - -/** - * A shader that draws a circular gradient. - */ -struct SkiaCircularGradientShader: public SkiaSweepGradientShader { - ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, - float* positions, int count, SkShader* key,SkShader::TileMode tileMode, - SkMatrix* matrix, bool blend); - SkiaShader* copy(); - - void describe(ProgramDescription& description, const Extensions& extensions); - -private: - SkiaCircularGradientShader() { - } -}; // struct SkiaCircularGradientShader +class SkiaGradientShader { +public: + static void describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader); + static void setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader); +}; /** * A shader that draws two shaders, composited with an xfermode. */ -struct SkiaComposeShader: public SkiaShader { - ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, - SkShader* key); - ~SkiaComposeShader(); - SkiaShader* copy(); - - void setCaches(Caches& caches) { - SkiaShader::setCaches(caches); - mFirst->setCaches(caches); - mSecond->setCaches(caches); - } - - void describe(ProgramDescription& description, const Extensions& extensions); - void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, - GLuint* textureUnit); - -private: - SkiaComposeShader(): mCleanup(false) { - } - - void cleanup() { - mCleanup = true; - } - - SkiaShader* mFirst; - SkiaShader* mSecond; - SkXfermode::Mode mMode; - - bool mCleanup; -}; // struct SkiaComposeShader +class SkiaComposeShader { +public: + static void describe(Caches* caches, ProgramDescription& description, + const Extensions& extensions, const SkShader& shader); + static void setupProgram(Caches* caches, const mat4& modelViewMatrix, + GLuint* textureUnit, const Extensions& extensions, const SkShader& shader); +}; // class SkiaComposeShader }; // namespace uirenderer }; // namespace android diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 34e2265..60b4b96 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -34,7 +34,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// TextureCache::TextureCache(): - mCache(LruCache<const SkBitmap*, Texture*>::kUnlimitedCapacity), + mCache(LruCache<const SkPixelRef*, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)), mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) { char property[PROPERTY_VALUE_MAX]; @@ -58,7 +58,7 @@ TextureCache::TextureCache(): } TextureCache::TextureCache(uint32_t maxByteSize): - mCache(LruCache<const SkBitmap*, Texture*>::kUnlimitedCapacity), + mCache(LruCache<const SkPixelRef*, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { init(); } @@ -103,7 +103,7 @@ void TextureCache::setFlushRate(float flushRate) { // Callbacks /////////////////////////////////////////////////////////////////////////////// -void TextureCache::operator()(const SkBitmap*&, Texture*& texture) { +void TextureCache::operator()(const SkPixelRef*&, Texture*& texture) { // This will be called already locked if (texture) { mSize -= texture->bitmapSize; @@ -122,7 +122,7 @@ void TextureCache::operator()(const SkBitmap*&, Texture*& texture) { /////////////////////////////////////////////////////////////////////////////// void TextureCache::resetMarkInUse() { - LruCache<const SkBitmap*, Texture*>::Iterator iter(mCache); + LruCache<const SkPixelRef*, Texture*>::Iterator iter(mCache); while (iter.next()) { iter.value()->isInUse = false; } @@ -140,7 +140,7 @@ bool TextureCache::canMakeTextureFromBitmap(const SkBitmap* bitmap) { // Returns a prepared Texture* that either is already in the cache or can fit // in the cache (and is thus added to the cache) Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) { - Texture* texture = mCache.get(bitmap); + Texture* texture = mCache.get(bitmap->pixelRef()); if (!texture) { if (!canMakeTextureFromBitmap(bitmap)) { @@ -170,7 +170,7 @@ Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) { if (mDebugEnabled) { ALOGD("Texture created, size = %d", size); } - mCache.put(bitmap, texture); + mCache.put(bitmap->pixelRef(), texture); } } else if (!texture->isInUse && bitmap->getGenerationID() != texture->generation) { // Texture was in the cache but is dirty, re-upload @@ -218,7 +218,7 @@ Texture* TextureCache::getTransient(const SkBitmap* bitmap) { } void TextureCache::remove(const SkBitmap* bitmap) { - mCache.remove(bitmap); + mCache.remove(bitmap->pixelRef()); } void TextureCache::removeDeferred(const SkBitmap* bitmap) { @@ -231,7 +231,7 @@ void TextureCache::clearGarbage() { size_t count = mGarbage.size(); for (size_t i = 0; i < count; i++) { const SkBitmap* bitmap = mGarbage.itemAt(i); - mCache.remove(bitmap); + mCache.remove(bitmap->pixelRef()); delete bitmap; } mGarbage.clear(); diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index 48a10c2..e5b5c1a 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -49,7 +49,7 @@ namespace uirenderer { * Any texture added to the cache causing the cache to grow beyond the maximum * allowed size will also cause the oldest texture to be kicked out. */ -class TextureCache: public OnEntryRemoved<const SkBitmap*, Texture*> { +class TextureCache: public OnEntryRemoved<const SkPixelRef*, Texture*> { public: TextureCache(); TextureCache(uint32_t maxByteSize); @@ -59,7 +59,7 @@ public: * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ - void operator()(const SkBitmap*& bitmap, Texture*& texture); + void operator()(const SkPixelRef*& pixelRef, Texture*& texture); /** * Resets all Textures to not be marked as in use @@ -147,7 +147,7 @@ private: void init(); - LruCache<const SkBitmap*, Texture*> mCache; + LruCache<const SkPixelRef*, Texture*> mCache; uint32_t mSize; uint32_t mMaxSize; diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h index d4a23b8..8355f83 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -52,6 +52,7 @@ struct TreeInfo { : hasFunctors(false) , hasAnimations(false) , requiresUiRedraw(false) + , canDrawThisFrame(true) {} bool hasFunctors; // This is only updated if evaluateAnimations is true @@ -60,6 +61,13 @@ struct TreeInfo { // animate itself, such as if hasFunctors is true // This is only set if hasAnimations is true bool requiresUiRedraw; + // This is set to true if draw() can be called this frame + // false means that we must delay until the next vsync pulse as frame + // production is outrunning consumption + // NOTE that if this is false CanvasContext will set either requiresUiRedraw + // *OR* will post itself for the next vsync automatically, use this + // only to avoid calling draw() + bool canDrawThisFrame; } out; // TODO: Damage calculations diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 839ef91..b6b3428 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -360,7 +360,9 @@ void CanvasContext::destroyCanvasAndSurface() { setSurface(NULL); } -void CanvasContext::setSurface(EGLNativeWindowType window) { +void CanvasContext::setSurface(ANativeWindow* window) { + mNativeWindow = window; + if (mEglSurface != EGL_NO_SURFACE) { mGlobalContext->destroySurface(mEglSurface); mEglSurface = EGL_NO_SURFACE; @@ -393,7 +395,7 @@ void CanvasContext::requireSurface() { makeCurrent(); } -bool CanvasContext::initialize(EGLNativeWindowType window) { +bool CanvasContext::initialize(ANativeWindow* window) { if (mCanvas) return false; setSurface(window); mCanvas = new OpenGLRenderer(); @@ -401,11 +403,11 @@ bool CanvasContext::initialize(EGLNativeWindowType window) { return true; } -void CanvasContext::updateSurface(EGLNativeWindowType window) { +void CanvasContext::updateSurface(ANativeWindow* window) { setSurface(window); } -void CanvasContext::pauseSurface(EGLNativeWindowType window) { +void CanvasContext::pauseSurface(ANativeWindow* window) { // TODO: For now we just need a fence, in the future suspend any animations // and such to prevent from trying to render into this surface } @@ -456,7 +458,15 @@ void CanvasContext::prepareTree(TreeInfo& info) { info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); mRootRenderNode->prepareTree(info); - if (info.out.hasAnimations) { + int runningBehind = 0; + // TODO: This query is moderately expensive, investigate adding some sort + // of fast-path based off when we last called eglSwapBuffers() as well as + // last vsync time. Or something. + mNativeWindow->query(mNativeWindow.get(), + NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind); + info.out.canDrawThisFrame = !runningBehind; + + if (info.out.hasAnimations || !info.out.canDrawThisFrame) { if (info.out.hasFunctors) { info.out.requiresUiRedraw = true; } else if (!info.out.requiresUiRedraw) { @@ -467,6 +477,11 @@ void CanvasContext::prepareTree(TreeInfo& info) { } } +void CanvasContext::notifyFramePending() { + ATRACE_CALL(); + mRenderThread.pushBackFrameCallback(this); +} + void CanvasContext::draw(Rect* dirty) { LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, "drawDisplayList called on a context with no canvas or surface!"); @@ -515,7 +530,9 @@ void CanvasContext::doFrame() { info.prepareTextures = false; prepareTree(info); - draw(NULL); + if (info.out.canDrawThisFrame) { + draw(NULL); + } } void CanvasContext::invokeFunctor(Functor* functor) { diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 4232f27..a54b33e 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -48,9 +48,9 @@ public: CanvasContext(bool translucent, RenderNode* rootRenderNode); virtual ~CanvasContext(); - bool initialize(EGLNativeWindowType window); - void updateSurface(EGLNativeWindowType window); - void pauseSurface(EGLNativeWindowType window); + bool initialize(ANativeWindow* window); + void updateSurface(ANativeWindow* window); + void pauseSurface(ANativeWindow* window); void setup(int width, int height, const Vector3& lightCenter, float lightRadius); void setOpaque(bool opaque); void makeCurrent(); @@ -73,11 +73,15 @@ public: ANDROID_API static void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); + void notifyFramePending(); + private: + friend class RegisterFrameCallbackTask; + void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info); void prepareTree(TreeInfo& info); - void setSurface(EGLNativeWindowType window); + void setSurface(ANativeWindow* window); void swapBuffers(); void requireSurface(); @@ -85,6 +89,7 @@ private: GlobalContext* mGlobalContext; RenderThread& mRenderThread; + sp<ANativeWindow> mNativeWindow; EGLSurface mEglSurface; bool mDirtyRegionsEnabled; diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 3b8786c..ee3e059 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -87,7 +87,13 @@ void DrawFrameTask::postAndWait() { void DrawFrameTask::run() { ATRACE_NAME("DrawFrame"); - bool canUnblockUiThread = syncFrameState(); + bool canUnblockUiThread; + bool canDrawThisFrame; + { + TreeInfo info; + canUnblockUiThread = syncFrameState(info); + canDrawThisFrame = info.out.canDrawThisFrame; + } // Grab a copy of everything we need Rect dirty(mDirty); @@ -98,7 +104,9 @@ void DrawFrameTask::run() { unblockUiThread(); } - context->draw(&dirty); + if (CC_LIKELY(canDrawThisFrame)) { + context->draw(&dirty); + } if (!canUnblockUiThread) { unblockUiThread(); @@ -111,12 +119,11 @@ static void initTreeInfo(TreeInfo& info) { info.evaluateAnimations = true; } -bool DrawFrameTask::syncFrameState() { +bool DrawFrameTask::syncFrameState(TreeInfo& info) { ATRACE_CALL(); mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos); mContext->makeCurrent(); Caches::getInstance().textureCache.resetMarkInUse(); - TreeInfo info; initTreeInfo(info); mContext->prepareDraw(&mLayers, info); if (info.out.hasAnimations) { diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index b9307e1..acbc02a 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -24,6 +24,7 @@ #include "RenderTask.h" #include "../Rect.h" +#include "../TreeInfo.h" namespace android { namespace uirenderer { @@ -65,7 +66,7 @@ public: private: void postAndWait(); - bool syncFrameState(); + bool syncFrameState(TreeInfo& info); void unblockUiThread(); Mutex mLock; diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index ef8e45b..2e103d8 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -112,7 +112,7 @@ bool RenderProxy::loadSystemProperties() { return (bool) postAndWait(task); } -CREATE_BRIDGE2(initialize, CanvasContext* context, EGLNativeWindowType window) { +CREATE_BRIDGE2(initialize, CanvasContext* context, ANativeWindow* window) { return (void*) args->context->initialize(args->window); } @@ -123,7 +123,7 @@ bool RenderProxy::initialize(const sp<ANativeWindow>& window) { return (bool) postAndWait(task); } -CREATE_BRIDGE2(updateSurface, CanvasContext* context, EGLNativeWindowType window) { +CREATE_BRIDGE2(updateSurface, CanvasContext* context, ANativeWindow* window) { args->context->updateSurface(args->window); return NULL; } @@ -135,7 +135,7 @@ void RenderProxy::updateSurface(const sp<ANativeWindow>& window) { postAndWait(task); } -CREATE_BRIDGE2(pauseSurface, CanvasContext* context, EGLNativeWindowType window) { +CREATE_BRIDGE2(pauseSurface, CanvasContext* context, ANativeWindow* window) { args->context->pauseSurface(args->window); return NULL; } @@ -292,6 +292,17 @@ void RenderProxy::fence() { postAndWait(task); } +CREATE_BRIDGE1(notifyFramePending, CanvasContext* context) { + args->context->notifyFramePending(); + return NULL; +} + +void RenderProxy::notifyFramePending() { + SETUP_TASK(notifyFramePending); + args->context = mContext; + mRenderThread.queueAtFront(task); +} + void RenderProxy::post(RenderTask* task) { mRenderThread.queue(task); } diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 4d3499e..8aeb264 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -82,6 +82,7 @@ public: ANDROID_API void destroyLayer(DeferredLayerUpdater* layer); ANDROID_API void fence(); + ANDROID_API void notifyFramePending(); private: RenderThread& mRenderThread; diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 35a3eab..4a4e254 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -37,7 +37,7 @@ namespace renderthread { static const size_t EVENT_BUFFER_SIZE = 100; // Slight delay to give the UI time to push us a new frame before we replay -static const int DISPATCH_FRAME_CALLBACKS_DELAY = 0; +static const int DISPATCH_FRAME_CALLBACKS_DELAY = 4; TaskQueue::TaskQueue() : mHead(0), mTail(0) {} @@ -91,6 +91,15 @@ void TaskQueue::queue(RenderTask* task) { } } +void TaskQueue::queueAtFront(RenderTask* task) { + if (mTail) { + task->mNext = mHead; + mHead = task; + } else { + mTail = mHead = task; + } +} + void TaskQueue::remove(RenderTask* task) { // TaskQueue is strict here to enforce that users are keeping track of // their RenderTasks due to how their memory is managed @@ -188,20 +197,22 @@ static nsecs_t latestVsyncEvent(DisplayEventReceiver* receiver) { return latest; } -void RenderThread::drainDisplayEventQueue() { +void RenderThread::drainDisplayEventQueue(bool skipCallbacks) { + ATRACE_CALL(); nsecs_t vsyncEvent = latestVsyncEvent(mDisplayEventReceiver); if (vsyncEvent > 0) { mVsyncRequested = false; mTimeLord.vsyncReceived(vsyncEvent); - if (!mFrameCallbackTaskPending) { + if (!skipCallbacks && !mFrameCallbackTaskPending) { + ATRACE_NAME("queue mFrameCallbackTask"); mFrameCallbackTaskPending = true; - //queueDelayed(mFrameCallbackTask, DISPATCH_FRAME_CALLBACKS_DELAY); - queue(mFrameCallbackTask); + queueDelayed(mFrameCallbackTask, DISPATCH_FRAME_CALLBACKS_DELAY); } } } void RenderThread::dispatchFrameCallbacks() { + ATRACE_CALL(); mFrameCallbackTaskPending = false; std::set<IFrameCallback*> callbacks; @@ -212,6 +223,15 @@ void RenderThread::dispatchFrameCallbacks() { } } +void RenderThread::requestVsync() { + if (!mVsyncRequested) { + mVsyncRequested = true; + status_t status = mDisplayEventReceiver->requestNextVsync(); + LOG_ALWAYS_FATAL_IF(status != NO_ERROR, + "requestNextVsync failed with status: %d", status); + } +} + bool RenderThread::threadLoop() { initializeDisplayEventReceiver(); @@ -236,6 +256,14 @@ bool RenderThread::threadLoop() { timeoutMillis = 0; } } + + if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) { + drainDisplayEventQueue(true); + mFrameCallbacks.insert( + mPendingRegistrationFrameCallbacks.begin(), mPendingRegistrationFrameCallbacks.end()); + mPendingRegistrationFrameCallbacks.clear(); + requestVsync(); + } } return false; @@ -250,6 +278,12 @@ void RenderThread::queue(RenderTask* task) { } } +void RenderThread::queueAtFront(RenderTask* task) { + AutoMutex _lock(mLock); + mQueue.queueAtFront(task); + mLooper->wake(); +} + void RenderThread::queueDelayed(RenderTask* task, int delayMs) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); task->mRunAt = now + milliseconds_to_nanoseconds(delayMs); @@ -262,17 +296,18 @@ void RenderThread::remove(RenderTask* task) { } void RenderThread::postFrameCallback(IFrameCallback* callback) { - mFrameCallbacks.insert(callback); - if (!mVsyncRequested) { - mVsyncRequested = true; - status_t status = mDisplayEventReceiver->requestNextVsync(); - LOG_ALWAYS_FATAL_IF(status != NO_ERROR, - "requestNextVsync failed with status: %d", status); - } + mPendingRegistrationFrameCallbacks.insert(callback); } void RenderThread::removeFrameCallback(IFrameCallback* callback) { mFrameCallbacks.erase(callback); + mPendingRegistrationFrameCallbacks.erase(callback); +} + +void RenderThread::pushBackFrameCallback(IFrameCallback* callback) { + if (mFrameCallbacks.erase(callback)) { + mPendingRegistrationFrameCallbacks.insert(callback); + } } RenderTask* RenderThread::nextTask(nsecs_t* nextWakeup) { @@ -281,11 +316,13 @@ RenderTask* RenderThread::nextTask(nsecs_t* nextWakeup) { if (!next) { mNextWakeup = LLONG_MAX; } else { + mNextWakeup = next->mRunAt; // Most tasks won't be delayed, so avoid unnecessary systemTime() calls if (next->mRunAt <= 0 || next->mRunAt <= systemTime(SYSTEM_TIME_MONOTONIC)) { next = mQueue.next(); + } else { + next = 0; } - mNextWakeup = next->mRunAt; } if (nextWakeup) { *nextWakeup = mNextWakeup; diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index 215d294..4412584 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -44,6 +44,7 @@ public: RenderTask* next(); void queue(RenderTask* task); + void queueAtFront(RenderTask* task); RenderTask* peek(); void remove(RenderTask* task); @@ -66,12 +67,16 @@ public: // RenderThread takes complete ownership of tasks that are queued // and will delete them after they are run ANDROID_API void queue(RenderTask* task); + ANDROID_API void queueAtFront(RenderTask* task); void queueDelayed(RenderTask* task, int delayMs); void remove(RenderTask* task); // Mimics android.view.Choreographer void postFrameCallback(IFrameCallback* callback); void removeFrameCallback(IFrameCallback* callback); + // If the callback is currently registered, it will be pushed back until + // the next vsync. If it is not currently registered this does nothing. + void pushBackFrameCallback(IFrameCallback* callback); TimeLord& timeLord() { return mTimeLord; } @@ -87,8 +92,9 @@ private: void initializeDisplayEventReceiver(); static int displayEventReceiverCallback(int fd, int events, void* data); - void drainDisplayEventQueue(); + void drainDisplayEventQueue(bool skipCallbacks = false); void dispatchFrameCallbacks(); + void requestVsync(); // Returns the next task to be run. If this returns NULL nextWakeup is set // to the time to requery for the nextTask to run. mNextWakeup is also @@ -104,6 +110,11 @@ private: DisplayEventReceiver* mDisplayEventReceiver; bool mVsyncRequested; std::set<IFrameCallback*> mFrameCallbacks; + // We defer the actual registration of these callbacks until + // both mQueue *and* mDisplayEventReceiver have been drained off all + // immediate events. This makes sure that we catch the next vsync, not + // the previous one + std::set<IFrameCallback*> mPendingRegistrationFrameCallbacks; bool mFrameCallbackTaskPending; DispatchFrameCallbacks* mFrameCallbackTask; diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index c736fc7..5b620fd 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -112,6 +112,9 @@ public class AudioService extends IAudioService.Stub { private static final boolean USE_SESSIONS = true; private static final boolean DEBUG_SESSIONS = true; + /** Allow volume changes to set ringer mode to silent? */ + private static final boolean VOLUME_SETS_RINGER_MODE_SILENT = false; + /** How long to delay before persisting a change in volume/ringer mode. */ private static final int PERSIST_DELAY = 500; @@ -1019,7 +1022,8 @@ public class AudioService extends IAudioService.Stub { int newRingerMode; if (index == 0) { newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE - : AudioManager.RINGER_MODE_SILENT; + : VOLUME_SETS_RINGER_MODE_SILENT ? AudioManager.RINGER_MODE_SILENT + : AudioManager.RINGER_MODE_NORMAL; } else { newRingerMode = AudioManager.RINGER_MODE_NORMAL; } @@ -2552,7 +2556,9 @@ public class AudioService extends IAudioService.Stub { } } else { // (oldIndex < step) is equivalent to (old UI index == 0) - if ((oldIndex < step) && mPrevVolDirection != AudioManager.ADJUST_LOWER) { + if ((oldIndex < step) + && VOLUME_SETS_RINGER_MODE_SILENT + && mPrevVolDirection != AudioManager.ADJUST_LOWER) { ringerMode = RINGER_MODE_SILENT; } } @@ -2565,7 +2571,8 @@ public class AudioService extends IAudioService.Stub { break; } if ((direction == AudioManager.ADJUST_LOWER)) { - if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { + if (VOLUME_SETS_RINGER_MODE_SILENT + && mPrevVolDirection != AudioManager.ADJUST_LOWER) { ringerMode = RINGER_MODE_SILENT; } } else if (direction == AudioManager.ADJUST_RAISE) { diff --git a/media/jni/Android.mk b/media/jni/Android.mk index d658654..90fe695 100644 --- a/media/jni/Android.mk +++ b/media/jni/Android.mk @@ -2,7 +2,6 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - android_media_DngCreator.cpp \ android_media_ImageReader.cpp \ android_media_MediaCrypto.cpp \ android_media_MediaCodec.cpp \ @@ -42,7 +41,6 @@ LOCAL_SHARED_LIBRARIES := \ libjhead \ libexif \ libstagefright_amrnb_common \ - libimg_utils \ LOCAL_REQUIRED_MODULES := \ libjhead_jni @@ -55,7 +53,6 @@ LOCAL_C_INCLUDES += \ external/tremor/Tremor \ frameworks/base/core/jni \ frameworks/av/media/libmedia \ - frameworks/av/media/img_utils/include \ frameworks/av/media/libstagefright \ frameworks/av/media/libstagefright/codecs/amrnb/enc/src \ frameworks/av/media/libstagefright/codecs/amrnb/common \ diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 9d03cc3..6f42057 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -884,7 +884,6 @@ static int register_android_media_MediaPlayer(JNIEnv *env) "android/media/MediaPlayer", gMethods, NELEM(gMethods)); } -extern int register_android_media_DngCreator(JNIEnv *env); extern int register_android_media_ImageReader(JNIEnv *env); extern int register_android_media_Crypto(JNIEnv *env); extern int register_android_media_Drm(JNIEnv *env); @@ -914,11 +913,6 @@ jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) } assert(env != NULL); - if (register_android_media_DngCreator(env) < 0) { - ALOGE("ERROR: ImageReader native registration failed"); - goto bail; - } - if (register_android_media_ImageReader(env) < 0) { ALOGE("ERROR: ImageReader native registration failed"); goto bail; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java index a77b647..a3caba2 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java @@ -17,6 +17,7 @@ package com.android.mediaframeworktest.unit; import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; import android.util.Range; import android.util.Rational; import android.util.SizeF; @@ -26,6 +27,8 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraMetadata; +import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; import android.util.Size; import android.hardware.camera2.impl.CameraMetadataNative; @@ -46,6 +49,7 @@ import static com.android.mediaframeworktest.unit.ByteArrayHelpers.*; import java.lang.reflect.Array; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.List; /** * <pre> @@ -56,6 +60,10 @@ import java.nio.ByteOrder; */ public class CameraMetadataTest extends junit.framework.TestCase { + private static final boolean VERBOSE = false; + private static final String TAG = "CameraMetadataTest"; + + CameraMetadataNative mMetadata; // Sections @@ -940,7 +948,7 @@ public class CameraMetadataTest extends junit.framework.TestCase { }; int availableFormatTag = CameraMetadataNative.getTag("android.scaler.availableFormats"); - Key<int[]> formatKey = CameraCharacteristics.SCALER_AVAILABLE_FORMATS; + Key<int[]> formatKey = CameraCharacteristics.SCALER_AVAILABLE_FORMATS.getNativeKey(); validateArrayMetadataReadWriteOverride(formatKey, availableFormats, expectedIntValues, availableFormatTag); @@ -1046,7 +1054,7 @@ public class CameraMetadataTest extends junit.framework.TestCase { 0x20, 320, 240, INPUT, // RAW16 }; Key<StreamConfiguration[]> configKey = - CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS; + CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS.getNativeKey(); mMetadata.writeValues(configKey.getTag(), toByteArray(rawAvailableStreamConfigs)); @@ -1074,7 +1082,7 @@ public class CameraMetadataTest extends junit.framework.TestCase { 0x21, 1920, 1080, 33333338 // BLOB }; Key<StreamConfigurationDuration[]> durationKey = - CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS; + CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS.getNativeKey(); mMetadata.writeValues(durationKey.getTag(), toByteArray(rawAvailableMinDurations)); @@ -1100,7 +1108,7 @@ public class CameraMetadataTest extends junit.framework.TestCase { 0x21, 1920, 1080, 33333338 // BLOB }; Key<StreamConfigurationDuration[]> stallDurationKey = - CameraCharacteristics.SCALER_AVAILABLE_STALL_DURATIONS; + CameraCharacteristics.SCALER_AVAILABLE_STALL_DURATIONS.getNativeKey(); mMetadata.writeValues(stallDurationKey.getTag(), toByteArray(rawAvailableStallDurations)); @@ -1158,6 +1166,31 @@ public class CameraMetadataTest extends junit.framework.TestCase { } } + @SmallTest + public void testCaptureResult() { + mMetadata.set(CaptureRequest.CONTROL_AE_MODE, + CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH); + + if (VERBOSE) mMetadata.dumpToLog(); + + CaptureResult captureResult = new CaptureResult(mMetadata, /*sequenceId*/0); + + List<CaptureResult.Key<?>> allKeys = captureResult.getKeys(); + if (VERBOSE) Log.v(TAG, "testCaptureResult: key list size " + allKeys); + for (CaptureResult.Key<?> key : captureResult.getKeys()) { + if (VERBOSE) { + Log.v(TAG, + "testCaptureResult: key " + key + " value" + captureResult.get(key)); + } + } + + assertTrue(allKeys.size() >= 1); // FIXME: android.statistics.faces counts as a key + assertTrue(allKeys.contains(CaptureResult.CONTROL_AE_MODE)); + + assertEquals(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH, + (int)captureResult.get(CaptureResult.CONTROL_AE_MODE)); + } + private static void checkStreamConfigurationMapByFormatSize(StreamConfigurationMap configMap, int format, int width, int height, boolean output) { diff --git a/packages/Keyguard/res/layout/keyguard_bouncer.xml b/packages/Keyguard/res/layout/keyguard_bouncer.xml index 975a139..489c5f5 100644 --- a/packages/Keyguard/res/layout/keyguard_bouncer.xml +++ b/packages/Keyguard/res/layout/keyguard_bouncer.xml @@ -18,12 +18,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - <View android:id="@+id/bouncer_background" - android:background="#cc000000" - android:clickable="true" - android:layout_width="match_parent" - android:layout_height="match_parent"/> - <include style="@style/BouncerSecurityContainer" layout="@layout/keyguard_simple_host_view" diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml index b2d0219..78b5746 100644 --- a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml +++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml @@ -37,6 +37,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:textSize="@dimen/kg_status_line_font_size" android:textColor="?android:attr/textColorSecondary" + android:visibility="gone" androidprv:allCaps="@bool/kg_use_all_caps" /> <LinearLayout diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml index f79819f..112e371 100644 --- a/packages/Keyguard/res/layout/keyguard_status_view.xml +++ b/packages/Keyguard/res/layout/keyguard_status_view.xml @@ -39,13 +39,12 @@ android:id="@+id/clock_view" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center_horizontal|top" + android:layout_gravity="center_horizontal" android:textColor="@color/clock_white" android:singleLine="true" style="@style/widget_big_thin" android:format12Hour="@string/keyguard_widget_12_hours_format" android:format24Hour="@string/keyguard_widget_24_hours_format" - android:baselineAligned="true" android:layout_marginBottom="@dimen/bottom_text_spacing_digital" /> <include layout="@layout/keyguard_status_area" /> diff --git a/packages/Keyguard/res/values-sw600dp-land/dimens.xml b/packages/Keyguard/res/values-sw600dp-land/dimens.xml index 5615ff7..13a6f62 100644 --- a/packages/Keyguard/res/values-sw600dp-land/dimens.xml +++ b/packages/Keyguard/res/values-sw600dp-land/dimens.xml @@ -26,5 +26,4 @@ <!-- Overload default clock widget parameters --> <dimen name="widget_big_font_size">88dp</dimen> - <dimen name="bottom_text_spacing_digital">-24dp</dimen> </resources>
\ No newline at end of file diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml index a5e93dc..b954792 100644 --- a/packages/Keyguard/res/values-sw600dp/dimens.xml +++ b/packages/Keyguard/res/values-sw600dp/dimens.xml @@ -65,7 +65,7 @@ <!-- Overload default clock widget parameters --> <dimen name="widget_big_font_size">96dp</dimen> <dimen name="widget_label_font_size">16sp</dimen> - <dimen name="bottom_text_spacing_digital">-24dp</dimen> + <dimen name="bottom_text_spacing_digital">-8dp</dimen> <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text. Should be 0 on devices with plenty of room (e.g. tablets) --> diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml index 6224aed..3830df7 100644 --- a/packages/Keyguard/res/values/dimens.xml +++ b/packages/Keyguard/res/values/dimens.xml @@ -155,7 +155,7 @@ <dimen name="eca_overlap">-10dip</dimen> <!-- Default clock parameters --> - <dimen name="bottom_text_spacing_digital">-18dp</dimen> + <dimen name="bottom_text_spacing_digital">-6dp</dimen> <dimen name="label_font_size">14dp</dimen> <dimen name="widget_label_font_size">14sp</dimen> <dimen name="widget_big_font_size">68dp</dimen> diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml index d20b269..8cf07fa 100644 --- a/packages/Keyguard/res/values/strings.xml +++ b/packages/Keyguard/res/values/strings.xml @@ -97,9 +97,9 @@ <string name="keyguard_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string> <!-- Time format strings for fall-back clock widget --> - <string name="keyguard_widget_12_hours_format" translatable="false">h:mm</string> + <string name="keyguard_widget_12_hours_format" translatable="false">h\uee01mm</string> <!-- Time format strings for fall-back clock widget --> - <string name="keyguard_widget_24_hours_format" translatable="false">kk:mm</string> + <string name="keyguard_widget_24_hours_format" translatable="false">kk\uee01mm</string> <!-- Accessibility description sent when user changes the current lock screen widget. [CHAR_LIMIT=none] --> <string name="keyguard_accessibility_widget_changed">%1$s. Widget %2$d of %3$d.</string> diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml index 5ab00d2..11142cf 100644 --- a/packages/Keyguard/res/values/styles.xml +++ b/packages/Keyguard/res/values/styles.xml @@ -59,8 +59,6 @@ <!-- Built-in clock widget stuff --> <style name="widget_label"> - <item name="android:textStyle">bold</item> - <item name="android:fontFamily">sans-serif-light</item> <item name="android:textSize">@dimen/widget_label_font_size</item> </style> <style name="big_thin"> diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java b/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java index 6d392fc..a592db9 100644 --- a/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java +++ b/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java @@ -17,13 +17,12 @@ package com.android.keyguard; import android.content.Context; +import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; -import com.android.keyguard.R; - public class EmergencyCarrierArea extends LinearLayout { private CarrierText mCarrierText; @@ -48,6 +47,7 @@ public class EmergencyCarrierArea extends LinearLayout { mEmergencyButton.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { + if (mCarrierText.getVisibility() != View.VISIBLE) return false; switch(event.getAction()) { case MotionEvent.ACTION_DOWN: mCarrierText.animate().alpha(0); @@ -59,4 +59,8 @@ public class EmergencyCarrierArea extends LinearLayout { return false; }}); } + + public void setCarrierTextVisible(boolean visible) { + mCarrierText.setVisibility(visible ? View.VISIBLE : View.GONE); + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java index f69fa5f..69abc7a 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java @@ -328,5 +328,10 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit @Override public void hideBouncer(int duration) { } + + @Override + public void startAppearAnimation() { + // TODO. + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java index 701d15f..c9fe93c 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java @@ -349,4 +349,8 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); } + @Override + public void startAppearAnimation() { + // TODO. + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java index 2685447..d2bf30c 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java @@ -112,7 +112,9 @@ public class KeyguardHostView extends KeyguardViewBase { } public interface OnDismissAction { - /* returns true if the dismiss should be deferred */ + /** + * @return true if the dismiss should be deferred + */ boolean onDismiss(); } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java index ede23ef..d589283 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java @@ -48,35 +48,19 @@ class KeyguardMessageArea extends TextView { */ private static final long ANNOUNCEMENT_DELAY = 250; - static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging; - static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery; - static final int SECURITY_MESSAGE_DURATION = 5000; protected static final int FADE_DURATION = 750; private static final String TAG = "KeyguardMessageArea"; - // are we showing battery information? - boolean mShowingBatteryInfo = false; - // is the bouncer up? boolean mShowingBouncer = false; - // last known plugged in state - boolean mCharging = false; - - // last known battery level - int mBatteryLevel = 100; - KeyguardUpdateMonitor mUpdateMonitor; // Timeout before we reset the message to show charging/owner info long mTimeout = SECURITY_MESSAGE_DURATION; - // Shadowed text values - protected boolean mBatteryCharged; - protected boolean mBatteryIsLow; - private Handler mHandler; CharSequence mMessage; @@ -146,16 +130,6 @@ class KeyguardMessageArea extends TextView { } private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { - @Override - public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) { - mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow(); - mCharging = status.status == BatteryManager.BATTERY_STATUS_CHARGING - || status.status == BatteryManager.BATTERY_STATUS_FULL; - mBatteryLevel = status.level; - mBatteryCharged = status.isCharged(); - mBatteryIsLow = status.isBatteryLow(); - update(); - } public void onScreenTurnedOff(int why) { setSelected(false); }; @@ -212,7 +186,7 @@ class KeyguardMessageArea extends TextView { */ void update() { MutableInt icon = new MutableInt(0); - CharSequence status = concat(getChargeInfo(icon), getOwnerInfo(), getCurrentMessage()); + CharSequence status = concat(getOwnerInfo(), getCurrentMessage()); setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0); setText(status); } @@ -248,25 +222,6 @@ class KeyguardMessageArea extends TextView { return info; } - private CharSequence getChargeInfo(MutableInt icon) { - CharSequence string = null; - if (mShowingBatteryInfo && !mShowingMessage) { - // Battery status - if (mCharging) { - // Charging, charged or waiting to charge. - string = getContext().getString(mBatteryCharged - ? R.string.keyguard_charged - : R.string.keyguard_plugged_in, mBatteryLevel); - icon.value = CHARGING_ICON; - } else if (mBatteryIsLow) { - // Battery is low - string = getContext().getString(R.string.keyguard_low_battery); - icon.value = BATTERY_LOW_ICON; - } - } - return string; - } - private void hideMessage(int duration, boolean thenUpdate) { if (duration > 0) { Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java index ca2d615..4dfda91 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java @@ -114,4 +114,11 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView public int getWrongPasswordStringId() { return R.string.kg_wrong_pin; } + + @Override + public void startAppearAnimation() { + // TODO: Fancy animation. + setAlpha(0); + animate().alpha(1).withLayer().setDuration(200); + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java index e733afc..0c385da 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java @@ -198,4 +198,11 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView public int getWrongPasswordStringId() { return R.string.kg_wrong_password; } + + @Override + public void startAppearAnimation() { + // TODO: Fancy animation. + setAlpha(0); + animate().alpha(1).withLayer().setDuration(200); + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java index 98122fc..5853ff9 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java @@ -400,4 +400,11 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit KeyguardSecurityViewHelper. hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); } + + @Override + public void startAppearAnimation() { + // TODO: Fancy animation. + setAlpha(0); + animate().alpha(1).withLayer().setDuration(200); + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java index 94edc07..382cbec 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -81,6 +81,10 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe getSecurityView(mCurrentSecuritySelection).onPause(); } + public void startAppearAnimation() { + getSecurityView(mCurrentSecuritySelection).startAppearAnimation(); + } + void updateSecurityViews(boolean isBouncing) { int children = mSecurityViewFlipper.getChildCount(); for (int i = 0; i < children; i++) { diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java index dfeacf3..86bd877 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java @@ -84,4 +84,9 @@ public interface KeyguardSecurityView { * @param duration millisends for the transisiton animation. */ void hideBouncer(int duration); + + /** + * Starts the animation which should run when the security view appears. + */ + void startAppearAnimation(); } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java index 07239d1..178ca5e 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java @@ -159,6 +159,14 @@ public class KeyguardSecurityViewFlipper extends ViewFlipper implements Keyguard } @Override + public void startAppearAnimation() { + KeyguardSecurityView ksv = getSecurityView(); + if (ksv != null) { + ksv.startAppearAnimation(); + } + } + + @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { return p instanceof LayoutParams; } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java index 03e7b07..98baa04 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java @@ -244,4 +244,9 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri KeyguardSecurityViewHelper. hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration); } + + @Override + public void startAppearAnimation() { + // noop. + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java index 4791956..09c4e7c 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java @@ -135,6 +135,9 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView mPasswordEntry.requestFocus(); mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default + if (mEcaView instanceof EmergencyCarrierArea) { + ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true); + } } @Override @@ -270,5 +273,10 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView mCheckSimPinThread.start(); } } + + @Override + public void startAppearAnimation() { + // noop. + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java index b9c7f51..6215d34 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java @@ -186,6 +186,9 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView mPasswordEntry.requestFocus(); mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default + if (mEcaView instanceof EmergencyCarrierArea) { + ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true); + } } @Override @@ -339,6 +342,11 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView protected void verifyPasswordAndUnlock() { mStateMachine.next(); } + + @Override + public void startAppearAnimation() { + // noop. + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java index 5d5168c..3f6ced6 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java @@ -39,7 +39,7 @@ public class KeyguardSimpleHostView extends KeyguardViewBase { @Override public void cleanUp() { - // TODO Auto-generated method stub + getSecurityContainer().onPause(); } @Override diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java index ae55c4a..bef94fa 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java @@ -95,6 +95,10 @@ public class KeyguardStatusView extends GridLayout { final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn(); setEnableMarquee(screenOn); refresh(); + + // Disable elegant text height because our fancy colon makes the ymin value huge for no + // reason. + mClockView.setElegantTextHeight(false); } protected void refresh() { @@ -164,6 +168,10 @@ public class KeyguardStatusView extends GridLayout { clockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel); + // Use fancy colon. + clockView24 = clockView24.replace(':', '\uee01'); + clockView12 = clockView12.replace(':', '\uee01'); + cacheKey = key; } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java index a9206e7..3e444fa 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java @@ -237,15 +237,17 @@ public abstract class KeyguardViewBase extends FrameLayout implements SecurityCa if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode())); mSecurityContainer.showPrimarySecurityScreen(false); mSecurityContainer.onResume(KeyguardSecurityView.SCREEN_ON); - - // This is a an attempt to fix bug 7137389 where the device comes back on but the entire - // layout is blank but forcing a layout causes it to reappear (e.g. with with - // hierarchyviewer). - requestLayout(); requestFocus(); } /** + * Starts the animation when the Keyguard gets shown. + */ + public void startAppearAnimation() { + mSecurityContainer.startAppearAnimation(); + } + + /** * Verify that the user can get past the keyguard securely. This is called, * for example, when the phone disables the keyguard but then wants to launch * something else that requires secure access. diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 6b62c25..e9cb197 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -52,6 +52,8 @@ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" /> + <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> + <!-- Physical hardware --> <uses-permission android:name="android.permission.MANAGE_USB" /> diff --git a/packages/SystemUI/res/drawable-hdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-hdpi/ic_lock_24dp.png Binary files differdeleted file mode 100644 index c779437..0000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_lock_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png Binary files differdeleted file mode 100644 index 18257e0..0000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png Binary files differdeleted file mode 100644 index 8ddb375..0000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png Binary files differdeleted file mode 100644 index 57a3b99..0000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/search_light.png b/packages/SystemUI/res/drawable-hdpi/search_light.png Binary files differdeleted file mode 100644 index 3c0dc4e..0000000 --- a/packages/SystemUI/res/drawable-hdpi/search_light.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/search_light_land.png b/packages/SystemUI/res/drawable-hdpi/search_light_land.png Binary files differdeleted file mode 100644 index 731f19b..0000000 --- a/packages/SystemUI/res/drawable-hdpi/search_light_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-mdpi/ic_lock_24dp.png Binary files differdeleted file mode 100644 index 98ba690..0000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_lock_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png Binary files differdeleted file mode 100644 index a35c30d..0000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png Binary files differdeleted file mode 100644 index 71e1303..0000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png Binary files differdeleted file mode 100644 index 1de0a3a..0000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/search_light.png b/packages/SystemUI/res/drawable-mdpi/search_light.png Binary files differdeleted file mode 100644 index 8010ce7..0000000 --- a/packages/SystemUI/res/drawable-mdpi/search_light.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/search_light_land.png b/packages/SystemUI/res/drawable-mdpi/search_light_land.png Binary files differdeleted file mode 100644 index a4d82f0..0000000 --- a/packages/SystemUI/res/drawable-mdpi/search_light_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png Binary files differdeleted file mode 100644 index b30cf15..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png Binary files differdeleted file mode 100644 index 8014b70..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png Binary files differdeleted file mode 100644 index 41a34e2..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png Binary files differdeleted file mode 100644 index 9c623e5..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png Binary files differdeleted file mode 100644 index a011aa1..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png Binary files differdeleted file mode 100644 index 31eb8f7..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png Binary files differdeleted file mode 100644 index 61a36e3..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png Binary files differdeleted file mode 100644 index 52bf290..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png Binary files differdeleted file mode 100644 index c76d0e1..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png Binary files differdeleted file mode 100644 index e5d4273..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png Binary files differdeleted file mode 100644 index 1cc5009..0000000 --- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-xhdpi/ic_lock_24dp.png Binary files differdeleted file mode 100644 index 61947ea..0000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_lock_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_lock_open_24dp.png b/packages/SystemUI/res/drawable-xhdpi/ic_lock_open_24dp.png Binary files differdeleted file mode 100644 index 467d558..0000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_lock_open_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png Binary files differdeleted file mode 100644 index d14a67f..0000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png Binary files differdeleted file mode 100644 index c44aafc..0000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png Binary files differdeleted file mode 100644 index 05da6da..0000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/search_light.png b/packages/SystemUI/res/drawable-xhdpi/search_light.png Binary files differdeleted file mode 100644 index 6d46fdd..0000000 --- a/packages/SystemUI/res/drawable-xhdpi/search_light.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/search_light_land.png b/packages/SystemUI/res/drawable-xhdpi/search_light_land.png Binary files differdeleted file mode 100644 index b62c74e..0000000 --- a/packages/SystemUI/res/drawable-xhdpi/search_light_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-xxhdpi/ic_lock_24dp.png Binary files differdeleted file mode 100644 index 0b563b1..0000000 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_lock_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png Binary files differdeleted file mode 100644 index 07f16c3..0000000 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png Binary files differdeleted file mode 100644 index 0df6203..0000000 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png Binary files differdeleted file mode 100644 index b400b14..0000000 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/search_light.png b/packages/SystemUI/res/drawable-xxhdpi/search_light.png Binary files differdeleted file mode 100644 index 7742207..0000000 --- a/packages/SystemUI/res/drawable-xxhdpi/search_light.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/search_light_land.png b/packages/SystemUI/res/drawable-xxhdpi/search_light_land.png Binary files differdeleted file mode 100644 index f364577..0000000 --- a/packages/SystemUI/res/drawable-xxhdpi/search_light_land.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_24dp.png Binary files differdeleted file mode 100644 index 3600ee6..0000000 --- a/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_open_24dp.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_open_24dp.png Binary files differdeleted file mode 100644 index e7d2a9a..0000000 --- a/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_open_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable/ic_account_circle.xml b/packages/SystemUI/res/drawable/ic_account_circle.xml new file mode 100644 index 0000000..a7e8514 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_account_circle.xml @@ -0,0 +1,28 @@ +<!-- +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" > + <size + android:width="24dp" + android:height="24dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> + + <path + android:fill="#FFFFFFFF" + android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0c5.5,0.0 10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,5.0c1.7,0.0 3.0,1.3 3.0,3.0c0.0,1.7 -1.3,3.0 -3.0,3.0c-1.7,0.0 -3.0,-1.3 -3.0,-3.0C9.0,6.3 10.3,5.0 12.0,5.0zM12.0,19.2c-2.5,0.0 -4.7,-1.3 -6.0,-3.2c0.0,-2.0 4.0,-3.1 6.0,-3.1c2.0,0.0 6.0,1.1 6.0,3.1C16.7,17.9 14.5,19.2 12.0,19.2z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_lock_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_24dp.xml new file mode 100644 index 0000000..b2e486c --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_lock_24dp.xml @@ -0,0 +1,28 @@ +<!-- +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" > + <size + android:width="24.0dp" + android:height="24.0dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> + + <path + android:fill="@color/keyguard_affordance" + android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml new file mode 100644 index 0000000..28b16dd --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml @@ -0,0 +1,28 @@ +<!-- +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" > + <size + android:width="24.0dp" + android:height="24.0dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> + + <path + android:fill="@color/keyguard_affordance" + android:pathData="M12.0,17.0c1.1,0.0 2.0,-0.9 2.0,-2.0s-0.9,-2.0 -2.0,-2.0c-1.1,0.0 -2.0,0.9 -2.0,2.0S10.9,17.0 12.0,17.0zM18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l1.9,0.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM18.0,20.0L6.0,20.0L6.0,10.0l12.0,0.0L18.0,20.0z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml index 3a20c58..787eec5 100644 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml +++ b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml @@ -24,5 +24,5 @@ Copyright (C) 2014 The Android Open Source Project <path android:fill="#FFFFFFFF" - android:pathData="M6.6,3.6L5.2,2.2C2.8,4.0 1.2,6.8 1.0,10.0l2.0,0.0C3.2,7.3 4.5,5.0 6.6,3.6zM20.0,10.0l2.0,0.0c-0.2,-3.2 -1.7,-6.0 -4.1,-7.8l-1.4,1.4C18.5,5.0 19.8,7.3 20.0,10.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0l-2.0,-2.0L18.0,10.5zM11.5,22.0c0.1,0.0 0.3,0.0 0.4,0.0c0.7,-0.1 1.2,-0.6 1.4,-1.2c0.1,-0.2 0.2,-0.5 0.2,-0.8l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0z" /> + android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_ringer_audible.xml new file mode 100644 index 0000000..2969948 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ringer_audible.xml @@ -0,0 +1,28 @@ +<!-- +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" > + <size + android:width="32dp" + android:height="32dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> + + <path + android:fill="#FFFFFFFF" + android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_ringer_silent.xml b/packages/SystemUI/res/drawable/ic_ringer_silent.xml new file mode 100644 index 0000000..b5837f6 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ringer_silent.xml @@ -0,0 +1,28 @@ +<!-- +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" > + <size + android:width="32dp" + android:height="32dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> + + <path + android:fill="#FFFFFFFF" + android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7C9.5,4.3 9.0,4.5 8.6,4.7l9.4,9.4L18.0,10.5zM17.7,19.0l2.0,2.0l1.3,-1.3L4.3,3.0L3.0,4.3l2.9,2.9C5.3,8.2 5.0,9.3 5.0,10.5L5.0,16.0l-2.0,2.0l0.0,1.0L17.7,19.0z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml new file mode 100644 index 0000000..d8ded58 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml @@ -0,0 +1,28 @@ +<!-- +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" > + <size + android:width="32dp" + android:height="32dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> + + <path + android:fill="#FFFFFFFF" + android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_vol_zen_off.xml b/packages/SystemUI/res/drawable/ic_vol_zen_off.xml new file mode 100644 index 0000000..ea5ab70 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_vol_zen_off.xml @@ -0,0 +1,30 @@ +<!-- +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" > + <size + android:width="32dp" + android:height="32dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> + + <path + android:fill="#00000000" + android:stroke="#CCCCCC" + android:strokeWidth="1.0" + android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0c5.5,0.0 10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM4.0,12.0c0.0,-4.4 3.6,-8.0 8.0,-8.0c1.8,0.0 3.5,0.6 4.9,1.7L5.7,16.9C4.6,15.5 4.0,13.8 4.0,12.0zM12.0,20.0c-1.8,0.0 -3.5,-0.6 -4.9,-1.7L18.3,7.1C19.4,8.5 20.0,10.2 20.0,12.0C20.0,16.4 16.4,20.0 12.0,20.0z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_vol_zen_on.xml b/packages/SystemUI/res/drawable/ic_vol_zen_on.xml new file mode 100644 index 0000000..44024f3 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_vol_zen_on.xml @@ -0,0 +1,28 @@ +<!-- +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" > + <size + android:width="32dp" + android:height="32dp"/> + + <viewport + android:viewportWidth="24.0" + android:viewportHeight="24.0"/> + + <path + android:fill="#FFFFFFFF" + android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0c5.5,0.0 10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM4.0,12.0c0.0,-4.4 3.6,-8.0 8.0,-8.0c1.8,0.0 3.5,0.6 4.9,1.7L5.7,16.9C4.6,15.5 4.0,13.8 4.0,12.0zM12.0,20.0c-1.8,0.0 -3.5,-0.6 -4.9,-1.7L18.3,7.1C19.4,8.5 20.0,10.2 20.0,12.0C20.0,16.4 16.4,20.0 12.0,20.0z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/notification_header_bg.xml b/packages/SystemUI/res/drawable/notification_header_bg.xml index 09d0d7d..5daec20 100644 --- a/packages/SystemUI/res/drawable/notification_header_bg.xml +++ b/packages/SystemUI/res/drawable/notification_header_bg.xml @@ -19,13 +19,11 @@ <item android:state_pressed="true"> <shape> <solid android:color="@color/background_color_1_press" /> - <corners android:radius="@*android:dimen/notification_quantum_rounded_rect_radius" /> </shape> </item> <item> <shape> <solid android:color="@color/background_color_1" /> - <corners android:radius="@*android:dimen/notification_quantum_rounded_rect_radius" /> </shape> </item> </selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/qs_panel_background.xml b/packages/SystemUI/res/drawable/qs_panel_background.xml index c324976..a1a5362 100644 --- a/packages/SystemUI/res/drawable/qs_panel_background.xml +++ b/packages/SystemUI/res/drawable/qs_panel_background.xml @@ -13,11 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. --> -<inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="@dimen/notification_side_padding" - android:insetRight="@dimen/notification_side_padding"> - <shape> - <solid android:color="@color/system_primary_color" /> - <corners android:radius="@*android:dimen/notification_quantum_rounded_rect_radius" /> - </shape> -</inset> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="@color/system_primary_color" /> + <corners + android:radius="@*android:dimen/notification_quantum_rounded_rect_radius"/> +</shape> diff --git a/packages/SystemUI/res/drawable/ripple_drawable.xml b/packages/SystemUI/res/drawable/ripple_drawable.xml new file mode 100644 index 0000000..d2bff42 --- /dev/null +++ b/packages/SystemUI/res/drawable/ripple_drawable.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:tint="?android:attr/colorControlHighlight" + android:tintMode="src_over" + android:pinned="true" /> diff --git a/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml b/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml index 5f12706..a291495 100644 --- a/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml +++ b/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml @@ -55,7 +55,7 @@ systemui:keyCode="4" android:layout_weight="0" android:scaleType="center" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_back" /> <View @@ -71,7 +71,7 @@ systemui:keyCode="3" systemui:keyRepeat="false" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_home" /> <View @@ -85,7 +85,7 @@ android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_recent" /> <FrameLayout @@ -99,7 +99,7 @@ android:contentDescription="@string/accessibility_menu" android:src="@drawable/ic_sysbar_menu" android:visibility="invisible" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" systemui:keyCode="82" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/ime_switcher" @@ -109,7 +109,7 @@ android:scaleType="centerInside" android:src="@drawable/ic_ime_switcher_default" android:visibility="invisible" - systemui:glowBackground="@drawable/ic_sysbar_highlight" /> + android:background="@drawable/ripple_drawable" /> </FrameLayout> </LinearLayout> @@ -158,17 +158,6 @@ /> </LinearLayout> - <com.android.systemui.statusbar.policy.KeyButtonView - android:layout_width="80dp" - android:id="@+id/search_light" - android:layout_height="match_parent" - android:layout_gravity="center_horizontal" - android:src="@drawable/search_light" - android:scaleType="center" - android:visibility="gone" - android:contentDescription="@string/accessibility_search_light" - /> - <com.android.systemui.statusbar.policy.DeadZone android:id="@+id/deadzone" android:layout_height="match_parent" @@ -212,7 +201,7 @@ android:layout_weight="0" android:visibility="invisible" android:contentDescription="@string/accessibility_menu" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" /> + android:background="@drawable/ripple_drawable" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/ime_switcher" android:layout_height="@dimen/navigation_extra_key_width" @@ -221,7 +210,7 @@ android:scaleType="centerInside" android:src="@drawable/ic_ime_switcher_default" android:visibility="invisible" - systemui:glowBackground="@drawable/ic_sysbar_highlight" /> + android:background="@drawable/ripple_drawable" /> </FrameLayout> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back" android:layout_height="80dp" @@ -231,7 +220,7 @@ systemui:keyCode="4" android:layout_weight="0" android:contentDescription="@string/accessibility_back" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" + android:background="@drawable/ripple_drawable" /> <View android:layout_height="match_parent" @@ -247,7 +236,7 @@ systemui:keyRepeat="false" android:layout_weight="0" android:contentDescription="@string/accessibility_home" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" + android:background="@drawable/ripple_drawable" /> <View android:layout_height="match_parent" @@ -261,7 +250,7 @@ android:src="@drawable/ic_sysbar_recent_land" android:layout_weight="0" android:contentDescription="@string/accessibility_recent" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" + android:background="@drawable/ripple_drawable" /> <View android:layout_height="40dp" @@ -316,17 +305,6 @@ /> </LinearLayout> - <com.android.systemui.statusbar.policy.KeyButtonView - android:id="@+id/search_light" - android:layout_height="80dp" - android:layout_width="match_parent" - android:layout_gravity="center_vertical" - android:src="@drawable/search_light" - android:scaleType="center" - android:visibility="gone" - android:contentDescription="@string/accessibility_search_light" - /> - <com.android.systemui.statusbar.policy.DeadZone android:id="@+id/deadzone" android:layout_height="match_parent" diff --git a/packages/SystemUI/res/layout-sw600dp/heads_up.xml b/packages/SystemUI/res/layout-sw600dp/heads_up.xml deleted file mode 100644 index f7035fe..0000000 --- a/packages/SystemUI/res/layout-sw600dp/heads_up.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 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. -*/ ---> -<com.android.systemui.statusbar.policy.HeadsUpNotificationView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_height="wrap_content" - android:layout_width="match_parent" - > - <FrameLayout - android:id="@+id/content_holder" - android:layout_height="wrap_content" - android:layout_width="@dimen/notification_panel_width" - android:background="@drawable/heads_up_window_bg" - /> -</com.android.systemui.statusbar.policy.HeadsUpNotificationView> diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml index 6a2e3c6..f8b7bae 100644 --- a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml +++ b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml @@ -59,7 +59,7 @@ android:src="@drawable/ic_sysbar_back" systemui:keyCode="4" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_back" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" @@ -69,7 +69,7 @@ systemui:keyCode="3" systemui:keyRepeat="true" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_home" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps" @@ -77,7 +77,7 @@ android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_recent" /> <Space @@ -98,7 +98,7 @@ systemui:keyCode="82" android:visibility="invisible" android:contentDescription="@string/accessibility_menu" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/ime_switcher" @@ -109,7 +109,7 @@ android:src="@drawable/ic_ime_switcher_default" android:visibility="invisible" android:contentDescription="@string/accessibility_ime_switch_button" - systemui:glowBackground="@drawable/ic_sysbar_highlight" /> + android:background="@drawable/ripple_drawable" /> </FrameLayout> </LinearLayout> @@ -156,17 +156,6 @@ /> </LinearLayout> - <com.android.systemui.statusbar.policy.KeyButtonView - android:layout_width="128dp" - android:id="@+id/search_light" - android:layout_height="match_parent" - android:layout_gravity="center_horizontal" - android:src="@drawable/search_light" - android:scaleType="center" - android:visibility="gone" - android:contentDescription="@string/accessibility_search_light" - /> - <com.android.systemui.statusbar.policy.DeadZone android:id="@+id/deadzone" android:layout_height="match_parent" @@ -216,7 +205,7 @@ android:src="@drawable/ic_sysbar_back" systemui:keyCode="4" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_back" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" @@ -226,7 +215,7 @@ systemui:keyCode="3" systemui:keyRepeat="true" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_home" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps" @@ -234,7 +223,7 @@ android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_recent" /> <Space @@ -255,7 +244,7 @@ systemui:keyCode="82" android:visibility="invisible" android:contentDescription="@string/accessibility_menu" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/ime_switcher" @@ -266,7 +255,7 @@ android:visibility="invisible" android:contentDescription="@string/accessibility_ime_switch_button" android:scaleType="centerInside" - systemui:glowBackground="@drawable/ic_sysbar_highlight" /> + android:background="@drawable/ripple_drawable" /> </FrameLayout> </LinearLayout> @@ -313,17 +302,6 @@ /> </LinearLayout> - <com.android.systemui.statusbar.policy.KeyButtonView - android:layout_width="162dp" - android:id="@+id/search_light" - android:layout_height="match_parent" - android:layout_gravity="center_horizontal" - android:src="@drawable/search_light" - android:scaleType="center" - android:visibility="gone" - android:contentDescription="@string/accessibility_search_light" - /> - <com.android.systemui.statusbar.policy.DeadZone android:id="@+id/deadzone" android:layout_height="match_parent" diff --git a/packages/SystemUI/res/layout/heads_up.xml b/packages/SystemUI/res/layout/heads_up.xml index 7d9cfa1..236fdc3 100644 --- a/packages/SystemUI/res/layout/heads_up.xml +++ b/packages/SystemUI/res/layout/heads_up.xml @@ -1,26 +1,30 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* apps/common/assets/default/default/skins/StatusBar.xml -** -** Copyright 2006, 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. -*/ + 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. --> <com.android.systemui.statusbar.policy.HeadsUpNotificationView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:id="@+id/content_holder" - android:background="@drawable/notification_panel_bg" - />
\ No newline at end of file + android:layout_height="match_parent" + android:layout_width="match_parent"> + + <FrameLayout + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/notification_side_padding" + android:layout_marginEnd="@dimen/notification_side_padding" + android:elevation="16dp" + android:id="@+id/content_holder" + style="@style/NotificationsQuickSettings" /> + +</com.android.systemui.statusbar.policy.HeadsUpNotificationView>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index 2ec3766..936f73b 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -31,7 +31,6 @@ android:src="@drawable/ic_camera_alt_24dp" android:scaleType="center" android:contentDescription="@string/accessibility_camera_button" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" systemui:swipeDirection="start"/> <com.android.systemui.statusbar.phone.SwipeAffordanceView @@ -43,7 +42,6 @@ android:src="@drawable/ic_phone_24dp" android:scaleType="center" android:contentDescription="@string/accessibility_phone_button" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" systemui:swipeDirection="end"/> <com.android.systemui.statusbar.phone.KeyguardIndicationTextView @@ -53,7 +51,8 @@ android:layout_marginBottom="100dp" android:layout_gravity="bottom|center_horizontal" android:textStyle="italic" - android:textAppearance="?android:attr/textAppearanceMedium"/> + android:textColor="#ffffff" + android:textAppearance="?android:attr/textAppearanceSmall"/> <ImageView android:id="@+id/lock_icon" @@ -66,4 +65,4 @@ android:layerType="hardware" android:tint="#ffffffff"/> -</com.android.systemui.statusbar.phone.KeyguardBottomAreaView>
\ No newline at end of file +</com.android.systemui.statusbar.phone.KeyguardBottomAreaView> diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml index 7470409..7616cb1 100644 --- a/packages/SystemUI/res/layout/navigation_bar.xml +++ b/packages/SystemUI/res/layout/navigation_bar.xml @@ -55,7 +55,7 @@ systemui:keyCode="4" android:layout_weight="0" android:scaleType="center" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_back" /> <View @@ -71,7 +71,7 @@ systemui:keyCode="3" systemui:keyRepeat="false" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_home" /> <View @@ -85,7 +85,7 @@ android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_recent" /> <FrameLayout @@ -99,7 +99,7 @@ android:contentDescription="@string/accessibility_menu" android:src="@drawable/ic_sysbar_menu" android:visibility="invisible" - systemui:glowBackground="@drawable/ic_sysbar_highlight" + android:background="@drawable/ripple_drawable" systemui:keyCode="82" /> <com.android.systemui.statusbar.policy.KeyButtonView @@ -110,7 +110,7 @@ android:scaleType="centerInside" android:src="@drawable/ic_ime_switcher_default" android:visibility="invisible" - systemui:glowBackground="@drawable/ic_sysbar_highlight" /> + android:background="@drawable/ripple_drawable" /> </FrameLayout> </LinearLayout> @@ -160,22 +160,6 @@ /> </LinearLayout> - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <com.android.systemui.statusbar.policy.KeyButtonView - android:layout_width="80dp" - android:id="@+id/search_light" - android:layout_height="match_parent" - android:layout_gravity="center" - android:src="@drawable/search_light" - android:scaleType="center" - android:visibility="gone" - android:contentDescription="@string/accessibility_search_light" - /> - </FrameLayout> - <com.android.systemui.statusbar.policy.DeadZone android:id="@+id/deadzone" android:layout_height="match_parent" @@ -219,7 +203,7 @@ android:scaleType="centerInside" android:src="@drawable/ic_ime_switcher_default" android:visibility="invisible" - systemui:glowBackground="@drawable/ic_sysbar_highlight" /> + android:background="@drawable/ripple_drawable" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" @@ -228,7 +212,7 @@ android:contentDescription="@string/accessibility_menu" android:src="@drawable/ic_sysbar_menu_land" android:visibility="invisible" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" + android:background="@drawable/ripple_drawable" systemui:keyCode="82" /> </FrameLayout> @@ -238,7 +222,7 @@ android:src="@drawable/ic_sysbar_recent_land" android:layout_weight="0" android:contentDescription="@string/accessibility_recent" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" + android:background="@drawable/ripple_drawable" /> <View android:layout_height="match_parent" @@ -254,7 +238,7 @@ systemui:keyRepeat="false" android:layout_weight="0" android:contentDescription="@string/accessibility_home" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" + android:background="@drawable/ripple_drawable" /> <View android:layout_height="match_parent" @@ -270,7 +254,7 @@ systemui:keyCode="4" android:layout_weight="0" android:contentDescription="@string/accessibility_back" - systemui:glowBackground="@drawable/ic_sysbar_highlight_land" + android:background="@drawable/ripple_drawable" /> <View android:layout_height="40dp" @@ -325,19 +309,6 @@ /> </LinearLayout> - <com.android.systemui.statusbar.policy.KeyButtonView - android:id="@+id/search_light" - android:layout_height="80dp" - android:layout_width="match_parent" - android:layout_gravity="center_vertical" - android:src="@drawable/search_light_land" - android:scaleType="center" - android:visibility="gone" - android:contentDescription="@string/accessibility_search_light" - /> - - <!-- No camera button in landscape mode --> - <com.android.systemui.statusbar.policy.DeadZone android:id="@+id/deadzone" android:layout_height="match_parent" diff --git a/packages/SystemUI/res/layout/qs_zen_mode_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml index 85b294d..e73b431 100644 --- a/packages/SystemUI/res/layout/qs_zen_mode_detail.xml +++ b/packages/SystemUI/res/layout/qs_detail.xml @@ -14,64 +14,44 @@ See the License for the specific language governing permissions and limitations under the License. --> -<com.android.systemui.qs.tiles.ZenModeDetail xmlns:android="http://schemas.android.com/apk/res/android" +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/system_secondary_color" > + android:background="@color/system_primary_color" > <ImageView android:id="@android:id/button1" - android:src="@drawable/ic_qs_close" android:layout_width="64dp" android:layout_height="64dp" android:layout_alignParentStart="true" - android:padding="@dimen/qs_panel_padding" /> - - <Switch - android:id="@android:id/checkbox" - android:layout_width="wrap_content" - android:layout_height="64dp" - android:layout_alignParentEnd="true" - android:gravity="center" - android:padding="@dimen/qs_panel_padding" /> + android:contentDescription="@string/accessibility_quick_settings_close" + android:padding="@dimen/qs_panel_padding" + android:src="@drawable/ic_qs_close" /> <TextView android:id="@android:id/title" android:layout_width="match_parent" android:layout_height="64dp" + android:layout_alignParentTop="true" android:layout_toEndOf="@android:id/button1" android:layout_toStartOf="@android:id/checkbox" - android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" android:gravity="center_vertical" - android:paddingStart="@dimen/qs_panel_padding" - android:text="@string/zen_mode_title" /> + android:textAppearance="@style/TextAppearance.QS.DetailHeader" /> - <View + <ImageView android:id="@android:id/custom" android:layout_width="match_parent" - android:layout_height="2dp" + android:layout_height="wrap_content" android:layout_below="@android:id/title" - android:background="#888" /> + android:layout_marginLeft="16dip" + android:layout_marginRight="16dip" + android:scaleType="fitXY" + android:src="?android:attr/dividerHorizontal" /> - <ListView + <FrameLayout android:id="@android:id/content" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_above="@android:id/button2" - android:layout_below="@android:id/custom" - android:divider="#00000000" - android:dividerHeight="0px" /> - - <TextView - android:id="@android:id/button2" - style="@style/QSBorderless" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true" - android:layout_alignParentEnd="true" - android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" - android:padding="@dimen/qs_panel_padding" - android:text="@string/quick_settings_more_settings" - android:textAllCaps="true" /> + android:layout_below="@android:id/custom" /> -</com.android.systemui.qs.tiles.ZenModeDetail>
\ No newline at end of file +</RelativeLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml index 85de645..398787f 100644 --- a/packages/SystemUI/res/layout/qs_panel.xml +++ b/packages/SystemUI/res/layout/qs_panel.xml @@ -16,11 +16,10 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/quick_settings_container" - android:paddingLeft="@dimen/notification_side_padding" - android:paddingRight="@dimen/notification_side_padding" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/qs_panel_background" > + android:background="@drawable/qs_panel_background" + android:elevation="2dp"> <com.android.systemui.qs.QSPanel android:id="@+id/quick_settings_panel" android:background="#0000" diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml index 1efda8c..97ed9a0 100644 --- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml +++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml @@ -15,7 +15,8 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" - style="@style/BrightnessDialogContainer"> + style="@style/BrightnessDialogContainer" + android:clickable="true"> <ImageView android:id="@+id/brightness_icon" diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 2ec9935..cde83bf 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -59,8 +59,8 @@ android:id="@+id/scroll_view" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="invisible" android:scrollbars="none" + android:overScrollMode="never" android:fillViewport="true"> <LinearLayout android:layout_width="match_parent" @@ -70,7 +70,9 @@ layout="@layout/qs_panel" android:layout_marginTop="@dimen/status_bar_header_height_expanded" android:layout_width="match_parent" - android:layout_height="wrap_content"/> + android:layout_height="wrap_content" + android:layout_marginLeft="@dimen/notification_side_padding" + android:layout_marginRight="@dimen/notification_side_padding"/> <!-- A view to reserve space for the collapsed stack --> <View @@ -79,7 +81,6 @@ </LinearLayout> </com.android.systemui.statusbar.phone.ObservableScrollView> - <com.android.systemui.statusbar.stack.NotificationStackScrollLayout android:id="@+id/notification_stack_scroller" android:layout_width="match_parent" diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml index 89fa988..7f34041 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml @@ -25,7 +25,7 @@ android:paddingStart="@dimen/notification_side_padding" android:paddingEnd="@dimen/notification_side_padding" android:baselineAligned="false" - android:elevation="10dp" + android:elevation="4dp" > <View @@ -65,22 +65,13 @@ /> </RelativeLayout> - <com.android.keyguard.CarrierText - android:id="@+id/keyguard_carrier_text" - android:layout_width="wrap_content" - android:layout_height="@dimen/status_bar_header_height_keyguard" - android:layout_marginLeft="8dp" - android:gravity="center_vertical" - android:ellipsize="marquee" - android:textAppearance="?android:attr/textAppearanceMedium" /> - <com.android.systemui.statusbar.phone.MultiUserSwitch android:id="@+id/multi_user_switch" android:layout_width="40dp" android:layout_height="@dimen/status_bar_header_height" android:layout_alignParentEnd="true" android:background="@null" android:scaleType="centerInside" - android:padding="6dp" + android:padding="8dp" /> <ImageButton android:id="@+id/settings_button" @@ -98,6 +89,18 @@ android:layout_marginEnd="4dp" /> + <com.android.keyguard.CarrierText + android:id="@+id/keyguard_carrier_text" + android:layout_width="match_parent" + android:layout_height="@dimen/status_bar_header_height_keyguard" + android:layout_marginLeft="8dp" + android:layout_toStartOf="@id/system_icons_container" + android:gravity="center_vertical" + android:ellipsize="marquee" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="#ffffff" + android:singleLine="true" /> + <include layout="@layout/quick_settings_brightness_dialog" android:id="@+id/brightness_container" diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml index 26616cd..e84300d 100644 --- a/packages/SystemUI/res/layout/super_status_bar.xml +++ b/packages/SystemUI/res/layout/super_status_bar.xml @@ -26,6 +26,10 @@ android:fitsSystemWindows="true" android:descendantFocusability="afterDescendants"> + <View android:id="@+id/scrim_behind" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + <include layout="@layout/status_bar" android:layout_width="match_parent" android:layout_height="@dimen/status_bar_height" /> @@ -40,4 +44,8 @@ android:visibility="gone" /> </com.android.systemui.statusbar.phone.PanelHolder> + <View android:id="@+id/scrim_in_front" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + </com.android.systemui.statusbar.phone.StatusBarWindowView> diff --git a/packages/SystemUI/res/layout/user_switcher_host.xml b/packages/SystemUI/res/layout/user_switcher_host.xml index 70c5042..816af57 100644 --- a/packages/SystemUI/res/layout/user_switcher_host.xml +++ b/packages/SystemUI/res/layout/user_switcher_host.xml @@ -27,7 +27,7 @@ <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@*android:dimen/volume_panel_top" + android:layout_marginTop="@dimen/volume_panel_top" android:background="@*android:drawable/dialog_full_holo_dark"> <ListView android:id="@android:id/list" android:layout_width="match_parent" diff --git a/packages/SystemUI/res/layout/volume_panel.xml b/packages/SystemUI/res/layout/volume_panel.xml new file mode 100644 index 0000000..bc7288d --- /dev/null +++ b/packages/SystemUI/res/layout/volume_panel.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2007 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. +--> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/visible_panel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" > + + <FrameLayout + android:id="@+id/slider_panel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_toLeftOf="@+id/expand_button_divider" /> + + <ImageView + android:id="@+id/expand_button_divider" + android:layout_width="wrap_content" + android:layout_height="32dip" + android:layout_gravity="top" + android:layout_marginBottom="16dip" + android:layout_marginTop="16dip" + android:layout_toLeftOf="@+id/expand_button" + android:scaleType="fitXY" + android:src="?android:attr/dividerVertical" /> + + <ImageView + android:id="@+id/expand_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_gravity="top" + style="@style/BorderlessButton.Tiny" + android:padding="16dip" /> + + <ImageView + android:id="@+id/zen_panel_divider" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@+id/slider_panel" + android:layout_marginLeft="16dip" + android:layout_marginRight="16dip" + android:scaleType="fitXY" + android:src="?android:attr/dividerHorizontal" /> + + <ViewStub + android:id="@+id/zen_panel_stub" + android:layout_below="@+id/zen_panel_divider" + android:inflatedId="@+id/zen_panel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout="@layout/zen_mode_panel" /> + +</RelativeLayout> diff --git a/core/res/res/layout/volume_adjust_item.xml b/packages/SystemUI/res/layout/volume_panel_item.xml index 57cecf4..98cb8f4 100644 --- a/core/res/res/layout/volume_adjust_item.xml +++ b/packages/SystemUI/res/layout/volume_panel_item.xml @@ -27,7 +27,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="16dip" - android:background="?attr/selectableItemBackground" + android:background="?android:attr/selectableItemBackground" android:contentDescription="@null" /> <SeekBar diff --git a/packages/SystemUI/res/layout/qs_zen_mode_detail_condition.xml b/packages/SystemUI/res/layout/zen_mode_condition.xml index fd27aaf..8b34400 100644 --- a/packages/SystemUI/res/layout/qs_zen_mode_detail_condition.xml +++ b/packages/SystemUI/res/layout/zen_mode_condition.xml @@ -16,44 +16,47 @@ --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent" > + android:layout_height="wrap_content" > <RadioButton android:id="@android:id/checkbox" android:layout_width="32dp" - android:layout_height="64dp" + android:layout_height="@dimen/zen_mode_condition_height" android:layout_alignParentStart="true" - android:layout_marginStart="@dimen/qs_panel_padding" android:gravity="center" /> <TextView android:id="@android:id/title" android:layout_width="match_parent" - android:layout_height="64dp" + android:layout_height="@dimen/zen_mode_condition_height" android:layout_toEndOf="@android:id/checkbox" android:layout_toStartOf="@android:id/button1" android:ellipsize="end" - android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" android:gravity="center_vertical" android:maxLines="1" - android:text="@string/accessibility_back" /> + android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary" /> <ImageView android:id="@android:id/button1" - android:src="@drawable/ic_qs_minus" - android:layout_width="64dp" - android:layout_height="64dp" + style="@style/BorderlessButton" + android:layout_width="@dimen/zen_mode_condition_height" + android:layout_height="@dimen/zen_mode_condition_height" android:layout_alignParentEnd="true" - android:layout_marginEnd="48dp" - android:padding="@dimen/qs_panel_padding" - android:paddingRight="0px" /> + android:layout_centerVertical="true" + android:layout_marginEnd="@dimen/zen_mode_condition_height" + android:contentDescription="@string/accessibility_quick_settings_less_time" + android:padding="@dimen/zen_mode_condition_detail_button_padding" + android:src="@drawable/ic_qs_minus" /> <ImageView android:id="@android:id/button2" - android:src="@drawable/ic_qs_plus" - android:layout_width="64dp" - android:layout_height="64dp" + style="@style/BorderlessButton" + android:layout_width="@dimen/zen_mode_condition_height" + android:layout_height="@dimen/zen_mode_condition_height" android:layout_alignParentEnd="true" - android:padding="@dimen/qs_panel_padding" /> + android:layout_centerVertical="true" + android:contentDescription="@string/accessibility_quick_settings_more_time" + android:padding="@dimen/zen_mode_condition_detail_button_padding" + android:src="@drawable/ic_qs_plus" /> -</RelativeLayout> +</RelativeLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml new file mode 100644 index 0000000..ae04bf5 --- /dev/null +++ b/packages/SystemUI/res/layout/zen_mode_panel.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<!-- extends LinearLayout --> +<com.android.systemui.volume.ZenModePanel xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/zen_mode_panel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/system_primary_color" + android:orientation="vertical" + android:padding="@dimen/qs_panel_padding" > + + <TextView + android:id="@android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_marginBottom="8dp" + android:text="@string/zen_mode_title" + android:textAppearance="@style/TextAppearance.QS.DetailHeader" /> + + <LinearLayout + android:id="@android:id/content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" /> + + <TextView + android:id="@android:id/button2" + style="@style/BorderlessButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_gravity="end" + android:text="@string/quick_settings_more_settings" + android:textAppearance="@style/TextAppearance.QS.DetailButton" /> + +</com.android.systemui.volume.ZenModePanel>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index 22815f3..5750faa 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -57,6 +57,6 @@ <!-- The margin between the clock and the notifications on Keyguard. See keyguard_clock_height_fraction_* for the difference between min and max.--> - <dimen name="keyguard_clock_notifications_margin_min">32dp</dimen> - <dimen name="keyguard_clock_notifications_margin_max">32dp</dimen> + <dimen name="keyguard_clock_notifications_margin_min">36dp</dimen> + <dimen name="keyguard_clock_notifications_margin_max">36dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index 8fd1206..3549689 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -20,8 +20,6 @@ <attr name="keyCode" format="integer" /> <!-- does this button generate longpress / repeat events? --> <attr name="keyRepeat" format="boolean" /> - <!-- drawable to use for a swelling, glowing background on press --> - <attr name="glowBackground" format="reference" /> </declare-styleable> <declare-styleable name="ToggleSlider"> <attr name="text" format="string" /> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index e5ed3d6..4e37dbb 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -31,8 +31,6 @@ <drawable name="recents_callout_line">#99ffffff</drawable> <drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable> <drawable name="heads_up_notification_bg_pressed">#ff33B5E5</drawable> - <color name="notification_panel_scrim_color">#A0000000</color> - <color name="notification_panel_scrim_color_keyguard">#80000000</color> <color name="batterymeter_frame_color">#66FFFFFF</color><!-- 40% white --> <color name="batterymeter_charge_color">#FFFFFFFF</color> <color name="batterymeter_bolt_color">#FFFFFFFF</color> @@ -75,6 +73,8 @@ <!-- The recents task bar dark dismiss icon color to be drawn on top of light backgrounds. --> <color name="recents_task_bar_dark_dismiss_color">#ff333333</color> + <color name="keyguard_affordance">#ffffffff</color> + <!-- Our quantum color palette (deep teal) --> <color name="primary_color">#ff7fcac3</color> <color name="background_color_1">#ff384248</color> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 0bd4f18..6405ae6 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -135,5 +135,8 @@ <!-- Defines the implementation of the velocity tracker to be used for the panel expansion. Can be 'platform' or 'noisy' (i.e. for noisy touch screens). --> <string name="velocity_tracker_impl" translatable="false">platform</string> + + <!-- Wait on the touch feedback this long before performing an action. --> + <integer name="feedback_start_delay">300</integer> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index c209434..6e35230 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -196,6 +196,12 @@ <dimen name="qs_dual_tile_height">109dp</dimen> <dimen name="qs_dual_tile_padding">12dp</dimen> + <!-- How far the expanded QS panel peeks from the header in collapsed state. --> + <dimen name="qs_peek_height">8dp</dimen> + + <dimen name="zen_mode_condition_detail_button_padding">8dp</dimen> + <dimen name="zen_mode_condition_height">48dp</dimen> + <!-- used by DessertCase --> <dimen name="dessert_case_cell_size">192dp</dimen> @@ -246,7 +252,7 @@ <dimen name="notification_side_padding">8dp</dimen> <!-- Z distance between notifications if they are in the stack --> - <dimen name="z_distance_between_notifications">2dp</dimen> + <dimen name="z_distance_between_notifications">1dp</dimen> <!-- The padding between the individual notification cards when dimmed. --> <dimen name="notification_padding_dimmed">0dp</dimen> @@ -288,4 +294,9 @@ <dimen name="keyguard_clock_notifications_margin_min">22dp</dimen> <dimen name="keyguard_clock_notifications_margin_max">36dp</dimen> + <!-- Volume panel dialog y offset --> + <dimen name="volume_panel_top">16dp</dimen> + + <!-- Volume panel dialog width --> + <dimen name="volume_panel_width">300dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index f5bc353..ef3956e 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -388,6 +388,12 @@ <string name="accessibility_quick_settings_location">Location <xliff:g id="state" example="Off">%s</xliff:g>.</string> <!-- Content description of the alarm tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_quick_settings_alarm">Alarm set for <xliff:g id="time" example="Wed 3:30 PM">%s</xliff:g>.</string> + <!-- Content description of quick settings detail panel close button (not shown on the screen). [CHAR LIMIT=NONE] --> + <string name="accessibility_quick_settings_close">Close panel</string> + <!-- Content description of zen mode time condition plus button (not shown on the screen). [CHAR LIMIT=NONE] --> + <string name="accessibility_quick_settings_more_time">More time</string> + <!-- Content description of zen mode time condition minus button (not shown on the screen). [CHAR LIMIT=NONE] --> + <string name="accessibility_quick_settings_less_time">Less time</string> <!-- Title of dialog shown when 2G-3G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] --> <string name="data_usage_disabled_dialog_3g_title">2G-3G data disabled</string> @@ -512,6 +518,8 @@ <string name="quick_settings_tethering_label">Tethering</string> <!-- QuickSettings: Hotspot. [CHAR LIMIT=NONE] --> <string name="quick_settings_hotspot_label">Hotspot</string> + <!-- QuickSettings: Notifications [CHAR LIMIT=NONE] --> + <string name="quick_settings_notifications_label">Notifications</string> <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] --> <string name="recents_empty_message">RECENTS</string> @@ -563,4 +571,19 @@ <string name="keyguard_unlock">Swipe up to unlock</string> <string name="bugreport_tile_extended" translatable="false">%s\n%s (%s)</string> + + <!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] --> + <string name="zen_mode_forever">Until you turn this off</string> + + <!-- Zen mode condition: time duration in minutes. [CHAR LIMIT=NONE] --> + <plurals name="zen_mode_duration_minutes"> + <item quantity="one">For one minute</item> + <item quantity="other">For %d minutes</item> + </plurals> + + <!-- Zen mode condition: time duration in hours. [CHAR LIMIT=NONE] --> + <plurals name="zen_mode_duration_hours"> + <item quantity="one">For one hour</item> + <item quantity="other">For %d hours</item> + </plurals> </resources> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 19888a8..6a12232 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -133,6 +133,32 @@ <item name="android:fadingEdge">horizontal</item> </style> + <style name="TextAppearance.QS"> + <item name="android:textStyle">normal</item> + <item name="android:textColor">#ffffff</item> + <item name="android:fontFamily">sans-serif</item> + </style> + + <style name="TextAppearance.QS.DetailHeader"> + <item name="android:textSize">20sp</item> + <item name="android:fontFamily">sans-serif-medium</item> + </style> + + <style name="TextAppearance.QS.DetailItemPrimary"> + <item name="android:textSize">16sp</item> + </style> + + <style name="TextAppearance.QS.DetailItemSecondary"> + <item name="android:textSize">14sp</item> + <item name="android:textColor">#7fcac3</item> + </style> + + <style name="TextAppearance.QS.DetailButton"> + <item name="android:textSize">14sp</item> + <item name="android:textAllCaps">true</item> + <item name="android:fontFamily">sans-serif-medium</item> + </style> + <style name="BaseBrightnessDialogContainer"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> @@ -192,9 +218,9 @@ <item name="android:colorControlActivated">@color/system_accent_color</item> </style> - <style name="QSBorderless" parent="@android:style/Widget.Quantum.Button.Borderless" /> + <style name="BorderlessButton" parent="@android:style/Widget.Quantum.Button.Borderless" /> - <style name="QSBorderless.Tiny"> + <style name="BorderlessButton.Tiny"> <item name="android:minHeight">12dip</item> <item name="android:minWidth">12dip</item> </style> diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 6387a92..1b12cb0 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -56,6 +56,7 @@ public class SwipeHelper implements Gefingerpoken { static final float ALPHA_FADE_END = 0.5f; // fraction of thumbnail width // beyond which alpha->0 private float mMinAlpha = 0f; + private float mMaxAlpha = 1f; private float mPagingTouchSlop; private Callback mCallback; @@ -140,6 +141,10 @@ public class SwipeHelper implements Gefingerpoken { mMinAlpha = minAlpha; } + public void setMaxAlpha(float maxAlpha) { + mMaxAlpha = maxAlpha; + } + private float getAlphaForOffset(View view) { float viewSize = getSize(view); final float fadeSize = ALPHA_FADE_END * viewSize; @@ -150,7 +155,7 @@ public class SwipeHelper implements Gefingerpoken { } else if (pos < viewSize * (1.0f - ALPHA_FADE_START)) { result = 1.0f + (viewSize * ALPHA_FADE_START + pos) / fadeSize; } - return Math.max(mMinAlpha, result); + return Math.min(Math.max(mMinAlpha, result), mMaxAlpha); } private void updateAlphaFromOffset(View animView, boolean dismissable) { diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index d7ce255..630ba13 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -42,12 +42,12 @@ public class SystemUIApplication extends Application { private final Class<?>[] SERVICES = new Class[] { com.android.systemui.keyguard.KeyguardViewMediator.class, com.android.systemui.recent.Recents.class, + com.android.systemui.volume.VolumeUI.class, com.android.systemui.statusbar.SystemBars.class, com.android.systemui.usb.StorageNotification.class, com.android.systemui.power.PowerUI.class, com.android.systemui.media.RingtonePlayer.class, com.android.systemui.settings.SettingsUI.class, - com.android.systemui.volume.VolumeUI.class, }; /** diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index e73e904..b2872fa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -62,6 +62,7 @@ import com.android.keyguard.analytics.KeyguardAnalytics; import com.android.keyguard.analytics.Session; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.phone.PhoneStatusBar; +import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.StatusBarWindowManager; @@ -1316,9 +1317,10 @@ public class KeyguardViewMediator extends SystemUI { } public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar, - ViewGroup container, StatusBarWindowManager statusBarWindowManager) { + ViewGroup container, StatusBarWindowManager statusBarWindowManager, + ScrimController scrimController) { mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container, - statusBarWindowManager); + statusBarWindowManager, scrimController); return mStatusBarKeyguardViewManager; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java index 835a5c4..c76ee8c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java @@ -26,6 +26,7 @@ import android.util.Log; import android.view.View; import android.view.ViewGroup; +import com.android.systemui.R; import com.android.systemui.qs.QSTile.State; import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.CastController; @@ -35,6 +36,7 @@ import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.TetheringController; import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.volume.VolumeComponent; import java.util.List; import java.util.Objects; @@ -49,12 +51,12 @@ import java.util.Objects; public abstract class QSTile<TState extends State> implements Listenable { protected final String TAG = "QSTile." + getClass().getSimpleName(); protected static final boolean DEBUG = false; - public static final int FEEDBACK_START_DELAY = 400; protected final Host mHost; protected final Context mContext; protected final H mHandler; protected final Handler mUiHandler = new Handler(Looper.getMainLooper()); + private final int mFeedbackStartDelay; private Callback mCallback; protected final TState mState = newTileState(); @@ -68,6 +70,7 @@ public abstract class QSTile<TState extends State> implements Listenable { mHost = host; mContext = host.getContext(); mHandler = new H(host.getLooper()); + mFeedbackStartDelay = mContext.getResources().getInteger(R.integer.feedback_start_delay); } public boolean supportsDualTargets() { @@ -116,6 +119,10 @@ public abstract class QSTile<TState extends State> implements Listenable { mHandler.obtainMessage(H.USER_SWITCH, newUserId).sendToTarget(); } + protected void postAfterFeedback(Runnable runnable) { + mHandler.postDelayed(runnable, mFeedbackStartDelay); + } + // call only on tile worker looper private void handleSetCallback(Callback callback) { @@ -213,6 +220,7 @@ public abstract class QSTile<TState extends State> implements Listenable { ZenModeController getZenModeController(); TetheringController getTetheringController(); CastController getCastController(); + VolumeComponent getVolumeComponent(); } public static class State { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java index 5eecc20..2edd8d5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java @@ -84,7 +84,8 @@ public class QSTileView extends ViewGroup { removeView(mLabel); } final Resources res = mContext.getResources(); - mLabel = new TextView(mDual ? new ContextThemeWrapper(mContext, R.style.QSBorderless_Tiny) + mLabel = new TextView(mDual + ? new ContextThemeWrapper(mContext, R.style.BorderlessButton_Tiny) : mContext); mLabel.setId(android.R.id.title); mLabel.setTextColor(res.getColor(R.color.qs_tile_text)); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index c0f9bf2..191bac9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -20,6 +20,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.ConnectivityManager; import android.provider.Settings.Global; import com.android.systemui.R; @@ -52,10 +53,9 @@ public class AirplaneModeTile extends QSTile<QSTile.BooleanState> { } private void setEnabled(boolean enabled) { - mSetting.setValue(enabled ? 1 : 0); - final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); - intent.putExtra("state", enabled); - mContext.sendBroadcast(intent); + final ConnectivityManager mgr = + (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mgr.setAirplaneMode(enabled); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java index fa41837..07ea825 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java @@ -58,13 +58,13 @@ public class BugreportTile extends QSTile<QSTile.State> { @Override protected void handleClick() { - mHandler.postDelayed(new Runnable() { + postAfterFeedback(new Runnable() { @Override public void run() { mHost.collapsePanels(); mUiHandler.post(mShowDialog); } - }, FEEDBACK_START_DELAY); + }); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index 907c77e..6793051 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -65,12 +65,12 @@ public class CastTile extends QSTile<QSTile.BooleanState> { @Override protected void handleClick() { - mHandler.postDelayed(new Runnable() { + postAfterFeedback(new Runnable() { public void run() { mHost.collapsePanels(); mUiHandler.post(mShowDialog); } - }, FEEDBACK_START_DELAY); + }); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java new file mode 100644 index 0000000..130f9ce --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java @@ -0,0 +1,172 @@ +/* + * 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. + */ + +package com.android.systemui.qs.tiles; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.media.AudioManager; +import android.util.Log; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnAttachStateChangeListener; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.android.systemui.R; +import com.android.systemui.qs.QSTile; +import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.volume.VolumeComponent; +import com.android.systemui.volume.VolumePanel; +import com.android.systemui.volume.ZenModePanel; + +/** Quick settings tile: Notifications **/ +public class NotificationsTile extends QSTile<NotificationsTile.NotificationsState> { + private final ZenModeController mZenController; + private final AudioManager mAudioManager; + + public NotificationsTile(Host host) { + super(host); + mZenController = host.getZenModeController(); + mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + } + + @Override + public View createDetailView(Context context, ViewGroup root) { + final Context themedContext = new ContextThemeWrapper(mContext, R.style.QSAccentTheme); + final View v = LayoutInflater.from(themedContext).inflate(R.layout.qs_detail, root, false); + final TextView title = (TextView) v.findViewById(android.R.id.title); + title.setText(R.string.quick_settings_notifications_label); + final View close = v.findViewById(android.R.id.button1); + close.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showDetail(false); + } + }); + final ViewGroup content = (ViewGroup) v.findViewById(android.R.id.content); + final VolumeComponent volumeComponent = mHost.getVolumeComponent(); + final VolumePanel vp = new VolumePanel(mContext, content, mZenController); + v.addOnAttachStateChangeListener(new OnAttachStateChangeListener() { + @Override + public void onViewDetachedFromWindow(View v) { + volumeComponent.setVolumePanel(null); + } + + @Override + public void onViewAttachedToWindow(View v) { + volumeComponent.setVolumePanel(vp); + } + }); + vp.setZenModePanelCallback(new ZenModePanel.Callback() { + @Override + public void onMoreSettings() { + mHost.startSettingsActivity(ZenModePanel.ZEN_SETTINGS); + } + + @Override + public void onInteraction() { + // noop + } + }); + vp.postVolumeChanged(AudioManager.STREAM_NOTIFICATION, AudioManager.FLAG_SHOW_UI); + return v; + } + + @Override + protected NotificationsState newTileState() { + return new NotificationsState(); + } + + @Override + public void setListening(boolean listening) { + if (listening) { + mZenController.addCallback(mCallback); + final IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); + mContext.registerReceiver(mReceiver, filter); + } else { + mZenController.removeCallback(mCallback); + mContext.unregisterReceiver(mReceiver); + } + } + + @Override + protected void handleClick() { + if (mState.zen) { + mZenController.setZen(false); + } else { + showDetail(true); + } + } + + @Override + protected void handleUpdateState(NotificationsState state, Object arg) { + state.visible = true; + state.zen = arg instanceof Boolean ? (Boolean) arg : mZenController.isZen(); + state.ringerMode = mAudioManager.getRingerMode(); + if (state.zen) { + state.iconId = R.drawable.ic_qs_zen_on; + } else if (state.ringerMode == AudioManager.RINGER_MODE_VIBRATE) { + state.iconId = R.drawable.ic_qs_ringer_vibrate; + } else if (state.ringerMode == AudioManager.RINGER_MODE_SILENT) { + state.iconId = R.drawable.ic_qs_ringer_silent; + } else { + state.iconId = R.drawable.ic_qs_ringer_audible; + } + state.label = mContext.getString(R.string.quick_settings_notifications_label); + } + + private final ZenModeController.Callback mCallback = new ZenModeController.Callback() { + @Override + public void onZenChanged(boolean zen) { + if (DEBUG) Log.d(TAG, "onZenChanged " + zen); + refreshState(zen); + } + }; + + public static final class NotificationsState extends QSTile.State { + public boolean zen; + public int ringerMode; + + @Override + public boolean copyTo(State other) { + final NotificationsState o = (NotificationsState) other; + final boolean changed = o.zen != zen || o.ringerMode != ringerMode; + o.zen = zen; + o.ringerMode = ringerMode; + return super.copyTo(other) || changed; + } + + @Override + protected StringBuilder toStringBuilder() { + final StringBuilder rt = super.toStringBuilder(); + rt.insert(rt.length() - 1, ",zen=" + zen + ",ringerMode=" + ringerMode); + return rt; + } + } + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(intent.getAction())) { + refreshState(); + } + } + }; +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RingerModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RingerModeTile.java deleted file mode 100644 index c5e9b52..0000000 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RingerModeTile.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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. - */ - -package com.android.systemui.qs.tiles; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.media.AudioManager; - -import com.android.systemui.R; -import com.android.systemui.qs.QSTile; - -/** Quick settings tile: Ringer mode **/ -public class RingerModeTile extends QSTile<RingerModeTile.IntState> { - - private final AudioManager mAudioManager; - - public RingerModeTile(Host host) { - super(host); - mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - } - - @Override - protected IntState newTileState() { - return new IntState(); - } - - @Override - public void setListening(boolean listening) { - if (listening) { - final IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); - mContext.registerReceiver(mReceiver, filter); - } else { - mContext.unregisterReceiver(mReceiver); - } - } - - @Override - protected void handleClick() { - final int oldValue = (Integer) mState.value; - final int newValue = - oldValue == AudioManager.RINGER_MODE_NORMAL ? AudioManager.RINGER_MODE_VIBRATE - : oldValue == AudioManager.RINGER_MODE_VIBRATE ? AudioManager.RINGER_MODE_SILENT - : AudioManager.RINGER_MODE_NORMAL; - - mAudioManager.setRingerMode(newValue); - } - - @Override - protected void handleUpdateState(IntState state, Object arg) { - final int ringerMode = mAudioManager.getRingerMode(); - state.visible = true; - state.value = ringerMode; - if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { - state.iconId = R.drawable.ic_qs_ringer_vibrate; - state.label = "Vibrate"; - } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) { - state.iconId = R.drawable.ic_qs_ringer_silent; - state.label = "Silent"; - } else { - state.iconId = R.drawable.ic_qs_ringer_audible; - state.label = "Audible"; - } - } - - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(intent.getAction())) { - refreshState(); - } - } - }; - - public static class IntState extends QSTile.State { - public int value; - - @Override - public boolean copyTo(State other) { - final IntState o = (IntState) other; - final boolean changed = o.value != value; - o.value = value; - return super.copyTo(other) || changed; - } - - @Override - protected StringBuilder toStringBuilder() { - final StringBuilder rt = super.toStringBuilder(); - rt.insert(rt.length() - 1, ",value=" + value); - return rt; - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index ef7fb89..a1e70b9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -83,7 +83,7 @@ public class WifiTile extends QSTile<QSTile.SignalState> { boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null); boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.enabledDesc == null); - state.enabled = wifiConnected; + state.enabled = cb.enabled; state.connected = wifiConnected; state.activityIn = cb.enabled && cb.activityIn; state.activityOut = cb.enabled && cb.activityOut; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeDetail.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeDetail.java deleted file mode 100644 index f30f791..0000000 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeDetail.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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. - */ - -package com.android.systemui.qs.tiles; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.provider.Settings; -import android.service.notification.Condition; -import android.util.AttributeSet; -import android.view.ContextThemeWrapper; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.RadioButton; -import android.widget.RelativeLayout; -import android.widget.Switch; -import android.widget.TextView; - -import com.android.systemui.R; -import com.android.systemui.qs.QSTile; -import com.android.systemui.statusbar.policy.ZenModeController; - -import java.util.HashSet; - -/** Quick settings control panel: Zen mode **/ -public class ZenModeDetail extends RelativeLayout { - private static final String TAG = "ZenModeDetail"; - private static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS); - private static final int[] MINUTES = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 }; - - private final H mHandler = new H(); - - private int mMinutesIndex = 3; - private Context mContext; - private ZenModeTile mTile; - private QSTile.Host mHost; - private ZenModeController mController; - - private Switch mSwitch; - private ConditionAdapter mAdapter; - - public ZenModeDetail(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public void init(ZenModeTile tile) { - mTile = tile; - mHost = mTile.getHost(); - mContext = getContext(); - mController = mHost.getZenModeController(); - - final ImageView close = (ImageView) findViewById(android.R.id.button1); - close.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mTile.showDetail(false); - } - }); - mSwitch = (Switch) findViewById(android.R.id.checkbox); - mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mController.setZen(isChecked); - } - }); - mSwitch.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final boolean isChecked = mSwitch.isChecked(); - mController.setZen(isChecked); - if (!isChecked) { - mTile.showDetail(false); - } - } - }); - - final View moreSettings = findViewById(android.R.id.button2); - moreSettings.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mHost.startSettingsActivity(ZEN_SETTINGS); - mTile.showDetail(false); - } - }); - final ListView conditions = (ListView) findViewById(android.R.id.content); - mAdapter = new ConditionAdapter(mContext); - conditions.setAdapter(mAdapter); - mAdapter.add(updateTimeCondition()); - - updateZen(mController.isZen()); - } - - private Condition updateTimeCondition() { - final int minutes = MINUTES[mMinutesIndex]; - final long millis = System.currentTimeMillis() + minutes * 60 * 1000; - final Uri id = new Uri.Builder().scheme(Condition.SCHEME).authority("android") - .appendPath("countdown").appendPath(Long.toString(millis)).build(); - final int num = minutes < 60 ? minutes : minutes / 60; - final String units = minutes < 60 ? "minutes" : minutes == 60 ? "hour" : "hours"; - return new Condition(id, "For " + num + " " + units, "", "", 0, Condition.STATE_TRUE, - Condition.FLAG_RELEVANT_NOW); - } - - private void editTimeCondition(int delta) { - final int i = mMinutesIndex + delta; - if (i < 0 || i >= MINUTES.length) return; - mMinutesIndex = i; - mAdapter.remove(mAdapter.getItem(0)); - final Condition c = updateTimeCondition(); - mAdapter.insert(c, 0); - select(c); - } - - private void select(Condition condition) { - mController.select(condition); - } - - private void updateZen(boolean zen) { - mHandler.obtainMessage(H.UPDATE_ZEN, zen ? 1 : 0, 0).sendToTarget(); - } - - private void updateConditions(Condition[] conditions) { - if (conditions == null) return; - mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget(); - } - - private void handleUpdateZen(boolean zen) { - mSwitch.setChecked(zen); - } - - private void handleUpdateConditions(Condition[] conditions) { - for (int i = mAdapter.getCount() - 1; i > 0; i--) { - mAdapter.remove(mAdapter.getItem(i)); - } - for (Condition condition : conditions) { - mAdapter.add(condition); - } - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - mController.addCallback(mCallback); - mController.requestConditions(true); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mController.removeCallback(mCallback); - mController.requestConditions(false); - } - - private final class H extends Handler { - private static final int UPDATE_ZEN = 1; - private static final int UPDATE_CONDITIONS = 2; - - public H() { - super(Looper.getMainLooper()); - } - - @Override - public void handleMessage(Message msg) { - if (msg.what == UPDATE_ZEN) { - handleUpdateZen(msg.arg1 == 1); - } else if (msg.what == UPDATE_CONDITIONS) { - handleUpdateConditions((Condition[])msg.obj); - } - } - } - - private final ZenModeController.Callback mCallback = new ZenModeController.Callback() { - @Override - public void onZenChanged(boolean zen) { - updateZen(zen); - } - public void onConditionsChanged(Condition[] conditions) { - updateConditions(conditions); - } - }; - - private final class ConditionAdapter extends ArrayAdapter<Condition> { - private final LayoutInflater mInflater; - private final HashSet<RadioButton> mRadioButtons = new HashSet<RadioButton>(); - - public ConditionAdapter(Context context) { - super(context, 0); - mInflater = LayoutInflater.from(new ContextThemeWrapper(context, R.style.QSWhiteTheme)); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final Condition condition = getItem(position); - final boolean enabled = condition.state == Condition.STATE_TRUE; - - final View row = convertView != null ? convertView : mInflater - .inflate(R.layout.qs_zen_mode_detail_condition, parent, false); - final RadioButton rb = (RadioButton) row.findViewById(android.R.id.checkbox); - mRadioButtons.add(rb); - rb.setEnabled(enabled); - rb.setOnCheckedChangeListener(new OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked) { - for (RadioButton otherButton : mRadioButtons) { - if (otherButton == rb) continue; - otherButton.setChecked(false); - } - select(condition); - } - } - }); - final TextView title = (TextView) row.findViewById(android.R.id.title); - title.setText(condition.summary); - title.setEnabled(enabled); - title.setAlpha(enabled ? 1 : .5f); - final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1); - button1.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - rb.setChecked(true); - editTimeCondition(-1); - } - }); - - final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2); - button2.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - rb.setChecked(true); - editTimeCondition(1); - } - }); - title.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - rb.setChecked(true); - } - }); - if (position != 0) { - button1.setVisibility(View.GONE); - button2.setVisibility(View.GONE); - } - if (position == 0 && mRadioButtons.size() == 1) { - rb.setChecked(true); - } - return row; - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeTile.java deleted file mode 100644 index bfa9c19..0000000 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeTile.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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. - */ - -package com.android.systemui.qs.tiles; - -import android.content.Context; -import android.util.Log; -import android.view.ContextThemeWrapper; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.android.systemui.R; -import com.android.systemui.qs.QSTile; -import com.android.systemui.statusbar.policy.ZenModeController; - -/** Quick settings tile: Zen mode **/ -public class ZenModeTile extends QSTile<QSTile.BooleanState> { - private final ZenModeController mController; - - public ZenModeTile(Host host) { - super(host); - mController = host.getZenModeController(); - } - - @Override - public View createDetailView(Context context, ViewGroup root) { - final Context themedContext = new ContextThemeWrapper(mContext, R.style.QSAccentTheme); - final ZenModeDetail v = (ZenModeDetail) LayoutInflater.from(themedContext) - .inflate(R.layout.qs_zen_mode_detail, root, false); - v.init(this); - return v; - } - - @Override - protected BooleanState newTileState() { - return new BooleanState(); - } - - @Override - public void setListening(boolean listening) { - if (listening) { - mController.addCallback(mCallback); - } else { - mController.removeCallback(mCallback); - } - } - - @Override - protected void handleClick() { - final boolean newZen = !mState.value; - mController.setZen(newZen); - if (newZen) { - showDetail(true); - } - } - - @Override - protected void handleUpdateState(BooleanState state, Object arg) { - final boolean zen = arg instanceof Boolean ? (Boolean)arg : mController.isZen(); - state.value = zen; - state.visible = true; - state.iconId = zen ? R.drawable.ic_qs_zen_on : R.drawable.ic_qs_zen_off; - state.label = mContext.getString(R.string.zen_mode_title); - } - - private final ZenModeController.Callback mCallback = new ZenModeController.Callback() { - @Override - public void onZenChanged(boolean zen) { - if (DEBUG) Log.d(TAG, "onZenChanged " + zen); - refreshState(zen); - } - }; -} diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java index 27881c4..65e1cc6 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java @@ -72,8 +72,7 @@ public class BrightnessDialog extends Dialog implements window.setGravity(Gravity.TOP); WindowManager.LayoutParams lp = window.getAttributes(); // Offset from the top - lp.y = getContext().getResources().getDimensionPixelOffset( - com.android.internal.R.dimen.volume_panel_top); + lp.y = getContext().getResources().getDimensionPixelOffset(R.dimen.volume_panel_top); lp.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index e3dac4a..dcd187c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -149,6 +149,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView super.onFinishInflate(); mBackgroundNormal = (NotificationBackgroundView) findViewById(R.id.backgroundNormal); mBackgroundDimmed = (NotificationBackgroundView) findViewById(R.id.backgroundDimmed); + updateBackground(); updateBackgroundResources(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 9435e85..f4db625 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -84,6 +84,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; +import static com.android.keyguard.KeyguardHostView.OnDismissAction; + public abstract class BaseStatusBar extends SystemUI implements CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener { public static final String TAG = "StatusBar"; @@ -213,33 +215,47 @@ public abstract class BaseStatusBar extends SystemUI implements private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() { @Override - public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) { + public boolean onClickHandler( + final View view, final PendingIntent pendingIntent, final Intent fillInIntent) { if (DEBUG) { Log.v(TAG, "Notification click handler invoked for intent: " + pendingIntent); } final boolean isActivity = pendingIntent.isActivity(); if (isActivity) { - try { - // The intent we are sending is for the application, which - // won't have permission to immediately start an activity after - // the user switches to home. We know it is safe to do at this - // point, so make sure new activity switches are now allowed. - ActivityManagerNative.getDefault().resumeAppSwitches(); - // Also, notifications can be launched from the lock screen, - // so dismiss the lock screen when the activity starts. - ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); - } catch (RemoteException e) { - } - } + startNotificationActivity(new OnDismissAction() { + @Override + public boolean onDismiss() { + try { + // The intent we are sending is for the application, which + // won't have permission to immediately start an activity after + // the user switches to home. We know it is safe to do at this + // point, so make sure new activity switches are now allowed. + ActivityManagerNative.getDefault().resumeAppSwitches(); + // Also, notifications can be launched from the lock screen, + // so dismiss the lock screen when the activity starts. + ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); + } catch (RemoteException e) { + } - boolean handled = super.onClickHandler(view, pendingIntent, fillInIntent); + boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent); - if (isActivity && handled) { - // close the shade if it was open - animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); - visibilityChanged(false); + // close the shade if it was open + if (handled) { + animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); + visibilityChanged(false); + } + return handled; // Wait for activity start. + } + }); + return true; + } else { + return super.onClickHandler(view, pendingIntent, fillInIntent); } - return handled; + } + + private boolean superOnClickHandler(View view, PendingIntent pendingIntent, + Intent fillInIntent) { + return super.onClickHandler(view, pendingIntent, fillInIntent); } }; @@ -434,6 +450,14 @@ public abstract class BaseStatusBar extends SystemUI implements } } + /** + * Takes the necessary steps to prepare the status bar for starting an activity, then starts it. + * @param action A dismiss action that is called if it's safe to start the activity. + */ + protected void startNotificationActivity(OnDismissAction action) { + action.onDismiss(); + } + @Override protected void onConfigurationChanged(Configuration newConfig) { final Locale locale = mContext.getResources().getConfiguration().locale; @@ -999,47 +1023,55 @@ public abstract class BaseStatusBar extends SystemUI implements mIsHeadsUp = forHun; } - public void onClick(View v) { - try { - // The intent we are sending is for the application, which - // won't have permission to immediately start an activity after - // the user switches to home. We know it is safe to do at this - // point, so make sure new activity switches are now allowed. - ActivityManagerNative.getDefault().resumeAppSwitches(); - // Also, notifications can be launched from the lock screen, - // so dismiss the lock screen when the activity starts. - ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); - } catch (RemoteException e) { - } + public void onClick(final View v) { + startNotificationActivity(new OnDismissAction() { + public boolean onDismiss() { + try { + // The intent we are sending is for the application, which + // won't have permission to immediately start an activity after + // the user switches to home. We know it is safe to do at this + // point, so make sure new activity switches are now allowed. + ActivityManagerNative.getDefault().resumeAppSwitches(); + // Also, notifications can be launched from the lock screen, + // so dismiss the lock screen when the activity starts. + ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); + } catch (RemoteException e) { + } - if (mIntent != null) { - int[] pos = new int[2]; - v.getLocationOnScreen(pos); - Intent overlay = new Intent(); - overlay.setSourceBounds( - new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight())); - try { - mIntent.send(mContext, 0, overlay); - } catch (PendingIntent.CanceledException e) { - // the stack trace isn't very helpful here. Just log the exception message. - Log.w(TAG, "Sending contentIntent failed: " + e); - } + boolean sent = false; + if (mIntent != null) { + int[] pos = new int[2]; + v.getLocationOnScreen(pos); + Intent overlay = new Intent(); + overlay.setSourceBounds(new Rect(pos[0], pos[1], + pos[0]+v.getWidth(), pos[1]+v.getHeight())); + try { + mIntent.send(mContext, 0, overlay); + sent = true; + } catch (PendingIntent.CanceledException e) { + // the stack trace isn't very helpful here. + // Just log the exception message. + Log.w(TAG, "Sending contentIntent failed: " + e); + } + } - KeyguardTouchDelegate.getInstance(mContext).dismiss(); - } + try { + if (mIsHeadsUp) { + mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); + } + mBarService.onNotificationClick(mNotificationKey); + } catch (RemoteException ex) { + // system process is dead if we're here. + } - try { - if (mIsHeadsUp) { - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); - } - mBarService.onNotificationClick(mNotificationKey); - } catch (RemoteException ex) { - // system process is dead if we're here. - } + // close the shade if it was open + animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); + visibilityChanged(false); - // close the shade if it was open - animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); - visibilityChanged(false); + boolean waitForActivityLaunch = sent && mIntent.isActivity(); + return waitForActivityLaunch; + } + }); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java index a2f8991..a84daef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java @@ -103,7 +103,11 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene @Override public int getIntrinsicHeight() { - return getActualHeight(); + if (mCurrentAnimator != null) { + // expand animation is running + return getActualHeight(); + } + return mIsExpanded ? getHeight() : mCollapsedHeight; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 5e9ce21..714ad06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -29,18 +29,11 @@ import android.os.UserHandle; import android.provider.MediaStore; import android.util.AttributeSet; import android.util.Log; -import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityManager; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.ImageView; -import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.R; /** @@ -48,7 +41,8 @@ import com.android.systemui.R; * text. */ public class KeyguardBottomAreaView extends FrameLayout - implements SwipeAffordanceView.AffordanceListener { + implements SwipeAffordanceView.AffordanceListener, + UnlockMethodCache.OnUnlockMethodChangedListener { final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView"; @@ -60,9 +54,7 @@ public class KeyguardBottomAreaView extends FrameLayout private PowerManager mPowerManager; private ActivityStarter mActivityStarter; - - private LockPatternUtils mLockPatternUtils; - private KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private UnlockMethodCache mUnlockMethodCache; public KeyguardBottomAreaView(Context context) { super(context); @@ -89,13 +81,12 @@ public class KeyguardBottomAreaView extends FrameLayout mLockIcon = (ImageView) findViewById(R.id.lock_icon); mCameraButton.setAffordanceListener(this); mPhoneButton.setAffordanceListener(this); - mLockPatternUtils = new LockPatternUtils(getContext()); - mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext()); - KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mCallback); watchForDevicePolicyChanges(); watchForAccessibilityChanges(); updateCameraVisibility(); updatePhoneVisibility(); + mUnlockMethodCache = UnlockMethodCache.getInstance(getContext()); + mUnlockMethodCache.addListener(this); updateTrust(); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); } @@ -211,28 +202,14 @@ public class KeyguardBottomAreaView extends FrameLayout if (getVisibility() != VISIBLE) { return; } - int user = mLockPatternUtils.getCurrentUser(); - boolean trust = !mLockPatternUtils.isSecure() || - mKeyguardUpdateMonitor.getUserHasTrust(user); - - int iconRes = trust ? R.drawable.ic_lock_open_24dp : R.drawable.ic_lock_24dp; + int iconRes = mUnlockMethodCache.isMethodInsecure() + ? R.drawable.ic_lock_open_24dp + : R.drawable.ic_lock_24dp; mLockIcon.setImageResource(iconRes); } - final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { - @Override - public void onScreenTurnedOn() { - updateTrust(); - } - - @Override - public void onUserSwitchComplete(int userId) { - updateTrust(); - } - - @Override - public void onTrustChanged(int userId) { - updateTrust(); - } - }; + @Override + public void onMethodSecureChanged(boolean methodSecure) { + updateTrust(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index d8e1766..b7a7b0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -28,6 +28,7 @@ import com.android.keyguard.R; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.keyguard.KeyguardViewMediator; +import static com.android.keyguard.KeyguardHostView.OnDismissAction; import static com.android.keyguard.KeyguardSecurityModel.*; /** @@ -53,27 +54,36 @@ public class KeyguardBouncer { mWindowManager = windowManager; } - public void prepare() { - ensureView(); - } - public void show() { ensureView(); + if (mRoot.getVisibility() == View.VISIBLE) { + return; + } // Try to dismiss the Keyguard. If no security pattern is set, this will dismiss the whole // Keyguard. If we need to authenticate, show the bouncer. if (!mKeyguardView.dismiss()) { mRoot.setVisibility(View.VISIBLE); - mKeyguardView.requestFocus(); mKeyguardView.onResume(); + mKeyguardView.startAppearAnimation(); } } - public void hide() { + public void showWithDismissAction(OnDismissAction r) { + ensureView(); + mKeyguardView.setOnDismissAction(r); + show(); + } + + public void hide(boolean destroyView) { if (mKeyguardView != null) { mKeyguardView.cleanUp(); } - removeView(); + if (destroyView) { + removeView(); + } else if (mRoot != null) { + mRoot.setVisibility(View.INVISIBLE); + } } /** @@ -103,6 +113,10 @@ public class KeyguardBouncer { return mRoot != null && mRoot.getVisibility() == View.VISIBLE; } + public void prepare() { + ensureView(); + } + private void ensureView() { if (mRoot == null) { inflateView(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java index 769b1b1..c5c3fff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java @@ -17,7 +17,9 @@ package com.android.systemui.statusbar.phone; import android.content.Context; +import android.text.TextUtils; import android.util.AttributeSet; +import android.view.View; import android.widget.TextView; /** @@ -50,7 +52,12 @@ public class KeyguardIndicationTextView extends TextView { public void switchIndication(CharSequence text) { // TODO: Animation, make sure that we will show one indication long enough. - setText(text); + if (TextUtils.isEmpty(text)) { + setVisibility(View.INVISIBLE); + } else { + setVisibility(View.VISIBLE); + setText(text); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java index c83b479..3753a72 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java @@ -30,7 +30,6 @@ import com.android.systemui.statusbar.policy.KeyButtonView; public final class NavigationBarTransitions extends BarTransitions { - private static final float KEYGUARD_QUIESCENT_ALPHA = 0.5f; private static final int CONTENT_FADE_DURATION = 200; private final NavigationBarView mView; @@ -81,8 +80,6 @@ public final class NavigationBarTransitions extends BarTransitions { setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate); setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate); - setKeyButtonViewQuiescentAlpha(mView.getSearchLight(), KEYGUARD_QUIESCENT_ALPHA, animate); - applyBackButtonQuiescentAlpha(mode, animate); // apply to lights out @@ -96,7 +93,6 @@ public final class NavigationBarTransitions extends BarTransitions { public void applyBackButtonQuiescentAlpha(int mode, boolean animate) { float backAlpha = 0; - backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getSearchLight()); backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getHomeButton()); backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getRecentsButton()); backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getMenuButton()); @@ -116,7 +112,6 @@ public final class NavigationBarTransitions extends BarTransitions { public void setContentVisible(boolean visible) { final float alpha = visible ? 1 : 0; fadeContent(mView.getBackButton(), alpha); - fadeContent(mView.getSearchLight(), alpha); } private void fadeContent(View v, float alpha) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 089757a..21842bf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -133,16 +133,6 @@ public class NavigationBarView extends LinearLayout { } } - // simplified click handler to be used when device is in accessibility mode - private final OnClickListener mAccessibilityClickListener = new OnClickListener() { - @Override - public void onClick(View v) { - if (v.getId() == R.id.search_light) { - KeyguardTouchDelegate.getInstance(getContext()).showAssistant(); - } - } - }; - private final OnClickListener mImeSwitcherClickListener = new OnClickListener() { @Override public void onClick(View view) { @@ -246,11 +236,6 @@ public class NavigationBarView extends LinearLayout { return mCurrentView.findViewById(R.id.ime_switcher); } - // for when home is disabled, but search isn't - public View getSearchLight() { - return mCurrentView.findViewById(R.id.search_light); - } - private void getIcons(Resources res) { mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back); mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land); @@ -345,9 +330,6 @@ public class NavigationBarView extends LinearLayout { getHomeButton() .setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE); getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE); - final boolean showSearch = disableHome && !disableSearch; - setVisibleOrGone(getSearchLight(), showSearch); - mBarTransitions.applyBackButtonQuiescentAlpha(mBarTransitions.getMode(), true /*animate*/); } @@ -402,38 +384,6 @@ public class NavigationBarView extends LinearLayout { mCurrentView = mRotatedViews[Surface.ROTATION_0]; getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener); - - watchForAccessibilityChanges(); - } - - private void watchForAccessibilityChanges() { - final AccessibilityManager am = - (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); - - // Set the initial state - enableAccessibility(am.isTouchExplorationEnabled()); - - // Watch for changes - am.addTouchExplorationStateChangeListener(new TouchExplorationStateChangeListener() { - @Override - public void onTouchExplorationStateChanged(boolean enabled) { - enableAccessibility(enabled); - } - }); - } - - private void enableAccessibility(boolean touchEnabled) { - Log.v(TAG, "touchEnabled:" + touchEnabled); - - // Add a touch handler or accessibility click listener for camera and search buttons - // for all view orientations. - final OnClickListener onClickListener = touchEnabled ? mAccessibilityClickListener : null; - for (int i = 0; i < mRotatedViews.length; i++) { - final View searchLight = mRotatedViews[i].findViewById(R.id.search_light); - if (searchLight != null) { - searchLight.setOnClickListener(onClickListener); - } - } } public boolean isVertical() { @@ -571,7 +521,6 @@ public class NavigationBarView extends LinearLayout { dumpButton(pw, "home", getHomeButton()); dumpButton(pw, "rcnt", getRecentsButton()); dumpButton(pw, "menu", getMenuButton()); - dumpButton(pw, "srch", getSearchLight()); pw.println(" }"); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 0a44904..52688df 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -21,9 +21,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; -import android.graphics.Path; import android.util.AttributeSet; -import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; @@ -32,7 +30,6 @@ import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityEvent; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; -import android.view.animation.PathInterpolator; import android.widget.LinearLayout; import com.android.systemui.R; @@ -50,6 +47,7 @@ public class NotificationPanelView extends PanelView implements PhoneStatusBar mStatusBar; private StatusBarHeaderView mHeader; private View mQsContainer; + private View mQsPanel; private View mKeyguardStatusView; private ObservableScrollView mScrollView; private View mStackScrollerContainer; @@ -68,6 +66,7 @@ public class NotificationPanelView extends PanelView implements */ private boolean mIntercepting; private boolean mQsExpanded; + private boolean mKeyguardShowing; private float mInitialHeightOnTouch; private float mInitialTouchX; private float mInitialTouchY; @@ -77,6 +76,7 @@ public class NotificationPanelView extends PanelView implements private int mQsMinExpansionHeight; private int mQsMaxExpansionHeight; private int mMinStackHeight; + private int mQsPeekHeight; private float mNotificationTranslation; private int mStackScrollerIntrinsicPadding; private boolean mQsExpansionEnabled = true; @@ -121,6 +121,7 @@ public class NotificationPanelView extends PanelView implements mKeyguardStatusView = findViewById(R.id.keyguard_status_view); mStackScrollerContainer = findViewById(R.id.notification_container_parent); mQsContainer = findViewById(R.id.quick_settings_container); + mQsPanel = findViewById(R.id.quick_settings_panel); mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view); mScrollView.setListener(this); mNotificationStackScroller = (NotificationStackScrollLayout) @@ -139,22 +140,21 @@ public class NotificationPanelView extends PanelView implements mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.4f); mStatusBarMinHeight = getResources().getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); + mQsPeekHeight = getResources().getDimensionPixelSize(R.dimen.qs_peek_height); mClockPositionAlgorithm.loadDimens(getResources()); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - if (!mQsExpanded) { - positionClockAndNotifications(); - mNotificationStackScroller.setStackHeight(getExpandedHeight()); - } // Calculate quick setting heights. - mQsMinExpansionHeight = mHeader.getCollapsedHeight(); + mQsMinExpansionHeight = mHeader.getCollapsedHeight() + mQsPeekHeight; mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight(); - if (mQsExpansionHeight == 0) { - mQsExpansionHeight = mQsMinExpansionHeight; + if (!mQsExpanded) { + setQsExpansion(mQsMinExpansionHeight); + positionClockAndNotifications(); + mNotificationStackScroller.setStackHeight(getExpandedHeight()); } } @@ -165,7 +165,8 @@ public class NotificationPanelView extends PanelView implements private void positionClockAndNotifications() { boolean animateClock = mNotificationStackScroller.isAddOrRemoveAnimationPending(); if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) { - mStackScrollerIntrinsicPadding = mHeader.getBottom() + mNotificationTopPadding; + mStackScrollerIntrinsicPadding = mHeader.getBottom() + mQsPeekHeight + + mNotificationTopPadding; mTopPaddingAdjustment = 0; } else { mClockPositionAlgorithm.setup( @@ -353,10 +354,12 @@ public class NotificationPanelView extends PanelView implements @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { - // Block request so we can still intercept the scrolling when QS is expanded. - if (!mQsExpanded) { - super.requestDisallowInterceptTouchEvent(disallowIntercept); + // Block request when interacting with the scroll view so we can still intercept the + // scrolling when QS is expanded. + if (mScrollView.isDispatchingTouchEvent()) { + return; } + super.requestDisallowInterceptTouchEvent(disallowIntercept); } private void flingWithCurrentVelocity() { @@ -453,29 +456,38 @@ public class NotificationPanelView extends PanelView implements setQsExpansion(height); } - private void expandQs() { - mHeader.setExpanded(true); - mNotificationStackScroller.setEnabled(false); - mScrollView.setVisibility(View.VISIBLE); - mQsExpanded = true; + private void setQsExpanded(boolean expanded) { + boolean changed = mQsExpanded != expanded; + if (changed) { + mQsExpanded = expanded; + updateQsState(); + } } - private void collapseQs() { - mHeader.setExpanded(false); - mNotificationStackScroller.setEnabled(true); - mScrollView.setVisibility(View.INVISIBLE); - mQsExpanded = false; + public void setKeyguardShowing(boolean keyguardShowing) { + mKeyguardShowing = keyguardShowing; + updateQsState(); + } + + private void updateQsState() { + mHeader.setExpanded(mQsExpanded); + mNotificationStackScroller.setEnabled(!mQsExpanded); + mQsPanel.setVisibility(mQsExpanded ? View.VISIBLE : View.INVISIBLE); + mQsContainer.setVisibility(mKeyguardShowing && !mQsExpanded + ? View.INVISIBLE + : View.VISIBLE); + mScrollView.setTouchEnabled(mQsExpanded); } private void setQsExpansion(float height) { height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight); if (height > mQsMinExpansionHeight && !mQsExpanded) { - expandQs(); + setQsExpanded(true); } else if (height <= mQsMinExpansionHeight && mQsExpanded) { - collapseQs(); + setQsExpanded(false); } mQsExpansionHeight = height; - mHeader.setExpansion(height); + mHeader.setExpansion(height - mQsPeekHeight); setQsTranslation(height); setQsStackScrollerPadding(height); mStatusBar.userActivity(); @@ -644,6 +656,23 @@ public class NotificationPanelView extends PanelView implements } @Override + protected void onOverExpansionChanged(float overExpansion) { + float currentOverScroll = mNotificationStackScroller.getCurrentOverScrolledPixels(true); + mNotificationStackScroller.setOverScrolledPixels(currentOverScroll + overExpansion + - mOverExpansion, true /* onTop */, false /* animate */); + super.onOverExpansionChanged(overExpansion); + } + + @Override + protected void onTrackingStopped(boolean expand) { + super.onTrackingStopped(expand); + mOverExpansion = 0.0f; + mNotificationStackScroller.setOverScrolledPixels(0.0f, true /* onTop */, + true /* animate */); + } + + + @Override public void onHeightChanged(ExpandableView view) { requestPanelHeightUpdate(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java index ba0b66e..ea5b309 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone; import android.content.Context; import android.util.AttributeSet; +import android.view.MotionEvent; import android.view.View; import android.widget.ScrollView; @@ -28,6 +29,8 @@ public class ObservableScrollView extends ScrollView { private Listener mListener; private int mLastOverscrollAmount; + private boolean mDispatchingTouchEvent; + private boolean mTouchEnabled = true; public ObservableScrollView(Context context, AttributeSet attrs) { super(context, attrs); @@ -37,10 +40,18 @@ public class ObservableScrollView extends ScrollView { mListener = listener; } + public void setTouchEnabled(boolean touchEnabled) { + mTouchEnabled = touchEnabled; + } + public boolean isScrolledToBottom() { return getScrollY() == getMaxScrollY(); } + public boolean isDispatchingTouchEvent() { + return mDispatchingTouchEvent; + } + private int getMaxScrollY() { int scrollRange = 0; if (getChildCount() > 0) { @@ -52,6 +63,17 @@ public class ObservableScrollView extends ScrollView { } @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (!mTouchEnabled) { + return false; + } + mDispatchingTouchEvent = true; + boolean result = super.dispatchTouchEvent(ev); + mDispatchingTouchEvent = false; + return result; + } + + @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (mListener != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index 8800625..1015d5b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -222,7 +222,11 @@ public class PanelBar extends FrameLayout { } } - public void onTrackingStopped(PanelView panel) { + public void onTrackingStopped(PanelView panel, boolean expand) { mTracking = false; } + + public void onExpandingFinished() { + + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 8631e3a..7500c10 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -38,6 +38,7 @@ import java.io.PrintWriter; public class PanelView extends FrameLayout { public static final boolean DEBUG = PanelBar.DEBUG; public static final String TAG = PanelView.class.getSimpleName(); + protected float mOverExpansion; private final void logf(String fmt, Object... args) { Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args)); @@ -66,6 +67,7 @@ public class PanelView extends FrameLayout { private float mInitialTouchX; protected void onExpandingFinished() { + mBar.onExpandingFinished(); } protected void onExpandingStarted() { @@ -183,9 +185,9 @@ public class PanelView extends FrameLayout { case MotionEvent.ACTION_CANCEL: mTracking = false; mTrackingPointer = -1; - onTrackingStopped(); trackMovement(event); - flingWithCurrentVelocity(); + boolean expand = flingWithCurrentVelocity(); + onTrackingStopped(expand); if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; @@ -195,8 +197,8 @@ public class PanelView extends FrameLayout { return true; } - protected void onTrackingStopped() { - mBar.onTrackingStopped(PanelView.this); + protected void onTrackingStopped(boolean expand) { + mBar.onTrackingStopped(PanelView.this, expand); } protected void onTrackingStarted() { @@ -302,7 +304,10 @@ public class PanelView extends FrameLayout { mMaxPanelHeight = -1; } - private void flingWithCurrentVelocity() { + /** + * @return whether the panel will be expanded after the animation + */ + private boolean flingWithCurrentVelocity() { float vel = getCurrentVelocity(); boolean expand; if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) { @@ -311,11 +316,16 @@ public class PanelView extends FrameLayout { expand = vel > 0; } fling(vel, expand); + return expand; } protected void fling(float vel, boolean expand) { cancelPeek(); float target = expand ? getMaxPanelHeight() : 0.0f; + if (target == mExpandedHeight) { + onExpandingFinished(); + return; + } ValueAnimator animator = ValueAnimator.ofFloat(mExpandedHeight, target); if (expand) { mFlingAnimationUtils.apply(animator, mExpandedHeight, target, vel, getHeight()); @@ -403,6 +413,11 @@ public class PanelView extends FrameLayout { public void setExpandedHeightInternal(float h) { float fh = getMaxPanelHeight(); mExpandedHeight = Math.min(fh, h); + float overExpansion = h - fh; + overExpansion = Math.max(0, overExpansion); + if (overExpansion != mOverExpansion) { + onOverExpansionChanged(overExpansion); + } if (DEBUG) { logf("setExpansion: height=%.1f fh=%.1f tracking=%s", h, fh, mTracking ? "T" : "f"); @@ -412,6 +427,10 @@ public class PanelView extends FrameLayout { mExpandedFraction = Math.min(1f, (fh == 0) ? 0 : h / fh); } + protected void onOverExpansionChanged(float overExpansion) { + mOverExpansion = overExpansion; + } + protected void onHeightUpdated(float expandedHeight) { requestLayout(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 152ca3f..15ad709 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -22,6 +22,7 @@ import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN; import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.app.StatusBarManager.windowStateToString; +import static com.android.keyguard.KeyguardHostView.OnDismissAction; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; @@ -85,7 +86,6 @@ import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -120,10 +120,12 @@ import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.LocationControllerImpl; import com.android.systemui.statusbar.policy.NetworkControllerImpl; import com.android.systemui.statusbar.policy.RotationLockControllerImpl; +import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.ZenModeControllerImpl; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener; import com.android.systemui.statusbar.stack.StackScrollState.ViewState; +import com.android.systemui.volume.VolumeComponent; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -195,8 +197,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, NetworkControllerImpl mNetworkController; RotationLockControllerImpl mRotationLockController; UserInfoController mUserInfoController; - ZenModeControllerImpl mZenModeController; + ZenModeController mZenModeController; CastControllerImpl mCastController; + VolumeComponent mVolumeComponent; int mNaturalBarHeight = -1; int mIconSize = -1; @@ -208,6 +211,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, PhoneStatusBarView mStatusBarView; private int mStatusBarWindowState = WINDOW_STATE_SHOWING; private StatusBarWindowManager mStatusBarWindowManager; + private UnlockMethodCache mUnlockMethodCache; int mPixelFormat; Object mQueueLock = new Object(); @@ -371,6 +375,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private ViewMediatorCallback mKeyguardViewMediatorCallback; + private ScrimController mScrimController; private final Runnable mAutohide = new Runnable() { @Override @@ -521,6 +526,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true, mHeadsUpObserver); } + mUnlockMethodCache = UnlockMethodCache.getInstance(mContext); startKeyguard(); } @@ -637,9 +643,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate( R.layout.status_bar_notification_speed_bump, mStackScroller, false); mStackScroller.setSpeedBumpView(speedBump); - mExpandedContents = mStackScroller; + mScrimController = new ScrimController(mStatusBarWindow.findViewById(R.id.scrim_behind), + mStatusBarWindow.findViewById(R.id.scrim_in_front)); + mStatusBarView.setScrimController(mScrimController); + mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header); mHeader.setActivityStarter(this); mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view); @@ -679,7 +688,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mRotationLockController = new RotationLockControllerImpl(mContext); } mUserInfoController = new UserInfoController(mContext); - mZenModeController = new ZenModeControllerImpl(mContext, mHandler); + mVolumeComponent = getComponent(VolumeComponent.class); + mZenModeController = mVolumeComponent.getZenController(); mCastController = new CastControllerImpl(mContext); final SignalClusterView signalCluster = (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster); @@ -742,7 +752,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, final QSTileHost qsh = new QSTileHost(mContext, this, mBluetoothController, mLocationController, mRotationLockController, mNetworkController, mZenModeController, null /*tethering*/, - mCastController); + mCastController, mVolumeComponent); for (QSTile<?> tile : qsh.getTiles()) { mQSPanel.addTile(tile); } @@ -774,7 +784,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void startKeyguard() { KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class); mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this, - mStatusBarWindow, mStatusBarWindowManager); + mStatusBarWindow, mStatusBarWindowManager, mScrimController); mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback(); } @@ -879,7 +889,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } }; - View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() { + View.OnTouchListener mHomeActionListener = new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: @@ -914,8 +924,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener); mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener); - mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener); - mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener); + mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener); updateSearchPanel(); } @@ -965,7 +974,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void addHeadsUpView() { WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar! WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS @@ -1445,6 +1454,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, startActivityDismissingKeyguard(intent, false); } + public ScrimController getScrimController() { + return mScrimController; + } + /** * All changes to the status bar and notifications funnel through here and are batched. */ @@ -2346,6 +2359,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } }; + @Override + protected void startNotificationActivity(OnDismissAction action) { + if (mStatusBarKeyguardViewManager.isShowing()) { + mStatusBarKeyguardViewManager.dismissWithAction(action); + } else { + action.onDismiss(); + } + } + // SystemUIService notifies SystemBars of configuration changes, which then calls down here @Override protected void onConfigurationChanged(Configuration newConfig) { @@ -2760,9 +2782,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) { mKeyguardBottomArea.setVisibility(View.VISIBLE); mHeader.setKeyguardShowing(true); + mNotificationPanel.setKeyguardShowing(true); + mScrimController.setKeyguardShowing(true); } else { mKeyguardBottomArea.setVisibility(View.GONE); mHeader.setKeyguardShowing(false); + mNotificationPanel.setKeyguardShowing(false); + mScrimController.setKeyguardShowing(false); } updateStackScrollerState(); @@ -2860,10 +2886,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } - public void onTrackingStopped() { + public void onTrackingStopped(boolean expand) { if (mState == StatusBarState.KEYGUARD) { mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase); } + if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) { + if (!expand && !mUnlockMethodCache.isMethodInsecure()) { + showBouncer(); + } + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 084bfcf..910d88c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -36,21 +36,16 @@ public class PhoneStatusBarView extends PanelBar { private static final boolean DEBUG_GESTURES = true; PhoneStatusBar mBar; - int mScrimColor; - int mScrimColorKeyguard; - PanelView mFadingPanel = null; PanelView mLastFullyOpenedPanel = null; PanelView mNotificationPanel; - private boolean mShouldFade; private final PhoneStatusBarTransitions mBarTransitions; + private ScrimController mScrimController; public PhoneStatusBarView(Context context, AttributeSet attrs) { super(context, attrs); Resources res = getContext().getResources(); - mScrimColor = res.getColor(R.color.notification_panel_scrim_color); - mScrimColorKeyguard = res.getColor(R.color.notification_panel_scrim_color_keyguard); mBarTransitions = new PhoneStatusBarTransitions(this); } @@ -62,6 +57,10 @@ public class PhoneStatusBarView extends PanelBar { mBar = bar; } + public void setScrimController(ScrimController scrimController) { + mScrimController = scrimController; + } + @Override public void onFinishInflate() { mBarTransitions.init(); @@ -110,27 +109,11 @@ public class PhoneStatusBarView extends PanelBar { } @Override - public void startOpeningPanel(PanelView panel) { - super.startOpeningPanel(panel); - // we only want to start fading if this is the "first" or "last" panel, - // which is kind of tricky to determine - mShouldFade = (mFadingPanel == null || mFadingPanel.isFullyExpanded()); - if (DEBUG) { - Log.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade); - } - mFadingPanel = panel; - } - - @Override public void onAllPanelsCollapsed() { super.onAllPanelsCollapsed(); // give animations time to settle mBar.makeExpandedInvisibleSoon(); - mFadingPanel = null; mLastFullyOpenedPanel = null; - if (mScrimColor != 0 && ActivityManager.isHighEndGfx() && mBar.mStatusBarWindow != null) { - mBar.mStatusBarWindow.setBackgroundColor(0); - } } @Override @@ -139,9 +122,7 @@ public class PhoneStatusBarView extends PanelBar { if (openPanel != mLastFullyOpenedPanel) { openPanel.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } - mFadingPanel = openPanel; mLastFullyOpenedPanel = openPanel; - mShouldFade = true; // now you own the fade, mister } @Override @@ -163,12 +144,19 @@ public class PhoneStatusBarView extends PanelBar { public void onTrackingStarted(PanelView panel) { super.onTrackingStarted(panel); mBar.onTrackingStarted(); + mScrimController.onTrackingStarted(); + } + + @Override + public void onTrackingStopped(PanelView panel, boolean expand) { + super.onTrackingStopped(panel, expand); + mBar.onTrackingStopped(expand); } @Override - public void onTrackingStopped(PanelView panel) { - super.onTrackingStopped(panel); - mBar.onTrackingStopped(); + public void onExpandingFinished() { + super.onExpandingFinished(); + mScrimController.onExpandingFinished(); } @Override @@ -184,27 +172,7 @@ public class PhoneStatusBarView extends PanelBar { Log.v(TAG, "panelExpansionChanged: f=" + frac); } - if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx() - && mBar.mStatusBarWindow != null) { - if (mShouldFade) { - int scrimColor = (mBar.getBarState() == StatusBarState.KEYGUARD - || mBar.getBarState() == StatusBarState.SHADE_LOCKED) - ? mScrimColorKeyguard - : mScrimColor; - frac = mPanelExpandedFractionSum; // don't judge me - // let's start this 20% of the way down the screen - frac = frac * 1.2f - 0.2f; - if (frac <= 0) { - mBar.mStatusBarWindow.setBackgroundColor(0); - } else { - // woo, special effects - final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f)))); - // attenuate background color alpha by k - final int color = (int) ((scrimColor >>> 24) * k) << 24 | (scrimColor & 0xFFFFFF); - mBar.mStatusBarWindow.setBackgroundColor(color); - } - } - } + mScrimController.setPanelExpansion(frac); // fade out the panel as it gets buried into the status bar to avoid overdrawing the // status bar on the last frame of a close animation diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java index 7029898..1344703 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java @@ -21,6 +21,7 @@ import android.content.Intent; import android.os.HandlerThread; import android.os.Looper; +import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.qs.tiles.AirplaneModeTile; import com.android.systemui.qs.tiles.BluetoothTile; @@ -29,11 +30,10 @@ import com.android.systemui.qs.tiles.CastTile; import com.android.systemui.qs.tiles.CellularTile; import com.android.systemui.qs.tiles.ColorInversionTile; import com.android.systemui.qs.tiles.LocationTile; -import com.android.systemui.qs.tiles.RingerModeTile; +import com.android.systemui.qs.tiles.NotificationsTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.qs.tiles.HotspotTile; import com.android.systemui.qs.tiles.WifiTile; -import com.android.systemui.qs.tiles.ZenModeTile; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.CastController; @@ -42,6 +42,7 @@ import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.TetheringController; import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.volume.VolumeComponent; import java.util.ArrayList; import java.util.List; @@ -60,13 +61,15 @@ public class QSTileHost implements QSTile.Host { private final CastController mCast; private final Looper mLooper; private final CurrentUserTracker mUserTracker; + private final VolumeComponent mVolume; private final ArrayList<QSTile<?>> mTiles = new ArrayList<QSTile<?>>(); + private final int mFeedbackStartDelay; public QSTileHost(Context context, PhoneStatusBar statusBar, BluetoothController bluetooth, LocationController location, RotationLockController rotation, NetworkController network, ZenModeController zen, TetheringController tethering, - CastController cast) { + CastController cast, VolumeComponent volume) { mContext = context; mStatusBar = statusBar; mBluetooth = bluetooth; @@ -76,6 +79,7 @@ public class QSTileHost implements QSTile.Host { mZen = zen; mTethering = tethering; mCast = cast; + mVolume = volume; final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName()); ht.start(); @@ -86,8 +90,7 @@ public class QSTileHost implements QSTile.Host { mTiles.add(new ColorInversionTile(this)); mTiles.add(new CellularTile(this)); mTiles.add(new AirplaneModeTile(this)); - mTiles.add(new ZenModeTile(this)); - mTiles.add(new RingerModeTile(this)); + mTiles.add(new NotificationsTile(this)); mTiles.add(new RotationLockTile(this)); mTiles.add(new LocationTile(this)); mTiles.add(new CastTile(this)); @@ -103,6 +106,7 @@ public class QSTileHost implements QSTile.Host { } }; mUserTracker.startTracking(); + mFeedbackStartDelay = mContext.getResources().getInteger(R.integer.feedback_start_delay); } @Override @@ -112,7 +116,7 @@ public class QSTileHost implements QSTile.Host { @Override public void startSettingsActivity(final Intent intent) { - mStatusBar.postStartSettingsActivity(intent, QSTile.FEEDBACK_START_DELAY); + mStatusBar.postStartSettingsActivity(intent, mFeedbackStartDelay); } @Override @@ -169,4 +173,9 @@ public class QSTileHost implements QSTile.Host { public CastController getCastController() { return mCast; } + + @Override + public VolumeComponent getVolumeComponent() { + return mVolume; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java new file mode 100644 index 0000000..6156fc3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -0,0 +1,193 @@ +/* + * 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 + */ + +package com.android.systemui.statusbar.phone; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.content.res.Resources; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.AnimationUtils; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; + +/** + * Controls both the scrim behind the notifications and in front of the notifications (when a + * security method gets shown). + */ +public class ScrimController implements ViewTreeObserver.OnPreDrawListener { + + private static final float SCRIM_BEHIND_ALPHA = 0.62f; + private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.5f; + private static final float SCRIM_IN_FRONT_ALPHA = 0.75f; + private static final long ANIMATION_DURATION = 220; + + private final View mScrimBehind; + private final View mScrimInFront; + private final UnlockMethodCache mUnlockMethodCache; + + private boolean mKeyguardShowing; + private float mFraction; + + private boolean mDarkenWhileDragging; + private boolean mBouncerShowing; + private boolean mAnimateChange; + private boolean mUpdatePending; + private boolean mExpanding; + + private final Interpolator mInterpolator = new DecelerateInterpolator(); + + public ScrimController(View scrimBehind, View scrimInFront) { + mScrimBehind = scrimBehind; + mScrimInFront = scrimInFront; + mUnlockMethodCache = UnlockMethodCache.getInstance(scrimBehind.getContext()); + } + + public void setKeyguardShowing(boolean showing) { + mKeyguardShowing = showing; + scheduleUpdate(); + } + + public void onTrackingStarted() { + mExpanding = true; + mDarkenWhileDragging = !mUnlockMethodCache.isMethodInsecure(); + } + + public void onExpandingFinished() { + mExpanding = false; + } + + public void setPanelExpansion(float fraction) { + mFraction = fraction; + scheduleUpdate(); + } + + public void setBouncerShowing(boolean showing) { + mBouncerShowing = showing; + mAnimateChange = !mExpanding; + scheduleUpdate(); + } + + private void scheduleUpdate() { + if (mUpdatePending) return; + mScrimBehind.getViewTreeObserver().addOnPreDrawListener(this); + mUpdatePending = true; + } + + private void updateScrims() { + if (!mKeyguardShowing) { + updateScrimNormal(); + setScrimInFrontColor(0); + } else { + updateScrimKeyguard(); + } + mAnimateChange = false; + } + + private void updateScrimKeyguard() { + if (mExpanding && mDarkenWhileDragging) { + float behindFraction = Math.max(0, Math.min(mFraction, 1)); + float fraction = 1 - behindFraction; + setScrimInFrontColor(fraction * SCRIM_IN_FRONT_ALPHA); + setScrimBehindColor(behindFraction * SCRIM_BEHIND_ALPHA_KEYGUARD); + } else if (mBouncerShowing) { + setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA); + setScrimBehindColor(0f); + } else { + setScrimInFrontColor(0f); + setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD); + } + } + + private void updateScrimNormal() { + float frac = mFraction; + // let's start this 20% of the way down the screen + frac = frac * 1.2f - 0.2f; + if (frac <= 0) { + setScrimBehindColor(0); + } else { + // woo, special effects + final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f)))); + setScrimBehindColor(k * SCRIM_BEHIND_ALPHA); + } + } + + private void setScrimBehindColor(float alpha) { + setScrimColor(mScrimBehind, alpha); + } + + private void setScrimInFrontColor(float alpha) { + setScrimColor(mScrimInFront, alpha); + if (alpha == 0f) { + mScrimInFront.setClickable(false); + } else { + + // Eat touch events. + mScrimInFront.setClickable(true); + } + } + + private void setScrimColor(View scrim, float alpha) { + int color = Color.argb((int) (alpha * 255), 0, 0, 0); + if (mAnimateChange) { + startScrimAnimation(scrim, color); + } else { + scrim.setBackgroundColor(color); + } + } + + private void startScrimAnimation(final View scrim, int targetColor) { + int current = getBackgroundAlpha(scrim); + int target = Color.alpha(targetColor); + if (current == targetColor) { + return; + } + ValueAnimator anim = ValueAnimator.ofInt(current, target); + anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + int value = (int) animation.getAnimatedValue(); + scrim.setBackgroundColor(Color.argb(value, 0, 0, 0)); + } + }); + anim.setInterpolator(mInterpolator); + anim.setDuration(ANIMATION_DURATION); + anim.start(); + } + + private int getBackgroundAlpha(View scrim) { + if (scrim.getBackground() instanceof ColorDrawable) { + ColorDrawable drawable = (ColorDrawable) scrim.getBackground(); + return Color.alpha(drawable.getColor()); + } else { + return 0; + } + } + + @Override + public boolean onPreDraw() { + mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this); + mUpdatePending = false; + updateScrims(); + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index 389e725..3245f1a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -38,6 +38,11 @@ import com.android.systemui.statusbar.policy.UserInfoController; */ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener { + /** + * How much the header expansion gets rubberbanded while expanding the panel. + */ + private static final float EXPANSION_RUBBERBAND_FACTOR = 0.35f; + private boolean mExpanded; private boolean mKeyguardShowing; @@ -128,6 +133,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL updateVisibilities(); updateSystemIconsLayoutParams(); updateBrightnessControllerState(); + updateZTranslation(); + updateClickTargets(); if (mQSPanel != null) { mQSPanel.setExpanded(expanded); } @@ -202,18 +209,30 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } } + private void updateClickTargets() { + mDateTime.setClickable(mExpanded); + mMultiUserSwitch.setClickable(mExpanded); + } + + private void updateZTranslation() { + + // If we are on the Keyguard, we need to set our z position to zero, so we don't get + // shadows. + if (mKeyguardShowing && !mExpanded) { + setZ(0); + } else { + setTranslationZ(0); + } + } + public void setExpansion(float height) { + height = (height - mCollapsedHeight) * EXPANSION_RUBBERBAND_FACTOR + mCollapsedHeight; if (height < mCollapsedHeight) { height = mCollapsedHeight; } if (height > mExpandedHeight) { height = mExpandedHeight; } - if (mExpanded) { - mBackground.setTranslationY(-(mExpandedHeight - height)); - } else { - mBackground.setTranslationY(0); - } setClipping(height); } @@ -247,14 +266,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL public void setKeyguardShowing(boolean keyguardShowing) { mKeyguardShowing = keyguardShowing; - if (keyguardShowing) { - setZ(0); - } else { - setTranslationZ(0); - } updateHeights(); updateWidth(); updateVisibilities(); + updateZTranslation(); } public void setUserInfoController(UserInfoController userInfoController) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 1040c15..d5551b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -29,6 +29,8 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.ViewMediatorCallback; +import static com.android.keyguard.KeyguardHostView.OnDismissAction; + /** * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done, @@ -43,6 +45,7 @@ public class StatusBarKeyguardViewManager { private LockPatternUtils mLockPatternUtils; private ViewMediatorCallback mViewMediatorCallback; private PhoneStatusBar mPhoneStatusBar; + private ScrimController mScrimController; private ViewGroup mContainer; private StatusBarWindowManager mStatusBarWindowManager; @@ -66,10 +69,12 @@ public class StatusBarKeyguardViewManager { } public void registerStatusBar(PhoneStatusBar phoneStatusBar, - ViewGroup container, StatusBarWindowManager statusBarWindowManager) { + ViewGroup container, StatusBarWindowManager statusBarWindowManager, + ScrimController scrimController) { mPhoneStatusBar = phoneStatusBar; mContainer = container; mStatusBarWindowManager = statusBarWindowManager; + mScrimController = scrimController; mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils, mStatusBarWindowManager, container); } @@ -96,7 +101,7 @@ public class StatusBarKeyguardViewManager { mBouncer.show(); } else { mPhoneStatusBar.showKeyguard(); - mBouncer.hide(); + mBouncer.hide(false /* destroyView */); mBouncer.prepare(); } } @@ -108,6 +113,13 @@ public class StatusBarKeyguardViewManager { updateStates(); } + public void dismissWithAction(OnDismissAction r) { + if (!mOccluded) { + mBouncer.showWithDismissAction(r); + } + updateStates(); + } + /** * Reset the state of the view. */ @@ -115,7 +127,7 @@ public class StatusBarKeyguardViewManager { if (mShowing) { if (mOccluded) { mPhoneStatusBar.hideKeyguard(); - mBouncer.hide(); + mBouncer.hide(false /* destroyView */); } else { showBouncerOrKeyguard(); } @@ -175,7 +187,7 @@ public class StatusBarKeyguardViewManager { mShowing = false; mPhoneStatusBar.hideKeyguard(); mStatusBarWindowManager.setKeyguardShowing(false); - mBouncer.hide(); + mBouncer.hide(true /* destroyView */); mViewMediatorCallback.keyguardGone(); updateStates(); } @@ -207,7 +219,7 @@ public class StatusBarKeyguardViewManager { */ public boolean onBackPressed() { if (mBouncer.isShowing()) { - mBouncer.hide(); + mBouncer.hide(false /* destroyView */); mPhoneStatusBar.showKeyguard(); updateStates(); return true; @@ -244,6 +256,7 @@ public class StatusBarKeyguardViewManager { if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) { mStatusBarWindowManager.setBouncerShowing(bouncerShowing); mPhoneStatusBar.setBouncerShowing(bouncerShowing); + mScrimController.setBouncerShowing(bouncerShowing); } KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java new file mode 100644 index 0000000..bfd657b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java @@ -0,0 +1,107 @@ +/* + * 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 + */ + +package com.android.systemui.statusbar.phone; + +import android.content.Context; + +import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; + +import java.util.ArrayList; + +/** + * Caches whether the current unlock method is insecure, taking trust into account. This information + * might be a little bit out of date and should not be used for actual security decisions; it should + * be only used for visual indications. + */ +public class UnlockMethodCache { + + private static UnlockMethodCache sInstance; + + private final LockPatternUtils mLockPatternUtils; + private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>(); + private boolean mMethodInsecure; + + private UnlockMethodCache(Context ctx) { + mLockPatternUtils = new LockPatternUtils(ctx); + mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx); + KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback); + updateMethodSecure(true /* updateAlways */); + } + + public static UnlockMethodCache getInstance(Context context) { + if (sInstance == null) { + sInstance = new UnlockMethodCache(context); + } + return sInstance; + } + + /** + * @return whether the current security method is secure, i. e. the bouncer will be shown + */ + public boolean isMethodInsecure() { + return mMethodInsecure; + } + + public void addListener(OnUnlockMethodChangedListener listener) { + mListeners.add(listener); + } + + public void removeListener(OnUnlockMethodChangedListener listener) { + mListeners.remove(listener); + } + + private void updateMethodSecure(boolean updateAlways) { + int user = mLockPatternUtils.getCurrentUser(); + boolean methodInsecure = !mLockPatternUtils.isSecure() || + mKeyguardUpdateMonitor.getUserHasTrust(user); + boolean changed = methodInsecure != mMethodInsecure; + if (changed || updateAlways) { + mMethodInsecure = methodInsecure; + notifyListeners(mMethodInsecure); + } + } + + private void notifyListeners(boolean secure) { + for (OnUnlockMethodChangedListener listener : mListeners) { + listener.onMethodSecureChanged(secure); + } + } + + private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { + @Override + public void onUserSwitchComplete(int userId) { + updateMethodSecure(false /* updateAlways */); + } + + @Override + public void onTrustChanged(int userId) { + updateMethodSecure(false /* updateAlways */); + } + + @Override + public void onScreenTurnedOn() { + updateMethodSecure(false /* updateAlways */); + } + }; + + public static interface OnUnlockMethodChangedListener { + void onMethodSecureChanged(boolean methodSecure); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java index 81e2cb3..9271e71 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy; import android.content.Context; import android.content.res.Configuration; +import android.graphics.Outline; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; @@ -25,6 +26,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.widget.FrameLayout; import com.android.systemui.ExpandHelper; @@ -35,14 +37,17 @@ import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.NotificationData; -public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback { +public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback, + ViewTreeObserver.OnComputeInternalInsetsListener { private static final String TAG = "HeadsUpNotificationView"; private static final boolean DEBUG = false; private static final boolean SPEW = DEBUG; Rect mTmpRect = new Rect(); + int[] mTmpTwoArray = new int[2]; private final int mTouchSensitivityDelay; + private final float mMaxAlpha = 0.95f; private SwipeHelper mSwipeHelper; private EdgeSwipeHelper mEdgeSwipeHelper; @@ -87,8 +92,9 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. } mContentHolder.setX(0); mContentHolder.setVisibility(View.VISIBLE); - mContentHolder.setAlpha(1f); + mContentHolder.setAlpha(mMaxAlpha); mContentHolder.addView(mHeadsUp.row); + mSwipeHelper.snapChild(mContentHolder, 1f); mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay; } @@ -99,32 +105,6 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. return mHeadsUp == null || mHeadsUp.notification.isClearable(); } - public void setMargin(int notificationPanelMarginPx) { - if (SPEW) Log.v(TAG, "setMargin() " + notificationPanelMarginPx); - if (mContentHolder != null && - mContentHolder.getLayoutParams() instanceof FrameLayout.LayoutParams) { - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentHolder.getLayoutParams(); - lp.setMarginStart(notificationPanelMarginPx); - mContentHolder.setLayoutParams(lp); - } - } - - // LinearLayout methods - - @Override - public void onDraw(android.graphics.Canvas c) { - super.onDraw(c); - if (DEBUG) { - //Log.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: " - // + getMeasuredHeight() + "px"); - c.save(); - c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6, - android.graphics.Region.Op.DIFFERENCE); - c.drawColor(0xFFcc00cc); - c.restore(); - } - } - // ViewGroup methods @Override @@ -134,6 +114,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. float pagingTouchSlop = viewConfiguration.getScaledPagingTouchSlop(); float touchSlop = viewConfiguration.getScaledTouchSlop(); mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop); + mSwipeHelper.setMaxAlpha(mMaxAlpha); mEdgeSwipeHelper = new EdgeSwipeHelper(touchSlop); int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height); @@ -146,6 +127,8 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. // whoops, we're on already! setNotification(mHeadsUp); } + + getViewTreeObserver().addOnComputeInternalInsetsListener(this); } @Override @@ -163,6 +146,20 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. // View methods @Override + public void onDraw(android.graphics.Canvas c) { + super.onDraw(c); + if (DEBUG) { + //Log.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: " + // + getMeasuredHeight() + "px"); + c.save(); + c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6, + android.graphics.Region.Op.DIFFERENCE); + c.drawColor(0xFFcc00cc); + c.restore(); + } + } + + @Override public boolean onTouchEvent(MotionEvent ev) { if (System.currentTimeMillis() < mStartTouchTime) { return false; @@ -183,6 +180,14 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. mSwipeHelper.setPagingTouchSlop(pagingTouchSlop); } + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + Outline o = new Outline(); + o.setRect(0, 0, mContentHolder.getWidth(), mContentHolder.getHeight()); + mContentHolder.setOutline(o); + } + // ExpandHelper.Callback methods @Override @@ -233,7 +238,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. @Override public void onDragCancelled(View v) { - mContentHolder.setAlpha(1f); // sometimes this isn't quite reset + mContentHolder.setAlpha(mMaxAlpha); // sometimes this isn't quite reset } @Override @@ -250,6 +255,16 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. return mContentHolder; } + @Override + public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) { + mContentHolder.getLocationOnScreen(mTmpTwoArray); + + info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); + info.touchableRegion.set(mTmpTwoArray[0], mTmpTwoArray[1], + mTmpTwoArray[0] + mContentHolder.getWidth(), + mTmpTwoArray[1] + mContentHolder.getHeight()); + } + private class EdgeSwipeHelper implements Gefingerpoken { private static final boolean DEBUG_EDGE_SWIPE = false; private final float mTouchSlop; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index 718acc3..330b599 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -17,12 +17,9 @@ package com.android.systemui.statusbar.policy; import android.animation.Animator; -import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.hardware.input.InputManager; import android.os.SystemClock; @@ -34,9 +31,7 @@ import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SoundEffectConstants; -import android.view.View; import android.view.ViewConfiguration; -import android.view.ViewDebug; import android.view.accessibility.AccessibilityEvent; import android.widget.ImageView; @@ -46,25 +41,18 @@ public class KeyButtonView extends ImageView { private static final String TAG = "StatusBar.KeyButtonView"; private static final boolean DEBUG = false; - final float GLOW_MAX_SCALE_FACTOR = 1.8f; public static final float DEFAULT_QUIESCENT_ALPHA = 0.70f; - long mDownTime; - int mCode; - int mTouchSlop; - Drawable mGlowBG; - int mGlowWidth, mGlowHeight; - float mGlowAlpha = 0f, mGlowScale = 1f; - @ViewDebug.ExportedProperty(category = "drawing") - float mDrawingAlpha = 1f; - @ViewDebug.ExportedProperty(category = "drawing") - float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA; - boolean mSupportsLongpress = true; - RectF mRect = new RectF(); - AnimatorSet mPressedAnim; - Animator mAnimateToQuiescent = new ObjectAnimator(); + private long mDownTime; + private int mCode; + private int mTouchSlop; + private float mDrawingAlpha = 1f; + private float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA; + private boolean mSupportsLongpress = true; + private Animator mAnimateToQuiescent = new ObjectAnimator(); + private Drawable mBackground; - Runnable mCheckLongPress = new Runnable() { + private final Runnable mCheckLongPress = new Runnable() { public void run() { if (isPressed()) { // Log.d("KeyButtonView", "longpressed: " + this); @@ -93,47 +81,27 @@ public class KeyButtonView extends ImageView { mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true); - mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground); - setDrawingAlpha(mQuiescentAlpha); - if (mGlowBG != null) { - mGlowWidth = mGlowBG.getIntrinsicWidth(); - mGlowHeight = mGlowBG.getIntrinsicHeight(); + Drawable d = getBackground(); + if (d != null) { + mBackground = d.mutate(); + setBackground(mBackground); } + setDrawingAlpha(mQuiescentAlpha); + a.recycle(); setClickable(true); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } - @Override - protected void onDraw(Canvas canvas) { - if (mGlowBG != null) { - canvas.save(); - final int w = getWidth(); - final int h = getHeight(); - final float aspect = (float)mGlowWidth / mGlowHeight; - final int drawW = (int)(h*aspect); - final int drawH = h; - final int margin = (drawW-w)/2; - canvas.scale(mGlowScale, mGlowScale, w*0.5f, h*0.5f); - mGlowBG.setBounds(-margin, 0, drawW-margin, drawH); - mGlowBG.setAlpha((int)(mDrawingAlpha * mGlowAlpha * 255)); - mGlowBG.draw(canvas); - canvas.restore(); - mRect.right = w; - mRect.bottom = h; - } - super.onDraw(canvas); - } - public void setQuiescentAlpha(float alpha, boolean animate) { mAnimateToQuiescent.cancel(); alpha = Math.min(Math.max(alpha, 0), 1); if (alpha == mQuiescentAlpha && alpha == mDrawingAlpha) return; mQuiescentAlpha = alpha; if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha); - if (mGlowBG != null && animate) { + if (mBackground != null && animate) { mAnimateToQuiescent = animateToQuiescent(); mAnimateToQuiescent.start(); } else { @@ -154,87 +122,35 @@ public class KeyButtonView extends ImageView { } public void setDrawingAlpha(float x) { - // Calling setAlpha(int), which is an ImageView-specific - // method that's different from setAlpha(float). This sets - // the alpha on this ImageView's drawable directly - setAlpha((int) (x * 255)); - mDrawingAlpha = x; - } - - public float getGlowAlpha() { - if (mGlowBG == null) return 0; - return mGlowAlpha; - } - - public void setGlowAlpha(float x) { - if (mGlowBG == null) return; - mGlowAlpha = x; - invalidate(); - } - - public float getGlowScale() { - if (mGlowBG == null) return 0; - return mGlowScale; - } - - public void setGlowScale(float x) { - if (mGlowBG == null) return; - mGlowScale = x; - final float w = getWidth(); - final float h = getHeight(); - if (GLOW_MAX_SCALE_FACTOR <= 1.0f) { - // this only works if we know the glow will never leave our bounds - invalidate(); - } else { - final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f; - final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f; - com.android.systemui.SwipeHelper.invalidateGlobalRegion( - this, - new RectF(getLeft() - rx, - getTop() - ry, - getRight() + rx, - getBottom() + ry)); - - // also invalidate our immediate parent to help avoid situations where nearby glows - // interfere - ((View)getParent()).invalidate(); + setImageAlpha((int) (x * 255)); + if (mBackground != null) { + mBackground.setAlpha((int)(x * 255)); } + mDrawingAlpha = x; } public void setPressed(boolean pressed) { - if (mGlowBG != null) { + if (mBackground != null) { if (pressed != isPressed()) { - if (mPressedAnim != null && mPressedAnim.isRunning()) { - mPressedAnim.cancel(); - } - final AnimatorSet as = mPressedAnim = new AnimatorSet(); if (pressed) { - if (mGlowScale < GLOW_MAX_SCALE_FACTOR) - mGlowScale = GLOW_MAX_SCALE_FACTOR; - if (mGlowAlpha < mQuiescentAlpha) - mGlowAlpha = mQuiescentAlpha; setDrawingAlpha(1f); - as.playTogether( - ObjectAnimator.ofFloat(this, "glowAlpha", 1f), - ObjectAnimator.ofFloat(this, "glowScale", GLOW_MAX_SCALE_FACTOR) - ); - as.setDuration(50); } else { mAnimateToQuiescent.cancel(); mAnimateToQuiescent = animateToQuiescent(); - as.playTogether( - ObjectAnimator.ofFloat(this, "glowAlpha", 0f), - ObjectAnimator.ofFloat(this, "glowScale", 1f), - mAnimateToQuiescent - ); - as.setDuration(500); + mAnimateToQuiescent.setDuration(500); + mAnimateToQuiescent.start(); } - as.start(); } } super.setPressed(pressed); } + private void setHotspot(float x, float y) { + if (mBackground != null) { + mBackground.setHotspot(x, y); + } + } + public boolean onTouchEvent(MotionEvent ev) { final int action = ev.getAction(); int x, y; @@ -254,6 +170,7 @@ public class KeyButtonView extends ImageView { removeCallbacks(mCheckLongPress); postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); } + setHotspot(ev.getX(), ev.getY()); break; case MotionEvent.ACTION_MOVE: x = (int)ev.getX(); @@ -262,6 +179,7 @@ public class KeyButtonView extends ImageView { && x < getWidth() + mTouchSlop && y >= -mTouchSlop && y < getHeight() + mTouchSlop); + setHotspot(ev.getX(), ev.getY()); break; case MotionEvent.ACTION_CANCEL: setPressed(false); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 966c0b0..56402a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -339,7 +339,7 @@ public class NetworkControllerImpl extends BroadcastReceiver boolean wifiOut = wifiEnabled && mWifiSsid != null && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT || mWifiActivity == WifiManager.DATA_ACTIVITY_OUT); - cb.onWifiSignalChanged(wifiEnabled, mQSWifiIconId, wifiIn, wifiOut, + cb.onWifiSignalChanged(mWifiEnabled, mQSWifiIconId, wifiIn, wifiOut, mContentDescriptionWifi, wifiDesc); boolean mobileIn = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java index 173af40..3ce6905 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java @@ -166,7 +166,7 @@ public final class UserInfoController { if (rawAvatar != null) { avatar = new BitmapDrawable(mContext.getResources(), circularClip(rawAvatar)); } else { - avatar = mContext.getResources().getDrawable(R.drawable.ic_qs_default_user); + avatar = mContext.getResources().getDrawable(R.drawable.ic_account_circle); mUseDefaultAvatar = true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java index ae2acab..44e10be 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java @@ -37,12 +37,15 @@ public class StackScrollState { private static final String CHILD_NOT_FOUND_TAG = "StackScrollStateNoSuchChild"; private final ViewGroup mHostView; + private final int mRoundedRectCornerRadius; private Map<ExpandableView, ViewState> mStateMap; private final Rect mClipRect = new Rect(); public StackScrollState(ViewGroup hostView) { mHostView = hostView; mStateMap = new HashMap<ExpandableView, ViewState>(); + mRoundedRectCornerRadius = mHostView.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.notification_quantum_rounded_rect_radius); } public ViewGroup getHostView() { @@ -155,11 +158,15 @@ public class StackScrollState { // apply clipping and shadow float newNotificationEnd = newYTranslation + newHeight; + // In the unlocked shade we have to clip a little bit higher because of the rounded + // corners of the notifications. + float clippingCorrection = state.dimmed ? 0 : mRoundedRectCornerRadius; + // When the previous notification is swiped, we don't clip the content to the // bottom of it. float clipHeight = previousNotificationIsSwiped ? newHeight - : newNotificationEnd - (previousNotificationEnd); + : newNotificationEnd - (previousNotificationEnd - clippingCorrection); updateChildClippingAndBackground(child, newHeight, clipHeight, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java index 045a99d..f019e6c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -315,14 +315,13 @@ public class StackStateAnimator { child.getAlpha(), newEndValue); animator.setInterpolator(mFastOutSlowInInterpolator); // Handle layer type - final int currentLayerType = child.getLayerType(); child.setLayerType(View.LAYER_TYPE_HARDWARE, null); animator.addListener(new AnimatorListenerAdapter() { public boolean mWasCancelled; @Override public void onAnimationEnd(Animator animation) { - child.setLayerType(currentLayerType, null); + child.setLayerType(View.LAYER_TYPE_NONE, null); if (newEndValue == 0 && !mWasCancelled) { child.setVisibility(View.INVISIBLE); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java new file mode 100644 index 0000000..5ee8925 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +package com.android.systemui.volume; + +import com.android.systemui.statusbar.policy.ZenModeController; + +public interface VolumeComponent { + ZenModeController getZenController(); + void setVolumePanel(VolumePanel panel); +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java index 8657e07..06f4c2e 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java @@ -16,14 +16,12 @@ package com.android.systemui.volume; -import com.android.internal.R; - import android.app.AlertDialog; import android.app.Dialog; -import android.content.DialogInterface.OnDismissListener; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; @@ -42,6 +40,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewStub; import android.view.Window; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; @@ -49,6 +48,9 @@ import android.widget.ImageView; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; +import com.android.internal.R; +import com.android.systemui.statusbar.policy.ZenModeController; + import java.util.HashMap; /** @@ -57,7 +59,6 @@ import java.util.HashMap; * @hide */ public class VolumePanel extends Handler { - private static final String TAG = VolumePanel.class.getSimpleName(); private static boolean LOGD = false; private static final int PLAY_SOUND_DELAY = AudioService.PLAY_SOUND_DELAY; @@ -88,33 +89,48 @@ public class VolumePanel extends Handler { private static final int MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN = 9; private static final int MSG_SLIDER_VISIBILITY_CHANGED = 10; private static final int MSG_DISPLAY_SAFE_VOLUME_WARNING = 11; + private static final int MSG_LAYOUT_DIRECTION = 12; + private static final int MSG_ZEN_MODE_CHANGED = 13; // Pseudo stream type for master volume private static final int STREAM_MASTER = -100; // Pseudo stream type for remote volume is defined in AudioService.STREAM_REMOTE_MUSIC + private final String mTag; protected final Context mContext; private final AudioManager mAudioManager; + private final ZenModeController mZenController; private boolean mRingIsSilent; - private boolean mShowCombinedVolumes; private boolean mVoiceCapable; + private boolean mZenModeCapable; // True if we want to play tones on the system stream when the master stream is specified. private final boolean mPlayMasterStreamTones; - /** Dialog containing all the sliders */ - private final Dialog mDialog; - /** Dialog's content view */ + + /** Volume panel content view */ private final View mView; + /** Dialog hosting the panel, if not embedded */ + private final Dialog mDialog; + /** Parent view hosting the panel, if embedded */ + private final ViewGroup mParent; /** The visible portion of the volume overlay */ private final ViewGroup mPanel; - /** Contains the sliders and their touchable icons */ - private final ViewGroup mSliderGroup; - /** The button that expands the dialog to show all sliders */ - private final View mMoreButton; - /** Dummy divider icon that needs to vanish with the more button */ - private final View mDivider; + /** Contains the slider and its touchable icons */ + private final ViewGroup mSliderPanel; + /** The button that expands the dialog to show the zen panel */ + private final ImageView mExpandButton; + /** Dummy divider icon that needs to vanish with the expand button */ + private final View mExpandDivider; + /** The zen mode configuration panel view stub */ + private final ViewStub mZenPanelStub; + /** The zen mode configuration panel view, once inflated */ + private ZenModePanel mZenPanel; + /** Dummy divider icon that needs to vanish with the zen panel */ + private final View mZenPanelDivider; + + private ZenModePanel.Callback mZenPanelCallback; /** Currently active stream that shows up at the top of the list of sliders */ private int mActiveStreamType = -1; @@ -129,8 +145,8 @@ public class VolumePanel extends Handler { false), RingerStream(AudioManager.STREAM_RING, R.string.volume_icon_description_ringer, - R.drawable.ic_audio_ring_notif, - R.drawable.ic_audio_ring_notif_mute, + com.android.systemui.R.drawable.ic_ringer_audible, + com.android.systemui.R.drawable.ic_ringer_silent, false), VoiceStream(AudioManager.STREAM_VOICE_CALL, R.string.volume_icon_description_incall, @@ -149,8 +165,8 @@ public class VolumePanel extends Handler { true), NotificationStream(AudioManager.STREAM_NOTIFICATION, R.string.volume_icon_description_notification, - R.drawable.ic_audio_notification, - R.drawable.ic_audio_notification_mute, + com.android.systemui.R.drawable.ic_ringer_audible, + com.android.systemui.R.drawable.ic_ringer_silent, true), // for now, use media resources for master volume MasterStream(STREAM_MASTER, @@ -245,8 +261,11 @@ public class VolumePanel extends Handler { } - public VolumePanel(Context context) { + public VolumePanel(Context context, ViewGroup parent, ZenModeController zenController) { + mTag = String.format("VolumePanel%s.%08x", parent == null ? "Dialog" : "", hashCode()); mContext = context; + mParent = parent; + mZenController = zenController; mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); // For now, only show master volume if master volume is supported @@ -258,74 +277,81 @@ public class VolumePanel extends Handler { streamRes.show = (streamRes.streamType == STREAM_MASTER); } } - - mDialog = new Dialog(context) { - @Override - public boolean onTouchEvent(MotionEvent event) { - if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE && - sConfirmSafeVolumeDialog == null) { - forceTimeout(); - return true; + if (LOGD) Log.d(mTag, String.format("new VolumePanel hasParent=%s", parent != null)); + final int layoutId = com.android.systemui.R.layout.volume_panel; + if (parent == null) { + // dialog mode + mDialog = new Dialog(context) { + @Override + public boolean onTouchEvent(MotionEvent event) { + if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE && + sConfirmSafeVolumeDialog == null) { + forceTimeout(); + return true; + } + return false; } - return false; - } - }; - - // Change some window properties - final Window window = mDialog.getWindow(); - final LayoutParams lp = window.getAttributes(); - lp.token = null; - // Offset from the top - lp.y = res.getDimensionPixelOffset(R.dimen.volume_panel_top); - lp.type = LayoutParams.TYPE_VOLUME_OVERLAY; - lp.windowAnimations = R.style.Animation_VolumePanel; - window.setAttributes(lp); - window.setGravity(Gravity.TOP); - window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); - window.requestFeature(Window.FEATURE_NO_TITLE); - window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE - | LayoutParams.FLAG_NOT_TOUCH_MODAL - | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH); - - mDialog.setCanceledOnTouchOutside(true); - mDialog.setContentView(R.layout.volume_adjust); - mDialog.setOnDismissListener(new OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - mActiveStreamType = -1; - mAudioManager.forceVolumeControlStream(mActiveStreamType); - } - }); + }; + + // Change some window properties + final Window window = mDialog.getWindow(); + final LayoutParams lp = window.getAttributes(); + lp.token = null; + // Offset from the top + lp.y = res.getDimensionPixelOffset(com.android.systemui.R.dimen.volume_panel_top); + lp.width = res.getDimensionPixelSize(com.android.systemui.R.dimen.volume_panel_width); + lp.type = LayoutParams.TYPE_VOLUME_OVERLAY; + lp.windowAnimations = R.style.Animation_VolumePanel; + window.setBackgroundDrawableResource(com.android.systemui.R.drawable.qs_panel_background); + window.setAttributes(lp); + window.setGravity(Gravity.TOP); + window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); + window.requestFeature(Window.FEATURE_NO_TITLE); + window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE + | LayoutParams.FLAG_NOT_TOUCH_MODAL + | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH); + mDialog.setCanceledOnTouchOutside(true); + mDialog.setContentView(layoutId); + mDialog.setOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + mActiveStreamType = -1; + mAudioManager.forceVolumeControlStream(mActiveStreamType); + } + }); - mDialog.create(); + mDialog.create(); - mView = window.findViewById(R.id.content); - mView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - resetTimeout(); - return false; - } - }); + mView = window.findViewById(R.id.content); + mView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + resetTimeout(); + return false; + } + }); - mPanel = (ViewGroup) mView.findViewById(R.id.visible_panel); - mSliderGroup = (ViewGroup) mView.findViewById(R.id.slider_group); - mMoreButton = mView.findViewById(R.id.expand_button); - mDivider = mView.findViewById(R.id.expand_button_divider); + } else { + // embedded mode + mDialog = null; + mView = LayoutInflater.from(mContext).inflate(layoutId, parent, true); + } + mPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.visible_panel); + mSliderPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.slider_panel); + mExpandButton = (ImageView) mView.findViewById(com.android.systemui.R.id.expand_button); + mExpandDivider = mView.findViewById(com.android.systemui.R.id.expand_button_divider); + mZenPanelStub = (ViewStub)mView.findViewById(com.android.systemui.R.id.zen_panel_stub); + mZenPanelDivider = mView.findViewById(com.android.systemui.R.id.zen_panel_divider); mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()]; mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable); - // If we don't want to show multiple volumes, hide the settings button - // and divider. - mShowCombinedVolumes = !mVoiceCapable && !useMasterVolume; - if (!mShowCombinedVolumes) { - mMoreButton.setVisibility(View.GONE); - mDivider.setVisibility(View.GONE); - } else { - mMoreButton.setOnClickListener(mClickListener); - } + mZenModeCapable = !useMasterVolume && mZenController != null; + mZenPanelDivider.setVisibility(View.GONE); + mExpandButton.setOnClickListener(mClickListener); + updateZenMode(mZenController == null ? false : mZenController.isZen()); + mZenController.addCallback(mZenCallback); final boolean masterVolumeOnly = res.getBoolean(R.bool.config_useMasterVolume); final boolean masterVolumeKeySounds = res.getBoolean(R.bool.config_useVolumeKeySounds); @@ -334,7 +360,7 @@ public class VolumePanel extends Handler { listenToRingerMode(); } - public void setLayoutDirection(int layoutDirection) { + private void setLayoutDirection(int layoutDirection) { mPanel.setLayoutDirection(layoutDirection); updateStates(); } @@ -406,21 +432,19 @@ public class VolumePanel extends Handler { StreamResources streamRes = STREAMS[i]; final int streamType = streamRes.streamType; - if (mVoiceCapable && streamRes == StreamResources.NotificationStream) { - streamRes = StreamResources.RingerStream; - } final StreamControl sc = new StreamControl(); sc.streamType = streamType; - sc.group = (ViewGroup) inflater.inflate(R.layout.volume_adjust_item, null); + sc.group = (ViewGroup) inflater.inflate( + com.android.systemui.R.layout.volume_panel_item, null); sc.group.setTag(sc); - sc.icon = (ImageView) sc.group.findViewById(R.id.stream_icon); + sc.icon = (ImageView) sc.group.findViewById(com.android.systemui.R.id.stream_icon); sc.icon.setTag(sc); sc.icon.setContentDescription(res.getString(streamRes.descRes)); sc.iconRes = streamRes.iconRes; sc.iconMuteRes = streamRes.iconMuteRes; sc.icon.setImageResource(sc.iconRes); - sc.seekbarView = (SeekBar) sc.group.findViewById(R.id.seekbar); + sc.seekbarView = (SeekBar) sc.group.findViewById(com.android.systemui.R.id.seekbar); final int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO || streamType == AudioSystem.STREAM_VOICE_CALL) ? 1 : 0; sc.seekbarView.setMax(getStreamMaxVolume(streamType) + plusOne); @@ -431,34 +455,18 @@ public class VolumePanel extends Handler { } private void reorderSliders(int activeStreamType) { - mSliderGroup.removeAllViews(); + mSliderPanel.removeAllViews(); final StreamControl active = mStreamControls.get(activeStreamType); if (active == null) { Log.e("VolumePanel", "Missing stream type! - " + activeStreamType); mActiveStreamType = -1; } else { - mSliderGroup.addView(active.group); + mSliderPanel.addView(active.group); mActiveStreamType = activeStreamType; active.group.setVisibility(View.VISIBLE); updateSlider(active); - } - - addOtherVolumes(); - } - - private void addOtherVolumes() { - if (!mShowCombinedVolumes) return; - - for (int i = 0; i < STREAMS.length; i++) { - // Skip the phone specific ones and the active one - final int streamType = STREAMS[i].streamType; - if (!STREAMS[i].show || streamType == mActiveStreamType) { - continue; - } - StreamControl sc = mStreamControls.get(streamType); - mSliderGroup.addView(sc.group); - updateSlider(sc); + updateZenMode(mZenController == null ? false : mZenController.isZen()); } } @@ -472,7 +480,7 @@ public class VolumePanel extends Handler { if (((sc.streamType == AudioManager.STREAM_RING) || (sc.streamType == AudioManager.STREAM_NOTIFICATION)) && mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) { - sc.icon.setImageResource(R.drawable.ic_audio_ring_notif_vibrate); + sc.icon.setImageResource(com.android.systemui.R.drawable.ic_ringer_vibrate); } if (sc.streamType == AudioService.STREAM_REMOTE_MUSIC) { // never disable touch interactions for remote playback, the muting is not tied to @@ -486,32 +494,70 @@ public class VolumePanel extends Handler { } } + public void setZenModePanelCallback(ZenModePanel.Callback callback) { + mZenPanelCallback = callback; + } + private void expand() { - final int count = mSliderGroup.getChildCount(); - for (int i = 0; i < count; i++) { - mSliderGroup.getChildAt(i).setVisibility(View.VISIBLE); + if (LOGD) Log.d(mTag, "expand mZenPanel=" + mZenPanel); + if (mZenPanel == null) { + mZenPanel = (ZenModePanel) mZenPanelStub.inflate(); + mZenPanel.init(mZenController); + mZenPanel.setCallback(new ZenModePanel.Callback() { + @Override + public void onMoreSettings() { + if (mZenPanelCallback != null) { + mZenPanelCallback.onMoreSettings(); + } + } + + @Override + public void onInteraction() { + if (mZenPanelCallback != null) { + mZenPanelCallback.onInteraction(); + } + } + }); } - mMoreButton.setVisibility(View.INVISIBLE); - mDivider.setVisibility(View.INVISIBLE); + mZenPanel.setVisibility(View.VISIBLE); + mZenPanelDivider.setVisibility(View.VISIBLE); } private void collapse() { - mMoreButton.setVisibility(View.VISIBLE); - mDivider.setVisibility(View.VISIBLE); - final int count = mSliderGroup.getChildCount(); - for (int i = 1; i < count; i++) { - mSliderGroup.getChildAt(i).setVisibility(View.GONE); + if (LOGD) Log.d(mTag, "collapse mZenPanel=" + mZenPanel); + if (mZenPanel != null) { + mZenPanel.setVisibility(View.GONE); } + mZenPanelDivider.setVisibility(View.GONE); } public void updateStates() { - final int count = mSliderGroup.getChildCount(); + final int count = mSliderPanel.getChildCount(); for (int i = 0; i < count; i++) { - StreamControl sc = (StreamControl) mSliderGroup.getChildAt(i).getTag(); + StreamControl sc = (StreamControl) mSliderPanel.getChildAt(i).getTag(); updateSlider(sc); } } + private void updateZenMode(boolean zen) { + if (mZenModeCapable) { + final boolean show = mActiveStreamType == AudioManager.STREAM_NOTIFICATION + || mActiveStreamType == AudioManager.STREAM_RING; + mExpandButton.setVisibility(show ? View.VISIBLE : View.GONE); + mExpandDivider.setVisibility(show ? View.VISIBLE : View.GONE); + mExpandButton.setImageResource(zen ? com.android.systemui.R.drawable.ic_vol_zen_on + : com.android.systemui.R.drawable.ic_vol_zen_off); + } else { + mExpandButton.setVisibility(View.GONE); + mExpandDivider.setVisibility(View.GONE); + } + } + + public void postZenModeChanged(boolean zen) { + removeMessages(MSG_ZEN_MODE_CHANGED); + obtainMessage(MSG_ZEN_MODE_CHANGED, zen ? 1 : 0).sendToTarget(); + } + public void postVolumeChanged(int streamType, int flags) { if (hasMessages(MSG_VOLUME_CHANGED)) return; synchronized (this) { @@ -582,8 +628,12 @@ public class VolumePanel extends Handler { } public void postDismiss() { - removeMessages(MSG_TIMEOUT); - sendEmptyMessage(MSG_TIMEOUT); + forceTimeout(); + } + + public void postLayoutDirection(int layoutDirection) { + removeMessages(MSG_LAYOUT_DIRECTION); + obtainMessage(MSG_LAYOUT_DIRECTION, layoutDirection).sendToTarget(); } /** @@ -593,7 +643,7 @@ public class VolumePanel extends Handler { */ protected void onVolumeChanged(int streamType, int flags) { - if (LOGD) Log.d(TAG, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")"); + if (LOGD) Log.d(mTag, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")"); if ((flags & AudioManager.FLAG_SHOW_UI) != 0) { synchronized (this) { @@ -622,7 +672,7 @@ public class VolumePanel extends Handler { protected void onMuteChanged(int streamType, int flags) { - if (LOGD) Log.d(TAG, "onMuteChanged(streamType: " + streamType + ", flags: " + flags + ")"); + if (LOGD) Log.d(mTag, "onMuteChanged(streamType: " + streamType + ", flags: " + flags + ")"); StreamControl sc = mStreamControls.get(streamType); if (sc != null) { @@ -638,7 +688,7 @@ public class VolumePanel extends Handler { mRingIsSilent = false; if (LOGD) { - Log.d(TAG, "onShowVolumeChanged(streamType: " + streamType + Log.d(mTag, "onShowVolumeChanged(streamType: " + streamType + ", flags: " + flags + "), index: " + index); } @@ -707,7 +757,7 @@ public class VolumePanel extends Handler { } case AudioService.STREAM_REMOTE_MUSIC: { - if (LOGD) { Log.d(TAG, "showing remote volume "+index+" over "+ max); } + if (LOGD) { Log.d(mTag, "showing remote volume "+index+" over "+ max); } break; } } @@ -730,16 +780,18 @@ public class VolumePanel extends Handler { } } - if (!mDialog.isShowing()) { + if (!isShowing()) { int stream = (streamType == AudioService.STREAM_REMOTE_MUSIC) ? -1 : streamType; // when the stream is for remote playback, use -1 to reset the stream type evaluation mAudioManager.forceVolumeControlStream(stream); // Showing dialog - use collapsed state - if (mShowCombinedVolumes) { + if (mZenModeCapable) { collapse(); } - mDialog.show(); + if (mDialog != null) { + mDialog.show(); + } } // Do a little vibrate if applicable (only when going into vibrate mode) @@ -751,6 +803,10 @@ public class VolumePanel extends Handler { } } + private boolean isShowing() { + return mDialog != null ? mDialog.isShowing() : mParent.isAttachedToWindow(); + } + protected void onPlaySound(int streamType, int flags) { if (hasMessages(MSG_STOP_SOUNDS)) { @@ -795,9 +851,9 @@ public class VolumePanel extends Handler { // streamType is the real stream type being affected, but for the UI sliders, we // refer to AudioService.STREAM_REMOTE_MUSIC. We still play the beeps on the real // stream type. - if (LOGD) Log.d(TAG, "onRemoteVolumeChanged(stream:"+streamType+", flags: " + flags + ")"); + if (LOGD) Log.d(mTag, "onRemoteVolumeChanged(stream:"+streamType+", flags: " + flags + ")"); - if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || mDialog.isShowing()) { + if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || isShowing()) { synchronized (this) { if (mActiveStreamType != AudioService.STREAM_REMOTE_MUSIC) { reorderSliders(AudioService.STREAM_REMOTE_MUSIC); @@ -805,7 +861,7 @@ public class VolumePanel extends Handler { onShowVolumeChanged(AudioService.STREAM_REMOTE_MUSIC, flags); } } else { - if (LOGD) Log.d(TAG, "not calling onShowVolumeChanged(), no FLAG_SHOW_UI or no UI"); + if (LOGD) Log.d(mTag, "not calling onShowVolumeChanged(), no FLAG_SHOW_UI or no UI"); } if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && ! mRingIsSilent) { @@ -825,8 +881,8 @@ public class VolumePanel extends Handler { } protected void onRemoteVolumeUpdateIfShown() { - if (LOGD) Log.d(TAG, "onRemoteVolumeUpdateIfShown()"); - if (mDialog.isShowing() + if (LOGD) Log.d(mTag, "onRemoteVolumeUpdateIfShown()"); + if (isShowing() && (mActiveStreamType == AudioService.STREAM_REMOTE_MUSIC) && (mStreamControls != null)) { onShowVolumeChanged(AudioService.STREAM_REMOTE_MUSIC, 0); @@ -842,7 +898,7 @@ public class VolumePanel extends Handler { * @param visible */ synchronized protected void onSliderVisibilityChanged(int streamType, int visible) { - if (LOGD) Log.d(TAG, "onSliderVisibilityChanged(stream="+streamType+", visi="+visible+")"); + if (LOGD) Log.d(mTag, "onSliderVisibilityChanged(stream="+streamType+", visi="+visible+")"); boolean isVisible = (visible == 1); for (int i = STREAMS.length - 1 ; i >= 0 ; i--) { StreamResources streamRes = STREAMS[i]; @@ -857,7 +913,7 @@ public class VolumePanel extends Handler { } protected void onDisplaySafeVolumeWarning(int flags) { - if ((flags & AudioManager.FLAG_SHOW_UI) != 0 || mDialog.isShowing()) { + if ((flags & AudioManager.FLAG_SHOW_UI) != 0 || isShowing()) { synchronized (sConfirmSafeVolumeLock) { if (sConfirmSafeVolumeDialog != null) { return; @@ -907,7 +963,7 @@ public class VolumePanel extends Handler { mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME); } catch (RuntimeException e) { if (LOGD) { - Log.d(TAG, "ToneGenerator constructor failed with " + Log.d(mTag, "ToneGenerator constructor failed with " + "RuntimeException: " + e); } } @@ -976,8 +1032,10 @@ public class VolumePanel extends Handler { } case MSG_TIMEOUT: { - if (mDialog.isShowing()) { - mDialog.dismiss(); + if (isShowing()) { + if (mDialog != null) { + mDialog.dismiss(); + } mActiveStreamType = -1; } synchronized (sConfirmSafeVolumeLock) { @@ -988,7 +1046,7 @@ public class VolumePanel extends Handler { break; } case MSG_RINGER_MODE_CHANGED: { - if (mDialog.isShowing()) { + if (isShowing()) { updateStates(); } break; @@ -1010,17 +1068,30 @@ public class VolumePanel extends Handler { case MSG_DISPLAY_SAFE_VOLUME_WARNING: onDisplaySafeVolumeWarning(msg.arg1); break; + + case MSG_LAYOUT_DIRECTION: + setLayoutDirection(msg.arg1); + break; + + case MSG_ZEN_MODE_CHANGED: + updateZenMode(msg.arg1 != 0); + break; } } - private void resetTimeout() { + public void resetTimeout() { + if (LOGD) Log.d(mTag, "resetTimeout at " + System.currentTimeMillis()); removeMessages(MSG_TIMEOUT); - sendMessageDelayed(obtainMessage(MSG_TIMEOUT), TIMEOUT_DELAY); + sendEmptyMessageDelayed(MSG_TIMEOUT, TIMEOUT_DELAY); } private void forceTimeout() { removeMessages(MSG_TIMEOUT); - sendMessage(obtainMessage(MSG_TIMEOUT)); + sendEmptyMessage(MSG_TIMEOUT); + } + + public ZenModeController getZenController() { + return mZenController; } private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { @@ -1061,10 +1132,22 @@ public class VolumePanel extends Handler { private final View.OnClickListener mClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - if (v == mMoreButton) { - expand(); + if (v == mExpandButton && mZenController != null) { + final boolean newZen = !mZenController.isZen(); + mZenController.setZen(newZen); + if (newZen) { + expand(); + } else { + collapse(); + } } resetTimeout(); } }; + + private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() { + public void onZenChanged(boolean zen) { + updateZenMode(zen); + } + }; } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java index 9bd75b7..7da90d8 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java @@ -1,16 +1,22 @@ package com.android.systemui.volume; import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; import android.database.ContentObserver; import android.media.AudioManager; import android.media.IVolumeController; import android.net.Uri; import android.os.Handler; import android.os.RemoteException; +import android.os.UserHandle; import android.provider.Settings; import android.util.Log; +import com.android.systemui.R; import com.android.systemui.SystemUI; +import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.statusbar.policy.ZenModeControllerImpl; /* * Copyright (C) 2014 The Android Open Source Project @@ -34,21 +40,21 @@ public class VolumeUI extends SystemUI { private static final Uri SETTING_URI = Settings.Global.getUriFor(SETTING); private static final int DEFAULT = 1; // enabled by default + private final Handler mHandler = new Handler(); private AudioManager mAudioManager; private VolumeController mVolumeController; @Override public void start() { mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + mVolumeController = new VolumeController(mContext); + putComponent(VolumeComponent.class, mVolumeController); updateController(); mContext.getContentResolver().registerContentObserver(SETTING_URI, false, mObserver); } private void updateController() { if (Settings.Global.getInt(mContext.getContentResolver(), SETTING, DEFAULT) != 0) { - if (mVolumeController == null) { - mVolumeController = new VolumeController(mContext); - } Log.d(TAG, "Registering volume controller"); mAudioManager.setVolumeController(mVolumeController); } else { @@ -57,7 +63,7 @@ public class VolumeUI extends SystemUI { } } - private final ContentObserver mObserver = new ContentObserver(new Handler()) { + private final ContentObserver mObserver = new ContentObserver(mHandler) { public void onChange(boolean selfChange, Uri uri) { if (SETTING_URI.equals(uri)) { updateController(); @@ -66,13 +72,38 @@ public class VolumeUI extends SystemUI { }; /** For now, simply host an unmodified base volume panel in this process. */ - private final class VolumeController extends IVolumeController.Stub { - private final VolumePanel mPanel; + private final class VolumeController extends IVolumeController.Stub implements VolumeComponent { + private final VolumePanel mDialogPanel; + private VolumePanel mPanel; public VolumeController(Context context) { - mPanel = new VolumePanel(context); + mPanel = new VolumePanel(context, null, new ZenModeControllerImpl(mContext, mHandler)); + final int delay = context.getResources().getInteger(R.integer.feedback_start_delay); + mPanel.setZenModePanelCallback(new ZenModePanel.Callback() { + @Override + public void onMoreSettings() { + mHandler.removeCallbacks(mStartZenSettings); + mHandler.postDelayed(mStartZenSettings, delay); + } + + @Override + public void onInteraction() { + mDialogPanel.resetTimeout(); + } + }); + mDialogPanel = mPanel; } + private final Runnable mStartZenSettings = new Runnable() { + @Override + public void run() { + mDialogPanel.postDismiss(); + final Intent intent = ZenModePanel.ZEN_SETTINGS; + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); + } + }; + @Override public void hasNewRemotePlaybackInfo() throws RemoteException { mPanel.postHasNewRemotePlaybackInfo(); @@ -114,12 +145,22 @@ public class VolumeUI extends SystemUI { @Override public void setLayoutDirection(int layoutDirection) throws RemoteException { - mPanel.setLayoutDirection(layoutDirection); + mPanel.postLayoutDirection(layoutDirection); } @Override public void dismiss() throws RemoteException { mPanel.postDismiss(); } + + @Override + public ZenModeController getZenController() { + return mDialogPanel.getZenController(); + } + + @Override + public void setVolumePanel(VolumePanel panel) { + mPanel = panel == null ? mDialogPanel : panel; + } } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java new file mode 100644 index 0000000..77d267e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java @@ -0,0 +1,248 @@ +/* + * 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. + */ + +package com.android.systemui.volume; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings; +import android.service.notification.Condition; +import android.util.AttributeSet; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import android.widget.TextView; + +import com.android.systemui.R; +import com.android.systemui.statusbar.policy.ZenModeController; + +import java.util.Arrays; +import java.util.HashSet; + +public class ZenModePanel extends LinearLayout { + private static final int[] MINUTES = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 }; + public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS); + + private final LayoutInflater mInflater; + private final HashSet<RadioButton> mRadioButtons = new HashSet<RadioButton>(); + private final H mHandler = new H(); + private LinearLayout mConditions; + private int mMinutesIndex = Arrays.binarySearch(MINUTES, 60); // default to one hour + private Callback mCallback; + private ZenModeController mController; + private boolean mRequestingConditions; + + public ZenModePanel(Context context, AttributeSet attrs) { + super(context, attrs); + mInflater = LayoutInflater.from(new ContextThemeWrapper(context, R.style.QSWhiteTheme)); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mConditions = (LinearLayout) findViewById(android.R.id.content); + findViewById(android.R.id.button2).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + fireMoreSettings(); + } + }); + } + + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); + setRequestingConditions(visibility == VISIBLE); + } + + /** Start or stop requesting relevant zen mode exit conditions */ + private void setRequestingConditions(boolean requesting) { + if (mRequestingConditions == requesting) return; + mRequestingConditions = requesting; + if (mRequestingConditions) { + mController.addCallback(mZenCallback); + } else { + mController.removeCallback(mZenCallback); + } + mController.requestConditions(mRequestingConditions); + } + + public void init(ZenModeController controller) { + mController = controller; + mConditions.removeAllViews(); + bind(updateTimeCondition(), mConditions.getChildAt(0)); + handleUpdateConditions(new Condition[0]); + } + + public void setCallback(Callback callback) { + mCallback = callback; + } + + private Condition updateTimeCondition() { + final int minutes = MINUTES[mMinutesIndex]; + final long millis = System.currentTimeMillis() + minutes * 60 * 1000; + final Uri id = new Uri.Builder().scheme(Condition.SCHEME).authority("android") + .appendPath("countdown").appendPath(Long.toString(millis)).build(); + final int num = minutes < 60 ? minutes : minutes / 60; + final int resId = minutes < 60 + ? R.plurals.zen_mode_duration_minutes + : R.plurals.zen_mode_duration_hours; + final String caption = mContext.getResources().getQuantityString(resId, num, num); + return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE, + Condition.FLAG_RELEVANT_NOW); + } + + private void handleUpdateConditions(Condition[] conditions) { + final int newCount = conditions == null ? 0 : conditions.length; + for (int i = mConditions.getChildCount() - 1; i > newCount; i--) { + mConditions.removeViewAt(i); + } + for (int i = 0; i < newCount; i++) { + bind(conditions[i], mConditions.getChildAt(i + 1)); + } + bind(null, mConditions.getChildAt(newCount + 1)); + } + + private void editTimeCondition(int delta) { + final int i = mMinutesIndex + delta; + if (i < 0 || i >= MINUTES.length) return; + mMinutesIndex = i; + final Condition c = updateTimeCondition(); + bind(c, mConditions.getChildAt(0)); + } + + private void bind(final Condition condition, View convertView) { + final boolean enabled = condition == null || condition.state == Condition.STATE_TRUE; + final View row; + if (convertView == null) { + row = mInflater.inflate(R.layout.zen_mode_condition, this, false); + mConditions.addView(row); + } else { + row = convertView; + } + final int position = mConditions.indexOfChild(row); + final RadioButton rb = (RadioButton) row.findViewById(android.R.id.checkbox); + mRadioButtons.add(rb); + rb.setEnabled(enabled); + rb.setOnCheckedChangeListener(new OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + for (RadioButton otherButton : mRadioButtons) { + if (otherButton == rb) continue; + otherButton.setChecked(false); + } + mController.select(condition); + fireInteraction(); + } + } + }); + final TextView title = (TextView) row.findViewById(android.R.id.title); + if (condition == null) { + title.setText(R.string.zen_mode_forever); + } else { + title.setText(condition.summary); + } + title.setEnabled(enabled); + title.setAlpha(enabled ? 1 : .5f); + final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1); + button1.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + rb.setChecked(true); + editTimeCondition(-1); + fireInteraction(); + } + }); + + final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2); + button2.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + rb.setChecked(true); + editTimeCondition(1); + fireInteraction(); + } + }); + title.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + rb.setChecked(true); + fireInteraction(); + } + }); + if (position == 0) { + button1.setEnabled(mMinutesIndex > 0); + button2.setEnabled(mMinutesIndex < MINUTES.length - 1); + button1.setImageAlpha(button1.isEnabled() ? 0xff : 0x7f); + button2.setImageAlpha(button2.isEnabled() ? 0xff : 0x7f); + } else { + button1.setVisibility(View.GONE); + button2.setVisibility(View.GONE); + } + if (position == 0 && mConditions.getChildCount() == 1) { + rb.setChecked(true); + } + } + + private void fireMoreSettings() { + if (mCallback != null) { + mCallback.onMoreSettings(); + } + } + + private void fireInteraction() { + if (mCallback != null) { + mCallback.onInteraction(); + } + } + + private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() { + @Override + public void onConditionsChanged(Condition[] conditions) { + mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget(); + } + }; + + private final class H extends Handler { + private static final int UPDATE_CONDITIONS = 1; + + private H() { + super(Looper.getMainLooper()); + } + + @Override + public void handleMessage(Message msg) { + if (msg.what == UPDATE_CONDITIONS) { + handleUpdateConditions((Condition[])msg.obj); + } + } + } + + public interface Callback { + void onMoreSettings(); + void onInteraction(); + } +} diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 9977193..e178773 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -478,6 +478,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private static final int MSG_DISABLE_POINTER_LOCATION = 2; private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3; private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4; + private static final int MSG_DISPATCH_SHOW_RECENTS = 5; private class PolicyHandler extends Handler { @Override @@ -495,6 +496,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK: dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj); break; + case MSG_DISPATCH_SHOW_RECENTS: + showRecentApps(false); + break; } } } @@ -2459,6 +2463,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + @Override + public void showRecentApps() { + mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS); + mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_RECENTS); + } + private void showRecentApps(boolean triggeredFromAltTab) { mPreloadedRecentApps = false; // preloading no longer needs to be canceled try { diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 7ecf248..1e21e1c 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -343,12 +343,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { private static final int EVENT_INET_CONDITION_HOLD_END = 5; /** - * used internally to set enable/disable cellular data - * arg1 = ENBALED or DISABLED - */ - private static final int EVENT_SET_MOBILE_DATA = 7; - - /** * used internally to clear a wakelock when transitioning * from one net to another */ @@ -1822,20 +1816,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { return true; } - /** - * @see ConnectivityManager#getMobileDataEnabled() - */ - public boolean getMobileDataEnabled() { - // TODO: This detail should probably be in DataConnectionTracker's - // which is where we store the value and maybe make this - // asynchronous. - enforceAccessPermission(); - boolean retVal = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.MOBILE_DATA, 1) == 1; - if (VDBG) log("getMobileDataEnabled returning " + retVal); - return retVal; - } - public void setDataDependency(int networkType, boolean met) { enforceConnectivityInternalPermission(); @@ -1908,22 +1888,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { } }; - /** - * @see ConnectivityManager#setMobileDataEnabled(boolean) - */ - public void setMobileDataEnabled(boolean enabled) { - enforceChangePermission(); - if (DBG) log("setMobileDataEnabled(" + enabled + ")"); - - mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA, - (enabled ? ENABLED : DISABLED), 0)); - } - - private void handleSetMobileData(boolean enabled) { - // TODO - handle this - probably generalize passing in a transport type and send to the - // factories? - } - @Override public void setPolicyDataEnable(int networkType, boolean enabled) { // only someone like NPMS should only be calling us @@ -3315,11 +3279,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { handleInetConditionHoldEnd(netType, sequence); break; } - case EVENT_SET_MOBILE_DATA: { - boolean enabled = (msg.arg1 == ENABLED); - handleSetMobileData(enabled); - break; - } case EVENT_APPLY_GLOBAL_HTTP_PROXY: { handleDeprecatedGlobalHttpProxy(); break; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ac30319..fc808ec 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -409,7 +409,7 @@ public final class ActivityManagerService extends ActivityManagerNative /** * List of intents that were used to start the most recent tasks. */ - final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); + ArrayList<TaskRecord> mRecentTasks; public class PendingAssistExtras extends Binder implements Runnable { public final ActivityRecord activity; @@ -822,6 +822,11 @@ public final class ActivityManagerService extends ActivityManagerNative final AppOpsService mAppOpsService; /** + * Save recent tasks information across reboots. + */ + final TaskPersister mTaskPersister; + + /** * Current configuration information. HistoryRecord objects are given * a reference to this object to indicate which configuration they are * currently running in, so this object must be kept immutable. @@ -2138,6 +2143,7 @@ public final class ActivityManagerService extends ActivityManagerNative mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); mStackSupervisor = new ActivityStackSupervisor(this); + mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); mProcessCpuThread = new Thread("CpuTracker") { @Override @@ -7079,14 +7085,18 @@ public final class ActivityManagerService extends ActivityManagerNative * Creates a new RecentTaskInfo from a TaskRecord. */ private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { + // Update the task description to reflect any changes in the task stack + tr.updateTaskDescription(); + + // Compose the recent task info ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); - rti.id = tr.numActivities > 0 ? tr.taskId : -1; + rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; rti.persistentId = tr.taskId; rti.baseIntent = new Intent(tr.getBaseIntent()); rti.origActivity = tr.origActivity; rti.description = tr.lastDescription; - rti.stackId = tr.stack.mStackId; + rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; rti.userId = tr.userId; rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); return rti; @@ -7320,6 +7330,9 @@ public final class ActivityManagerService extends ActivityManagerNative if (tr != null) { tr.removeTaskActivitiesLocked(-1, false); cleanUpRemovedTaskLocked(tr, flags); + if (tr.isPersistable) { + notifyTaskPersisterLocked(tr, true); + } return true; } return false; @@ -7559,14 +7572,11 @@ public final class ActivityManagerService extends ActivityManagerNative try { synchronized (this) { TaskRecord tr = recentTaskForIdLocked(taskId); - if (tr != null) { - return tr.stack.isHomeStack(); - } + return tr != null && tr.stack != null && tr.stack.isHomeStack(); } } finally { Binder.restoreCallingIdentity(ident); } - return false; } @Override @@ -8635,6 +8645,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } + void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { + mTaskPersister.notify(task, flush); + } + @Override public boolean shutdown(int timeout) { if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) @@ -8657,6 +8671,7 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized (this) { mProcessStats.shutdownLocked(); } + notifyTaskPersisterLocked(null, true); return timedout; } @@ -9562,7 +9577,15 @@ public final class ActivityManagerService extends ActivityManagerNative if (goingCallback != null) goingCallback.run(); return; } - + + if (mRecentTasks == null) { + mRecentTasks = mTaskPersister.restoreTasksLocked(); + if (!mRecentTasks.isEmpty()) { + mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); + } + mTaskPersister.startPersisting(); + } + // Check to see if there are any update receivers to run. if (!mDidUpdate) { if (mWaitingUpdate) { @@ -17179,7 +17202,7 @@ public final class ActivityManagerService extends ActivityManagerNative /** * An implementation of IAppTask, that allows an app to manage its own tasks via - * {@link android.app.ActivityManager#AppTask}. We keep track of the callingUid to ensure that + * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that * only the process that calls getAppTasks() can call the AppTask methods. */ class AppTaskImpl extends IAppTask.Stub { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index dbe2ca1..b429b93 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -16,14 +16,15 @@ package com.android.server.am; +import android.app.ActivityManager.TaskDescription; import android.os.PersistableBundle; import android.os.Trace; import com.android.internal.app.ResolverActivity; +import com.android.internal.util.XmlUtils; import com.android.server.AttributeCache; import com.android.server.am.ActivityStack.ActivityState; import com.android.server.am.ActivityStackSupervisor.ActivityContainer; -import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ResultInfo; import android.content.ComponentName; @@ -48,7 +49,11 @@ import android.util.Slog; import android.util.TimeUtils; import android.view.IApplicationToken; import android.view.WindowManager; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; +import java.io.IOException; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -62,6 +67,19 @@ final class ActivityRecord { static final boolean DEBUG_SAVED_STATE = ActivityStackSupervisor.DEBUG_SAVED_STATE; final public static String RECENTS_PACKAGE_NAME = "com.android.systemui.recent"; + private static final String TAG_ACTIVITY = "activity"; + private static final String ATTR_ID = "id"; + private static final String TAG_INTENT = "intent"; + private static final String ATTR_USERID = "user_id"; + private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle"; + private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid"; + private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package"; + private static final String ATTR_RESOLVEDTYPE = "resolved_type"; + private static final String ATTR_COMPONENTSPECIFIED = "component_specified"; + private static final String ATTR_TASKDESCRIPTIONLABEL = "task_description_label"; + private static final String ATTR_TASKDESCRIPTIONCOLOR = "task_description_color"; + private static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_"; + final ActivityManagerService service; // owner final IApplicationToken.Stub appToken; // window manager token final ActivityInfo info; // all about me @@ -97,6 +115,7 @@ final class ActivityRecord { int windowFlags; // custom window flags for preview window. TaskRecord task; // the task this is in. ThumbnailHolder thumbHolder; // where our thumbnails should go. + long createTime = System.currentTimeMillis(); long displayStartTime; // when we started launching this activity long fullyDrawnStartTime; // when we started launching this activity long startTime; // last time this activity was started @@ -149,7 +168,7 @@ final class ActivityRecord { boolean mStartingWindowShown = false; ActivityContainer mInitialActivityContainer; - ActivityManager.TaskDescription taskDescription; // the recents information for this activity + TaskDescription taskDescription; // the recents information for this activity void dump(PrintWriter pw, String prefix) { final long now = SystemClock.uptimeMillis(); @@ -490,14 +509,6 @@ final class ActivityRecord { (newTask == null ? null : newTask.stack)); } } - if (inHistory && !finishing) { - if (task != null) { - task.numActivities--; - } - if (newTask != null) { - newTask.numActivities++; - } - } if (newThumbHolder == null) { newThumbHolder = newTask; } @@ -527,9 +538,6 @@ final class ActivityRecord { void putInHistory() { if (!inHistory) { inHistory = true; - if (task != null && !finishing) { - task.numActivities++; - } } } @@ -537,7 +545,6 @@ final class ActivityRecord { if (inHistory) { inHistory = false; if (task != null && !finishing) { - task.numActivities--; task = null; } clearOptionsLocked(); @@ -560,12 +567,13 @@ final class ActivityRecord { return mActivityType == APPLICATION_ACTIVITY_TYPE; } + boolean isPersistable() { + return (info.flags & ActivityInfo.FLAG_PERSISTABLE) != 0; + } + void makeFinishing() { if (!finishing) { finishing = true; - if (task != null && inHistory) { - task.numActivities--; - } if (stopped) { clearOptionsLocked(); } @@ -767,6 +775,9 @@ final class ActivityRecord { "Setting thumbnail of " + this + " holder " + thumbHolder + " to " + newThumbnail); thumbHolder.lastThumbnail = newThumbnail; + if (isPersistable()) { + mStackSupervisor.mService.notifyTaskPersisterLocked(task, false); + } } thumbHolder.lastDescription = description; } @@ -1042,7 +1053,134 @@ final class ActivityRecord { return null; } - private String activityTypeToString(int type) { + void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException { + out.attribute(null, ATTR_ID, String.valueOf(createTime)); + out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid)); + if (launchedFromPackage != null) { + out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage); + } + if (resolvedType != null) { + out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType); + } + out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified)); + out.attribute(null, ATTR_USERID, String.valueOf(userId)); + if (taskDescription != null) { + final String label = taskDescription.getLabel(); + if (label != null) { + out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, label); + } + final int colorPrimary = taskDescription.getPrimaryColor(); + if (colorPrimary != 0) { + out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(colorPrimary)); + } + final Bitmap icon = taskDescription.getIcon(); + if (icon != null) { + TaskPersister.saveImage(icon, String.valueOf(task.taskId) + ACTIVITY_ICON_SUFFIX + + createTime); + } + } + + out.startTag(null, TAG_INTENT); + intent.saveToXml(out); + out.endTag(null, TAG_INTENT); + + if (isPersistable() && persistentState != null) { + out.startTag(null, TAG_PERSISTABLEBUNDLE); + persistentState.saveToXml(out); + out.endTag(null, TAG_PERSISTABLEBUNDLE); + } + } + + static ActivityRecord restoreFromXml(XmlPullParser in, int taskId, + ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException { + Intent intent = null; + PersistableBundle persistentState = null; + int launchedFromUid = 0; + String launchedFromPackage = null; + String resolvedType = null; + boolean componentSpecified = false; + int userId = 0; + String activityLabel = null; + int activityColor = 0; + long createTime = -1; + final int outerDepth = in.getDepth(); + + for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) { + final String attrName = in.getAttributeName(attrNdx); + final String attrValue = in.getAttributeValue(attrNdx); + if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "ActivityRecord: attribute name=" + + attrName + " value=" + attrValue); + if (ATTR_ID.equals(attrName)) { + createTime = Long.valueOf(attrValue); + } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) { + launchedFromUid = Integer.valueOf(attrValue); + } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) { + launchedFromPackage = attrValue; + } else if (ATTR_RESOLVEDTYPE.equals(attrName)) { + resolvedType = attrValue; + } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) { + componentSpecified = Boolean.valueOf(attrValue); + } else if (ATTR_USERID.equals(attrName)) { + userId = Integer.valueOf(attrValue); + } else if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) { + activityLabel = attrValue; + } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) { + activityColor = (int) Long.parseLong(attrValue, 16); + } else { + Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName); + } + } + + int event; + while (((event = in.next()) != XmlPullParser.END_DOCUMENT) && + (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) { + if (event == XmlPullParser.START_TAG) { + final String name = in.getName(); + if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, + "ActivityRecord: START_TAG name=" + name); + if (TAG_INTENT.equals(name)) { + intent = Intent.restoreFromXml(in); + if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, + "ActivityRecord: intent=" + intent); + } else if (TAG_PERSISTABLEBUNDLE.equals(name)) { + persistentState = PersistableBundle.restoreFromXml(in); + if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, + "ActivityRecord: persistentState=" + persistentState); + } else { + Slog.w(TAG, "restoreActivity: unexpected name=" + name); + XmlUtils.skipCurrentTag(in); + } + } + } + + if (intent == null) { + throw new XmlPullParserException("restoreActivity error intent=" + intent); + } + + final ActivityManagerService service = stackSupervisor.mService; + final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null, + null, userId); + if (aInfo == null) { + throw new XmlPullParserException("restoreActivity resolver error."); + } + final ActivityRecord r = new ActivityRecord(service, /*caller*/null, launchedFromUid, + launchedFromPackage, intent, resolvedType, aInfo, service.getConfiguration(), + null, null, 0, componentSpecified, stackSupervisor, null, null); + + r.persistentState = persistentState; + + Bitmap icon = null; + if (createTime >= 0) { + icon = TaskPersister.restoreImage(String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + + createTime); + } + r.taskDescription = new TaskDescription(activityLabel, icon, activityColor); + r.createTime = createTime; + + return r; + } + + private static String activityTypeToString(int type) { switch (type) { case APPLICATION_ACTIVITY_TYPE: return "APPLICATION_ACTIVITY_TYPE"; case HOME_ACTIVITY_TYPE: return "HOME_ACTIVITY_TYPE"; diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 33e59a7..a0440cb 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -30,9 +30,14 @@ import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING; import static com.android.server.am.ActivityManagerService.DEBUG_VISBILITY; import static com.android.server.am.ActivityManagerService.VALIDATE_TOKENS; +import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; +import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; +import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; + import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE; import static com.android.server.am.ActivityStackSupervisor.DEBUG_APP; import static com.android.server.am.ActivityStackSupervisor.DEBUG_SAVED_STATE; +import static com.android.server.am.ActivityStackSupervisor.DEBUG_SCREENSHOTS; import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES; import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; @@ -342,6 +347,10 @@ final class ActivityStack { mWindowManager = mService.mWindowManager; mStackId = activityContainer.mStackId; mCurrentUser = mService.mCurrentUserId; + // Get the activity screenshot thumbnail dimensions + Resources res = mService.mContext.getResources(); + mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); + mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); } /** @@ -725,42 +734,54 @@ final class ActivityStack { } } + /** + * This resets the saved state from the last screenshot, forcing a new screenshot to be taken + * again when requested. + */ + private void invalidateLastScreenshot() { + mLastScreenshotActivity = null; + if (mLastScreenshotBitmap != null) { + mLastScreenshotBitmap.recycle(); + } + mLastScreenshotBitmap = null; + } + public final Bitmap screenshotActivities(ActivityRecord who) { + if (DEBUG_SCREENSHOTS) Slog.d(TAG, "screenshotActivities: " + who); if (who.noDisplay) { + if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tNo display"); return null; } TaskRecord tr = who.task; - if (mService.getMostRecentTask() != tr && tr.intent != null && - (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0) { - // If this task is being excluded from recents, we don't want to take - // the expense of capturing a thumbnail, since we will never show it. + if (mService.getMostRecentTask() != tr || isHomeStack()) { + // This is an optimization -- since we never show Home or Recents within Recents itself, + // we can just go ahead and skip taking the screenshot if this is the home stack. In + // the case where the most recent task is not the task that was supplied, then the stack + // has changed, so invalidate the last screenshot(). + invalidateLastScreenshot(); + if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tIs Home stack? " + isHomeStack()); return null; } - Resources res = mService.mContext.getResources(); int w = mThumbnailWidth; int h = mThumbnailHeight; - if (w < 0) { - mThumbnailWidth = w = - res.getDimensionPixelSize(com.android.internal.R.dimen.recents_thumbnail_width); - mThumbnailHeight = h = - res.getDimensionPixelSize(com.android.internal.R.dimen.recents_thumbnail_height); - } - if (w > 0) { if (who != mLastScreenshotActivity || mLastScreenshotBitmap == null || mLastScreenshotActivity.state == ActivityState.RESUMED || mLastScreenshotBitmap.getWidth() != w || mLastScreenshotBitmap.getHeight() != h) { + if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tUpdating screenshot"); mLastScreenshotActivity = who; mLastScreenshotBitmap = mWindowManager.screenshotApplications( who.appToken, Display.DEFAULT_DISPLAY, w, h, SCREENSHOT_FORCE_565); } if (mLastScreenshotBitmap != null) { + if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tReusing last screenshot"); return mLastScreenshotBitmap.copy(mLastScreenshotBitmap.getConfig(), true); } } + Slog.e(TAG, "Invalid thumbnail dimensions: " + w + "x" + h); return null; } @@ -863,7 +884,10 @@ final class ActivityStack { final ActivityRecord r = isInStackLocked(token); if (r != null) { mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); - r.persistentState = persistentState; + if (persistentState != null) { + r.persistentState = persistentState; + mService.notifyTaskPersisterLocked(r.task, false); + } if (mPausingActivity == r) { if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r + (timeout ? " (due to timeout)" : " (pause complete)")); @@ -885,7 +909,10 @@ final class ActivityStack { mHandler.removeMessages(STOP_TIMEOUT_MSG, r); return; } - r.persistentState = persistentState; + if (persistentState != null) { + r.persistentState = persistentState; + mService.notifyTaskPersisterLocked(r.task, false); + } if (DEBUG_SAVED_STATE) Slog.i(TAG, "Saving icicle of " + r + ": " + icicle); if (icicle != null) { // If icicle is null, this is happening due to a timeout, so we @@ -1032,40 +1059,12 @@ final class ActivityStack { } else { next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process } - } - /** - * Determine if home should be visible below the passed record. - * @param record activity we are querying for. - * @return true if home is visible below the passed activity, false otherwise. - */ - boolean isActivityOverHome(ActivityRecord record) { - // Start at record and go down, look for either home or a visible fullscreen activity. - final TaskRecord recordTask = record.task; - for (int taskNdx = mTaskHistory.indexOf(recordTask); taskNdx >= 0; --taskNdx) { - TaskRecord task = mTaskHistory.get(taskNdx); - final ArrayList<ActivityRecord> activities = task.mActivities; - final int startNdx = - task == recordTask ? activities.indexOf(record) : activities.size() - 1; - for (int activityNdx = startNdx; activityNdx >= 0; --activityNdx) { - final ActivityRecord r = activities.get(activityNdx); - if (r.isHomeActivity()) { - return true; - } - if (!r.finishing && r.fullscreen) { - // Passed activity is over a fullscreen activity. - return false; - } - } - if (task.mOnTopOfHome) { - // Got to the bottom of a task on top of home without finding a visible fullscreen - // activity. Home is visible. - return true; - } + // If we are resuming the activity that we had last screenshotted, then we know it will be + // updated, so invalidate the last screenshot to ensure we take a fresh one when requested + if (next == mLastScreenshotActivity) { + invalidateLastScreenshot(); } - // Got to the bottom of this stack and still don't know. If this is over the home stack - // then record is over home. May not work if we ever get more than two layers. - return mStackSupervisor.isFrontStack(this); } private void setVisibile(ActivityRecord r, boolean visible) { @@ -1097,7 +1096,8 @@ final class ActivityStack { for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) { final ArrayList<TaskRecord> tasks = mStacks.get(i).getAllTasks(); for (int taskNdx = 0; taskNdx < tasks.size(); taskNdx++) { - final ArrayList<ActivityRecord> activities = tasks.get(taskNdx).mActivities; + final TaskRecord task = tasks.get(taskNdx); + final ArrayList<ActivityRecord> activities = task.mActivities; for (int activityNdx = 0; activityNdx < activities.size(); activityNdx++) { final ActivityRecord r = activities.get(activityNdx); @@ -1108,7 +1108,7 @@ final class ActivityStack { // - Full Screen Activity OR // - On top of Home and our stack is NOT home if (!r.finishing && r.visible && (r.fullscreen || - (!isHomeStack() && r.frontOfTask && tasks.get(taskNdx).mOnTopOfHome))) { + (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()))) { return false; } } @@ -1236,7 +1236,7 @@ final class ActivityStack { // At this point, nothing else needs to be shown if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r); behindFullscreen = true; - } else if (!isHomeStack() && r.frontOfTask && task.mOnTopOfHome) { + } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) { if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r); behindFullscreen = true; } @@ -1390,6 +1390,7 @@ final class ActivityStack { final boolean userLeaving = mStackSupervisor.mUserLeaving; mStackSupervisor.mUserLeaving = false; + final TaskRecord prevTask = prev != null ? prev.task : null; if (next == null) { // There are no more activities! Let's just start up the // Launcher... @@ -1397,7 +1398,10 @@ final class ActivityStack { if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home"); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); // Only resume home if on home display - return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev); + final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? + HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo(); + return isOnHomeDisplay() && + mStackSupervisor.resumeHomeStackTask(returnTaskType, prev); } next.delayedResume = false; @@ -1416,22 +1420,24 @@ final class ActivityStack { } final TaskRecord nextTask = next.task; - final TaskRecord prevTask = prev != null ? prev.task : null; if (prevTask != null && prevTask.stack == this && - prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) { + prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) { if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); if (prevTask == nextTask) { prevTask.setFrontOfTask(); } else if (prevTask != topTask()) { - // This task is going away but it was supposed to return to the home task. + // This task is going away but it was supposed to return to the home stack. // Now the task above it has to return to the home task instead. final int taskNdx = mTaskHistory.indexOf(prevTask) + 1; - mTaskHistory.get(taskNdx).mOnTopOfHome = true; + mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE); } else { if (DEBUG_STATES && isOnHomeDisplay()) Slog.d(TAG, "resumeTopActivityLocked: Launching home next"); // Only resume home if on home display - return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev); + final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? + HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo(); + return isOnHomeDisplay() && + mStackSupervisor.resumeHomeStackTask(returnTaskType, prev); } } @@ -1802,10 +1808,11 @@ final class ActivityStack { ActivityStack lastStack = mStackSupervisor.getLastStack(); final boolean fromHome = lastStack.isHomeStack(); if (!isHomeStack() && (fromHome || topTask() != task)) { - task.mOnTopOfHome = fromHome; + task.setTaskToReturnTo(fromHome ? + lastStack.topTask().taskType : APPLICATION_ACTIVITY_TYPE); } } else { - task.mOnTopOfHome = false; + task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); } mTaskHistory.remove(task); @@ -1821,6 +1828,7 @@ final class ActivityStack { ++stackNdx; } mTaskHistory.add(stackNdx, task); + updateTaskMovement(task, true); } final void startActivityLocked(ActivityRecord r, boolean newTask, @@ -2349,8 +2357,8 @@ final class ActivityStack { ActivityRecord next = topRunningActivityLocked(null); if (next != r) { final TaskRecord task = r.task; - if (r.frontOfTask && task == topTask() && task.mOnTopOfHome) { - mStackSupervisor.moveHomeToTop(); + if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) { + mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo()); } } ActivityRecord top = mStackSupervisor.topRunningActivityLocked(); @@ -2834,8 +2842,9 @@ final class ActivityStack { if (task != null && task.removeActivity(r)) { if (DEBUG_STACK) Slog.i(TAG, "removeActivityFromHistoryLocked: last activity removed from " + this); - if (mStackSupervisor.isFrontStack(this) && task == topTask() && task.mOnTopOfHome) { - mStackSupervisor.moveHomeToTop(); + if (mStackSupervisor.isFrontStack(this) && task == topTask() && + task.isOverHomeStack()) { + mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo()); } removeTask(task); } @@ -3138,14 +3147,28 @@ final class ActivityStack { mWindowManager.prepareAppTransition(transit, false); } - void moveHomeTaskToTop() { + void updateTaskMovement(TaskRecord task, boolean toFront) { + if (task.isPersistable) { + task.mLastTimeMoved = System.currentTimeMillis(); + // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most + // recently will be most negative, tasks sent to the bottom before that will be less + // negative. Similarly for recent tasks moved to the top which will be most positive. + if (!toFront) { + task.mLastTimeMoved *= -1; + } + } + } + + void moveHomeStackTaskToTop(int homeStackTaskType) { final int top = mTaskHistory.size() - 1; for (int taskNdx = top; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); - if (task.isHomeTask()) { - if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG, "moveHomeTaskToTop: moving " + task); + if (task.taskType == homeStackTaskType) { + if (DEBUG_TASKS || DEBUG_STACK) + Slog.d(TAG, "moveHomeStackTaskToTop: moving " + task); mTaskHistory.remove(taskNdx); mTaskHistory.add(top, task); + updateTaskMovement(task, true); mWindowManager.moveTaskToTop(task.taskId); return; } @@ -3247,19 +3270,19 @@ final class ActivityStack { mTaskHistory.remove(tr); mTaskHistory.add(0, tr); + updateTaskMovement(tr, false); // There is an assumption that moving a task to the back moves it behind the home activity. // We make sure here that some activity in the stack will launch home. - ActivityRecord lastActivity = null; int numTasks = mTaskHistory.size(); for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); - if (task.mOnTopOfHome) { + if (task.isOverHomeStack()) { break; } if (taskNdx == 1) { // Set the last task before tr to go to home. - task.mOnTopOfHome = true; + task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); } } @@ -3280,9 +3303,10 @@ final class ActivityStack { } final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null; - if (task == tr && tr.mOnTopOfHome || numTasks <= 1 && isOnHomeDisplay()) { - tr.mOnTopOfHome = false; - return mStackSupervisor.resumeHomeActivity(null); + if (task == tr && tr.isOverHomeStack() || numTasks <= 1 && isOnHomeDisplay()) { + final int taskToReturnTo = tr.getTaskToReturnTo(); + tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); + return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null); } mStackSupervisor.resumeTopActivitiesLocked(); @@ -3723,10 +3747,14 @@ final class ActivityStack { final int taskNdx = mTaskHistory.indexOf(task); final int topTaskNdx = mTaskHistory.size() - 1; - if (task.mOnTopOfHome && taskNdx < topTaskNdx) { - mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true; + if (task.isOverHomeStack() && taskNdx < topTaskNdx) { + final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1); + if (!nextTask.isOverHomeStack()) { + nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE); + } } mTaskHistory.remove(task); + updateTaskMovement(task, true); if (task.mActivities.isEmpty()) { final boolean isVoiceSession = task.voiceSession != null; @@ -3758,7 +3786,8 @@ final class ActivityStack { TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, boolean toTop) { - TaskRecord task = new TaskRecord(taskId, info, intent, voiceSession, voiceInteractor); + TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession, + voiceInteractor); addTask(task, toTop, false); return task; } @@ -3773,6 +3802,7 @@ final class ActivityStack { insertTaskAtTop(task); } else { mTaskHistory.add(0, task); + updateTaskMovement(task, false); } if (!moving && task.voiceSession != null) { try { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 252c0bb..ae7fab3 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -31,6 +31,9 @@ import static com.android.server.am.ActivityManagerService.DEBUG_TASKS; import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING; import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; import static com.android.server.am.ActivityManagerService.TAG; +import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; +import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; +import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; import android.app.Activity; import android.app.ActivityManager; @@ -106,6 +109,7 @@ public final class ActivityStackSupervisor implements DisplayListener { static final boolean DEBUG_SAVED_STATE = DEBUG || false; static final boolean DEBUG_STATES = DEBUG || false; static final boolean DEBUG_IDLE = DEBUG || false; + static final boolean DEBUG_SCREENSHOTS = DEBUG || false; public static final int HOME_STACK_ID = 0; @@ -318,18 +322,27 @@ public final class ActivityStackSupervisor implements DisplayListener { } } - void moveHomeToTop() { + void moveHomeStackTaskToTop(int homeStackTaskType) { + if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { + mWindowManager.showRecentApps(); + return; + } moveHomeStack(true); - mHomeStack.moveHomeTaskToTop(); + mHomeStack.moveHomeStackTaskToTop(homeStackTaskType); } - boolean resumeHomeActivity(ActivityRecord prev) { - moveHomeToTop(); + boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) { + if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { + mWindowManager.showRecentApps(); + return false; + } + moveHomeStackTaskToTop(homeStackTaskType); if (prev != null) { - prev.task.mOnTopOfHome = false; + prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); } + ActivityRecord r = mHomeStack.topRunningActivityLocked(null); - if (r != null && r.isHomeActivity()) { + if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) { mService.setFocusedActivityLocked(r); return resumeTopActivitiesLocked(mHomeStack, prev, null); } @@ -370,6 +383,12 @@ public final class ActivityStackSupervisor implements DisplayListener { return null; } + void setNextTaskId(int taskId) { + if (taskId > mCurTaskId) { + mCurTaskId = taskId; + } + } + int getNextTaskId() { do { mCurTaskId++; @@ -677,7 +696,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } void startHomeActivity(Intent intent, ActivityInfo aInfo) { - moveHomeToTop(); + moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE); startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); } @@ -1194,8 +1213,7 @@ public final class ActivityStackSupervisor implements DisplayListener { requestCode = sourceRecord.requestCode; sourceRecord.resultTo = null; if (resultRecord != null) { - resultRecord.removeResultsLocked( - sourceRecord, resultWho, requestCode); + resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); } if (sourceRecord.launchedFromUid == callingUid) { // The new activity is being launched from the same uid as the previous @@ -1367,7 +1385,7 @@ public final class ActivityStackSupervisor implements DisplayListener { return err; } - ActivityStack adjustStackFocus(ActivityRecord r) { + ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) { final TaskRecord task = r.task; if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { if (task != null) { @@ -1392,7 +1410,8 @@ public final class ActivityStackSupervisor implements DisplayListener { return container.mStack; } - if (mFocusedStack != mHomeStack) { + if (mFocusedStack != mHomeStack && (!newTask || + mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Have a focused stack=" + mFocusedStack); return mFocusedStack; @@ -1445,7 +1464,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // We'll invoke onUserLeaving before onPause only if the launching // activity did not explicitly state that this is an automated launch. - mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; + mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); // If the caller has asked not to resume at this point, we make note @@ -1455,7 +1474,8 @@ public final class ActivityStackSupervisor implements DisplayListener { r.delayedResume = true; } - ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; + ActivityRecord notTop = + (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; // If the onlyIfNeeded flag is set, then we can do this if the activity // being launched is the same as the one making the call... or, as @@ -1478,9 +1498,11 @@ public final class ActivityStackSupervisor implements DisplayListener { case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: intent.addFlags( Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + launchFlags = intent.getFlags(); break; case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + launchFlags = intent.getFlags(); break; } final boolean newDocument = intent.isDocument(); @@ -1609,7 +1631,7 @@ public final class ActivityStackSupervisor implements DisplayListener { (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { // Caller wants to appear on home activity. - intentActivity.task.mOnTopOfHome = true; + intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); } options = null; } @@ -1786,26 +1808,31 @@ public final class ActivityStackSupervisor implements DisplayListener { Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; } - targetStack = adjustStackFocus(r); + newTask = true; + targetStack = adjustStackFocus(r, newTask); targetStack.moveToFront(); if (reuseTask == null) { r.setTask(targetStack.createTaskRecord(getNextTaskId(), newTaskInfo != null ? newTaskInfo : r.info, newTaskIntent != null ? newTaskIntent : intent, voiceSession, voiceInteractor, true), null, true); + if (sourceRecord == null) { + // Launched from a service or notification or task that is finishing. + r.task.setTaskToReturnTo(isFrontStack(mHomeStack) ? + mHomeStack.topTask().taskType : RECENTS_ACTIVITY_TYPE); + } if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + r.task); } else { r.setTask(reuseTask, reuseTask, true); } - newTask = true; if (!movedHome) { if ((launchFlags & (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { // Caller wants to appear on home activity, so before starting // their own activity we will bring home to the front. - r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay(); + r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); } } } else if (sourceRecord != null) { @@ -1866,7 +1893,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // This not being started from an existing activity, and not part // of a new task... just put it in the top task, though these days // this case should never happen. - targetStack = adjustStackFocus(r); + targetStack = adjustStackFocus(r, newTask); targetStack.moveToFront(); ActivityRecord prev = targetStack.topActivity(); r.setTask(prev != null ? prev.task @@ -2156,7 +2183,7 @@ public final class ActivityStackSupervisor implements DisplayListener { if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { // Caller wants the home activity moved with it. To accomplish this, // we'll just indicate that this task returns to the home task. - task.mOnTopOfHome = true; + task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); } task.stack.moveTaskToFrontLocked(task, null, options); if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" @@ -2250,6 +2277,26 @@ public final class ActivityStackSupervisor implements DisplayListener { return mLastStackId; } + void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) { + int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); + final ActivityStack stack = getStack(stackId); + for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { + final TaskRecord task = tasks.get(taskNdx); + stack.addTask(task, false, false); + final int taskId = task.taskId; + final ArrayList<ActivityRecord> activities = task.mActivities; + for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { + final ActivityRecord r = activities.get(activityNdx); + mWindowManager.addAppToken(0, r.appToken, taskId, stackId, + r.info.screenOrientation, r.fullscreen, + (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, + r.userId, r.info.configChanges); + } + mWindowManager.addTask(taskId, stackId, false); + } + resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); + } + void moveTaskToStack(int taskId, int stackId, boolean toTop) { final TaskRecord task = anyTaskForIdLocked(taskId); if (task == null) { @@ -2273,7 +2320,12 @@ public final class ActivityStackSupervisor implements DisplayListener { for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (!r.isApplicationActivity() && !stack.isHomeStack()) { - if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack); + if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack); + continue; + } + if (!stack.mActivityContainer.isEligibleForNewTasks()) { + if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " + + stack); continue; } final ActivityRecord ar = stack.findTaskLocked(r); @@ -2504,7 +2556,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } } else { // Stack was moved to another display while user was swapped out. - resumeHomeActivity(null); + resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); } return homeInFront; } @@ -3204,6 +3256,11 @@ public final class ActivityStackSupervisor implements DisplayListener { void setDrawn() { } + // You can always start a new task on a regular ActivityStack. + boolean isEligibleForNewTasks() { + return true; + } + @Override public String toString() { return mIdString + (mActivityDisplay == null ? "N" : "A"); @@ -3284,6 +3341,12 @@ public final class ActivityStackSupervisor implements DisplayListener { } } + // Never start a new task on an ActivityView if it isn't explicitly specified. + @Override + boolean isEligibleForNewTasks() { + return false; + } + private void setSurfaceIfReady() { if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn + " mContainerState=" + mContainerState + " mSurface=" + mSurface); diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java new file mode 100644 index 0000000..3bfaca9 --- /dev/null +++ b/services/core/java/com/android/server/am/TaskPersister.java @@ -0,0 +1,353 @@ +/* + * 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. + */ + +package com.android.server.am; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Debug; +import android.os.SystemClock; +import android.util.ArraySet; +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.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +public class TaskPersister { + static final String TAG = "TaskPersister"; + static final boolean DEBUG = false; + + /** When in slow mode don't write tasks out faster than this */ + private static final long INTER_TASK_DELAY_MS = 60000; + private static final long DEBUG_INTER_TASK_DELAY_MS = 5000; + + private static final String RECENTS_FILENAME = "_task"; + private static final String TASKS_DIRNAME = "recent_tasks"; + private static final String TASK_EXTENSION = ".xml"; + private static final String IMAGES_DIRNAME = "recent_images"; + private static final String IMAGE_EXTENSION = ".png"; + + private static final String TAG_TASK = "task"; + + private static File sImagesDir; + private static File sTasksDir; + + private final ActivityManagerService mService; + private final ActivityStackSupervisor mStackSupervisor; + + private boolean mRecentsChanged = false; + + private final LazyTaskWriterThread mLazyTaskWriterThread; + + TaskPersister(File systemDir, ActivityStackSupervisor stackSupervisor) { + sTasksDir = new File(systemDir, TASKS_DIRNAME); + if (!sTasksDir.exists()) { + if (!sTasksDir.mkdir()) { + Slog.e(TAG, "Failure creating tasks directory " + sTasksDir); + } + } + + sImagesDir = new File(systemDir, IMAGES_DIRNAME); + if (!sImagesDir.exists()) { + if (!sImagesDir.mkdir()) { + Slog.e(TAG, "Failure creating images directory " + sImagesDir); + } + } + + mStackSupervisor = stackSupervisor; + mService = stackSupervisor.mService; + + mLazyTaskWriterThread = new LazyTaskWriterThread("LazyTaskWriterThread"); + } + + void startPersisting() { + mLazyTaskWriterThread.start(); + } + + public void notify(TaskRecord task, boolean flush) { + if (DEBUG) Slog.d(TAG, "notify: task=" + task + " flush=" + flush + + " Callers=" + Debug.getCallers(4)); + if (task != null) { + task.needsPersisting = true; + } + synchronized (this) { + mLazyTaskWriterThread.mSlow = !flush; + mRecentsChanged = true; + notifyAll(); + } + } + + private StringWriter saveToXml(TaskRecord task) throws IOException, XmlPullParserException { + if (DEBUG) Slog.d(TAG, "saveToXml: task=" + task); + final XmlSerializer xmlSerializer = new FastXmlSerializer(); + StringWriter stringWriter = new StringWriter(); + xmlSerializer.setOutput(stringWriter); + + if (DEBUG) xmlSerializer.setFeature( + "http://xmlpull.org/v1/doc/features.html#indent-output", true); + + // save task + xmlSerializer.startDocument(null, true); + + xmlSerializer.startTag(null, TAG_TASK); + task.saveToXml(xmlSerializer); + xmlSerializer.endTag(null, TAG_TASK); + + xmlSerializer.endDocument(); + xmlSerializer.flush(); + + return stringWriter; + } + + static void saveImage(Bitmap image, String filename) throws IOException { + if (DEBUG) Slog.d(TAG, "saveImage: filename=" + filename); + FileOutputStream imageFile = null; + try { + imageFile = new FileOutputStream(new File(sImagesDir, filename + IMAGE_EXTENSION)); + image.compress(Bitmap.CompressFormat.PNG, 100, imageFile); + } catch (Exception e) { + Slog.e(TAG, "saveImage: unable to save " + filename, e); + } finally { + if (imageFile != null) { + imageFile.close(); + } + } + } + + ArrayList<TaskRecord> restoreTasksLocked() { + final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>(); + ArraySet<Integer> recoveredTaskIds = new ArraySet<Integer>(); + + File[] recentFiles = sTasksDir.listFiles(); + if (recentFiles == null) { + Slog.e(TAG, "Unable to list files from " + sTasksDir); + return tasks; + } + + for (int taskNdx = 0; taskNdx < recentFiles.length; ++taskNdx) { + File taskFile = recentFiles[taskNdx]; + if (DEBUG) Slog.d(TAG, "restoreTasksLocked: taskFile=" + taskFile.getName()); + BufferedReader reader = null; + boolean deleteFile = false; + try { + reader = new BufferedReader(new FileReader(taskFile)); + final XmlPullParser in = Xml.newPullParser(); + in.setInput(reader); + + int event; + while (((event = in.next()) != XmlPullParser.END_DOCUMENT) && + event != XmlPullParser.END_TAG) { + final String name = in.getName(); + if (event == XmlPullParser.START_TAG) { + if (DEBUG) Slog.d(TAG, "restoreTasksLocked: START_TAG name=" + name); + if (TAG_TASK.equals(name)) { + final TaskRecord task = + TaskRecord.restoreFromXml(in, mStackSupervisor); + if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" + task); + if (task != null) { + tasks.add(task); + final int taskId = task.taskId; + recoveredTaskIds.add(taskId); + mStackSupervisor.setNextTaskId(taskId); + } + } else { + Slog.e(TAG, "restoreTasksLocked Unknown xml event=" + event + " name=" + + name); + } + } + XmlUtils.skipCurrentTag(in); + } + } catch (Exception e) { + Slog.wtf(TAG, "Unable to parse " + taskFile + ". Error " + e); + deleteFile = true; + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + } + } + if (!DEBUG && deleteFile) { + taskFile.delete(); + } + } + } + + if (!DEBUG) { + removeObsoleteFiles(recoveredTaskIds); + } + + TaskRecord[] tasksArray = new TaskRecord[tasks.size()]; + tasks.toArray(tasksArray); + Arrays.sort(tasksArray, new Comparator<TaskRecord>() { + @Override + public int compare(TaskRecord lhs, TaskRecord rhs) { + final long diff = lhs.mLastTimeMoved - rhs.mLastTimeMoved; + if (diff < 0) { + return -1; + } else if (diff > 0) { + return +1; + } else { + return 0; + } + } + }); + + return new ArrayList<TaskRecord>(Arrays.asList(tasksArray)); + } + + private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) { + for (int fileNdx = 0; fileNdx < files.length; ++fileNdx) { + File file = files[fileNdx]; + String filename = file.getName(); + final int taskIdEnd = filename.indexOf('_') + 1; + if (taskIdEnd > 0) { + final int taskId; + try { + taskId = Integer.valueOf(filename.substring(0, taskIdEnd)); + } catch (Exception e) { + if (DEBUG) Slog.d(TAG, "removeObsoleteFile: Can't parse file=" + + file.getName()); + file.delete(); + continue; + } + if (!persistentTaskIds.contains(taskId)) { + if (DEBUG) Slog.d(TAG, "removeObsoleteFile: deleting file=" + file.getName()); + file.delete(); + } + } + } + } + + private void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds) { + removeObsoleteFiles(persistentTaskIds, sTasksDir.listFiles()); + removeObsoleteFiles(persistentTaskIds, sImagesDir.listFiles()); + } + + static Bitmap restoreImage(String filename) { + if (DEBUG) Slog.d(TAG, "restoreImage: restoring " + filename); + return BitmapFactory.decodeFile(sImagesDir + File.separator + filename + IMAGE_EXTENSION); + } + + private class LazyTaskWriterThread extends Thread { + boolean mSlow = true; + + LazyTaskWriterThread(String name) { + super(name); + } + + @Override + public void run() { + ArraySet<Integer> persistentTaskIds = new ArraySet<Integer>(); + while (true) { + // If mSlow, then delay between each call to saveToXml(). + synchronized (TaskPersister.this) { + long now = SystemClock.uptimeMillis(); + final long releaseTime = + now + (DEBUG ? DEBUG_INTER_TASK_DELAY_MS: INTER_TASK_DELAY_MS); + while (mSlow && now < releaseTime) { + try { + if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting " + + (releaseTime - now)); + TaskPersister.this.wait(releaseTime - now); + } catch (InterruptedException e) { + } + now = SystemClock.uptimeMillis(); + } + } + + StringWriter stringWriter = null; + TaskRecord task = null; + synchronized(mService) { + final ArrayList<TaskRecord> tasks = mService.mRecentTasks; + persistentTaskIds.clear(); + for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { + task = tasks.get(taskNdx); + if (DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task + " persistable=" + + task.isPersistable + " needsPersisting=" + task.needsPersisting); + if (task.isPersistable) { + persistentTaskIds.add(task.taskId); + + if (task.needsPersisting) { + try { + stringWriter = saveToXml(task); + break; + } catch (IOException e) { + } catch (XmlPullParserException e) { + } finally { + task.needsPersisting = false; + } + } + } + } + } + + if (stringWriter != null) { + // Write out xml file while not holding mService lock. + FileOutputStream file = null; + AtomicFile atomicFile = null; + try { + atomicFile = new AtomicFile(new File(sTasksDir, + String.valueOf(task.taskId) + RECENTS_FILENAME + TASK_EXTENSION)); + file = atomicFile.startWrite(); + file.write(stringWriter.toString().getBytes()); + file.write('\n'); + atomicFile.finishWrite(file); + } catch (IOException e) { + if (file != null) { + atomicFile.failWrite(file); + } + Slog.e(TAG, "Unable to open " + atomicFile + " for persisting. " + e); + } + } else { + // Made it through the entire list and didn't find anything new that needed + // persisting. + if (!DEBUG) { + removeObsoleteFiles(persistentTaskIds); + } + + // Wait here for someone to call setRecentsChanged(). + synchronized (TaskPersister.this) { + while (!mRecentsChanged) { + if (DEBUG) Slog.d(TAG, "LazyTaskWriter: Waiting."); + try { + TaskPersister.this.wait(); + } catch (InterruptedException e) { + } + } + mRecentsChanged = false; + if (DEBUG) Slog.d(TAG, "LazyTaskWriter: Awake"); + } + } + // Some recents file needs to be written. + } + } + } +} diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 6d66b29..c07bc1e 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -17,6 +17,9 @@ package com.android.server.am; import static com.android.server.am.ActivityManagerService.TAG; +import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; +import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; +import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE; import android.app.Activity; @@ -27,15 +30,38 @@ import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; +import android.os.SystemClock; import android.os.UserHandle; import android.service.voice.IVoiceInteractionSession; import android.util.Slog; import com.android.internal.app.IVoiceInteractor; +import com.android.internal.util.XmlUtils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; +import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; final class TaskRecord extends ThumbnailHolder { + private static final String TAG_TASK = "task"; + private static final String ATTR_TASKID = "task_id"; + private static final String TAG_INTENT = "intent"; + private static final String TAG_AFFINITYINTENT = "affinity_intent"; + private static final String ATTR_REALACTIVITY = "real_activity"; + private static final String ATTR_ORIGACTIVITY = "orig_activity"; + private static final String TAG_ACTIVITY = "activity"; + private static final String ATTR_AFFINITY = "affinity"; + private static final String ATTR_ROOTHASRESET = "root_has_reset"; + private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode"; + private static final String ATTR_USERID = "user_id"; + private static final String ATTR_TASKTYPE = "task_type"; + private static final String ATTR_LASTDESCRIPTION = "last_description"; + private static final String ATTR_LASTTIMEMOVED = "last_time_moved"; + + private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail"; + final int taskId; // Unique identifier for this task. final String affinity; // The affinity name for this task, or null. final IVoiceInteractionSession voiceSession; // Voice interaction session driving task @@ -62,25 +88,64 @@ final class TaskRecord extends ThumbnailHolder { new ActivityManager.TaskDescription(); /** List of all activities in the task arranged in history order */ - final ArrayList<ActivityRecord> mActivities = new ArrayList<ActivityRecord>(); + final ArrayList<ActivityRecord> mActivities; /** Current stack */ ActivityStack stack; /** Takes on same set of values as ActivityRecord.mActivityType */ - private int mTaskType; + int taskType; + + /** Takes on same value as first root activity */ + boolean isPersistable = false; + + /** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for + * determining the order when restoring. Sign indicates whether last task movement was to front + * (positive) or back (negative). Absolute value indicates time. */ + long mLastTimeMoved = System.currentTimeMillis(); + + /** True if persistable, has changed, and has not yet been persisted */ + boolean needsPersisting = false; - /** Launch the home activity when leaving this task. Will be false for tasks that are not on - * Display.DEFAULT_DISPLAY. */ - boolean mOnTopOfHome = false; + /** Indication of what to run next when task exits. Use ActivityRecord types. + * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the + * task stack. */ + private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE; - TaskRecord(int _taskId, ActivityInfo info, Intent _intent, + final ActivityManagerService mService; + + TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent, IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) { + mService = service; taskId = _taskId; affinity = info.taskAffinity; voiceSession = _voiceSession; voiceInteractor = _voiceInteractor; setIntent(_intent, info); + mActivities = new ArrayList<ActivityRecord>(); + } + + TaskRecord(ActivityManagerService service, int _taskId, Intent _intent, Intent _affinityIntent, + String _affinity, ComponentName _realActivity, ComponentName _origActivity, + boolean _rootWasReset, boolean _askedCompatMode, int _taskType, int _userId, + String _lastDescription, ArrayList<ActivityRecord> activities, long lastTimeMoved) { + mService = service; + taskId = _taskId; + intent = _intent; + affinityIntent = _affinityIntent; + affinity = _affinity; + voiceSession = null; + voiceInteractor = null; + realActivity = _realActivity; + origActivity = _origActivity; + rootWasReset = _rootWasReset; + askedCompatMode = _askedCompatMode; + taskType = _taskType; + mTaskToReturnTo = HOME_ACTIVITY_TYPE; + userId = _userId; + lastDescription = _lastDescription; + mActivities = activities; + mLastTimeMoved = lastTimeMoved; } void touchActiveTime() { @@ -144,6 +209,14 @@ final class TaskRecord extends ThumbnailHolder { } } + void setTaskToReturnTo(int taskToReturnTo) { + mTaskToReturnTo = taskToReturnTo; + } + + int getTaskToReturnTo() { + return mTaskToReturnTo; + } + void disposeThumbnail() { super.disposeThumbnail(); for (int i=mActivities.size()-1; i>=0; i--) { @@ -237,12 +310,16 @@ final class TaskRecord extends ThumbnailHolder { } // Only set this based on the first activity if (mActivities.isEmpty()) { - mTaskType = r.mActivityType; + taskType = r.mActivityType; + isPersistable = r.isPersistable(); } else { // Otherwise make all added activities match this one. - r.mActivityType = mTaskType; + r.mActivityType = taskType; } mActivities.add(index, r); + if (r.isPersistable()) { + mService.notifyTaskPersisterLocked(this, false); + } } /** @return true if this was the last activity in the task */ @@ -251,6 +328,9 @@ final class TaskRecord extends ThumbnailHolder { // Was previously in list. numFullscreen--; } + if (r.isPersistable()) { + mService.notifyTaskPersisterLocked(this, false); + } return mActivities.size() == 0; } @@ -270,7 +350,14 @@ final class TaskRecord extends ThumbnailHolder { if (r.finishing) { continue; } - if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear", false)) { + if (stack == null) { + // Task was restored from persistent storage. + r.takeFromHistory(); + mActivities.remove(activityNdx); + --activityNdx; + --numActivities; + } else if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear", + false)) { --activityNdx; --numActivities; } @@ -354,11 +441,13 @@ final class TaskRecord extends ThumbnailHolder { } public Bitmap getTaskTopThumbnailLocked() { - final ActivityRecord resumedActivity = stack.mResumedActivity; - if (resumedActivity != null && resumedActivity.task == this) { - // This task is the current resumed task, we just need to take - // a screenshot of it and return that. - return stack.screenshotActivities(resumedActivity); + if (stack != null) { + final ActivityRecord resumedActivity = stack.mResumedActivity; + if (resumedActivity != null && resumedActivity.task == this) { + // This task is the current resumed task, we just need to take + // a screenshot of it and return that. + return stack.screenshotActivities(resumedActivity); + } } // Return the information about the task, to figure out the top // thumbnail to return. @@ -399,11 +488,15 @@ final class TaskRecord extends ThumbnailHolder { } boolean isHomeTask() { - return mTaskType == ActivityRecord.HOME_ACTIVITY_TYPE; + return taskType == HOME_ACTIVITY_TYPE; } boolean isApplicationTask() { - return mTaskType == ActivityRecord.APPLICATION_ACTIVITY_TYPE; + return taskType == APPLICATION_ACTIVITY_TYPE; + } + + boolean isOverHomeStack() { + return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE; } public TaskAccessInfo getTaskAccessInfoLocked() { @@ -493,7 +586,7 @@ final class TaskRecord extends ThumbnailHolder { int activityNdx; final int numActivities = mActivities.size(); for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; - ++activityNdx) { + ++activityNdx) { final ActivityRecord r = mActivities.get(activityNdx); if (r.intent != null && (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) @@ -528,14 +621,152 @@ final class TaskRecord extends ThumbnailHolder { } } + void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException { + Slog.i(TAG, "Saving task=" + this); + + out.attribute(null, ATTR_TASKID, String.valueOf(taskId)); + if (realActivity != null) { + out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString()); + } + if (origActivity != null) { + out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString()); + } + if (affinity != null) { + out.attribute(null, ATTR_AFFINITY, affinity); + } + out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset)); + out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode)); + out.attribute(null, ATTR_USERID, String.valueOf(userId)); + out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType)); + out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved)); + if (lastDescription != null) { + out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString()); + } + + if (affinityIntent != null) { + out.startTag(null, TAG_AFFINITYINTENT); + affinityIntent.saveToXml(out); + out.endTag(null, TAG_AFFINITYINTENT); + } + + out.startTag(null, TAG_INTENT); + intent.saveToXml(out); + out.endTag(null, TAG_INTENT); + + final ArrayList<ActivityRecord> activities = mActivities; + final int numActivities = activities.size(); + for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) { + final ActivityRecord r = activities.get(activityNdx); + if (!r.isPersistable() || (r.intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == + Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) { + break; + } + out.startTag(null, TAG_ACTIVITY); + r.saveToXml(out); + out.endTag(null, TAG_ACTIVITY); + } + + final Bitmap thumbnail = getTaskTopThumbnailLocked(); + if (thumbnail != null) { + TaskPersister.saveImage(thumbnail, String.valueOf(taskId) + TASK_THUMBNAIL_SUFFIX); + } + } + + static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor) + throws IOException, XmlPullParserException { + Intent intent = null; + Intent affinityIntent = null; + ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); + ComponentName realActivity = null; + ComponentName origActivity = null; + String affinity = null; + boolean rootHasReset = false; + boolean askedCompatMode = false; + int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE; + int userId = 0; + String lastDescription = null; + long lastTimeOnTop = 0; + int taskId = -1; + final int outerDepth = in.getDepth(); + + for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) { + final String attrName = in.getAttributeName(attrNdx); + final String attrValue = in.getAttributeValue(attrNdx); + if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: attribute name=" + + attrName + " value=" + attrValue); + if (ATTR_TASKID.equals(attrName)) { + taskId = Integer.valueOf(attrValue); + } else if (ATTR_REALACTIVITY.equals(attrName)) { + realActivity = ComponentName.unflattenFromString(attrValue); + } else if (ATTR_ORIGACTIVITY.equals(attrName)) { + origActivity = ComponentName.unflattenFromString(attrValue); + } else if (ATTR_AFFINITY.equals(attrName)) { + affinity = attrValue; + } else if (ATTR_ROOTHASRESET.equals(attrName)) { + rootHasReset = Boolean.valueOf(attrValue); + } else if (ATTR_ASKEDCOMPATMODE.equals(attrName)) { + askedCompatMode = Boolean.valueOf(attrValue); + } else if (ATTR_USERID.equals(attrName)) { + userId = Integer.valueOf(attrValue); + } else if (ATTR_TASKTYPE.equals(attrName)) { + taskType = Integer.valueOf(attrValue); + } else if (ATTR_LASTDESCRIPTION.equals(attrName)) { + lastDescription = attrValue; + } else if (ATTR_LASTTIMEMOVED.equals(attrName)) { + lastTimeOnTop = Long.valueOf(attrValue); + } else { + Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName); + } + } + + int event; + while (((event = in.next()) != XmlPullParser.END_DOCUMENT) && + (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) { + if (event == XmlPullParser.START_TAG) { + final String name = in.getName(); + if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: START_TAG name=" + + name); + if (TAG_AFFINITYINTENT.equals(name)) { + affinityIntent = Intent.restoreFromXml(in); + } else if (TAG_INTENT.equals(name)) { + intent = Intent.restoreFromXml(in); + } else if (TAG_ACTIVITY.equals(name)) { + ActivityRecord activity = + ActivityRecord.restoreFromXml(in, taskId, stackSupervisor); + if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG, "TaskRecord: activity=" + + activity); + if (activity != null) { + activities.add(activity); + } + } else { + Slog.e(TAG, "restoreTask: Unexpected name=" + name); + XmlUtils.skipCurrentTag(in); + } + } + } + + final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent, + affinityIntent, affinity, realActivity, origActivity, rootHasReset, + askedCompatMode, taskType, userId, lastDescription, activities, lastTimeOnTop); + + for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) { + final ActivityRecord r = activities.get(activityNdx); + r.thumbHolder = r.task = task; + } + + task.lastThumbnail = TaskPersister.restoreImage(taskId + TASK_THUMBNAIL_SUFFIX); + + Slog.i(TAG, "Restored task=" + task); + return task; + } + void dump(PrintWriter pw, String prefix) { - if (numActivities != 0 || rootWasReset || userId != 0 || numFullscreen != 0) { - pw.print(prefix); pw.print("numActivities="); pw.print(numActivities); - pw.print(" rootWasReset="); pw.print(rootWasReset); + if (rootWasReset || userId != 0 || numFullscreen != 0) { + pw.print(prefix); pw.print(" rootWasReset="); pw.print(rootWasReset); pw.print(" userId="); pw.print(userId); - pw.print(" mTaskType="); pw.print(mTaskType); + pw.print(" taskType="); pw.print(taskType); pw.print(" numFullscreen="); pw.print(numFullscreen); - pw.print(" mOnTopOfHome="); pw.println(mOnTopOfHome); + pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo); } if (affinity != null) { pw.print(prefix); pw.print("affinity="); pw.println(affinity); diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java index d81a25e..66cc532 100644 --- a/services/core/java/com/android/server/notification/NotificationUsageStats.java +++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java @@ -46,12 +46,14 @@ import java.util.Map; * {@hide} */ public class NotificationUsageStats { + private static final boolean ENABLE_SQLITE_LOG = false; + // Guarded by synchronized(this). private final Map<String, AggregatedStats> mStats = new HashMap<String, AggregatedStats>(); private final SQLiteLog mSQLiteLog; public NotificationUsageStats(Context context) { - mSQLiteLog = new SQLiteLog(context); + mSQLiteLog = ENABLE_SQLITE_LOG ? new SQLiteLog(context) : null; } /** @@ -63,7 +65,9 @@ public class NotificationUsageStats { for (AggregatedStats stats : getAggregatedStatsLocked(notification)) { stats.numPostedByApp++; } - mSQLiteLog.logPosted(notification); + if (ENABLE_SQLITE_LOG) { + mSQLiteLog.logPosted(notification); + } } /** @@ -85,7 +89,9 @@ public class NotificationUsageStats { stats.numRemovedByApp++; stats.collect(notification.stats); } - mSQLiteLog.logRemoved(notification); + if (ENABLE_SQLITE_LOG) { + mSQLiteLog.logRemoved(notification); + } } /** @@ -97,7 +103,9 @@ public class NotificationUsageStats { stats.numDismissedByUser++; stats.collect(notification.stats); } - mSQLiteLog.logDismissed(notification); + if (ENABLE_SQLITE_LOG) { + mSQLiteLog.logDismissed(notification); + } } /** @@ -108,7 +116,9 @@ public class NotificationUsageStats { for (AggregatedStats stats : getAggregatedStatsLocked(notification)) { stats.numClickedByUser++; } - mSQLiteLog.logClicked(notification); + if (ENABLE_SQLITE_LOG) { + mSQLiteLog.logClicked(notification); + } } /** @@ -164,7 +174,9 @@ public class NotificationUsageStats { for (AggregatedStats as : mStats.values()) { as.dump(pw, indent); } - mSQLiteLog.dump(pw, indent); + if (ENABLE_SQLITE_LOG) { + mSQLiteLog.dump(pw, indent); + } } /** diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java index 157d749..a629a5f 100644 --- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java +++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java @@ -139,56 +139,64 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor { } private String[] getExtraPeople(Bundle extras) { - String[] people = extras.getStringArray(Notification.EXTRA_PEOPLE); - if (people != null) { - return people; + Object people = extras.get(Notification.EXTRA_PEOPLE); + if (people instanceof String[]) { + return (String[]) people; } - ArrayList<String> stringArray = extras.getStringArrayList(Notification.EXTRA_PEOPLE); - if (stringArray != null) { - return (String[]) stringArray.toArray(); + if (people instanceof ArrayList) { + ArrayList arrayList = (ArrayList) people; + + if (arrayList.isEmpty()) { + return null; + } + + if (arrayList.get(0) instanceof String) { + ArrayList<String> stringArray = (ArrayList<String>) arrayList; + return stringArray.toArray(new String[stringArray.size()]); + } + + if (arrayList.get(0) instanceof CharSequence) { + ArrayList<CharSequence> charSeqList = (ArrayList<CharSequence>) arrayList; + final int N = charSeqList.size(); + String[] array = new String[N]; + for (int i = 0; i < N; i++) { + array[i] = charSeqList.get(i).toString(); + } + return array; + } + + return null; } - String string = extras.getString(Notification.EXTRA_PEOPLE); - if (string != null) { - people = new String[1]; - people[0] = string; - return people; + if (people instanceof String) { + String[] array = new String[1]; + array[0] = (String) people; + return array; } - char[] charArray = extras.getCharArray(Notification.EXTRA_PEOPLE); - if (charArray != null) { - people = new String[1]; - people[0] = new String(charArray); - return people; + + if (people instanceof char[]) { + String[] array = new String[1]; + array[0] = new String((char[]) people); + return array; } - CharSequence charSeq = extras.getCharSequence(Notification.EXTRA_PEOPLE); - if (charSeq != null) { - people = new String[1]; - people[0] = charSeq.toString(); - return people; + if (people instanceof CharSequence) { + String[] array = new String[1]; + array[0] = ((CharSequence) people).toString(); + return array; } - CharSequence[] charSeqArray = extras.getCharSequenceArray(Notification.EXTRA_PEOPLE); - if (charSeqArray != null) { + if (people instanceof CharSequence[]) { + CharSequence[] charSeqArray = (CharSequence[]) people; final int N = charSeqArray.length; - people = new String[N]; + String[] array = new String[N]; for (int i = 0; i < N; i++) { - people[i] = charSeqArray[i].toString(); + array[i] = charSeqArray[i].toString(); } - return people; + return array; } - ArrayList<CharSequence> charSeqList = - extras.getCharSequenceArrayList(Notification.EXTRA_PEOPLE); - if (charSeqList != null) { - final int N = charSeqList.size(); - people = new String[N]; - for (int i = 0; i < N; i++) { - people[i] = charSeqList.get(i).toString(); - } - return people; - } return null; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 0fa0b14..b06b090 100755 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -6140,7 +6140,12 @@ public class PackageManagerService extends IPackageManager.Stub { } final String nativeLibraryPath = (new File(libDir, apkName)).getPath(); pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath; - pkgSetting.nativeLibraryPathString = nativeLibraryPath; + // pkgSetting might be null during rescan following uninstall of updates + // to a bundled app, so accommodate that possibility. The settings in + // that case will be established later from the parsed package. + if (pkgSetting != null) { + pkgSetting.nativeLibraryPathString = nativeLibraryPath; + } } // Deduces the required ABI of an upgraded system app. diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java index 47ce3b6..f18939f 100644 --- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java +++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java @@ -63,6 +63,11 @@ public class TrustAgentWrapper { public void handleMessage(Message msg) { switch (msg.what) { case MSG_GRANT_TRUST: + if (!isConnected()) { + Log.w(TAG, "Agent is not connected, cannot grant trust: " + + mName.flattenToShortString()); + return; + } mTrusted = true; mMessage = (CharSequence) msg.obj; boolean initiatedByUser = msg.arg1 != 0; @@ -119,6 +124,7 @@ public class TrustAgentWrapper { public void onServiceConnected(ComponentName name, IBinder service) { if (DEBUG) Log.v(TAG, "TrustAgent started : " + name.flattenToString()); mTrustAgentService = ITrustAgentService.Stub.asInterface(service); + mTrustManagerService.mArchive.logAgentConnected(mUserId, name); setCallback(mCallback); } @@ -179,7 +185,10 @@ public class TrustAgentWrapper { public void unbind() { if (DEBUG) Log.v(TAG, "TrustAgent unbound : " + mName.flattenToShortString()); + mTrustManagerService.mArchive.logAgentStopped(mUserId, mName); mContext.unbindService(mConnection); + mTrustAgentService = null; + mHandler.sendEmptyMessage(MSG_REVOKE_TRUST); } public boolean isConnected() { diff --git a/services/core/java/com/android/server/trust/TrustArchive.java b/services/core/java/com/android/server/trust/TrustArchive.java index aad156c..56950d2 100644 --- a/services/core/java/com/android/server/trust/TrustArchive.java +++ b/services/core/java/com/android/server/trust/TrustArchive.java @@ -33,6 +33,8 @@ public class TrustArchive { private static final int TYPE_REVOKE_TRUST = 1; private static final int TYPE_TRUST_TIMEOUT = 2; private static final int TYPE_AGENT_DIED = 3; + private static final int TYPE_AGENT_CONNECTED = 4; + private static final int TYPE_AGENT_STOPPED = 5; private static final int HISTORY_LIMIT = 200; @@ -79,6 +81,14 @@ public class TrustArchive { addEvent(new Event(TYPE_AGENT_DIED, userId, agent, null, 0, false)); } + public void logAgentConnected(int userId, ComponentName agent) { + addEvent(new Event(TYPE_AGENT_CONNECTED, userId, agent, null, 0, false)); + } + + public void logAgentStopped(int userId, ComponentName agent) { + addEvent(new Event(TYPE_AGENT_STOPPED, userId, agent, null, 0, false)); + } + private void addEvent(Event e) { if (mEvents.size() >= HISTORY_LIMIT) { mEvents.removeFirst(); @@ -152,6 +162,10 @@ public class TrustArchive { return "TrustTimeout"; case TYPE_AGENT_DIED: return "AgentDied"; + case TYPE_AGENT_CONNECTED: + return "AgentConnected"; + case TYPE_AGENT_STOPPED: + return "AgentStopped"; default: return "Unknown(" + type + ")"; } diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java new file mode 100644 index 0000000..4bdd2be --- /dev/null +++ b/services/core/java/com/android/server/tv/TvInputHal.java @@ -0,0 +1,128 @@ +/* + * Copyright 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. + */ + +package com.android.server.tv; + +import android.os.Handler; +import android.os.HandlerThread; +import android.tv.TvInputHardwareInfo; +import android.tv.TvStreamConfig; +import android.view.Surface; + +/** + * Provides access to the low-level TV input hardware abstraction layer. + */ +final class TvInputHal { + public final static int SUCCESS = 0; + public final static int ERROR_NO_INIT = -1; + public final static int ERROR_STALE_CONFIG = -2; + public final static int ERROR_UNKNOWN = -3; + + public static final int TYPE_HDMI = 1; + public static final int TYPE_BUILT_IN_TUNER = 2; + public static final int TYPE_PASSTHROUGH = 3; + + public interface Callback { + public void onDeviceAvailable( + TvInputHardwareInfo info, TvStreamConfig[] configs); + public void onDeviceUnavailable(int deviceId); + public void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs); + } + + private native long nativeOpen(); + + private static native int nativeSetSurface(long ptr, int deviceId, int streamId, + Surface surface); + private static native TvStreamConfig[] nativeGetStreamConfigs(long ptr, int deviceId, + int generation); + private static native void nativeClose(long ptr); + + private long mPtr = 0l; + private final Callback mCallback; + private final HandlerThread mThread = new HandlerThread("TV input HAL event thread"); + private final Handler mHandler; + private int mStreamConfigGeneration = 0; + private TvStreamConfig[] mStreamConfigs; + + public TvInputHal(Callback callback) { + mCallback = callback; + mThread.start(); + mHandler = new Handler(mThread.getLooper()); + } + + public void init() { + mPtr = nativeOpen(); + } + + public int setSurface(int deviceId, Surface surface, TvStreamConfig streamConfig) { + if (mPtr == 0) { + return ERROR_NO_INIT; + } + if (mStreamConfigGeneration != streamConfig.getGeneration()) { + return ERROR_STALE_CONFIG; + } + if (nativeSetSurface(mPtr, deviceId, streamConfig.getStreamId(), surface) == 0) { + return SUCCESS; + } else { + return ERROR_UNKNOWN; + } + } + + public void close() { + if (mPtr != 0l) { + nativeClose(mPtr); + mThread.quitSafely(); + } + } + + private synchronized void retrieveStreamConfigs(int deviceId) { + ++mStreamConfigGeneration; + mStreamConfigs = nativeGetStreamConfigs(mPtr, deviceId, mStreamConfigGeneration); + } + + // Called from native + private void deviceAvailableFromNative(int deviceId, int type) { + final TvInputHardwareInfo info = new TvInputHardwareInfo(deviceId, type); + mHandler.post(new Runnable() { + @Override + public void run() { + retrieveStreamConfigs(info.getDeviceId()); + mCallback.onDeviceAvailable(info, mStreamConfigs); + } + }); + } + + private void deviceUnavailableFromNative(int deviceId) { + final int id = deviceId; + mHandler.post(new Runnable() { + @Override + public void run() { + mCallback.onDeviceUnavailable(id); + } + }); + } + + private void streamConfigsChangedFromNative(int deviceId) { + final int id = deviceId; + mHandler.post(new Runnable() { + @Override + public void run() { + retrieveStreamConfigs(id); + mCallback.onStreamConfigurationChanged(id, mStreamConfigs); + } + }); + } +} diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java new file mode 100644 index 0000000..b95b0f0 --- /dev/null +++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java @@ -0,0 +1,308 @@ +/* + * 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. + */ + +package com.android.server.tv; + +import android.content.Context; +import android.os.IBinder; +import android.os.RemoteException; +import android.tv.ITvInputHardware; +import android.tv.ITvInputHardwareCallback; +import android.tv.TvInputHardwareInfo; +import android.tv.TvStreamConfig; +import android.util.Slog; +import android.util.SparseArray; +import android.view.KeyEvent; +import android.view.Surface; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * A helper class for TvInputManagerService to handle TV input hardware. + * + * This class does a basic connection management and forwarding calls to TvInputHal which eventually + * calls to tv_input HAL module. + * + * @hide + */ +class TvInputHardwareManager implements TvInputHal.Callback { + private static final String TAG = TvInputHardwareManager.class.getSimpleName(); + private final TvInputHal mHal = new TvInputHal(this); + private final SparseArray<Connection> mConnections = new SparseArray<Connection>(); + private final List<TvInputHardwareInfo> mInfoList = new ArrayList<TvInputHardwareInfo>(); + private final Context mContext; + private final Set<Integer> mActiveHdmiSources = new HashSet<Integer>(); + + private final Object mLock = new Object(); + + public TvInputHardwareManager(Context context) { + mContext = context; + // TODO(hdmi): mHdmiManager = mContext.getSystemService(...); + // TODO(hdmi): mHdmiClient = mHdmiManager.getTvClient(); + mHal.init(); + } + + @Override + public void onDeviceAvailable( + TvInputHardwareInfo info, TvStreamConfig[] configs) { + synchronized (mLock) { + Connection connection = new Connection(info); + connection.updateConfigsLocked(configs); + mConnections.put(info.getDeviceId(), connection); + buildInfoListLocked(); + // TODO: notify if necessary + } + } + + private void buildInfoListLocked() { + mInfoList.clear(); + for (int i = 0; i < mConnections.size(); ++i) { + mInfoList.add(mConnections.valueAt(i).getInfoLocked()); + } + } + + @Override + public void onDeviceUnavailable(int deviceId) { + synchronized (mLock) { + Connection connection = mConnections.get(deviceId); + if (connection == null) { + Slog.e(TAG, "onDeviceUnavailable: Cannot find a connection with " + deviceId); + return; + } + connection.resetLocked(null, null, null, null); + mConnections.remove(deviceId); + buildInfoListLocked(); + // TODO: notify if necessary + } + } + + @Override + public void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs) { + synchronized (mLock) { + Connection connection = mConnections.get(deviceId); + if (connection == null) { + Slog.e(TAG, "StreamConfigurationChanged: Cannot find a connection with " + + deviceId); + return; + } + connection.updateConfigsLocked(configs); + try { + connection.getCallbackLocked().onStreamConfigChanged(configs); + } catch (RemoteException e) { + Slog.e(TAG, "onStreamConfigurationChanged: " + e); + } + } + } + + public List<TvInputHardwareInfo> getHardwareList() { + synchronized (mLock) { + return mInfoList; + } + } + + /** + * Create a TvInputHardware object with a specific deviceId. One service at a time can access + * the object, and if more than one process attempts to create hardware with the same deviceId, + * the latest service will get the object and all the other hardware are released. The + * release is notified via ITvInputHardwareCallback.onReleased(). + */ + public ITvInputHardware acquireHardware(int deviceId, ITvInputHardwareCallback callback, + int callingUid, int resolvedUserId) { + if (callback == null) { + throw new NullPointerException(); + } + synchronized (mLock) { + Connection connection = mConnections.get(deviceId); + if (connection == null) { + Slog.e(TAG, "Invalid deviceId : " + deviceId); + return null; + } + if (connection.getCallingUidLocked() != callingUid + || connection.getResolvedUserIdLocked() != resolvedUserId) { + TvInputHardwareImpl hardware = new TvInputHardwareImpl(connection.getInfoLocked()); + try { + callback.asBinder().linkToDeath(connection, 0); + } catch (RemoteException e) { + hardware.release(); + return null; + } + connection.resetLocked(hardware, callback, callingUid, resolvedUserId); + } + return connection.getHardwareLocked(); + } + } + + /** + * Release the specified hardware. + */ + public void releaseHardware(int deviceId, ITvInputHardware hardware, int callingUid, + int resolvedUserId) { + synchronized (mLock) { + Connection connection = mConnections.get(deviceId); + if (connection == null) { + Slog.e(TAG, "Invalid deviceId : " + deviceId); + return; + } + if (connection.getHardwareLocked() != hardware + || connection.getCallingUidLocked() != callingUid + || connection.getResolvedUserIdLocked() != resolvedUserId) { + return; + } + connection.resetLocked(null, null, null, null); + } + } + + private class Connection implements IBinder.DeathRecipient { + private final TvInputHardwareInfo mInfo; + private TvInputHardwareImpl mHardware = null; + private ITvInputHardwareCallback mCallback; + private TvStreamConfig[] mConfigs = null; + private Integer mCallingUid = null; + private Integer mResolvedUserId = null; + + public Connection(TvInputHardwareInfo info) { + mInfo = info; + } + + // *Locked methods assume TvInputHardwareManager.mLock is held. + + public void resetLocked(TvInputHardwareImpl hardware, + ITvInputHardwareCallback callback, Integer callingUid, Integer resolvedUserId) { + if (mHardware != null) { + try { + mCallback.onReleased(); + } catch (RemoteException e) { + Slog.e(TAG, "Connection::resetHardware: " + e); + } + mHardware.release(); + } + mHardware = hardware; + mCallback = callback; + mCallingUid = callingUid; + mResolvedUserId = resolvedUserId; + + if (mHardware != null && mCallback != null) { + try { + mCallback.onStreamConfigChanged(getConfigsLocked()); + } catch (RemoteException e) { + Slog.e(TAG, "Connection::resetHardware: " + e); + } + } + } + + public void updateConfigsLocked(TvStreamConfig[] configs) { + mConfigs = configs; + } + + public TvInputHardwareInfo getInfoLocked() { + return mInfo; + } + + public ITvInputHardware getHardwareLocked() { + return mHardware; + } + + public ITvInputHardwareCallback getCallbackLocked() { + return mCallback; + } + + public TvStreamConfig[] getConfigsLocked() { + return mConfigs; + } + + public int getCallingUidLocked() { + return mCallingUid; + } + + public int getResolvedUserIdLocked() { + return mResolvedUserId; + } + + @Override + public void binderDied() { + synchronized (mLock) { + resetLocked(null, null, null, null); + } + } + } + + private class TvInputHardwareImpl extends ITvInputHardware.Stub { + private final TvInputHardwareInfo mInfo; + private boolean mReleased = false; + private final Object mImplLock = new Object(); + + public TvInputHardwareImpl(TvInputHardwareInfo info) { + mInfo = info; + } + + public void release() { + synchronized (mImplLock) { + mReleased = true; + } + } + + @Override + public boolean setSurface(Surface surface, TvStreamConfig config) + throws RemoteException { + synchronized (mImplLock) { + if (mReleased) { + throw new IllegalStateException("Device already released."); + } + if (mInfo.getType() == TvInputHal.TYPE_HDMI) { + if (surface != null) { + // Set "Active Source" for HDMI. + // TODO(hdmi): mHdmiClient.deviceSelect(...); + mActiveHdmiSources.add(mInfo.getDeviceId()); + } else { + mActiveHdmiSources.remove(mInfo.getDeviceId()); + if (mActiveHdmiSources.size() == 0) { + // Tell HDMI that no HDMI source is active + // TODO(hdmi): mHdmiClient.portSelect(null); + } + } + } + return mHal.setSurface(mInfo.getDeviceId(), surface, config) == TvInputHal.SUCCESS; + } + } + + @Override + public void setVolume(float volume) throws RemoteException { + synchronized (mImplLock) { + if (mReleased) { + throw new IllegalStateException("Device already released."); + } + } + // TODO + } + + @Override + public boolean dispatchKeyEventToHdmi(KeyEvent event) throws RemoteException { + synchronized (mImplLock) { + if (mReleased) { + throw new IllegalStateException("Device already released."); + } + } + if (mInfo.getType() != TvInputHal.TYPE_HDMI) { + return false; + } + // TODO(hdmi): mHdmiClient.sendKeyEvent(event); + return false; + } + } +} diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 8ad7fff..6c38a4c 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -42,11 +42,14 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.TvContract; import android.tv.ITvInputClient; +import android.tv.ITvInputHardware; +import android.tv.ITvInputHardwareCallback; import android.tv.ITvInputManager; import android.tv.ITvInputService; import android.tv.ITvInputServiceCallback; import android.tv.ITvInputSession; import android.tv.ITvInputSessionCallback; +import android.tv.TvInputHardwareInfo; import android.tv.TvInputInfo; import android.tv.TvInputService; import android.util.Slog; @@ -71,6 +74,7 @@ public final class TvInputManagerService extends SystemService { private static final String TAG = "TvInputManagerService"; private final Context mContext; + private final TvInputHardwareManager mTvInputHardwareManager; private final ContentResolver mContentResolver; @@ -92,6 +96,7 @@ public final class TvInputManagerService extends SystemService { mContentResolver = context.getContentResolver(); mLogHandler = new LogHandler(IoThread.get().getLooper()); + mTvInputHardwareManager = new TvInputHardwareManager(context); registerBroadcastReceivers(); synchronized (mLock) { @@ -730,6 +735,64 @@ public final class TvInputManagerService extends SystemService { Binder.restoreCallingIdentity(identity); } } + + @Override + public List<TvInputHardwareInfo> getHardwareList() throws RemoteException { + if (mContext.checkCallingPermission( + android.Manifest.permission.TV_INPUT_HARDWARE) + != PackageManager.PERMISSION_GRANTED) { + return null; + } + + final long identity = Binder.clearCallingIdentity(); + try { + return mTvInputHardwareManager.getHardwareList(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public ITvInputHardware acquireTvInputHardware(int deviceId, + ITvInputHardwareCallback callback, int userId) throws RemoteException { + if (mContext.checkCallingPermission( + android.Manifest.permission.TV_INPUT_HARDWARE) + != PackageManager.PERMISSION_GRANTED) { + return null; + } + + final long identity = Binder.clearCallingIdentity(); + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "acquireTvInputHardware"); + try { + return mTvInputHardwareManager.acquireHardware( + deviceId, callback, callingUid, resolvedUserId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void releaseTvInputHardware(int deviceId, ITvInputHardware hardware, int userId) + throws RemoteException { + if (mContext.checkCallingPermission( + android.Manifest.permission.TV_INPUT_HARDWARE) + != PackageManager.PERMISSION_GRANTED) { + return; + } + + final long identity = Binder.clearCallingIdentity(); + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "releaseTvInputHardware"); + try { + mTvInputHardwareManager.releaseHardware( + deviceId, hardware, callingUid, resolvedUserId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } } private static final class UserState { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 1a0dd82..c23d1ea 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3189,6 +3189,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState win = atoken.findMainWindow(); Rect containingFrame = new Rect(0, 0, width, height); Rect contentInsets = new Rect(); + boolean isFullScreen = true; if (win != null) { if (win.mContainingFrame != null) { containingFrame.set(win.mContainingFrame); @@ -3196,11 +3197,11 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mContentInsets != null) { contentInsets.set(win.mContentInsets); } + isFullScreen = + ((win.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) == + SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN); } - boolean isFullScreen = - ((win.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) - == SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN); Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height, mCurConfiguration.orientation, containingFrame, contentInsets, isFullScreen); if (a != null) { @@ -10265,6 +10266,10 @@ public class WindowManagerService extends IWindowManager.Stub mPolicy.lockNow(options); } + public void showRecentApps() { + mPolicy.showRecentApps(); + } + @Override public boolean isSafeModeEnabled() { return mSafeMode; diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk index 51583a5..3cfb45b 100644 --- a/services/core/jni/Android.mk +++ b/services/core/jni/Android.mk @@ -23,6 +23,7 @@ LOCAL_SRC_FILES += \ $(LOCAL_REL_DIR)/com_android_server_power_PowerManagerService.cpp \ $(LOCAL_REL_DIR)/com_android_server_SerialService.cpp \ $(LOCAL_REL_DIR)/com_android_server_SystemServer.cpp \ + $(LOCAL_REL_DIR)/com_android_server_tv_TvInputHal.cpp \ $(LOCAL_REL_DIR)/com_android_server_UsbDeviceManager.cpp \ $(LOCAL_REL_DIR)/com_android_server_UsbHostManager.cpp \ $(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \ diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp new file mode 100644 index 0000000..f0c4f3a --- /dev/null +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -0,0 +1,388 @@ +/* + * Copyright 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. + */ + +#define LOG_TAG "TvInputHal" + +//#define LOG_NDEBUG 0 + +#include "android_runtime/AndroidRuntime.h" +#include "android_runtime/android_view_Surface.h" +#include "JNIHelp.h" +#include "jni.h" + +#include <gui/Surface.h> +#include <utils/Errors.h> +#include <utils/KeyedVector.h> +#include <utils/Log.h> +#include <utils/NativeHandle.h> +#include <hardware/tv_input.h> + +namespace android { + +static struct { + jmethodID deviceAvailable; + jmethodID deviceUnavailable; + jmethodID streamConfigsChanged; +} gTvInputHalClassInfo; + +static struct { + jclass clazz; +} gTvStreamConfigClassInfo; + +static struct { + jclass clazz; + + jmethodID constructor; + jmethodID streamId; + jmethodID type; + jmethodID maxWidth; + jmethodID maxHeight; + jmethodID generation; + jmethodID build; +} gTvStreamConfigBuilderClassInfo; + +//////////////////////////////////////////////////////////////////////////////// + +class JTvInputHal { +public: + ~JTvInputHal(); + + static JTvInputHal* createInstance(JNIEnv* env, jobject thiz); + + int setSurface(int deviceId, int streamId, const sp<Surface>& surface); + void getStreamConfigs(int deviceId, jobjectArray* array); + const tv_stream_config_t* getStreamConfigs(int deviceId, int* numConfigs); + +private: + class Connection { + public: + Connection() : mStreamId(0) {} + + sp<Surface> mSurface; + sp<NativeHandle> mSourceHandle; + int mStreamId; + }; + + JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* dev); + + static void notify( + tv_input_device_t* dev,tv_input_event_t* event, void* data); + + void onDeviceAvailable(const tv_input_device_info_t& info); + void onDeviceUnavailable(int deviceId); + void onStreamConfigurationsChanged(int deviceId); + + jweak mThiz; + tv_input_device_t* mDevice; + tv_input_callback_ops_t mCallback; + + KeyedVector<int, Connection> mConnections; +}; + +JTvInputHal::JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* device) { + mThiz = env->NewWeakGlobalRef(thiz); + mDevice = device; + mCallback.notify = &JTvInputHal::notify; + + mDevice->initialize(mDevice, &mCallback, this); +} + +JTvInputHal::~JTvInputHal() { + mDevice->common.close((hw_device_t*)mDevice); + + JNIEnv* env = AndroidRuntime::getJNIEnv(); + env->DeleteWeakGlobalRef(mThiz); + mThiz = NULL; +} + +JTvInputHal* JTvInputHal::createInstance(JNIEnv* env, jobject thiz) { + tv_input_module_t* module = NULL; + status_t err = hw_get_module(TV_INPUT_HARDWARE_MODULE_ID, + (hw_module_t const**)&module); + if (err) { + ALOGE("Couldn't load %s module (%s)", + TV_INPUT_HARDWARE_MODULE_ID, strerror(-err)); + return 0; + } + + tv_input_device_t* device = NULL; + err = module->common.methods->open( + (hw_module_t*)module, + TV_INPUT_DEFAULT_DEVICE, + (hw_device_t**)&device); + if (err) { + ALOGE("Couldn't open %s device (%s)", + TV_INPUT_DEFAULT_DEVICE, strerror(-err)); + return 0; + } + + return new JTvInputHal(env, thiz, device); +} + +int JTvInputHal::setSurface(int deviceId, int streamId, const sp<Surface>& surface) { + Connection& connection = mConnections.editValueFor(deviceId); + if (connection.mStreamId == streamId && connection.mSurface == surface) { + // Nothing to do + return NO_ERROR; + } + if (Surface::isValid(connection.mSurface)) { + connection.mSurface.clear(); + } + if (surface == NULL) { + if (connection.mSurface != NULL) { + connection.mSurface->setSidebandStream(NULL); + connection.mSurface.clear(); + } + if (connection.mSourceHandle != NULL) { + // Need to reset streams + if (mDevice->close_stream( + mDevice, deviceId, connection.mStreamId) != 0) { + ALOGE("Couldn't remove stream"); + return BAD_VALUE; + } + connection.mSourceHandle.clear(); + } + return NO_ERROR; + } + connection.mSurface = surface; + if (connection.mSourceHandle == NULL) { + // Need to configure stream + int numConfigs = 0; + const tv_stream_config_t* configs = NULL; + if (mDevice->get_stream_configurations( + mDevice, deviceId, &numConfigs, &configs) != 0) { + ALOGE("Couldn't get stream configs"); + return UNKNOWN_ERROR; + } + int configIndex = -1; + for (int i = 0; i < numConfigs; ++i) { + if (configs[i].stream_id == streamId) { + configIndex = i; + break; + } + } + if (configIndex == -1) { + ALOGE("Cannot find a config with given stream ID: %d", streamId); + return BAD_VALUE; + } + // TODO: handle buffer producer profile. + if (configs[configIndex].type != + TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE) { + ALOGE("Profiles other than independent video source is not yet " + "supported : type = %d", configs[configIndex].type); + return INVALID_OPERATION; + } + tv_stream_t stream; + stream.stream_id = configs[configIndex].stream_id; + if (mDevice->open_stream(mDevice, deviceId, &stream) != 0) { + ALOGE("Couldn't add stream"); + return UNKNOWN_ERROR; + } + connection.mSourceHandle = NativeHandle::create( + stream.sideband_stream_source_handle, false); + connection.mStreamId = stream.stream_id; + connection.mSurface->setSidebandStream(connection.mSourceHandle); + } + return NO_ERROR; +} + +const tv_stream_config_t* JTvInputHal::getStreamConfigs(int deviceId, int* numConfigs) { + const tv_stream_config_t* configs = NULL; + if (mDevice->get_stream_configurations( + mDevice, deviceId, numConfigs, &configs) != 0) { + ALOGE("Couldn't get stream configs"); + return NULL; + } + return configs; +} + + +// static +void JTvInputHal::notify( + tv_input_device_t* dev, tv_input_event_t* event, void* data) { + JTvInputHal* thiz = (JTvInputHal*)data; + switch (event->type) { + case TV_INPUT_EVENT_DEVICE_AVAILABLE: { + thiz->onDeviceAvailable(event->device_info); + } break; + case TV_INPUT_EVENT_DEVICE_UNAVAILABLE: { + thiz->onDeviceUnavailable(event->device_info.device_id); + } break; + case TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED: { + thiz->onStreamConfigurationsChanged(event->device_info.device_id); + } break; + default: + ALOGE("Unrecognizable event"); + } +} + +void JTvInputHal::onDeviceAvailable(const tv_input_device_info_t& info) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + mConnections.add(info.device_id, Connection()); + env->CallVoidMethod( + mThiz, + gTvInputHalClassInfo.deviceAvailable, + info.device_id, + info.type); +} + +void JTvInputHal::onDeviceUnavailable(int deviceId) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + mConnections.removeItem(deviceId); + env->CallVoidMethod( + mThiz, + gTvInputHalClassInfo.deviceUnavailable, + deviceId); +} + +void JTvInputHal::onStreamConfigurationsChanged(int deviceId) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + mConnections.removeItem(deviceId); + env->CallVoidMethod( + mThiz, + gTvInputHalClassInfo.streamConfigsChanged, + deviceId); +} + +//////////////////////////////////////////////////////////////////////////////// + +static jlong nativeOpen(JNIEnv* env, jobject thiz) { + return (jlong)JTvInputHal::createInstance(env, thiz); +} + +static int nativeSetSurface(JNIEnv* env, jclass clazz, + jlong ptr, jint deviceId, jint streamId, jobject jsurface) { + JTvInputHal* tvInputHal = (JTvInputHal*)ptr; + sp<Surface> surface( + jsurface + ? android_view_Surface_getSurface(env, jsurface) + : NULL); + return tvInputHal->setSurface(deviceId, streamId, surface); +} + +static jobjectArray nativeGetStreamConfigs(JNIEnv* env, jclass clazz, + jlong ptr, jint deviceId, jint generation) { + JTvInputHal* tvInputHal = (JTvInputHal*)ptr; + int numConfigs = 0; + const tv_stream_config_t* configs = tvInputHal->getStreamConfigs(deviceId, &numConfigs); + + jobjectArray result = env->NewObjectArray(numConfigs, gTvStreamConfigClassInfo.clazz, NULL); + for (int i = 0; i < numConfigs; ++i) { + jobject builder = env->NewObject( + gTvStreamConfigBuilderClassInfo.clazz, + gTvStreamConfigBuilderClassInfo.constructor); + env->CallObjectMethod( + builder, gTvStreamConfigBuilderClassInfo.streamId, configs[i].stream_id); + env->CallObjectMethod( + builder, gTvStreamConfigBuilderClassInfo.type, configs[i].type); + env->CallObjectMethod( + builder, gTvStreamConfigBuilderClassInfo.maxWidth, configs[i].max_video_width); + env->CallObjectMethod( + builder, gTvStreamConfigBuilderClassInfo.maxHeight, configs[i].max_video_height); + env->CallObjectMethod( + builder, gTvStreamConfigBuilderClassInfo.generation, generation); + + jobject config = env->CallObjectMethod(builder, gTvStreamConfigBuilderClassInfo.build); + + env->SetObjectArrayElement(result, i, config); + + env->DeleteLocalRef(config); + env->DeleteLocalRef(builder); + } + return result; +} + +static void nativeClose(JNIEnv* env, jclass clazz, jlong ptr) { + JTvInputHal* tvInputHal = (JTvInputHal*)ptr; + delete tvInputHal; +} + +static JNINativeMethod gTvInputHalMethods[] = { + /* name, signature, funcPtr */ + { "nativeOpen", "()J", + (void*) nativeOpen }, + { "nativeSetSurface", "(JIILandroid/view/Surface;)I", + (void*) nativeSetSurface }, + { "nativeGetStreamConfigs", "(JII)[Landroid/tv/TvStreamConfig;", + (void*) nativeGetStreamConfigs }, + { "nativeClose", "(J)V", + (void*) nativeClose }, +}; + +#define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(! var, "Unable to find class " className) + +#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \ + var = env->GetMethodID(clazz, methodName, fieldDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find method" methodName) + +int register_android_server_tv_TvInputHal(JNIEnv* env) { + int res = jniRegisterNativeMethods(env, "com/android/server/tv/TvInputHal", + gTvInputHalMethods, NELEM(gTvInputHalMethods)); + LOG_FATAL_IF(res < 0, "Unable to register native methods."); + + jclass clazz; + FIND_CLASS(clazz, "com/android/server/tv/TvInputHal"); + + GET_METHOD_ID( + gTvInputHalClassInfo.deviceAvailable, clazz, "deviceAvailableFromNative", "(II)V"); + GET_METHOD_ID( + gTvInputHalClassInfo.deviceUnavailable, clazz, "deviceUnavailableFromNative", "(I)V"); + GET_METHOD_ID( + gTvInputHalClassInfo.streamConfigsChanged, clazz, + "streamConfigsChangedFromNative", "(I)V"); + + FIND_CLASS(gTvStreamConfigClassInfo.clazz, "android/tv/TvStreamConfig"); + gTvStreamConfigClassInfo.clazz = jclass(env->NewGlobalRef(gTvStreamConfigClassInfo.clazz)); + + FIND_CLASS(gTvStreamConfigBuilderClassInfo.clazz, "android/tv/TvStreamConfig$Builder"); + gTvStreamConfigBuilderClassInfo.clazz = + jclass(env->NewGlobalRef(gTvStreamConfigBuilderClassInfo.clazz)); + + GET_METHOD_ID( + gTvStreamConfigBuilderClassInfo.constructor, + gTvStreamConfigBuilderClassInfo.clazz, + "<init>", "()V"); + GET_METHOD_ID( + gTvStreamConfigBuilderClassInfo.streamId, + gTvStreamConfigBuilderClassInfo.clazz, + "streamId", "(I)Landroid/tv/TvStreamConfig$Builder;"); + GET_METHOD_ID( + gTvStreamConfigBuilderClassInfo.type, + gTvStreamConfigBuilderClassInfo.clazz, + "type", "(I)Landroid/tv/TvStreamConfig$Builder;"); + GET_METHOD_ID( + gTvStreamConfigBuilderClassInfo.maxWidth, + gTvStreamConfigBuilderClassInfo.clazz, + "maxWidth", "(I)Landroid/tv/TvStreamConfig$Builder;"); + GET_METHOD_ID( + gTvStreamConfigBuilderClassInfo.maxHeight, + gTvStreamConfigBuilderClassInfo.clazz, + "maxHeight", "(I)Landroid/tv/TvStreamConfig$Builder;"); + GET_METHOD_ID( + gTvStreamConfigBuilderClassInfo.generation, + gTvStreamConfigBuilderClassInfo.clazz, + "generation", "(I)Landroid/tv/TvStreamConfig$Builder;"); + GET_METHOD_ID( + gTvStreamConfigBuilderClassInfo.build, + gTvStreamConfigBuilderClassInfo.clazz, + "build", "()Landroid/tv/TvStreamConfig;"); + + return 0; +} + +} /* namespace android */ diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 1feb325..bfa8286 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -41,6 +41,7 @@ int register_android_server_dreams_McuHal(JNIEnv* env); int register_android_server_hdmi_HdmiCecController(JNIEnv* env); int register_android_server_hdmi_HdmiCecService(JNIEnv* env); int register_android_server_hdmi_HdmiMhlController(JNIEnv* env); +int register_android_server_tv_TvInputHal(JNIEnv* env); }; using namespace android; @@ -78,6 +79,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) // TODO: remove this once replaces HdmiCecService with HdmiControlService. register_android_server_hdmi_HdmiCecService(env); register_android_server_hdmi_HdmiMhlController(env); + register_android_server_tv_TvInputHal(env); return JNI_VERSION_1_4; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 5d485c5..a896861 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -2249,4 +2249,25 @@ public class TelephonyManager { } return false; } + + /** @hide */ + @PrivateApi + public void setDataEnabled(boolean enable) { + try { + getITelephony().setDataEnabled(enable); + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelephony#setDataEnabled", e); + } + } + + /** @hide */ + @PrivateApi + public boolean getDataEnabled() { + try { + return getITelephony().getDataEnabled(); + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelephony#getDataEnabled", e); + } + return false; + } } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index baacb74..6d7f158 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -436,4 +436,18 @@ interface ITelephony { * @return true on success; false on any failure. */ boolean setPreferredNetworkType(int networkType); + + /** + * User enable/disable Mobile Data. + * + * @param enable true to turn on, else false + */ + void setDataEnabled(boolean enable); + + /** + * Get the user enabled state of Mobile Data. + * + * @return true on enabled + */ + boolean getDataEnabled(); } diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/samples/simplecamera/Camera2Source.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/samples/simplecamera/Camera2Source.java index fa0f995..6876f5a 100644 --- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/samples/simplecamera/Camera2Source.java +++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/samples/simplecamera/Camera2Source.java @@ -26,6 +26,7 @@ import android.hardware.camera2.CameraManager; import android.hardware.camera2.CaptureFailure; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; +import android.hardware.camera2.TotalCaptureResult; import android.os.Handler; import android.renderscript.Allocation; import android.renderscript.Element; @@ -86,7 +87,7 @@ public class Camera2Source extends Filter implements Allocation.OnBufferAvailabl @Override public void onCaptureCompleted(CameraDevice camera, CaptureRequest request, - CaptureResult result) { + TotalCaptureResult result) { // TODO Auto-generated method stub Log.v(TAG, "in onCaptureComplete"); diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java index 6ad01a0..0f4e122 100644 --- a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java +++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java @@ -302,6 +302,36 @@ public abstract class DisplayModifier { paint.setShader(ResourceModifiers.instance().mVertGradient); } }); + put("radGradient", new DisplayModifier() { + @Override + public void modifyDrawing(Paint paint, Canvas canvas) { + paint.setShader(ResourceModifiers.instance().mRadGradient); + } + }); + put("sweepGradient", new DisplayModifier() { + @Override + public void modifyDrawing(Paint paint, Canvas canvas) { + paint.setShader(ResourceModifiers.instance().mSweepGradient); + } + }); + put("composeShader", new DisplayModifier() { + @Override + public void modifyDrawing(Paint paint, Canvas canvas) { + paint.setShader(ResourceModifiers.instance().mComposeShader); + } + }); + put("bad composeShader", new DisplayModifier() { + @Override + public void modifyDrawing(Paint paint, Canvas canvas) { + paint.setShader(ResourceModifiers.instance().mBadComposeShader); + } + }); + put("bad composeShader 2", new DisplayModifier() { + @Override + public void modifyDrawing(Paint paint, Canvas canvas) { + paint.setShader(ResourceModifiers.instance().mAnotherBadComposeShader); + } + }); } }); diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java index c705443..d522481 100644 --- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java +++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java @@ -23,7 +23,11 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapShader; import android.graphics.Color; +import android.graphics.ComposeShader; import android.graphics.LinearGradient; +import android.graphics.PorterDuff; +import android.graphics.RadialGradient; +import android.graphics.SweepGradient; import android.graphics.Matrix; import android.graphics.Shader; @@ -38,6 +42,11 @@ public class ResourceModifiers { public final LinearGradient mHorGradient; public final LinearGradient mDiagGradient; public final LinearGradient mVertGradient; + public final RadialGradient mRadGradient; + public final SweepGradient mSweepGradient; + public final ComposeShader mComposeShader; + public final ComposeShader mBadComposeShader; + public final ComposeShader mAnotherBadComposeShader; public final Bitmap mBitmap; private final Matrix mMtx1; private final Matrix mMtx2; @@ -90,6 +99,12 @@ public class ResourceModifiers { mVertGradient = new LinearGradient(0.0f, 0.0f, 0.0f, mDrawHeight / 2.0f, Color.YELLOW, Color.MAGENTA, Shader.TileMode.MIRROR); + mSweepGradient = new SweepGradient(mDrawWidth / 2.0f, mDrawHeight / 2.0f, + Color.YELLOW, Color.MAGENTA); + + mComposeShader = new ComposeShader(mRepeatShader, mHorGradient, + PorterDuff.Mode.MULTIPLY); + final float width = mBitmap.getWidth() / 8.0f; final float height = mBitmap.getHeight() / 8.0f; @@ -106,6 +121,16 @@ public class ResourceModifiers { 0xff00ff00, 0xff0000ff, 0xffff0000, 0xff00ff00, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ff0000, }; + + // Use a repeating gradient with many colors to test the non simple case. + mRadGradient = new RadialGradient(mDrawWidth / 4.0f, mDrawHeight / 4.0f, 4.0f, + mBitmapColors, null, Shader.TileMode.REPEAT); + + mBadComposeShader = new ComposeShader(mRadGradient, mComposeShader, + PorterDuff.Mode.MULTIPLY); + + mAnotherBadComposeShader = new ComposeShader(mRadGradient, mVertGradient, + PorterDuff.Mode.MULTIPLY); } } |