Merge "Need to call getApplicationInfo from System id"
diff --git a/Android.mk b/Android.mk
index 1d797c4..c947b0e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -288,6 +288,7 @@
core/java/com/android/internal/app/IBatteryStats.aidl \
core/java/com/android/internal/app/IEphemeralResolver.aidl \
core/java/com/android/internal/app/IProcessStats.aidl \
+ core/java/com/android/internal/app/ISoundTriggerService.aidl \
core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl \
core/java/com/android/internal/app/IVoiceInteractionSessionShowCallback.aidl \
core/java/com/android/internal/app/IVoiceInteractor.aidl \
@@ -384,6 +385,8 @@
media/java/android/media/tv/ITvInputSessionCallback.aidl \
media/java/android/service/media/IMediaBrowserService.aidl \
media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl \
+ telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl \
+ telecomm/java/com/android/internal/telecom/ICallScreeningService.aidl \
telecomm/java/com/android/internal/telecom/IVideoCallback.aidl \
telecomm/java/com/android/internal/telecom/IVideoProvider.aidl \
telecomm/java/com/android/internal/telecom/IConnectionService.aidl \
diff --git a/api/current.txt b/api/current.txt
index a10c510..bfbb17e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33,6 +33,7 @@
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
@@ -5788,6 +5789,7 @@
method public void clearCrossProfileIntentFilters(android.content.ComponentName);
method public void clearDeviceOwnerApp(java.lang.String);
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
+ method public void clearProfileOwner(android.content.ComponentName);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
method public android.os.UserHandle createAndManageUser(android.content.ComponentName, java.lang.String, android.content.ComponentName, android.os.PersistableBundle, int);
@@ -13370,11 +13372,13 @@
field public static final java.lang.String STRING_TYPE_GRAVITY = "android.sensor.gravity";
field public static final java.lang.String STRING_TYPE_GYROSCOPE = "android.sensor.gyroscope";
field public static final java.lang.String STRING_TYPE_GYROSCOPE_UNCALIBRATED = "android.sensor.gyroscope_uncalibrated";
+ field public static final java.lang.String STRING_TYPE_HEART_BEAT = "android.sensor.heart_beat";
field public static final java.lang.String STRING_TYPE_HEART_RATE = "android.sensor.heart_rate";
field public static final java.lang.String STRING_TYPE_LIGHT = "android.sensor.light";
field public static final java.lang.String STRING_TYPE_LINEAR_ACCELERATION = "android.sensor.linear_acceleration";
field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field";
field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated";
+ field public static final java.lang.String STRING_TYPE_MOTION_DETECT = "android.sensor.motion_detect";
field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation";
field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof";
field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure";
@@ -13382,6 +13386,7 @@
field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity";
field public static final java.lang.String STRING_TYPE_ROTATION_VECTOR = "android.sensor.rotation_vector";
field public static final java.lang.String STRING_TYPE_SIGNIFICANT_MOTION = "android.sensor.significant_motion";
+ field public static final java.lang.String STRING_TYPE_STATIONARY_DETECT = "android.sensor.stationary_detect";
field public static final java.lang.String STRING_TYPE_STEP_COUNTER = "android.sensor.step_counter";
field public static final java.lang.String STRING_TYPE_STEP_DETECTOR = "android.sensor.step_detector";
field public static final deprecated java.lang.String STRING_TYPE_TEMPERATURE = "android.sensor.temperature";
@@ -13393,11 +13398,13 @@
field public static final int TYPE_GRAVITY = 9; // 0x9
field public static final int TYPE_GYROSCOPE = 4; // 0x4
field public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16; // 0x10
+ field public static final int TYPE_HEART_BEAT = 31; // 0x1f
field public static final int TYPE_HEART_RATE = 21; // 0x15
field public static final int TYPE_LIGHT = 5; // 0x5
field public static final int TYPE_LINEAR_ACCELERATION = 10; // 0xa
field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2
field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe
+ field public static final int TYPE_MOTION_DETECT = 30; // 0x1e
field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3
field public static final int TYPE_POSE_6DOF = 28; // 0x1c
field public static final int TYPE_PRESSURE = 6; // 0x6
@@ -13405,6 +13412,7 @@
field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
field public static final int TYPE_ROTATION_VECTOR = 11; // 0xb
field public static final int TYPE_SIGNIFICANT_MOTION = 17; // 0x11
+ field public static final int TYPE_STATIONARY_DETECT = 29; // 0x1d
field public static final int TYPE_STEP_COUNTER = 19; // 0x13
field public static final int TYPE_STEP_DETECTOR = 18; // 0x12
field public static final deprecated int TYPE_TEMPERATURE = 7; // 0x7
@@ -19320,6 +19328,7 @@
field public static final int ENCODING_DTS = 7; // 0x7
field public static final int ENCODING_DTS_HD = 8; // 0x8
field public static final int ENCODING_E_AC3 = 6; // 0x6
+ field public static final int ENCODING_IEC61937 = 13; // 0xd
field public static final int ENCODING_INVALID = 0; // 0x0
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
@@ -20225,6 +20234,24 @@
field public static final int VP8Level_Version2 = 4; // 0x4
field public static final int VP8Level_Version3 = 8; // 0x8
field public static final int VP8ProfileMain = 1; // 0x1
+ field public static final int VP9Level1 = 0; // 0x0
+ field public static final int VP9Level11 = 1; // 0x1
+ field public static final int VP9Level2 = 2; // 0x2
+ field public static final int VP9Level21 = 4; // 0x4
+ field public static final int VP9Level3 = 8; // 0x8
+ field public static final int VP9Level31 = 16; // 0x10
+ field public static final int VP9Level4 = 32; // 0x20
+ field public static final int VP9Level41 = 64; // 0x40
+ field public static final int VP9Level5 = 128; // 0x80
+ field public static final int VP9Level51 = 256; // 0x100
+ field public static final int VP9Level52 = 512; // 0x200
+ field public static final int VP9Level6 = 1024; // 0x400
+ field public static final int VP9Level61 = 2048; // 0x800
+ field public static final int VP9Level62 = 4096; // 0x1000
+ field public static final int VP9Profile0 = 0; // 0x0
+ field public static final int VP9Profile1 = 1; // 0x1
+ field public static final int VP9Profile2 = 2; // 0x2
+ field public static final int VP9Profile3 = 3; // 0x3
field public int level;
field public int profile;
}
@@ -28553,6 +28580,7 @@
field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
+ field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100
}
public final class PowerManager.WakeLock {
@@ -32282,6 +32310,7 @@
public class VoicemailContract {
field public static final java.lang.String ACTION_FETCH_VOICEMAIL = "android.intent.action.FETCH_VOICEMAIL";
field public static final java.lang.String ACTION_NEW_VOICEMAIL = "android.intent.action.NEW_VOICEMAIL";
+ field public static final java.lang.String ACTION_SYNC_VOICEMAIL = "android.intent.action.SYNC_VOICEMAIL";
field public static final java.lang.String AUTHORITY = "com.android.voicemail";
field public static final java.lang.String EXTRA_SELF_CHANGE = "com.android.voicemail.extra.SELF_CHANGE";
field public static final java.lang.String PARAM_KEY_SOURCE_PACKAGE = "source_package";
@@ -32296,8 +32325,13 @@
field public static final int CONFIGURATION_STATE_OK = 0; // 0x0
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATA_CHANNEL_STATE = "data_channel_state";
+ field public static final int DATA_CHANNEL_STATE_BAD_CONFIGURATION = 3; // 0x3
+ field public static final int DATA_CHANNEL_STATE_COMMUNICATION_ERROR = 4; // 0x4
field public static final int DATA_CHANNEL_STATE_NO_CONNECTION = 1; // 0x1
+ field public static final int DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED = 2; // 0x2
field public static final int DATA_CHANNEL_STATE_OK = 0; // 0x0
+ field public static final int DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR = 6; // 0x6
+ field public static final int DATA_CHANNEL_STATE_SERVER_ERROR = 5; // 0x5
field public static final java.lang.String DIR_TYPE = "vnd.android.cursor.dir/voicemail.source.status";
field public static final java.lang.String ITEM_TYPE = "vnd.android.cursor.item/voicemail.source.status";
field public static final java.lang.String NOTIFICATION_CHANNEL_STATE = "notification_channel_state";
@@ -35353,6 +35387,30 @@
field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
}
+ public abstract class CallScreeningService extends android.app.Service {
+ ctor public CallScreeningService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onScreenCall(android.telecom.Call.Details);
+ method public final void respondToCall(android.telecom.Call.Details, android.telecom.CallScreeningService.CallResponse);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.CallScreeningService";
+ }
+
+ public class CallScreeningService.CallResponse {
+ method public boolean getDisallowCall();
+ method public boolean getRejectCall();
+ method public boolean getSkipCallLog();
+ method public boolean getSkipNotification();
+ }
+
+ public class CallScreeningService.CallResponse.Builder {
+ ctor public CallScreeningService.CallResponse.Builder();
+ method public android.telecom.CallScreeningService.CallResponse build();
+ method public android.telecom.CallScreeningService.CallResponse.Builder setDisallowCall(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setRejectCall(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setSkipCallLog(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setSkipNotification(boolean);
+ }
+
public abstract class Conference extends android.telecom.Conferenceable {
ctor public Conference(android.telecom.PhoneAccountHandle);
method public final boolean addConnection(android.telecom.Connection);
@@ -35592,6 +35650,7 @@
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onCallRemoved(android.telecom.Call);
method public void onCanAddCallChanged(boolean);
+ method public void onSilenceRinger();
method public final void setAudioRoute(int);
method public final void setMuted(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
@@ -35852,6 +35911,7 @@
field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+ field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
@@ -36003,6 +36063,7 @@
field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN = "vvm_cellular_data_required";
field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
+ field public static final java.lang.String KEY_VVM_PREFETCH_BOOLEAN = "vvm_prefetch";
field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 8e247ad..c10954c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -46,6 +46,7 @@
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
@@ -7607,6 +7608,8 @@
method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
method public void startScan(android.bluetooth.le.ScanCallback);
method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
+ method public void startScanFromSource(android.os.WorkSource, android.bluetooth.le.ScanCallback);
+ method public void startScanFromSource(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.os.WorkSource, android.bluetooth.le.ScanCallback);
method public void startTruncatedScan(java.util.List<android.bluetooth.le.TruncatedFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
method public void stopScan(android.bluetooth.le.ScanCallback);
}
@@ -13770,11 +13773,13 @@
field public static final java.lang.String STRING_TYPE_GRAVITY = "android.sensor.gravity";
field public static final java.lang.String STRING_TYPE_GYROSCOPE = "android.sensor.gyroscope";
field public static final java.lang.String STRING_TYPE_GYROSCOPE_UNCALIBRATED = "android.sensor.gyroscope_uncalibrated";
+ field public static final java.lang.String STRING_TYPE_HEART_BEAT = "android.sensor.heart_beat";
field public static final java.lang.String STRING_TYPE_HEART_RATE = "android.sensor.heart_rate";
field public static final java.lang.String STRING_TYPE_LIGHT = "android.sensor.light";
field public static final java.lang.String STRING_TYPE_LINEAR_ACCELERATION = "android.sensor.linear_acceleration";
field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field";
field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated";
+ field public static final java.lang.String STRING_TYPE_MOTION_DETECT = "android.sensor.motion_detect";
field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation";
field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof";
field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure";
@@ -13782,6 +13787,7 @@
field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity";
field public static final java.lang.String STRING_TYPE_ROTATION_VECTOR = "android.sensor.rotation_vector";
field public static final java.lang.String STRING_TYPE_SIGNIFICANT_MOTION = "android.sensor.significant_motion";
+ field public static final java.lang.String STRING_TYPE_STATIONARY_DETECT = "android.sensor.stationary_detect";
field public static final java.lang.String STRING_TYPE_STEP_COUNTER = "android.sensor.step_counter";
field public static final java.lang.String STRING_TYPE_STEP_DETECTOR = "android.sensor.step_detector";
field public static final deprecated java.lang.String STRING_TYPE_TEMPERATURE = "android.sensor.temperature";
@@ -13794,11 +13800,13 @@
field public static final int TYPE_GRAVITY = 9; // 0x9
field public static final int TYPE_GYROSCOPE = 4; // 0x4
field public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16; // 0x10
+ field public static final int TYPE_HEART_BEAT = 31; // 0x1f
field public static final int TYPE_HEART_RATE = 21; // 0x15
field public static final int TYPE_LIGHT = 5; // 0x5
field public static final int TYPE_LINEAR_ACCELERATION = 10; // 0xa
field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2
field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe
+ field public static final int TYPE_MOTION_DETECT = 30; // 0x1e
field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3
field public static final int TYPE_POSE_6DOF = 28; // 0x1c
field public static final int TYPE_PRESSURE = 6; // 0x6
@@ -13806,6 +13814,7 @@
field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
field public static final int TYPE_ROTATION_VECTOR = 11; // 0xb
field public static final int TYPE_SIGNIFICANT_MOTION = 17; // 0x11
+ field public static final int TYPE_STATIONARY_DETECT = 29; // 0x1d
field public static final int TYPE_STEP_COUNTER = 19; // 0x13
field public static final int TYPE_STEP_DETECTOR = 18; // 0x12
field public static final deprecated int TYPE_TEMPERATURE = 7; // 0x7
@@ -20658,6 +20667,7 @@
field public static final int ENCODING_DTS = 7; // 0x7
field public static final int ENCODING_DTS_HD = 8; // 0x8
field public static final int ENCODING_E_AC3 = 6; // 0x6
+ field public static final int ENCODING_IEC61937 = 13; // 0xd
field public static final int ENCODING_INVALID = 0; // 0x0
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
@@ -21575,6 +21585,24 @@
field public static final int VP8Level_Version2 = 4; // 0x4
field public static final int VP8Level_Version3 = 8; // 0x8
field public static final int VP8ProfileMain = 1; // 0x1
+ field public static final int VP9Level1 = 0; // 0x0
+ field public static final int VP9Level11 = 1; // 0x1
+ field public static final int VP9Level2 = 2; // 0x2
+ field public static final int VP9Level21 = 4; // 0x4
+ field public static final int VP9Level3 = 8; // 0x8
+ field public static final int VP9Level31 = 16; // 0x10
+ field public static final int VP9Level4 = 32; // 0x20
+ field public static final int VP9Level41 = 64; // 0x40
+ field public static final int VP9Level5 = 128; // 0x80
+ field public static final int VP9Level51 = 256; // 0x100
+ field public static final int VP9Level52 = 512; // 0x200
+ field public static final int VP9Level6 = 1024; // 0x400
+ field public static final int VP9Level61 = 2048; // 0x800
+ field public static final int VP9Level62 = 4096; // 0x1000
+ field public static final int VP9Profile0 = 0; // 0x0
+ field public static final int VP9Profile1 = 1; // 0x1
+ field public static final int VP9Profile2 = 2; // 0x2
+ field public static final int VP9Profile3 = 3; // 0x3
field public int level;
field public int profile;
}
@@ -30631,6 +30659,7 @@
field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
+ field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100
field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1
field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0
field public static final int USER_ACTIVITY_EVENT_TOUCH = 2; // 0x2
@@ -34507,6 +34536,7 @@
public class VoicemailContract {
field public static final java.lang.String ACTION_FETCH_VOICEMAIL = "android.intent.action.FETCH_VOICEMAIL";
field public static final java.lang.String ACTION_NEW_VOICEMAIL = "android.intent.action.NEW_VOICEMAIL";
+ field public static final java.lang.String ACTION_SYNC_VOICEMAIL = "android.intent.action.SYNC_VOICEMAIL";
field public static final java.lang.String AUTHORITY = "com.android.voicemail";
field public static final java.lang.String EXTRA_SELF_CHANGE = "com.android.voicemail.extra.SELF_CHANGE";
field public static final java.lang.String PARAM_KEY_SOURCE_PACKAGE = "source_package";
@@ -34521,8 +34551,13 @@
field public static final int CONFIGURATION_STATE_OK = 0; // 0x0
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATA_CHANNEL_STATE = "data_channel_state";
+ field public static final int DATA_CHANNEL_STATE_BAD_CONFIGURATION = 3; // 0x3
+ field public static final int DATA_CHANNEL_STATE_COMMUNICATION_ERROR = 4; // 0x4
field public static final int DATA_CHANNEL_STATE_NO_CONNECTION = 1; // 0x1
+ field public static final int DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED = 2; // 0x2
field public static final int DATA_CHANNEL_STATE_OK = 0; // 0x0
+ field public static final int DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR = 6; // 0x6
+ field public static final int DATA_CHANNEL_STATE_SERVER_ERROR = 5; // 0x5
field public static final java.lang.String DIR_TYPE = "vnd.android.cursor.dir/voicemail.source.status";
field public static final java.lang.String ITEM_TYPE = "vnd.android.cursor.item/voicemail.source.status";
field public static final java.lang.String NOTIFICATION_CHANNEL_STATE = "notification_channel_state";
@@ -37658,6 +37693,30 @@
field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
}
+ public abstract class CallScreeningService extends android.app.Service {
+ ctor public CallScreeningService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onScreenCall(android.telecom.Call.Details);
+ method public final void respondToCall(android.telecom.Call.Details, android.telecom.CallScreeningService.CallResponse);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.CallScreeningService";
+ }
+
+ public class CallScreeningService.CallResponse {
+ method public boolean getDisallowCall();
+ method public boolean getRejectCall();
+ method public boolean getSkipCallLog();
+ method public boolean getSkipNotification();
+ }
+
+ public class CallScreeningService.CallResponse.Builder {
+ ctor public CallScreeningService.CallResponse.Builder();
+ method public android.telecom.CallScreeningService.CallResponse build();
+ method public android.telecom.CallScreeningService.CallResponse.Builder setDisallowCall(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setRejectCall(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setSkipCallLog(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setSkipNotification(boolean);
+ }
+
public abstract class Conference extends android.telecom.Conferenceable {
ctor public Conference(android.telecom.PhoneAccountHandle);
method public final boolean addConnection(android.telecom.Connection);
@@ -37907,6 +37966,7 @@
method public void onCanAddCallChanged(boolean);
method public deprecated void onPhoneCreated(android.telecom.Phone);
method public deprecated void onPhoneDestroyed(android.telecom.Phone);
+ method public void onSilenceRinger();
method public final void setAudioRoute(int);
method public final void setMuted(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
@@ -37988,6 +38048,7 @@
method public void onCallAudioStateChanged(android.telecom.Phone, android.telecom.CallAudioState);
method public void onCallRemoved(android.telecom.Phone, android.telecom.Call);
method public void onCanAddCallChanged(android.telecom.Phone, boolean);
+ method public void onSilenceRinger(android.telecom.Phone);
}
public final class PhoneAccount implements android.os.Parcelable {
@@ -38247,6 +38308,7 @@
field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+ field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
@@ -38400,6 +38462,7 @@
field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN = "vvm_cellular_data_required";
field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
+ field public static final java.lang.String KEY_VVM_PREFETCH_BOOLEAN = "vvm_prefetch";
field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 25b72c0..c076ad6 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -33,6 +33,7 @@
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
@@ -5790,6 +5791,7 @@
method public void clearCrossProfileIntentFilters(android.content.ComponentName);
method public void clearDeviceOwnerApp(java.lang.String);
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
+ method public void clearProfileOwner(android.content.ComponentName);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
method public android.os.UserHandle createAndManageUser(android.content.ComponentName, java.lang.String, android.content.ComponentName, android.os.PersistableBundle, int);
@@ -13378,11 +13380,13 @@
field public static final java.lang.String STRING_TYPE_GRAVITY = "android.sensor.gravity";
field public static final java.lang.String STRING_TYPE_GYROSCOPE = "android.sensor.gyroscope";
field public static final java.lang.String STRING_TYPE_GYROSCOPE_UNCALIBRATED = "android.sensor.gyroscope_uncalibrated";
+ field public static final java.lang.String STRING_TYPE_HEART_BEAT = "android.sensor.heart_beat";
field public static final java.lang.String STRING_TYPE_HEART_RATE = "android.sensor.heart_rate";
field public static final java.lang.String STRING_TYPE_LIGHT = "android.sensor.light";
field public static final java.lang.String STRING_TYPE_LINEAR_ACCELERATION = "android.sensor.linear_acceleration";
field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field";
field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated";
+ field public static final java.lang.String STRING_TYPE_MOTION_DETECT = "android.sensor.motion_detect";
field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation";
field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof";
field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure";
@@ -13390,6 +13394,7 @@
field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity";
field public static final java.lang.String STRING_TYPE_ROTATION_VECTOR = "android.sensor.rotation_vector";
field public static final java.lang.String STRING_TYPE_SIGNIFICANT_MOTION = "android.sensor.significant_motion";
+ field public static final java.lang.String STRING_TYPE_STATIONARY_DETECT = "android.sensor.stationary_detect";
field public static final java.lang.String STRING_TYPE_STEP_COUNTER = "android.sensor.step_counter";
field public static final java.lang.String STRING_TYPE_STEP_DETECTOR = "android.sensor.step_detector";
field public static final deprecated java.lang.String STRING_TYPE_TEMPERATURE = "android.sensor.temperature";
@@ -13401,11 +13406,13 @@
field public static final int TYPE_GRAVITY = 9; // 0x9
field public static final int TYPE_GYROSCOPE = 4; // 0x4
field public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16; // 0x10
+ field public static final int TYPE_HEART_BEAT = 31; // 0x1f
field public static final int TYPE_HEART_RATE = 21; // 0x15
field public static final int TYPE_LIGHT = 5; // 0x5
field public static final int TYPE_LINEAR_ACCELERATION = 10; // 0xa
field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2
field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe
+ field public static final int TYPE_MOTION_DETECT = 30; // 0x1e
field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3
field public static final int TYPE_POSE_6DOF = 28; // 0x1c
field public static final int TYPE_PRESSURE = 6; // 0x6
@@ -13413,6 +13420,7 @@
field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
field public static final int TYPE_ROTATION_VECTOR = 11; // 0xb
field public static final int TYPE_SIGNIFICANT_MOTION = 17; // 0x11
+ field public static final int TYPE_STATIONARY_DETECT = 29; // 0x1d
field public static final int TYPE_STEP_COUNTER = 19; // 0x13
field public static final int TYPE_STEP_DETECTOR = 18; // 0x12
field public static final deprecated int TYPE_TEMPERATURE = 7; // 0x7
@@ -19328,6 +19336,7 @@
field public static final int ENCODING_DTS = 7; // 0x7
field public static final int ENCODING_DTS_HD = 8; // 0x8
field public static final int ENCODING_E_AC3 = 6; // 0x6
+ field public static final int ENCODING_IEC61937 = 13; // 0xd
field public static final int ENCODING_INVALID = 0; // 0x0
field public static final int ENCODING_PCM_16BIT = 2; // 0x2
field public static final int ENCODING_PCM_8BIT = 3; // 0x3
@@ -20233,6 +20242,24 @@
field public static final int VP8Level_Version2 = 4; // 0x4
field public static final int VP8Level_Version3 = 8; // 0x8
field public static final int VP8ProfileMain = 1; // 0x1
+ field public static final int VP9Level1 = 0; // 0x0
+ field public static final int VP9Level11 = 1; // 0x1
+ field public static final int VP9Level2 = 2; // 0x2
+ field public static final int VP9Level21 = 4; // 0x4
+ field public static final int VP9Level3 = 8; // 0x8
+ field public static final int VP9Level31 = 16; // 0x10
+ field public static final int VP9Level4 = 32; // 0x20
+ field public static final int VP9Level41 = 64; // 0x40
+ field public static final int VP9Level5 = 128; // 0x80
+ field public static final int VP9Level51 = 256; // 0x100
+ field public static final int VP9Level52 = 512; // 0x200
+ field public static final int VP9Level6 = 1024; // 0x400
+ field public static final int VP9Level61 = 2048; // 0x800
+ field public static final int VP9Level62 = 4096; // 0x1000
+ field public static final int VP9Profile0 = 0; // 0x0
+ field public static final int VP9Profile1 = 1; // 0x1
+ field public static final int VP9Profile2 = 2; // 0x2
+ field public static final int VP9Profile3 = 3; // 0x3
field public int level;
field public int profile;
}
@@ -28561,6 +28588,7 @@
field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
+ field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100
}
public final class PowerManager.WakeLock {
@@ -32296,6 +32324,7 @@
public class VoicemailContract {
field public static final java.lang.String ACTION_FETCH_VOICEMAIL = "android.intent.action.FETCH_VOICEMAIL";
field public static final java.lang.String ACTION_NEW_VOICEMAIL = "android.intent.action.NEW_VOICEMAIL";
+ field public static final java.lang.String ACTION_SYNC_VOICEMAIL = "android.intent.action.SYNC_VOICEMAIL";
field public static final java.lang.String AUTHORITY = "com.android.voicemail";
field public static final java.lang.String EXTRA_SELF_CHANGE = "com.android.voicemail.extra.SELF_CHANGE";
field public static final java.lang.String PARAM_KEY_SOURCE_PACKAGE = "source_package";
@@ -32310,8 +32339,13 @@
field public static final int CONFIGURATION_STATE_OK = 0; // 0x0
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATA_CHANNEL_STATE = "data_channel_state";
+ field public static final int DATA_CHANNEL_STATE_BAD_CONFIGURATION = 3; // 0x3
+ field public static final int DATA_CHANNEL_STATE_COMMUNICATION_ERROR = 4; // 0x4
field public static final int DATA_CHANNEL_STATE_NO_CONNECTION = 1; // 0x1
+ field public static final int DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED = 2; // 0x2
field public static final int DATA_CHANNEL_STATE_OK = 0; // 0x0
+ field public static final int DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR = 6; // 0x6
+ field public static final int DATA_CHANNEL_STATE_SERVER_ERROR = 5; // 0x5
field public static final java.lang.String DIR_TYPE = "vnd.android.cursor.dir/voicemail.source.status";
field public static final java.lang.String ITEM_TYPE = "vnd.android.cursor.item/voicemail.source.status";
field public static final java.lang.String NOTIFICATION_CHANNEL_STATE = "notification_channel_state";
@@ -35367,6 +35401,30 @@
field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
}
+ public abstract class CallScreeningService extends android.app.Service {
+ ctor public CallScreeningService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onScreenCall(android.telecom.Call.Details);
+ method public final void respondToCall(android.telecom.Call.Details, android.telecom.CallScreeningService.CallResponse);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.CallScreeningService";
+ }
+
+ public class CallScreeningService.CallResponse {
+ method public boolean getDisallowCall();
+ method public boolean getRejectCall();
+ method public boolean getSkipCallLog();
+ method public boolean getSkipNotification();
+ }
+
+ public class CallScreeningService.CallResponse.Builder {
+ ctor public CallScreeningService.CallResponse.Builder();
+ method public android.telecom.CallScreeningService.CallResponse build();
+ method public android.telecom.CallScreeningService.CallResponse.Builder setDisallowCall(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setRejectCall(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setSkipCallLog(boolean);
+ method public android.telecom.CallScreeningService.CallResponse.Builder setSkipNotification(boolean);
+ }
+
public abstract class Conference extends android.telecom.Conferenceable {
ctor public Conference(android.telecom.PhoneAccountHandle);
method public final boolean addConnection(android.telecom.Connection);
@@ -35606,6 +35664,7 @@
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onCallRemoved(android.telecom.Call);
method public void onCanAddCallChanged(boolean);
+ method public void onSilenceRinger();
method public final void setAudioRoute(int);
method public final void setMuted(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
@@ -35866,6 +35925,7 @@
field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+ field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
@@ -36017,6 +36077,7 @@
field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN = "vvm_cellular_data_required";
field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
+ field public static final java.lang.String KEY_VVM_PREFETCH_BOOLEAN = "vvm_prefetch";
field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index fc1a355..5eed781 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -17,6 +17,7 @@
package android.app;
import com.android.internal.app.IAppOpsService;
+import com.android.internal.app.ISoundTriggerService;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.IDropBoxManagerService;
@@ -61,6 +62,7 @@
import android.media.midi.MidiManager;
import android.media.projection.MediaProjectionManager;
import android.media.session.MediaSessionManager;
+import android.media.soundtrigger.SoundTriggerManager;
import android.media.tv.ITvInputManager;
import android.media.tv.TvInputManager;
import android.net.ConnectivityManager;
@@ -708,12 +710,22 @@
public RadioManager createService(ContextImpl ctx) {
return new RadioManager(ctx);
}});
+
registerService(Context.HARDWARE_PROPERTIES_SERVICE, HardwarePropertiesManager.class,
new CachedServiceFetcher<HardwarePropertiesManager>() {
@Override
public HardwarePropertiesManager createService(ContextImpl ctx) {
return new HardwarePropertiesManager();
}});
+
+ registerService(Context.SOUND_TRIGGER_SERVICE, SoundTriggerManager.class,
+ new CachedServiceFetcher<SoundTriggerManager>() {
+ @Override
+ public SoundTriggerManager createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE);
+ Log.i(TAG, "Creating new instance of SoundTriggerManager object.");
+ return new SoundTriggerManager(ctx, ISoundTriggerService.Stub.asInterface(b));
+ }});
}
/**
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 1c1526f..fef2a0e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2770,6 +2770,45 @@
}
/**
+ * Called by a device owner to set whether all users created on the device should be ephemeral.
+ *
+ * <p>The system user is exempt from this policy - it is never ephemeral.
+ *
+ * <p>The calling device admin must be the device owner. If it is not, a security exception will
+ * be thrown.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param forceEphemeralUsers If true, all the existing users will be deleted and all
+ * subsequently created users will be ephemeral.
+ * @hide
+ */
+ public void setForceEphemeralUsers(
+ @NonNull ComponentName admin, boolean forceEphemeralUsers) {
+ if (mService != null) {
+ try {
+ mService.setForceEphemeralUsers(admin, forceEphemeralUsers);
+ } catch (RemoteException e) {
+ Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+ }
+ }
+ }
+
+ /**
+ * @return true if all users are created ephemeral.
+ * @hide
+ */
+ public boolean getForceEphemeralUsers(@NonNull ComponentName admin) {
+ if (mService != null) {
+ try {
+ return mService.getForceEphemeralUsers(admin);
+ } catch (RemoteException e) {
+ Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+ }
+ }
+ return false;
+ }
+
+ /**
* Called by an application that is administering the device to disable keyguard customizations,
* such as widgets. After setting this, keyguard features will be disabled according to the
* provided feature list.
@@ -3205,15 +3244,14 @@
}
/**
- * @hide
* Clears the active profile owner and removes all user restrictions. The caller must
* be from the same package as the active profile owner for this user, otherwise a
* SecurityException will be thrown.
*
+ * <p>This doesn't work for managed profile owners.
+ *
* @param admin The component to remove as the profile owner.
- * @return
*/
- @SystemApi
public void clearProfileOwner(@NonNull ComponentName admin) {
if (mService != null) {
try {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index a80ed9b..20d4a29 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -230,6 +230,9 @@
void setAutoTimeRequired(in ComponentName who, boolean required);
boolean getAutoTimeRequired();
+ void setForceEphemeralUsers(in ComponentName who, boolean forceEpehemeralUsers);
+ boolean getForceEphemeralUsers(in ComponentName who);
+
boolean isRemovingAdmin(in ComponentName adminReceiver, int userHandle);
void setUserIcon(in ComponentName admin, in Bitmap icon);
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 3660be7..6b5f77f 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -23,6 +23,7 @@
import android.bluetooth.le.ScanSettings;
import android.bluetooth.le.ResultStorageDescriptor;
import android.os.ParcelUuid;
+import android.os.WorkSource;
import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothGattServerCallback;
@@ -35,8 +36,8 @@
List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
void startScan(in int appIf, in boolean isServer, in ScanSettings settings,
- in List<ScanFilter> filters,
- in List scanStorages, in String callingPackage);
+ in List<ScanFilter> filters, in WorkSource workSource, in List scanStorages,
+ in String callingPackage);
void stopScan(in int appIf, in boolean isServer);
void flushPendingBatchResults(in int appIf, in boolean isServer);
void startMultiAdvertising(in int appIf,
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 2ba87744..03449cc 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -29,6 +29,7 @@
import android.os.Looper;
import android.os.ParcelUuid;
import android.os.RemoteException;
+import android.os.WorkSource;
import android.util.Log;
import java.util.ArrayList;
@@ -89,9 +90,6 @@
*/
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void startScan(final ScanCallback callback) {
- if (callback == null) {
- throw new IllegalArgumentException("callback is null");
- }
startScan(null, new ScanSettings.Builder().build(), callback);
}
@@ -112,14 +110,53 @@
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void startScan(List<ScanFilter> filters, ScanSettings settings,
final ScanCallback callback) {
- startScan(filters, settings, callback, null);
+ startScan(filters, settings, null, callback, null);
+ }
+
+ /**
+ * Start Bluetooth LE scan. Same as {@link #startScan(ScanCallback)} but allows the caller to
+ * specify on behalf of which application(s) the work is being done.
+ *
+ * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
+ * the scan.
+ * @param callback Callback used to deliver scan results.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(allOf = {
+ Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
+ public void startScanFromSource(final WorkSource workSource, final ScanCallback callback) {
+ startScanFromSource(null, new ScanSettings.Builder().build(), workSource, callback);
+ }
+
+ /**
+ * Start Bluetooth LE scan. Same as {@link #startScan(List, ScanSettings, ScanCallback)} but
+ * allows the caller to specify on behalf of which application(s) the work is being done.
+ *
+ * @param filters {@link ScanFilter}s for finding exact BLE devices.
+ * @param settings Settings for the scan.
+ * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
+ * the scan.
+ * @param callback Callback used to deliver scan results.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(allOf = {
+ Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
+ public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
+ final WorkSource workSource, final ScanCallback callback) {
+ startScan(filters, settings, workSource, callback, null);
}
private void startScan(List<ScanFilter> filters, ScanSettings settings,
- final ScanCallback callback, List<List<ResultStorageDescriptor>> resultStorages) {
+ final WorkSource workSource, final ScanCallback callback,
+ List<List<ResultStorageDescriptor>> resultStorages) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
- if (settings == null || callback == null) {
- throw new IllegalArgumentException("settings or callback is null");
+ if (callback == null) {
+ throw new IllegalArgumentException("callback is null");
+ }
+ if (settings == null) {
+ throw new IllegalArgumentException("settings is null");
}
synchronized (mLeScanClients) {
if (mLeScanClients.containsKey(callback)) {
@@ -152,7 +189,7 @@
return;
}
BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
- settings, callback, resultStorages);
+ settings, workSource, callback, resultStorages);
wrapper.startRegisteration();
}
}
@@ -215,7 +252,7 @@
scanFilters.add(filter.getFilter());
scanStorages.add(filter.getStorageDescriptors());
}
- startScan(scanFilters, settings, callback, scanStorages);
+ startScan(scanFilters, settings, null, callback, scanStorages);
}
/**
@@ -235,6 +272,7 @@
private final ScanCallback mScanCallback;
private final List<ScanFilter> mFilters;
+ private final WorkSource mWorkSource;
private ScanSettings mSettings;
private IBluetoothGatt mBluetoothGatt;
private List<List<ResultStorageDescriptor>> mResultStorages;
@@ -246,10 +284,12 @@
public BleScanCallbackWrapper(IBluetoothGatt bluetoothGatt,
List<ScanFilter> filters, ScanSettings settings,
- ScanCallback scanCallback, List<List<ResultStorageDescriptor>> resultStorages) {
+ WorkSource workSource, ScanCallback scanCallback,
+ List<List<ResultStorageDescriptor>> resultStorages) {
mBluetoothGatt = bluetoothGatt;
mFilters = filters;
mSettings = settings;
+ mWorkSource = workSource;
mScanCallback = scanCallback;
mClientIf = 0;
mResultStorages = resultStorages;
@@ -322,7 +362,9 @@
mClientIf = clientIf;
try {
mBluetoothGatt.startScan(mClientIf, false, mSettings, mFilters,
- mResultStorages, ActivityThread.currentOpPackageName());
+ mWorkSource, mResultStorages,
+ ActivityThread.currentOpPackageName());
+
} catch (RemoteException e) {
Log.e(TAG, "fail to start le scan: " + e);
mClientIf = -1;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 27cdd50..3142b40 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2613,6 +2613,7 @@
MIDI_SERVICE,
RADIO_SERVICE,
HARDWARE_PROPERTIES_SERVICE,
+ //@hide: SOUND_TRIGGER_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -3195,6 +3196,16 @@
public static final String VOICE_INTERACTION_MANAGER_SERVICE = "voiceinteraction";
/**
+ * Use with {@link #getSystemService} to access the
+ * {@link com.android.server.voiceinteraction.SoundTriggerService}.
+ *
+ * @hide
+ * @see #getSystemService
+ */
+ public static final String SOUND_TRIGGER_SERVICE = "soundtrigger";
+
+
+ /**
* Use with {@link #getSystemService} to retrieve an
* {@link android.app.backup.IBackupManager IBackupManager} for communicating
* with the backup mechanism.
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index e5efd56..c710f21 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -557,6 +557,8 @@
* Similar to {@link #TYPE_ROTATION_VECTOR}, with additional delta
* translation from an arbitrary reference point.
*
+ * See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
+ *
* Can use camera, depth sensor etc to compute output value.
*
* This is expected to be a high power sensor and expected only to be
@@ -574,9 +576,55 @@
*/
public static final String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof";
+ /**
+ * A constant describing a stationary detect sensor.
+ *
+ * See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
+ *
+ */
+ public static final int TYPE_STATIONARY_DETECT = 29;
+
+ /**
+ * A constant string describing a stationary detection sensor.
+ *
+ * @see #TYPE_STATIONARY_DETECT
+ */
+ public static final String STRING_TYPE_STATIONARY_DETECT = "android.sensor.stationary_detect";
+
+ /**
+ * A constant describing a motion detect sensor.
+ *
+ * See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
+ *
+ */
+ public static final int TYPE_MOTION_DETECT = 30;
+
+ /**
+ * A constant string describing a motion detection sensor.
+ *
+ * @see #TYPE_MOTION_DETECT
+ */
+ public static final String STRING_TYPE_MOTION_DETECT = "android.sensor.motion_detect";
+
+ /**
+ * A constant describing a motion detect sensor.
+ *
+ * See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
+ *
+ */
+ public static final int TYPE_HEART_BEAT = 31;
+
+ /**
+ * A constant string describing a heart beat sensor.
+ *
+ * @see #TYPE_HEART_BEAT
+ */
+
+ public static final String STRING_TYPE_HEART_BEAT = "android.sensor.heart_beat";
/**
* A constant describing all sensor types.
*/
+
public static final int TYPE_ALL = -1;
// If this flag is set, the sensor defined as a wake up sensor. This field and REPORTING_MODE_*
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 416c74c..35c96f7 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -396,7 +396,7 @@
* dv = 216.7 *
* (rh / 100.0 * 6.112 * Math.exp(17.62 * t / (243.12 + t)) / (273.15 + t));
* </pre>
- *
+ *
* <h4>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE Sensor.TYPE_AMBIENT_TEMPERATURE}:
* </h4>
*
@@ -531,6 +531,53 @@
*
* </ul>
*
+ * <h4>{@link android.hardware.Sensor#TYPE_STATIONARY_DETECT
+ * Sensor.TYPE_STATIONARY_DETECT}:</h4>
+ *
+ * A TYPE_STATIONARY_DETECT event is produced if the device has been
+ * stationary for at least 5 seconds with a maximal latency of 5
+ * additional seconds. ie: it may take up anywhere from 5 to 10 seconds
+ * afte the device has been at rest to trigger this event.
+ *
+ * The only allowed value is 1.0.
+ *
+ * <ul>
+ * <li> values[0]: 1.0 </li>
+ * </ul>
+ *
+ * <h4>{@link android.hardware.Sensor#TYPE_MOTION_DETECT
+ * Sensor.TYPE_MOTION_DETECT}:</h4>
+ *
+ * A TYPE_MOTION_DETECT event is produced if the device has been in
+ * motion for at least 5 seconds with a maximal latency of 5
+ * additional seconds. ie: it may take up anywhere from 5 to 10 seconds
+ * afte the device has been at rest to trigger this event.
+ *
+ * The only allowed value is 1.0.
+ *
+ * <ul>
+ * <li> values[0]: 1.0 </li>
+ * </ul>
+ *
+ * <h4>{@link android.hardware.Sensor#TYPE_HEART_BEAT
+ * Sensor.TYPE_HEART_BEAT}:</h4>
+ *
+ * A sensor of this type returns an event everytime a hear beat peak is
+ * detected.
+ *
+ * Peak here ideally corresponds to the positive peak in the QRS complex of
+ * an ECG signal.
+ *
+ * <ul>
+ * <li> values[0]: confidence</li>
+ * </ul>
+ *
+ * <p>
+ * A confidence value of 0.0 indicates complete uncertainty - that a peak
+ * is as likely to be at the indicated timestamp as anywhere else.
+ * A confidence value of 1.0 indicates complete certainly - that a peak is
+ * completely unlikely to be anywhere else on the QRS complex.
+ * </p>
*/
public final float[] values;
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 28bb22a..6aacc9c 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -575,14 +575,16 @@
* {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_3 LEVEL_3}) devices
* support at least the following stream combinations for creating a reprocessable capture
* session in addition to those for
- * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL} devices. Note that targets in the "Reprocess-only target" column may only be
- * used as an output target for a reprocess capture request, not as an output to a regular capture request.
+ * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL} devices. Note that while
+ * the second configuration allows for configuring {@code MAXIMUM} {@code YUV} and {@code JPEG}
+ * outputs at the same time, that configuration is not listed for regular capture sessions, and
+ * therefore simultaneous output to both targets is not allowed.
*
* <table>
* <tr><th colspan="13">LEVEL-3 additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is always guaranteed.</th></tr>
- * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th colspan="2" id="rb">Reprocess-only target</th><th rowspan="2">Sample use case(s)</th> </tr>
+ * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th colspan="2" id="rb">Target 5</th><th rowspan="2">Sample use case(s)</th> </tr>
* <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr>
- * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code 640x480}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>In-app viewfinder analysis with ZSL and RAW.</td> </tr>
+ * <tr> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code 640x480}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>In-app viewfinder analysis with ZSL and RAW.</td> </tr>
* <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code 640x480}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td><td>In-app viewfinder analysis with ZSL, RAW, and JPEG reprocessing output.</td> </tr>
* </table><br>
* </p>
diff --git a/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl b/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
index 2f6dbe7..597efa5 100644
--- a/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
+++ b/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
@@ -25,9 +25,12 @@
/**
* Called when the keyphrase is spoken.
*
- * @param data Optional trigger audio data, if it was requested and is available.
+ * @param recognitionEvent Object containing data relating to the
+ * recognition event such as trigger audio data, if it was requested
+ * and is available.
*/
- void onDetected(in SoundTrigger.KeyphraseRecognitionEvent recognitionEvent);
+ void onDetected(in SoundTrigger.RecognitionEvent recognitionEvent);
+
/**
* Called when the detection fails due to an error.
*
@@ -42,4 +45,4 @@
* Called when the recognition is resumed after it was temporarily paused.
*/
void onRecognitionResumed();
-}
\ No newline at end of file
+}
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.aidl b/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
index e16ea71..fec64ea 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
@@ -18,8 +18,11 @@
parcelable SoundTrigger.ConfidenceLevel;
parcelable SoundTrigger.Keyphrase;
+parcelable SoundTrigger.RecognitionEvent;
parcelable SoundTrigger.KeyphraseRecognitionEvent;
+parcelable SoundTrigger.GenericSoundRecognitionEvent;
parcelable SoundTrigger.KeyphraseRecognitionExtra;
parcelable SoundTrigger.KeyphraseSoundModel;
+parcelable SoundTrigger.GenericSoundModel;
parcelable SoundTrigger.ModuleProperties;
parcelable SoundTrigger.RecognitionConfig;
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index d490409..882908a 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -195,6 +195,12 @@
/** Keyphrase sound model */
public static final int TYPE_KEYPHRASE = 0;
+ /**
+ * A generic sound model. Use this type only for non-keyphrase sound models such as
+ * ones that match a particular sound pattern.
+ */
+ public static final int TYPE_GENERIC_SOUND = 1;
+
/** Unique sound model identifier */
public final UUID uuid;
@@ -458,6 +464,63 @@
}
}
+
+ /*****************************************************************************
+ * A GenericSoundModel is a specialized {@link SoundModel} for non-voice sound
+ * patterns.
+ ****************************************************************************/
+ public static class GenericSoundModel extends SoundModel implements Parcelable {
+
+ public static final Parcelable.Creator<GenericSoundModel> CREATOR
+ = new Parcelable.Creator<GenericSoundModel>() {
+ public GenericSoundModel createFromParcel(Parcel in) {
+ return GenericSoundModel.fromParcel(in);
+ }
+
+ public GenericSoundModel[] newArray(int size) {
+ return new GenericSoundModel[size];
+ }
+ };
+
+ public GenericSoundModel(UUID uuid, UUID vendorUuid, byte[] data) {
+ super(uuid, vendorUuid, TYPE_GENERIC_SOUND, data);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ private static GenericSoundModel fromParcel(Parcel in) {
+ UUID uuid = UUID.fromString(in.readString());
+ UUID vendorUuid = null;
+ int length = in.readInt();
+ if (length >= 0) {
+ vendorUuid = UUID.fromString(in.readString());
+ }
+ byte[] data = in.readBlob();
+ return new GenericSoundModel(uuid, vendorUuid, data);
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(uuid.toString());
+ if (vendorUuid == null) {
+ dest.writeInt(-1);
+ } else {
+ dest.writeInt(vendorUuid.toString().length());
+ dest.writeString(vendorUuid.toString());
+ }
+ dest.writeBlob(data);
+ }
+
+ @Override
+ public String toString() {
+ return "GenericSoundModel [uuid=" + uuid + ", vendorUuid=" + vendorUuid
+ + ", type=" + type + ", data=" + (data == null ? 0 : data.length) + "]";
+ }
+ }
+
/**
* Modes for key phrase recognition
*/
@@ -1019,6 +1082,21 @@
}
/**
+ * Sub-class of RecognitionEvent specifically for sound-trigger based sound
+ * models(non-keyphrase). Currently does not contain any additional fields.
+ */
+ public static class GenericRecognitionEvent extends RecognitionEvent {
+ public GenericRecognitionEvent(int status, int soundModelHandle,
+ boolean captureAvailable, int captureSession, int captureDelayMs,
+ int capturePreambleMs, boolean triggerInData, AudioFormat captureFormat,
+ byte[] data) {
+ super(status, soundModelHandle, captureAvailable, captureSession,
+ captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
+ data);
+ }
+ }
+
+ /**
* Status codes for {@link SoundModelEvent}
*/
/** Sound Model was updated */
@@ -1118,7 +1196,7 @@
public static final int SERVICE_STATE_DISABLED = 1;
/**
- * Returns a list of descriptors for all harware modules loaded.
+ * Returns a list of descriptors for all hardware modules loaded.
* @param modules A ModuleProperties array where the list will be returned.
* @return - {@link #STATUS_OK} in case of success
* - {@link #STATUS_ERROR} in case of unspecified error
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 4159d89..314b7d5 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -219,6 +219,15 @@
public static final int DRAW_WAKE_LOCK = 0x00000080;
/**
+ * Wake lock level: Enables Sustained Performance Mode.
+ * <p>
+ * This is used by Gaming and VR applications to ensure the device provides
+ * will provide consistent performance over a large amount of time.
+ * </p>
+ */
+ public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 0x00000100;
+
+ /**
* Mask for the wake lock level component of a combined wake lock level and flags integer.
*
* @hide
@@ -525,6 +534,7 @@
case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
case DOZE_WAKE_LOCK:
case DRAW_WAKE_LOCK:
+ case SUSTAINED_PERFORMANCE_WAKE_LOCK:
break;
default:
throw new IllegalArgumentException("Must specify a valid wake lock level.");
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index f765336..58a0269 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -91,4 +91,19 @@
* the icon is in this method.
*/
public abstract void setUserIcon(int userId, Bitmap bitmap);
+
+ /**
+ * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to inform the
+ * user manager whether all users should be created ephemeral.
+ */
+ public abstract void setForceEphemeralUsers(boolean forceEphemeralUsers);
+
+ /**
+ * Switches to the system user and deletes all other users.
+ *
+ * <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when
+ * the force-ephemeral-users policy is toggled on to make sure there are no pre-existing
+ * non-ephemeral users left.
+ */
+ public abstract void removeAllUsers();
}
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index 24683cb..8ee9d1e 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -101,6 +101,12 @@
public static final String ACTION_FETCH_VOICEMAIL = "android.intent.action.FETCH_VOICEMAIL";
/**
+ * Broadcast intent to request all voicemail sources to perform a sync with the remote server.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_SYNC_VOICEMAIL = "android.intent.action.SYNC_VOICEMAIL";
+
+ /**
* Extra included in {@link Intent#ACTION_PROVIDER_CHANGED} broadcast intents to indicate if the
* receiving package made this change.
*/
@@ -393,6 +399,14 @@
* <P>Type: INTEGER</P>
*/
public static final String CONFIGURATION_STATE = "configuration_state";
+ /**
+ * Value of {@link #CONFIGURATION_STATE} passed into
+ * {@link #setStatus(Context, PhoneAccountHandle, int, int, int)} to indicate that the
+ * {@link #CONFIGURATION_STATE} field is not to be changed
+ *
+ * @hide
+ */
+ public static final int CONFIGURATION_STATE_IGNORE = -1;
/** Value of {@link #CONFIGURATION_STATE} to indicate an all OK configuration status. */
public static final int CONFIGURATION_STATE_OK = 0;
/**
@@ -418,15 +432,50 @@
*/
public static final String DATA_CHANNEL_STATE = "data_channel_state";
/**
+ * Value of {@link #DATA_CHANNEL_STATE} passed into
+ * {@link #setStatus(Context, PhoneAccountHandle, int, int, int)} to indicate that the
+ * {@link #DATA_CHANNEL_STATE} field is not to be changed
+ *
+ * @hide
+ */
+ public static final int DATA_CHANNEL_STATE_IGNORE = -1;
+ /**
* Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel is working fine.
*/
public static final int DATA_CHANNEL_STATE_OK = 0;
/**
- * Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel connection is not
- * working.
+ * Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel failed to find a
+ * suitable network to connect to the server.
*/
public static final int DATA_CHANNEL_STATE_NO_CONNECTION = 1;
/**
+ * Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel failed to find a
+ * suitable network to connect to the server, and the carrier requires using cellular
+ * data network to connect to the server.
+ */
+ public static final int DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED = 2;
+ /**
+ * Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel received incorrect
+ * settings or credentials to connect to the server
+ */
+ public static final int DATA_CHANNEL_STATE_BAD_CONFIGURATION = 3;
+ /**
+ * Value of {@link #DATA_CHANNEL_STATE} to indicate that a error has occurred in the data
+ * channel while communicating with the server
+ */
+ public static final int DATA_CHANNEL_STATE_COMMUNICATION_ERROR = 4;
+ /**
+ * Value of {@link #DATA_CHANNEL_STATE} to indicate that the server reported an internal
+ * error to the data channel.
+ */
+ public static final int DATA_CHANNEL_STATE_SERVER_ERROR = 5;
+ /**
+ * Value of {@link #DATA_CHANNEL_STATE} to indicate that while there is a suitable network,
+ * the data channel is unable to establish a connection with the server.
+ */
+ public static final int DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR = 6;
+
+ /**
* The notification channel state of the voicemail source. This is the channel through which
* the source gets notified of new voicemails on the remote server.
* <P> Possible values:
@@ -438,6 +487,14 @@
*/
public static final String NOTIFICATION_CHANNEL_STATE = "notification_channel_state";
/**
+ * Value of {@link #NOTIFICATION_CHANNEL_STATE} passed into
+ * {@link #setStatus(Context, PhoneAccountHandle, int, int, int)} to indicate that the
+ * {@link #NOTIFICATION_CHANNEL_STATE} field is not to be changed
+ *
+ * @hide
+ */
+ public static final int NOTIFICATION_CHANNEL_STATE_IGNORE = -1;
+ /**
* Value of {@link #NOTIFICATION_CHANNEL_STATE} to indicate that the notification channel is
* working fine.
*/
@@ -497,21 +554,22 @@
*/
public static void setStatus(Context context, PhoneAccountHandle accountHandle,
int configurationState, int dataChannelState, int notificationChannelState) {
- ContentResolver contentResolver = context.getContentResolver();
- Uri statusUri = buildSourceUri(context.getPackageName());
ContentValues values = new ContentValues();
values.put(Status.PHONE_ACCOUNT_COMPONENT_NAME,
accountHandle.getComponentName().flattenToString());
values.put(Status.PHONE_ACCOUNT_ID, accountHandle.getId());
- values.put(Status.CONFIGURATION_STATE, configurationState);
- values.put(Status.DATA_CHANNEL_STATE, dataChannelState);
- values.put(Status.NOTIFICATION_CHANNEL_STATE, notificationChannelState);
-
- if (isStatusPresent(contentResolver, statusUri)) {
- contentResolver.update(statusUri, values, null, null);
- } else {
- contentResolver.insert(statusUri, values);
+ if(configurationState != CONFIGURATION_STATE_IGNORE) {
+ values.put(Status.CONFIGURATION_STATE, configurationState);
}
+ if(dataChannelState != DATA_CHANNEL_STATE_IGNORE) {
+ values.put(Status.DATA_CHANNEL_STATE, dataChannelState);
+ }
+ if(notificationChannelState != NOTIFICATION_CHANNEL_STATE_IGNORE) {
+ values.put(Status.NOTIFICATION_CHANNEL_STATE, notificationChannelState);
+ }
+ ContentResolver contentResolver = context.getContentResolver();
+ Uri statusUri = buildSourceUri(context.getPackageName());
+ contentResolver.insert(statusUri, values);
}
/**
@@ -540,28 +598,7 @@
ContentResolver contentResolver = context.getContentResolver();
Uri statusUri = buildSourceUri(context.getPackageName());
- if (isStatusPresent(contentResolver, statusUri)) {
- contentResolver.update(statusUri, values, null, null);
- } else {
- contentResolver.insert(statusUri, values);
- }
- }
-
- /**
- * Determines if a voicemail source exists in the status table.
- *
- * @param contentResolver A content resolver constructed from the appropriate context.
- * @param statusUri The content uri for the source.
- * @return {@code true} if a status entry for this source exists
- */
- private static boolean isStatusPresent(ContentResolver contentResolver, Uri statusUri) {
- Cursor cursor = null;
- try {
- cursor = contentResolver.query(statusUri, null, null, null, null);
- return cursor != null && cursor.getCount() != 0;
- } finally {
- if (cursor != null) cursor.close();
- }
+ contentResolver.insert(statusUri, values);
}
}
}
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index ac7d539..76a401d 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -31,6 +31,7 @@
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
import android.media.AudioFormat;
import android.os.AsyncTask;
import android.os.Handler;
@@ -616,7 +617,11 @@
}
@Override
- public void onDetected(KeyphraseRecognitionEvent event) {
+ public void onDetected(RecognitionEvent event) {
+ if (! (event instanceof KeyphraseRecognitionEvent)) {
+ Slog.e(TAG, "onDetected() called for a soundtrigger event.");
+ return;
+ }
if (DBG) {
Slog.d(TAG, "onDetected(" + event + ")");
} else {
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index cd19607..a985517 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -271,7 +271,7 @@
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
- Configuration newConfig, Rect backDropRect) {
+ Configuration newConfig, Rect backDropRect, boolean forceLayout) {
Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED,
reportDraw ? 1 : 0, outsets);
mCaller.sendMessage(msg);
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index c5ed39a..3688d50 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -49,7 +49,7 @@
void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets,
in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw,
- in Configuration newConfig, in Rect backDropFrame);
+ in Configuration newConfig, in Rect backDropFrame, boolean forceLayout);
void moved(int newX, int newY);
void dispatchAppVisibility(boolean visible);
void dispatchGetNewSurface();
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 9f6d3e5..5b48e28 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -698,7 +698,7 @@
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
- Configuration newConfig, Rect backDropRect) {
+ Configuration newConfig, Rect backDropRect, boolean forceLayout) {
SurfaceView surfaceView = mSurfaceView.get();
if (surfaceView != null) {
if (DEBUG) Log.v(
@@ -711,7 +711,8 @@
surfaceView.mReportDrawNeeded = true;
surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
} else if (surfaceView.mWinFrame.width() != frame.width()
- || surfaceView.mWinFrame.height() != frame.height()) {
+ || surfaceView.mWinFrame.height() != frame.height()
+ || forceLayout) {
surfaceView.mUpdateWindowNeeded = true;
surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5d41477..98e3289 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -263,6 +264,7 @@
boolean mNewSurfaceNeeded;
boolean mHasHadWindowFocus;
boolean mLastWasImTarget;
+ boolean mForceNextWindowRelayout;
CountDownLatch mWindowDrawCountDown;
boolean mIsDrawing;
@@ -1625,7 +1627,8 @@
final boolean isViewVisible = viewVisibility == View.VISIBLE;
if (mFirst || windowShouldResize || insetsChanged ||
- viewVisibilityChanged || params != null) {
+ viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
+ mForceNextWindowRelayout = false;
if (isViewVisible) {
// If this window is giving internal insets to the window
@@ -2099,7 +2102,7 @@
boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
- if (!cancelDraw && !newSurface) {
+ if (!cancelDraw) {
if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
for (int i = 0; i < mPendingTransitions.size(); ++i) {
mPendingTransitions.get(i).startChangingAnimations();
@@ -2148,6 +2151,7 @@
}
}
}
+
private void handleOutOfResourcesException(Surface.OutOfResourcesException e) {
Log.e(mTag, "OutOfResourcesException initializing HW surface", e);
try {
@@ -3365,7 +3369,8 @@
&& mPendingVisibleInsets.equals(args.arg3)
&& mPendingOutsets.equals(args.arg7)
&& mPendingBackDropFrame.equals(args.arg8)
- && args.arg4 == null) {
+ && args.arg4 == null
+ && args.argi1 == 0) {
break;
}
} // fall through...
@@ -3385,6 +3390,7 @@
mPendingVisibleInsets.set((Rect) args.arg3);
mPendingOutsets.set((Rect) args.arg7);
mPendingBackDropFrame.set((Rect) args.arg8);
+ mForceNextWindowRelayout = args.argi1 != 0;
args.recycle();
@@ -5829,7 +5835,7 @@
public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
- Configuration newConfig, Rect backDropFrame) {
+ Configuration newConfig, Rect backDropFrame, boolean forceLayout) {
if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString()
+ " contentInsets=" + contentInsets.toShortString()
+ " visibleInsets=" + visibleInsets.toShortString()
@@ -5863,6 +5869,7 @@
args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
args.arg7 = sameProcessCall ? new Rect(outsets) : outsets;
args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame;
+ args.argi1 = forceLayout ? 1 : 0;
msg.obj = args;
mHandler.sendMessage(msg);
}
@@ -6878,11 +6885,12 @@
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
- Configuration newConfig, Rect backDropFrame) {
+ Configuration newConfig, Rect backDropFrame, boolean forceLayout) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchResized(frame, overscanInsets, contentInsets,
- visibleInsets, stableInsets, outsets, reportDraw, newConfig, backDropFrame);
+ visibleInsets, stableInsets, outsets, reportDraw, newConfig, backDropFrame,
+ forceLayout);
}
}
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 3b9b8db..ec53a2e 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -121,4 +121,7 @@
void setBatteryState(int status, int health, int plugType, int level, int temp, int volt);
long getAwakeTimeBattery();
long getAwakeTimePlugged();
+
+ void noteBleScanStarted(in WorkSource ws);
+ void noteBleScanStopped(in WorkSource ws);
}
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
new file mode 100644
index 0000000..9de4a6c
--- /dev/null
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.internal.app;
+
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.ParcelUuid;
+
+/**
+ * Service interface for a generic sound recognition model.
+ * @hide
+ */
+interface ISoundTriggerService {
+
+
+ SoundTrigger.GenericSoundModel getSoundModel(in ParcelUuid soundModelId);
+
+ void updateSoundModel(in SoundTrigger.GenericSoundModel soundModel);
+
+ void deleteSoundModel(in ParcelUuid soundModelId);
+
+ void startRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
+
+ /**
+ * Stops recognition.
+ */
+ void stopRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
+}
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index a572486..a38139f 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -139,7 +139,12 @@
}
public SnapTarget getClosestDismissTarget(int position) {
- if (position - mDismissStartTarget.position < mDismissEndTarget.position - position) {
+ if (position < mFirstSplitTarget.position) {
+ return mDismissStartTarget;
+ } else if (position > mLastSplitTarget.position) {
+ return mDismissEndTarget;
+ } else if (position - mDismissStartTarget.position
+ < mDismissEndTarget.position - position) {
return mDismissStartTarget;
} else {
return mDismissEndTarget;
diff --git a/core/java/com/android/internal/policy/DockedDividerUtils.java b/core/java/com/android/internal/policy/DockedDividerUtils.java
index f7f5f15..00c65bd 100644
--- a/core/java/com/android/internal/policy/DockedDividerUtils.java
+++ b/core/java/com/android/internal/policy/DockedDividerUtils.java
@@ -48,17 +48,21 @@
outRect.top = position + dividerSize;
break;
}
- if (outRect.left >= outRect.right) {
- outRect.left = outRect.right - 1;
+ sanitizeStackBounds(outRect);
+ }
+
+ public static void sanitizeStackBounds(Rect bounds) {
+ if (bounds.left >= bounds.right) {
+ bounds.left = bounds.right - 1;
}
- if (outRect.top >= outRect.bottom) {
- outRect.top = outRect.bottom - 1;
+ if (bounds.top >= bounds.bottom) {
+ bounds.top = bounds.bottom - 1;
}
- if (outRect.right <= outRect.left) {
- outRect.right = outRect.left + 1;
+ if (bounds.right <= bounds.left) {
+ bounds.right = bounds.left + 1;
}
- if (outRect.bottom <= outRect.top) {
- outRect.bottom = outRect.top + 1;
+ if (bounds.bottom <= bounds.top) {
+ bounds.bottom = bounds.top + 1;
}
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 7dfc15d..bcc310f 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -38,7 +38,7 @@
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig,
- Rect backDropFrame) {
+ Rect backDropFrame, boolean forceLayout) {
if (reportDraw) {
try {
mSession.finishDrawing(this);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 56c3fc8..3aa7de5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1407,6 +1407,13 @@
<permission android:name="android.permission.BIND_INCALL_SERVICE"
android:protectionLevel="signature|privileged" />
+ <!-- Must be required by a {@link android.telecom.CallScreeningService},
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature|privileged
+ -->
+ <permission android:name="android.permission.BIND_SCREENING_SERVICE"
+ android:protectionLevel="signature|privileged" />
+
<!-- Must be required by a {@link android.telecom.ConnectionService},
to ensure that only the system can bind to it.
@deprecated {@link android.telecom.ConnectionService}s should require
@@ -2860,6 +2867,12 @@
<permission android:name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"
android:protectionLevel="signature|privileged" />
+ <!-- Must be required by system/priv apps when accessing the sound trigger
+ APIs given by {@link SoundTriggerManager}.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.MANAGE_SOUND_TRIGGER"
+ android:protectionLevel="signature|privileged" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index bde3d19..000a56d 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -251,6 +251,10 @@
* @hide
* */
public static final int ENCODING_AAC_HE_V2 = 12;
+ /** Audio data format: compressed audio wrapped in PCM for HDMI
+ * or S/PDIF passthrough.
+ */
+ public static final int ENCODING_IEC61937 = 13;
/** Invalid audio channel configuration */
/** @deprecated Use {@link #CHANNEL_INVALID} instead. */
@@ -418,6 +422,7 @@
case ENCODING_PCM_8BIT:
return 1;
case ENCODING_PCM_16BIT:
+ case ENCODING_IEC61937:
case ENCODING_DEFAULT:
return 2;
case ENCODING_PCM_FLOAT:
@@ -443,6 +448,7 @@
case ENCODING_AAC_LC:
case ENCODING_AAC_HE_V1:
case ENCODING_AAC_HE_V2:
+ case ENCODING_IEC61937:
return true;
default:
return false;
@@ -460,6 +466,7 @@
case ENCODING_E_AC3:
case ENCODING_DTS:
case ENCODING_DTS_HD:
+ case ENCODING_IEC61937:
return true;
default:
return false;
@@ -483,6 +490,7 @@
case ENCODING_AAC_LC:
case ENCODING_AAC_HE_V1:
case ENCODING_AAC_HE_V2:
+ case ENCODING_IEC61937: // wrapped in PCM but compressed
return false;
case ENCODING_INVALID:
default:
@@ -490,6 +498,30 @@
}
}
+ /** @hide */
+ public static boolean isEncodingLinearFrames(int audioFormat)
+ {
+ switch (audioFormat) {
+ case ENCODING_PCM_8BIT:
+ case ENCODING_PCM_16BIT:
+ case ENCODING_PCM_FLOAT:
+ case ENCODING_IEC61937: // same size as stereo PCM
+ case ENCODING_DEFAULT:
+ return true;
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
+ case ENCODING_DTS:
+ case ENCODING_DTS_HD:
+ case ENCODING_MP3:
+ case ENCODING_AAC_LC:
+ case ENCODING_AAC_HE_V1:
+ case ENCODING_AAC_HE_V2:
+ return false;
+ case ENCODING_INVALID:
+ default:
+ throw new IllegalArgumentException("Bad audio format " + audioFormat);
+ }
+ }
/**
* Returns an array of public encoding values extracted from an array of
* encoding values.
@@ -715,6 +747,7 @@
case ENCODING_E_AC3:
case ENCODING_DTS:
case ENCODING_DTS_HD:
+ case ENCODING_IEC61937:
mEncoding = encoding;
break;
case ENCODING_INVALID:
@@ -859,7 +892,8 @@
ENCODING_AC3,
ENCODING_E_AC3,
ENCODING_DTS,
- ENCODING_DTS_HD
+ ENCODING_DTS_HD,
+ ENCODING_IEC61937
})
@Retention(RetentionPolicy.SOURCE)
public @interface Encoding {}
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 331fde1..d9690f0 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -1735,7 +1735,7 @@
}
private void applyLevelLimits() {
- int maxBlocksPerSecond = 0;
+ long maxBlocksPerSecond = 0;
int maxBlocks = 0;
int maxBps = 0;
int maxDPBBlocks = 0;
@@ -2061,11 +2061,11 @@
16 /* blockWidth */, 16 /* blockHeight */,
1 /* widthAlignment */, 1 /* heightAlignment */);
mFrameRateRange = Range.create(1, maxRate);
- } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ||
- mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
- maxBlocks = maxBlocksPerSecond = Integer.MAX_VALUE;
+ } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8)) {
+ maxBlocks = Integer.MAX_VALUE;
+ maxBlocksPerSecond = Integer.MAX_VALUE;
- // TODO: set to 100Mbps for now, need a number for VPX
+ // TODO: set to 100Mbps for now, need a number for VP8
maxBps = 100000000;
// profile levels are not indicative for VPx, but verify
@@ -2093,11 +2093,80 @@
errors &= ~ERROR_NONE_SUPPORTED;
}
- final int blockSize =
- mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ? 16 : 8;
+ final int blockSize = 16;
applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE,
maxBlocks, maxBlocksPerSecond, blockSize, blockSize,
1 /* widthAlignment */, 1 /* heightAlignment */);
+ } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+ maxBlocksPerSecond = 829440;
+ maxBlocks = 36864;
+ maxBps = 200000;
+
+ for (CodecProfileLevel profileLevel: profileLevels) {
+ long SR = 0;
+ int FS = 0;
+ int BR = 0;
+ switch (profileLevel.level) {
+ case CodecProfileLevel.VP9Level1:
+ SR = 829440; FS = 36864; BR = 200; break;
+ case CodecProfileLevel.VP9Level11:
+ SR = 2764800; FS = 73728; BR = 800; break;
+ case CodecProfileLevel.VP9Level2:
+ SR = 4608000; FS = 122880; BR = 1800; break;
+ case CodecProfileLevel.VP9Level21:
+ SR = 9216000; FS = 245760; BR = 3600; break;
+ case CodecProfileLevel.VP9Level3:
+ SR = 20736000; FS = 552960; BR = 7200; break;
+ case CodecProfileLevel.VP9Level31:
+ SR = 36864000; FS = 983040; BR = 12000; break;
+ case CodecProfileLevel.VP9Level4:
+ SR = 83558400; FS = 2228224; BR = 18000; break;
+ case CodecProfileLevel.VP9Level41:
+ SR = 160432128; FS = 2228224; BR = 30000; break;
+ case CodecProfileLevel.VP9Level5:
+ SR = 311951360; FS = 8912896; BR = 60000; break;
+ case CodecProfileLevel.VP9Level51:
+ SR = 588251136; FS = 8912896; BR = 120000; break;
+ case CodecProfileLevel.VP9Level52:
+ SR = 1176502272; FS = 8912896; BR = 180000; break;
+ case CodecProfileLevel.VP9Level6:
+ SR = 1176502272; FS = 35651584; BR = 180000; break;
+ case CodecProfileLevel.VP9Level61:
+ SR = 2353004544L; FS = 35651584; BR = 240000; break;
+ case CodecProfileLevel.VP9Level62:
+ SR = 4706009088L; FS = 35651584; BR = 480000; break;
+ default:
+ Log.w(TAG, "Unrecognized level "
+ + profileLevel.level + " for " + mime);
+ errors |= ERROR_UNRECOGNIZED;
+ }
+ switch (profileLevel.profile) {
+ case CodecProfileLevel.VP9Profile0:
+ case CodecProfileLevel.VP9Profile1:
+ case CodecProfileLevel.VP9Profile2:
+ case CodecProfileLevel.VP9Profile3:
+ break;
+ default:
+ Log.w(TAG, "Unrecognized profile "
+ + profileLevel.profile + " for " + mime);
+ errors |= ERROR_UNRECOGNIZED;
+ }
+ errors &= ~ERROR_NONE_SUPPORTED;
+ maxBlocksPerSecond = Math.max(SR, maxBlocksPerSecond);
+ maxBlocks = Math.max(FS, maxBlocks);
+ maxBps = Math.max(BR * 1000, maxBps);
+ }
+
+ final int blockSize = 8;
+ int maxLengthInBlocks = Utils.divUp(maxBlocks, blockSize);
+ maxBlocks = Utils.divUp(maxBlocks, blockSize * blockSize);
+ maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, blockSize * blockSize);
+
+ applyMacroBlockLimits(
+ maxLengthInBlocks, maxLengthInBlocks,
+ maxBlocks, maxBlocksPerSecond,
+ blockSize, blockSize,
+ 1 /* widthAlignment */, 1 /* heightAlignment */);
} else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
maxBlocks = 36864;
maxBlocksPerSecond = maxBlocks * 15;
@@ -2540,6 +2609,28 @@
// from OMX_VIDEO_VP8PROFILETYPE
public static final int VP8ProfileMain = 0x01;
+ // from OMX_VIDEO_VP9PROFILETYPE
+ public static final int VP9Profile0 = 0x00;
+ public static final int VP9Profile1 = 0x01;
+ public static final int VP9Profile2 = 0x02;
+ public static final int VP9Profile3 = 0x03;
+
+ // from OMX_VIDEO_VP9LEVELTYPE
+ public static final int VP9Level1 = 0x0;
+ public static final int VP9Level11 = 0x1;
+ public static final int VP9Level2 = 0x2;
+ public static final int VP9Level21 = 0x4;
+ public static final int VP9Level3 = 0x8;
+ public static final int VP9Level31 = 0x10;
+ public static final int VP9Level4 = 0x20;
+ public static final int VP9Level41 = 0x40;
+ public static final int VP9Level5 = 0x80;
+ public static final int VP9Level51 = 0x100;
+ public static final int VP9Level52 = 0x200;
+ public static final int VP9Level6 = 0x400;
+ public static final int VP9Level61 = 0x800;
+ public static final int VP9Level62 = 0x1000;
+
// from OMX_VIDEO_HEVCPROFILETYPE
public static final int HEVCProfileMain = 0x01;
public static final int HEVCProfileMain10 = 0x02;
@@ -2594,14 +2685,18 @@
/**
* Defined in the OpenMAX IL specs, depending on the type of media
* this can be OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE,
- * OMX_VIDEO_MPEG4PROFILETYPE or OMX_VIDEO_VP8PROFILETYPE.
+ * OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_VP8PROFILETYPE or OMX_VIDEO_VP9PROFILETYPE.
*/
public int profile;
/**
* Defined in the OpenMAX IL specs, depending on the type of media
* this can be OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE
- * OMX_VIDEO_MPEG4LEVELTYPE or OMX_VIDEO_VP8LEVELTYPE.
+ * OMX_VIDEO_MPEG4LEVELTYPE, OMX_VIDEO_VP8LEVELTYPE or OMX_VIDEO_VP9LEVELTYPE.
+ *
+ * Note that VP9 decoder on platforms before {@link android.os.Build.VERSION_CODES#N} may
+ * not advertise a profile level support. For those VP9 decoders, please use
+ * {@link VideoCapabilities} to determine the codec capabilities.
*/
public int level;
};
diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java
index 2cd3c43..35b083e 100644
--- a/media/java/android/media/Utils.java
+++ b/media/java/android/media/Utils.java
@@ -174,7 +174,7 @@
return (num + den - 1) / den;
}
- private static long divUp(long num, long den) {
+ static long divUp(long num, long den) {
return (num + den - 1) / den;
}
diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
new file mode 100644
index 0000000..ebba343
--- /dev/null
+++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
@@ -0,0 +1,180 @@
+/**
+ * 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.media.soundtrigger;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.Handler;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.app.ISoundTriggerService;
+
+import java.io.PrintWriter;
+import java.util.UUID;
+
+/**
+ * A class that allows interaction with the actual sound trigger detection on the system.
+ * Sound trigger detection refers to a detectors that match generic sound patterns that are
+ * not voice-based. The voice-based recognition models should utilize the {@link
+ * VoiceInteractionService} instead. Access to this class is protected by a permission
+ * granted only to system or privileged apps.
+ *
+ * @hide
+ */
+public final class SoundTriggerDetector {
+ private static final boolean DBG = false;
+ private static final String TAG = "SoundTriggerDetector";
+
+ private final Object mLock = new Object();
+
+ private final ISoundTriggerService mSoundTriggerService;
+ private final UUID mSoundModelId;
+ private final Callback mCallback;
+ private final Handler mHandler;
+ private final RecognitionCallback mRecognitionCallback;
+
+ public abstract class Callback {
+ /**
+ * Called when the availability of the sound model changes.
+ */
+ public abstract void onAvailabilityChanged(int status);
+
+ /**
+ * Called when the sound model has triggered (such as when it matched a
+ * given sound pattern).
+ */
+ public abstract void onDetected();
+
+ /**
+ * Called when the detection fails due to an error.
+ */
+ public abstract void onError();
+
+ /**
+ * Called when the recognition is paused temporarily for some reason.
+ * This is an informational callback, and the clients shouldn't be doing anything here
+ * except showing an indication on their UI if they have to.
+ */
+ public abstract void onRecognitionPaused();
+
+ /**
+ * Called when the recognition is resumed after it was temporarily paused.
+ * This is an informational callback, and the clients shouldn't be doing anything here
+ * except showing an indication on their UI if they have to.
+ */
+ public abstract void onRecognitionResumed();
+ }
+
+ /**
+ * This class should be constructed by the {@link SoundTriggerManager}.
+ * @hide
+ */
+ SoundTriggerDetector(ISoundTriggerService soundTriggerService, UUID soundModelId,
+ @NonNull Callback callback, @Nullable Handler handler) {
+ mSoundTriggerService = soundTriggerService;
+ mSoundModelId = soundModelId;
+ mCallback = callback;
+ if (handler == null) {
+ mHandler = new Handler();
+ } else {
+ mHandler = handler;
+ }
+ mRecognitionCallback = new RecognitionCallback();
+ }
+
+ /**
+ * Starts recognition on the associated sound model. Result is indicated via the
+ * {@link Callback}.
+ * @return Indicates whether the call succeeded or not.
+ */
+ public boolean startRecognition() {
+ if (DBG) {
+ Slog.d(TAG, "startRecognition()");
+ }
+ try {
+ mSoundTriggerService.startRecognition(new ParcelUuid(mSoundModelId),
+ mRecognitionCallback);
+ } catch (RemoteException e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Stops recognition for the associated model.
+ */
+ public boolean stopRecognition() {
+ try {
+ mSoundTriggerService.stopRecognition(new ParcelUuid(mSoundModelId),
+ mRecognitionCallback);
+ } catch (RemoteException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public void dump(String prefix, PrintWriter pw) {
+ synchronized (mLock) {
+ // TODO: Dump useful debug information.
+ }
+ }
+
+ /**
+ * Callback that handles events from the lower sound trigger layer.
+ * @hide
+ */
+ private static class RecognitionCallback extends
+ IRecognitionStatusCallback.Stub {
+
+ /**
+ * @hide
+ */
+ @Override
+ public void onDetected(SoundTrigger.RecognitionEvent event) {
+ Slog.e(TAG, "onDetected()" + event);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void onError(int status) {
+ Slog.e(TAG, "onError()" + status);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void onRecognitionPaused() {
+ Slog.e(TAG, "onRecognitionPaused()");
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void onRecognitionResumed() {
+ Slog.e(TAG, "onRecognitionResumed()");
+ }
+ }
+}
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
new file mode 100644
index 0000000..4ae8e72
--- /dev/null
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.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 android.media.soundtrigger;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.Handler;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.app.ISoundTriggerService;
+
+import java.util.HashMap;
+import java.util.UUID;
+
+/**
+ * This class provides management of non-voice (general sound trigger) based sound recognition
+ * models. Usage of this class is restricted to system or signature applications only. This allows
+ * OEMs to write apps that can manage non-voice based sound trigger models.
+ *
+ * @hide
+ * TODO: Mark this as a SystemApi and get approval.
+ */
+public final class SoundTriggerManager {
+ private static final boolean DBG = false;
+ private static final String TAG = "SoundTriggerManager";
+
+ private final Context mContext;
+ private final ISoundTriggerService mSoundTriggerService;
+
+ // Stores a mapping from the sound model UUID to the SoundTriggerInstance created by
+ // the createSoundTriggerDetector() call.
+ private final HashMap<UUID, SoundTriggerDetector> mReceiverInstanceMap;
+
+ /**
+ * @hide
+ */
+ public SoundTriggerManager(Context context, ISoundTriggerService soundTriggerService ) {
+ if (DBG) {
+ Slog.i(TAG, "SoundTriggerManager created.");
+ }
+ mSoundTriggerService = soundTriggerService;
+ mContext = context;
+ mReceiverInstanceMap = new HashMap<UUID, SoundTriggerDetector>();
+ }
+
+ /**
+ * Updates the given sound trigger model.
+ */
+ public void updateModel(Model model) {
+ try {
+ mSoundTriggerService.updateSoundModel(model.getGenericSoundModel());
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Returns the sound trigger model represented by the given UUID. An instance of {@link Model}
+ * is returned.
+ */
+ public Model getModel(UUID soundModelId) {
+ try {
+ return new Model(mSoundTriggerService.getSoundModel(
+ new ParcelUuid(soundModelId)));
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Deletes the sound model represented by the provided UUID.
+ */
+ public void deleteModel(UUID soundModelId) {
+ try {
+ mSoundTriggerService.deleteSoundModel(new ParcelUuid(soundModelId));
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Creates an instance of {@link SoundTriggerDetector} which can be used to start/stop
+ * recognition on the model and register for triggers from the model. Note that this call
+ * invalidates any previously returned instances for the same sound model Uuid.
+ *
+ * @param soundModelId UUID of the sound model to create the receiver object for.
+ * @param callback Instance of the {@link SoundTriggerDetector#Callback} object for the
+ * callbacks for the given sound model.
+ * @param handler The Handler to use for the callback operations. A null value will use the
+ * current thread's Looper.
+ * @return Instance of {@link SoundTriggerDetector} or null on error.
+ */
+ @Nullable
+ public SoundTriggerDetector createSoundTriggerDetector(UUID soundModelId,
+ @NonNull SoundTriggerDetector.Callback callback, @Nullable Handler handler) {
+ if (soundModelId == null) {
+ return null;
+ }
+
+ SoundTriggerDetector oldInstance = mReceiverInstanceMap.get(soundModelId);
+ if (oldInstance != null) {
+ // Shutdown old instance.
+ }
+ SoundTriggerDetector newInstance = new SoundTriggerDetector(mSoundTriggerService,
+ soundModelId, callback, handler);
+ mReceiverInstanceMap.put(soundModelId, newInstance);
+ return newInstance;
+ }
+
+ /**
+ * Class captures the data and fields that represent a non-keyphrase sound model. Use the
+ * factory constructor {@link Model#create()} to create an instance.
+ */
+ // We use encapsulation to expose the SoundTrigger.GenericSoundModel as a SystemApi. This
+ // prevents us from exposing SoundTrigger.GenericSoundModel as an Api.
+ public static class Model {
+
+ private SoundTrigger.GenericSoundModel mGenericSoundModel;
+
+ /**
+ * @hide
+ */
+ Model(SoundTrigger.GenericSoundModel soundTriggerModel) {
+ mGenericSoundModel = soundTriggerModel;
+ }
+
+ /**
+ * Factory constructor to create a SoundModel instance for use with methods in this
+ * class.
+ */
+ public static Model create(UUID modelUuid, UUID vendorUuid, byte[] data) {
+ return new Model(new SoundTrigger.GenericSoundModel(modelUuid,
+ vendorUuid, data));
+ }
+
+ public UUID getModelUuid() {
+ return mGenericSoundModel.uuid;
+ }
+
+ public UUID getVendorUuid() {
+ return mGenericSoundModel.vendorUuid;
+ }
+
+ public byte[] getModelData() {
+ return mGenericSoundModel.data;
+ }
+
+ /**
+ * @hide
+ */
+ SoundTrigger.GenericSoundModel getGenericSoundModel() {
+ return mGenericSoundModel;
+ }
+ }
+}
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index fa9ff01..c3452d5 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -54,7 +54,8 @@
android:name=".LauncherActivity"
android:theme="@android:style/Theme.NoDisplay"
android:icon="@drawable/ic_files_app"
- android:label="@string/files_label">
+ android:label="@string/files_label"
+ android:enabled="@bool/productivity_device">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml
index e8d8c8e..ff28e15 100644
--- a/packages/DocumentsUI/res/values/config.xml
+++ b/packages/DocumentsUI/res/values/config.xml
@@ -18,6 +18,7 @@
<!-- Allow Advanced Devices default value to be customised -->
<bool name="config_defaultAdvancedDevices">false</bool>
+ <bool name="productivity_device">true</bool>
<!-- Intentionally unset. Vendors should set this in an overlay. -->
<string name="trusted_quick_viewer_package"></string>
</resources>
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index ff7b7b9..aefdc67 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -65,13 +65,9 @@
<string name="menu_paste_from_clipboard">Paste</string>
<!-- Menu item that reveals internal storage built into the device [CHAR LIMIT=24] -->
- <string name="menu_advanced_show" product="nosdcard">Show internal storage</string>
- <!-- Menu item that reveals SD cards built into the device [CHAR LIMIT=24] -->
- <string name="menu_advanced_show" product="default">Show SD card</string>
+ <string name="menu_advanced_show">Show internal storage</string>
<!-- Menu item that hides internal storage built into the device [CHAR LIMIT=24] -->
- <string name="menu_advanced_hide" product="nosdcard">Hide internal storage</string>
- <!-- Menu item that hides SD cards built into the device [CHAR LIMIT=24] -->
- <string name="menu_advanced_hide" product="default">Hide SD card</string>
+ <string name="menu_advanced_hide">Hide internal storage</string>
<!-- Menu item that reveals the sizes of displayed files [CHAR LIMIT=24] -->
<string name="menu_file_size_show">Show file size</string>
diff --git a/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
new file mode 100644
index 0000000..b4144a3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="40.0"
+ android:viewportHeight="40.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M19.0,6.41L17.59,5.0 12.0,10.59 6.41,5.0 5.0,6.41 10.59,12.0 5.0,17.59 6.41,19.0 12.0,13.41 17.59,19.0 19.0,17.59 13.41,12.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_disabled.xml b/packages/SystemUI/res/drawable/stat_sys_data_disabled.xml
new file mode 100644
index 0000000..4e2a024
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_disabled.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="17.0dp"
+ android:height="17.0dp"
+ android:viewportWidth="40.0"
+ android:viewportHeight="40.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M19.0,6.41L17.59,5.0 12.0,10.59 6.41,5.0 5.0,6.41 10.59,12.0 5.0,17.59 6.41,19.0 12.0,13.41 17.59,19.0 19.0,17.59 13.41,12.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e245c24..8b0350a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -137,6 +137,8 @@
<dimen name="standard_notification_panel_width">416dp</dimen>
<dimen name="notification_panel_width">@dimen/match_parent</dimen>
+ <dimen name="volume_dialog_panel_width">@dimen/standard_notification_panel_width</dimen>
+
<!-- Gravity for the notification panel -->
<integer name="standard_notification_panel_layout_gravity">0x31</integer><!-- top|center_horizontal -->
<integer name="notification_panel_layout_gravity">0x37</integer><!-- fill_horizontal|top -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 02158ac..a490635 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -359,6 +359,9 @@
<!-- Content description of the data connection with no SIM for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_no_sim">No SIM.</string>
+ <!-- Content description of the cell data being disabled. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_cell_data_off">Cellular Data Off</string>
+
<!-- Content description of the bluetooth tethering icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_bluetooth_tether">Bluetooth tethering.</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 5b955a4..6b74652 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -67,6 +67,7 @@
private FalsingManager mFalsingManager;
private float mInitialTouchPos;
+ private float mPerpendicularInitialTouchPos;
private boolean mDragging;
private View mCurrView;
private View mCurrAnimView;
@@ -117,6 +118,10 @@
return mSwipeDirection == X ? ev.getX() : ev.getY();
}
+ private float getPerpendicularPos(MotionEvent ev) {
+ return mSwipeDirection == X ? ev.getY() : ev.getX();
+ }
+
private float getTranslation(View v) {
return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY();
}
@@ -240,6 +245,7 @@
mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
mVelocityTracker.addMovement(ev);
mInitialTouchPos = getPos(ev);
+ mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
if (mLongPressListener != null) {
if (mWatchLongPress == null) {
@@ -271,8 +277,11 @@
if (mCurrView != null && !mLongPressSent) {
mVelocityTracker.addMovement(ev);
float pos = getPos(ev);
+ float perpendicularPos = getPerpendicularPos(ev);
float delta = pos - mInitialTouchPos;
- if (Math.abs(delta) > mPagingTouchSlop) {
+ float deltaPerpendicular = perpendicularPos - mPerpendicularInitialTouchPos;
+ if (Math.abs(delta) > mPagingTouchSlop
+ && Math.abs(delta) > Math.abs(deltaPerpendicular)) {
mCallback.onBeginDrag(mCurrView);
mDragging = true;
mInitialTouchPos = getPos(ev) - getTranslation(mCurrAnimView);
@@ -280,7 +289,6 @@
removeLongPressCallback();
}
}
-
break;
case MotionEvent.ACTION_UP:
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index e9f6f39..7019444 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -215,8 +215,11 @@
case MotionEvent.ACTION_MOVE: {
int activePointerIndex = ev.findPointerIndex(mActivePointerId);
int y = (int) ev.getY(activePointerIndex);
+ int x = (int) ev.getX(activePointerIndex);
if (!mIsScrolling) {
- if (Math.abs(y - mDownY) > mScrollTouchSlop) {
+ int yDiff = Math.abs(y - mDownY);
+ int xDiff = Math.abs(x - mDownX);
+ if (Math.abs(y - mDownY) > mScrollTouchSlop && yDiff > xDiff) {
mIsScrolling = true;
// Disallow parents from intercepting touch events
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index c0e1e44..dca7fd9 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -73,8 +73,6 @@
private static final String TAG = "DividerView";
private static final int TASK_POSITION_SAME = Integer.MAX_VALUE;
- private static final float DIM_START_FRACTION = 0.5f;
- private static final float DIM_DAMP_FACTOR = 1.7f;
/**
* Fraction of the divider position between two snap targets to switch to the full-screen
@@ -90,6 +88,8 @@
private static final PathInterpolator SLOWDOWN_INTERPOLATOR =
new PathInterpolator(0.5f, 1f, 0.5f, 1f);
+ private static final PathInterpolator DIM_INTERPOLATOR =
+ new PathInterpolator(.23f, .87f, .52f, -0.11f);
private DividerHandleView mHandle;
private View mBackground;
@@ -497,8 +497,8 @@
mWindowManagerProxy.resizeDockedStack(mDockedRect, null, null, null, null);
}
float fraction = mSnapAlgorithm.calculateDismissingFraction(position);
- fraction = Math.max(0,
- Math.min((fraction / DIM_START_FRACTION - 1f) / DIM_DAMP_FACTOR, 1f));
+ fraction = Math.max(0, Math.min(fraction, 1f));
+ fraction = DIM_INTERPOLATOR.getInterpolation(fraction);
mWindowManagerProxy.setResizeDimLayer(fraction != 0f,
getStackIdForDismissTarget(mSnapAlgorithm.getClosestDismissTarget(position)),
fraction);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index 4e3ecb1..dba7130 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -170,12 +170,13 @@
invalidate();
return;
}
- area.left = Math.max(area.left, 0);
- area.top = Math.max(area.top, 0);
- area.right = Math.min(area.right, getWidth());
- area.bottom = Math.min(area.bottom, getHeight());
- mExcludedRect.set(area);
- mHasExcludedArea = area.left < area.right && area.top < area.bottom;
+
+ int left = Math.max(area.left, 0);
+ int top = Math.max(area.top, 0);
+ int right = Math.min(area.right, getWidth());
+ int bottom = Math.min(area.bottom, getHeight());
+ mExcludedRect.set(left, top, right, bottom);
+ mHasExcludedArea = left < right && top < bottom;
invalidate();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 7395a33..ba08ee7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -14,6 +14,7 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -37,20 +38,20 @@
public static final String NAV_BAR_VIEWS = "sysui_nav_bar";
- private static final String MENU_IME = "menu_ime";
- private static final String BACK = "back";
- private static final String HOME = "home";
- private static final String RECENT = "recent";
- private static final String NAVSPACE = "space";
+ protected static final String MENU_IME = "menu_ime";
+ protected static final String BACK = "back";
+ protected static final String HOME = "home";
+ protected static final String RECENT = "recent";
+ protected static final String NAVSPACE = "space";
public static final String GRAVITY_SEPARATOR = ";";
public static final String BUTTON_SEPARATOR = ",";
- private final LayoutInflater mLayoutInflater;
- private final LayoutInflater mLandscapeInflater;
+ protected final LayoutInflater mLayoutInflater;
+ protected final LayoutInflater mLandscapeInflater;
- private FrameLayout mRot0;
- private FrameLayout mRot90;
+ protected FrameLayout mRot0;
+ protected FrameLayout mRot90;
private SparseArray<ButtonDispatcher> mButtonDispatchers;
private String mCurrentLayout;
@@ -72,7 +73,7 @@
inflateLayout(getDefaultLayout());
}
- private String getDefaultLayout() {
+ protected String getDefaultLayout() {
return mContext.getString(R.string.config_navBarLayout);
}
@@ -128,9 +129,9 @@
}
}
- private void inflateLayout(String newLayout) {
+ protected void inflateLayout(String newLayout) {
mCurrentLayout = newLayout;
- String[] sets = newLayout.split(GRAVITY_SEPARATOR);
+ String[] sets = newLayout.split(GRAVITY_SEPARATOR, 3);
String[] start = sets[0].split(BUTTON_SEPARATOR);
String[] center = sets[1].split(BUTTON_SEPARATOR);
String[] end = sets[2].split(BUTTON_SEPARATOR);
@@ -165,6 +166,8 @@
}
private void copyToLightsout(View view, ViewGroup lightsOutParent) {
+ if (view == null) return;
+
if (view instanceof FrameLayout) {
// The only ViewGroup we support in here is a FrameLayout, so copy those manually.
FrameLayout original = (FrameLayout) view;
@@ -202,35 +205,33 @@
return new LayoutParams(layoutParams.width, layoutParams.height);
}
- private View inflateButton(String button, ViewGroup parent, boolean landscape) {
- View v = null;
+ @Nullable
+ protected View inflateButton(String button, ViewGroup parent, boolean landscape) {
+ View v;
+ LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
if (HOME.equals(button)) {
- v = (landscape ? mLandscapeInflater : mLayoutInflater)
- .inflate(R.layout.home, parent, false);
+ v = inflater.inflate(R.layout.home, parent, false);
if (landscape && isSw600Dp()) {
setupLandButton(v);
}
} else if (BACK.equals(button)) {
- v = (landscape ? mLandscapeInflater : mLayoutInflater)
- .inflate(R.layout.back, parent, false);
+ v = inflater.inflate(R.layout.back, parent, false);
if (landscape && isSw600Dp()) {
setupLandButton(v);
}
} else if (RECENT.equals(button)) {
- v = (landscape ? mLandscapeInflater : mLayoutInflater)
- .inflate(R.layout.recent_apps, parent, false);
+ v = inflater.inflate(R.layout.recent_apps, parent, false);
if (landscape && isSw600Dp()) {
setupLandButton(v);
}
} else if (MENU_IME.equals(button)) {
- v = (landscape ? mLandscapeInflater : mLayoutInflater)
- .inflate(R.layout.menu_ime, parent, false);
+ v = inflater.inflate(R.layout.menu_ime, parent, false);
} else if (NAVSPACE.equals(button)) {
- v = (landscape ? mLandscapeInflater : mLayoutInflater)
- .inflate(R.layout.nav_key_space, parent, false);
+ v = inflater.inflate(R.layout.nav_key_space, parent, false);
} else {
- throw new IllegalArgumentException("Unknown button " + button);
+ return null;
}
+
parent.addView(v);
addToDispatchers(v);
return v;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index ad8e3bd..8fd4d9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -206,7 +206,8 @@
// Show icon in QS when we are connected or need to show roaming.
boolean showDataIcon = mCurrentState.dataConnected
- || mCurrentState.iconGroup == TelephonyIcons.ROAMING;
+ || mCurrentState.iconGroup == TelephonyIcons.ROAMING
+ || mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED;
IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
getCurrentIconId(), contentDescription);
@@ -227,7 +228,8 @@
&& !mCurrentState.carrierNetworkChangeMode
&& mCurrentState.activityOut;
showDataIcon &= mCurrentState.isDefault
- || mCurrentState.iconGroup == TelephonyIcons.ROAMING;
+ || mCurrentState.iconGroup == TelephonyIcons.ROAMING
+ || mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED;
int typeIcon = showDataIcon ? icons.mDataType : 0;
mCallbackHandler.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
@@ -385,6 +387,8 @@
mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
} else if (isRoaming()) {
mCurrentState.iconGroup = TelephonyIcons.ROAMING;
+ } else if (isDataDisabled()) {
+ mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;
}
if (isEmergencyOnly() != mCurrentState.isEmergency) {
mCurrentState.isEmergency = isEmergencyOnly();
@@ -399,6 +403,10 @@
notifyListenersIfNecessary();
}
+ private boolean isDataDisabled() {
+ return !mPhone.getDataEnabled(mSubscriptionInfo.getSubscriptionId());
+ }
+
@VisibleForTesting
void setActivity(int activity) {
mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index 83e0446..6ff8f77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -208,6 +208,8 @@
static final int ICON_CARRIER_NETWORK_CHANGE =
R.drawable.stat_sys_signal_carrier_network_change_animation;
+ static final int ICON_DATA_DISABLED = R.drawable.stat_sys_data_disabled;
+
static final int QS_ICON_LTE = R.drawable.ic_qs_signal_lte;
static final int QS_ICON_3G = R.drawable.ic_qs_signal_3g;
static final int QS_ICON_4G = R.drawable.ic_qs_signal_4g;
@@ -215,6 +217,8 @@
static final int QS_ICON_CARRIER_NETWORK_CHANGE =
R.drawable.ic_qs_signal_carrier_network_change_animation;
+ static final int QS_ICON_DATA_DISABLED = R.drawable.ic_qs_data_disabled;
+
static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup(
"CARRIER_NETWORK_CHANGE",
TelephonyIcons.TELEPHONY_CARRIER_NETWORK_CHANGE,
@@ -373,5 +377,20 @@
false,
TelephonyIcons.QS_DATA_R
);
+
+ static final MobileIconGroup DATA_DISABLED = new MobileIconGroup(
+ "DataDisabled",
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+ TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+ 0, 0,
+ TelephonyIcons.TELEPHONY_NO_NETWORK,
+ TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+ R.string.accessibility_cell_data_off,
+ TelephonyIcons.ICON_DATA_DISABLED,
+ false,
+ TelephonyIcons.QS_ICON_DATA_DISABLED
+ );
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index d5b57ac..60dca99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1649,8 +1649,8 @@
bottom = Math.min(bottom, getHeight());
}
}
- mBackgroundBounds.top = top;
- mBackgroundBounds.bottom = bottom;
+ mBackgroundBounds.top = Math.max(0, top);
+ mBackgroundBounds.bottom = Math.min(getHeight(), bottom);
}
private ActivatableNotificationView getFirstPinnedHeadsUp() {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index b005a2b..5dc468b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -254,7 +254,7 @@
if (D.BUG) Log.d(TAG, "updateWindowWidth dm.w=" + dm.widthPixels);
int w = dm.widthPixels;
final int max = mContext.getResources()
- .getDimensionPixelSize(R.dimen.standard_notification_panel_width);
+ .getDimensionPixelSize(R.dimen.volume_dialog_panel_width);
if (w > max) {
w = max;
}
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index a71ba636..4bda87e 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -55,12 +55,16 @@
**/
public class Allocation extends BaseObj {
+ private static final int MAX_NUMBER_IO_INPUT_ALLOC = 16;
+
Type mType;
Bitmap mBitmap;
int mUsage;
Allocation mAdaptedAllocation;
int mSize;
+ MipmapControl mMipmapControl;
+ long mTimeStamp = -1;
boolean mReadAllowed = true;
boolean mWriteAllowed = true;
boolean mAutoPadding = false;
@@ -278,6 +282,17 @@
}
/**
+ * @hide
+ * Get the Mipmap control flag of the Allocation.
+ *
+ * @return the Mipmap control flag of the Allocation
+ *
+ */
+ public MipmapControl getMipmap() {
+ return mMipmapControl;
+ }
+
+ /**
* Enable/Disable AutoPadding for Vec3 elements.
* By default: Diabled.
*
@@ -359,6 +374,11 @@
}
}
+ Allocation(long id, RenderScript rs, Type t, int usage, MipmapControl mips) {
+ this(id, rs, t, usage);
+ mMipmapControl = mips;
+ }
+
protected void finalize() throws Throwable {
RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
super.finalize();
@@ -521,7 +541,7 @@
"Can only receive if IO_INPUT usage specified.");
}
mRS.validate();
- mRS.nAllocationIoReceive(getID(mRS));
+ mTimeStamp = mRS.nAllocationIoReceive(getID(mRS));
} finally {
Trace.traceEnd(RenderScript.TRACE_TAG);
}
@@ -1890,7 +1910,7 @@
if (id == 0) {
throw new RSRuntimeException("Allocation creation failed.");
}
- return new Allocation(id, rs, type, usage);
+ return new Allocation(id, rs, type, usage, mips);
} finally {
Trace.traceEnd(RenderScript.TRACE_TAG);
}
@@ -1948,7 +1968,7 @@
if (id == 0) {
throw new RSRuntimeException("Allocation creation failed.");
}
- return new Allocation(id, rs, t, usage);
+ return new Allocation(id, rs, t, usage, MipmapControl.MIPMAP_NONE);
} finally {
Trace.traceEnd(RenderScript.TRACE_TAG);
}
@@ -2037,7 +2057,7 @@
}
// keep a reference to the Bitmap around to prevent GC
- Allocation alloc = new Allocation(id, rs, t, usage);
+ Allocation alloc = new Allocation(id, rs, t, usage, mips);
alloc.setBitmap(b);
return alloc;
}
@@ -2047,7 +2067,7 @@
if (id == 0) {
throw new RSRuntimeException("Load failed.");
}
- return new Allocation(id, rs, t, usage);
+ return new Allocation(id, rs, t, usage, mips);
} finally {
Trace.traceEnd(RenderScript.TRACE_TAG);
}
@@ -2090,6 +2110,108 @@
/**
* @hide
+ * Creates a new Allocation Array with the given {@link
+ * android.renderscript.Type}, and usage flags.
+ * Note: If the input allocation is of usage: USAGE_IO_INPUT,
+ * the created Allocation will be sharing the same BufferQueue.
+ *
+ * @param rs RenderScript context
+ * @param t RenderScript type describing data layout
+ * @param usage bit field specifying how the Allocation is
+ * utilized
+ * @param numAlloc Number of Allocations in the array.
+ * @return Allocation[]
+ */
+ public static Allocation[] createAllocations(RenderScript rs, Type t, int usage, int numAlloc) {
+ try {
+ Trace.traceBegin(RenderScript.TRACE_TAG, "createAllocations");
+ rs.validate();
+ if (t.getID(rs) == 0) {
+ throw new RSInvalidStateException("Bad Type");
+ }
+
+ Allocation[] mAllocationArray = new Allocation[numAlloc];
+ mAllocationArray[0] = createTyped(rs, t, usage);
+ if ((usage & USAGE_IO_INPUT) != 0) {
+ if (numAlloc > MAX_NUMBER_IO_INPUT_ALLOC) {
+ throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " +
+ MAX_NUMBER_IO_INPUT_ALLOC);
+ }
+ mAllocationArray[0].setupBufferQueue(numAlloc);;
+ }
+
+ for (int i=1; i<numAlloc; i++) {
+ mAllocationArray[i] = createFromAllcation(rs, mAllocationArray[0]);
+ }
+ return mAllocationArray;
+ } finally {
+ Trace.traceEnd(RenderScript.TRACE_TAG);
+ }
+ }
+
+ /**
+ * Creates a new Allocation with the given {@link
+ * android.renderscript.Allocation}. The same data layout of
+ * the input Allocation will be applied.
+ * If the input allocation is of usage: USAGE_IO_INPUT, the created
+ * Allocation will be sharing the same BufferQueue.
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param alloc RenderScript Allocation describing data layout.
+ * @return Allocation sharing the same data structure.
+ */
+ static Allocation createFromAllcation(RenderScript rs, Allocation alloc) {
+ try {
+ Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation");
+ rs.validate();
+ if (alloc.getID(rs) == 0) {
+ throw new RSInvalidStateException("Bad input Allocation");
+ }
+
+ Type type = alloc.getType();
+ int usage = alloc.getUsage();
+ MipmapControl mips = alloc.getMipmap();
+ long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
+ if (id == 0) {
+ throw new RSRuntimeException("Allocation creation failed.");
+ }
+ Allocation outAlloc = new Allocation(id, rs, type, usage, mips);
+ if ((usage & USAGE_IO_INPUT) != 0) {
+ outAlloc.shareBufferQueue(alloc);
+ }
+ return outAlloc;
+ } finally {
+ Trace.traceEnd(RenderScript.TRACE_TAG);
+ }
+ }
+
+ /**
+ * Initialize BufferQueue with specified max number of buffers.
+ */
+ void setupBufferQueue(int numAlloc) {
+ mRS.validate();
+ if ((mUsage & USAGE_IO_INPUT) == 0) {
+ throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
+ }
+ mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc);
+ }
+
+ /**
+ * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation.
+ *
+ * @param alloc Allocation to associate with allocation
+ */
+ void shareBufferQueue(Allocation alloc) {
+ mRS.validate();
+ if ((mUsage & USAGE_IO_INPUT) == 0) {
+ throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
+ }
+ mGetSurfaceSurface = alloc.getSurface();
+ mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS));
+ }
+
+ /**
+ * @hide
* Gets the stride of the Allocation.
* For a 2D or 3D Allocation, the raw data maybe padded so that each row of
* the Allocation has certain alignment. The size of each row including such
@@ -2107,6 +2229,27 @@
}
/**
+ * @hide
+ * Get the timestamp for the most recent buffer held by this Allocation.
+ * The timestamp is guaranteed to be unique and monotonically increasing.
+ * Default value: -1. The timestamp will be updated after each {@link
+ * #ioReceive ioReceive()} call.
+ *
+ * It can be used to identify the images by comparing the unique timestamps
+ * when used with {@link android.hardware.camera2} APIs.
+ * Example steps:
+ * 1. Save {@link android.hardware.camera2.TotalCaptureResult} when the
+ * capture is completed.
+ * 2. Get the timestamp after {@link #ioReceive ioReceive()} call.
+ * 3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with
+ * alloc.getTimeStamp().
+ * @return long Timestamp associated with the buffer held by the Allocation.
+ */
+ public long getTimeStamp() {
+ return mTimeStamp;
+ }
+
+ /**
* Returns the handle to a raw buffer that is being managed by the screen
* compositor. This operation is only valid for Allocations with {@link
* #USAGE_IO_INPUT}.
@@ -2210,7 +2353,7 @@
if(id == 0) {
throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
}
- return new Allocation(id, rs, t, usage);
+ return new Allocation(id, rs, t, usage, mips);
}
/**
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 4788223..51fc7dd 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -484,7 +484,6 @@
rsnAllocationCopyToBitmap(mContext, alloc, bmp);
}
-
native void rsnAllocationSyncAll(long con, long alloc, int src);
synchronized void nAllocationSyncAll(long alloc, int src) {
validate();
@@ -497,6 +496,16 @@
return rsnAllocationGetByteBuffer(mContext, alloc, stride, xBytesSize, dimY, dimZ);
}
+ native void rsnAllocationSetupBufferQueue(long con, long alloc, int numAlloc);
+ synchronized void nAllocationSetupBufferQueue(long alloc, int numAlloc) {
+ validate();
+ rsnAllocationSetupBufferQueue(mContext, alloc, numAlloc);
+ }
+ native void rsnAllocationShareBufferQueue(long con, long alloc1, long alloc2);
+ synchronized void nAllocationShareBufferQueue(long alloc1, long alloc2) {
+ validate();
+ rsnAllocationShareBufferQueue(mContext, alloc1, alloc2);
+ }
native Surface rsnAllocationGetSurface(long con, long alloc);
synchronized Surface nAllocationGetSurface(long alloc) {
validate();
@@ -512,13 +521,12 @@
validate();
rsnAllocationIoSend(mContext, alloc);
}
- native void rsnAllocationIoReceive(long con, long alloc);
- synchronized void nAllocationIoReceive(long alloc) {
+ native long rsnAllocationIoReceive(long con, long alloc);
+ synchronized long nAllocationIoReceive(long alloc) {
validate();
- rsnAllocationIoReceive(mContext, alloc);
+ return rsnAllocationIoReceive(mContext, alloc);
}
-
native void rsnAllocationGenerateMipmaps(long con, long alloc);
synchronized void nAllocationGenerateMipmaps(long alloc) {
validate();
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 398d89b..3dff37b 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1223,6 +1223,27 @@
rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
}
+static void
+nAllocationSetupBufferQueue(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint numAlloc)
+{
+ if (kLogApi) {
+ ALOGD("nAllocationSetupBufferQueue, con(%p), alloc(%p), numAlloc(%d)", (RsContext)con,
+ (RsAllocation)alloc, numAlloc);
+ }
+ rsAllocationSetupBufferQueue((RsContext)con, (RsAllocation)alloc, (uint32_t)numAlloc);
+}
+
+static void
+nAllocationShareBufferQueue(JNIEnv *_env, jobject _this, jlong con, jlong alloc1, jlong alloc2)
+{
+ if (kLogApi) {
+ ALOGD("nAllocationShareBufferQueue, con(%p), alloc1(%p), alloc2(%p)", (RsContext)con,
+ (RsAllocation)alloc1, (RsAllocation)alloc2);
+ }
+
+ rsAllocationShareBufferQueue((RsContext)con, (RsAllocation)alloc1, (RsAllocation)alloc2);
+}
+
static jobject
nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a)
{
@@ -1265,16 +1286,15 @@
rsAllocationIoSend((RsContext)con, (RsAllocation)alloc);
}
-static void
+static jlong
nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
{
if (kLogApi) {
ALOGD("nAllocationIoReceive, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
}
- rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
+ return (jlong) rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
}
-
static void
nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
{
@@ -2856,10 +2876,12 @@
{"rsnAllocationCopyToBitmap", "(JJLandroid/graphics/Bitmap;)V", (void*)nAllocationCopyToBitmap },
{"rsnAllocationSyncAll", "(JJI)V", (void*)nAllocationSyncAll },
+{"rsnAllocationSetupBufferQueue", "(JJI)V", (void*)nAllocationSetupBufferQueue },
+{"rsnAllocationShareBufferQueue", "(JJJ)V", (void*)nAllocationShareBufferQueue },
{"rsnAllocationGetSurface", "(JJ)Landroid/view/Surface;", (void*)nAllocationGetSurface },
{"rsnAllocationSetSurface", "(JJLandroid/view/Surface;)V", (void*)nAllocationSetSurface },
{"rsnAllocationIoSend", "(JJ)V", (void*)nAllocationIoSend },
-{"rsnAllocationIoReceive", "(JJ)V", (void*)nAllocationIoReceive },
+{"rsnAllocationIoReceive", "(JJ)J", (void*)nAllocationIoReceive },
{"rsnAllocationData1D", "(JJIIILjava/lang/Object;IIIZ)V", (void*)nAllocationData1D },
{"rsnAllocationElementData", "(JJIIIII[BI)V", (void*)nAllocationElementData },
{"rsnAllocationData2D", "(JJIIIIIILjava/lang/Object;IIIZ)V", (void*)nAllocationData2D },
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 3c13630..c3c3e3f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -745,7 +745,7 @@
mTestMode = SystemProperties.get("cm.test.mode").equals("true")
&& SystemProperties.get("ro.build.type").equals("eng");
- mTethering = new Tethering(mContext, mNetd, statsService, mHandler.getLooper());
+ mTethering = new Tethering(mContext, mNetd, statsService);
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 82862e8..0f7dff2 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -855,6 +855,18 @@
}
}
+ @Override
+ public void noteBleScanStarted(WorkSource ws) {
+ enforceCallingPermission();
+ Slog.d(TAG, "BLE scan started for " + ws);
+ }
+
+ @Override
+ public void noteBleScanStopped(WorkSource ws) {
+ enforceCallingPermission();
+ Slog.d(TAG, "BLE scan stopped for " + ws);
+ }
+
public boolean isOnBattery() {
return mStats.isOnBattery();
}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 6648efd..a73a67a 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -153,11 +153,10 @@
// when RNDIS is enabled
public Tethering(Context context, INetworkManagementService nmService,
- INetworkStatsService statsService, Looper looper) {
+ INetworkStatsService statsService) {
mContext = context;
mNMService = nmService;
mStatsService = statsService;
- mLooper = looper;
mPublicSync = new Object();
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index fc79849..0f614ca 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -25,9 +25,11 @@
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.IStopUserCallback;
+import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -302,6 +304,12 @@
private final LockPatternUtils mLockPatternUtils;
+ /**
+ * Whether all users should be created ephemeral.
+ */
+ @GuardedBy("mUsersLock")
+ private boolean mForceEphemeralUsers;
+
private static UserManagerService sInstance;
public static UserManagerService getInstance() {
@@ -1836,23 +1844,25 @@
}
}
- // Add ephemeral flag to guests if required. Also inherit it from parent.
+ userId = getNextAvailableId();
+ Environment.getUserSystemDirectory(userId).mkdirs();
boolean ephemeralGuests = Resources.getSystem()
.getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
- if ((isGuest && ephemeralGuests)
- || (parent != null && parent.info.isEphemeral())) {
- flags |= UserInfo.FLAG_EPHEMERAL;
- }
- userId = getNextAvailableId();
- userInfo = new UserInfo(userId, name, null, flags);
- userInfo.serialNumber = mNextSerialNumber++;
- long now = System.currentTimeMillis();
- userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
- userInfo.partial = true;
- userData = new UserData();
- userData.info = userInfo;
- Environment.getUserSystemDirectory(userInfo.id).mkdirs();
+
synchronized (mUsersLock) {
+ // Add ephemeral flag to guests/users if required. Also inherit it from parent.
+ if ((isGuest && ephemeralGuests) || mForceEphemeralUsers
+ || (parent != null && parent.info.isEphemeral())) {
+ flags |= UserInfo.FLAG_EPHEMERAL;
+ }
+
+ userInfo = new UserInfo(userId, name, null, flags);
+ userInfo.serialNumber = mNextSerialNumber++;
+ long now = System.currentTimeMillis();
+ userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
+ userInfo.partial = true;
+ userData = new UserData();
+ userData.info = userInfo;
mUsers.put(userId, userData);
}
writeUserListLP();
@@ -2914,6 +2924,61 @@
Binder.restoreCallingIdentity(ident);
}
}
+
+ @Override
+ public void setForceEphemeralUsers(boolean forceEphemeralUsers) {
+ synchronized (mUsersLock) {
+ mForceEphemeralUsers = forceEphemeralUsers;
+ }
+ }
+
+ @Override
+ public void removeAllUsers() {
+ if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) {
+ // Remove the non-system users straight away.
+ removeNonSystemUsers();
+ } else {
+ // Switch to the system user first and then remove the other users.
+ BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ int userId =
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ if (userId != UserHandle.USER_SYSTEM) {
+ return;
+ }
+ mContext.unregisterReceiver(this);
+ removeNonSystemUsers();
+ }
+ };
+ IntentFilter userSwitchedFilter = new IntentFilter();
+ userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED);
+ mContext.registerReceiver(
+ userSwitchedReceiver, userSwitchedFilter, null, mHandler);
+
+ // Switch to the system user.
+ ActivityManager am =
+ (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ am.switchUser(UserHandle.USER_SYSTEM);
+ }
+ }
+ }
+
+ /* Remove all the users except of the system one. */
+ private void removeNonSystemUsers() {
+ ArrayList<UserInfo> usersToRemove = new ArrayList<>();
+ synchronized (mUsersLock) {
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
+ UserInfo ui = mUsers.valueAt(i).info;
+ if (ui.id != UserHandle.USER_SYSTEM) {
+ usersToRemove.add(ui);
+ }
+ }
+ }
+ for (UserInfo ui: usersToRemove) {
+ removeUser(ui.id);
+ }
}
private class Shell extends ShellCommand {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 290019c..a1f24f7 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -131,6 +131,7 @@
private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
private static final int WAKE_LOCK_DOZE = 1 << 6;
private static final int WAKE_LOCK_DRAW = 1 << 7;
+ private static final int WAKE_LOCK_SUSTAINED_PERFORMANCE = 1 << 8;
// Summarizes the user activity state.
private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
@@ -149,6 +150,7 @@
// Power hints defined in hardware/libhardware/include/hardware/power.h.
private static final int POWER_HINT_LOW_POWER = 5;
+ private static final int POWER_HINT_SUSTAINED_PERFORMANCE = 6;
// Power features defined in hardware/libhardware/include/hardware/power.h.
private static final int POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 1;
@@ -444,6 +446,9 @@
// True if we are currently in light device idle mode.
private boolean mLightDeviceIdleMode;
+ // True if we are currently in sustained performance mode.
+ private boolean mSustainedPerformanceMode;
+
// Set of app ids that we will always respect the wake locks for.
int[] mDeviceIdleWhitelist = new int[0];
@@ -452,6 +457,8 @@
private final SparseIntArray mUidState = new SparseIntArray();
+ private final SparseIntArray mSustainedPerformanceUid = new SparseIntArray();
+
// True if theater mode is enabled
private boolean mTheaterModeEnabled;
@@ -811,6 +818,12 @@
throw new IllegalArgumentException("Wake lock is already dead.");
}
mWakeLocks.add(wakeLock);
+
+ if ((flags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+ == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) {
+ int numberWakelock = mSustainedPerformanceUid.get(uid);
+ mSustainedPerformanceUid.put(uid, numberWakelock + 1);
+ }
setWakeLockDisabledStateLocked(wakeLock);
notifyAcquire = true;
}
@@ -879,6 +892,17 @@
mRequestWaitForNegativeProximity = true;
}
+
+ if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+ == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) {
+ int numberWakelock = mSustainedPerformanceUid.get(wakeLock.mOwnerUid);
+ if (numberWakelock == 1) {
+ mSustainedPerformanceUid.delete(wakeLock.mOwnerUid);
+ } else {
+ mSustainedPerformanceUid.put(wakeLock.mOwnerUid, numberWakelock - 1);
+ }
+ }
+
wakeLock.mLock.unlinkToDeath(wakeLock, 0);
removeWakeLockLocked(wakeLock, index);
}
@@ -1501,6 +1525,10 @@
break;
case PowerManager.DRAW_WAKE_LOCK:
mWakeLockSummary |= WAKE_LOCK_DRAW;
+ case PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK:
+ if (!wakeLock.mDisabled) {
+ mWakeLockSummary |= WAKE_LOCK_SUSTAINED_PERFORMANCE;
+ }
break;
}
}
@@ -2198,6 +2226,14 @@
if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(true);
}
+
+ if (mSustainedPerformanceMode
+ && (mWakeLockSummary & WAKE_LOCK_SUSTAINED_PERFORMANCE) == 0) {
+ setSustainedPerformanceModeLocked(false);
+ } else if (!mSustainedPerformanceMode
+ && (mWakeLockSummary & WAKE_LOCK_SUSTAINED_PERFORMANCE) != 0) {
+ setSustainedPerformanceModeLocked(true);
+ }
}
/**
@@ -2296,6 +2332,12 @@
}
}
+ private void setSustainedPerformanceModeLocked(boolean mode) {
+ mSustainedPerformanceMode = mode;
+ powerHintInternal(POWER_HINT_SUSTAINED_PERFORMANCE,
+ mSustainedPerformanceMode ? 1 : 0);
+ }
+
boolean isDeviceIdleModeInternal() {
synchronized (mLock) {
return mDeviceIdleMode;
@@ -2425,7 +2467,7 @@
void updateUidProcStateInternal(int uid, int procState) {
synchronized (mLock) {
mUidState.put(uid, procState);
- if (mDeviceIdleMode) {
+ if (mDeviceIdleMode || mSustainedPerformanceUid.get(uid) != 0) {
updateWakeLockDisabledStatesLocked();
}
}
@@ -2446,7 +2488,9 @@
for (int i = 0; i < numWakeLocks; i++) {
final WakeLock wakeLock = mWakeLocks.get(i);
if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
- == PowerManager.PARTIAL_WAKE_LOCK) {
+ == PowerManager.PARTIAL_WAKE_LOCK
+ || (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+ == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) {
if (setWakeLockDisabledStateLocked(wakeLock)) {
changed = true;
if (wakeLock.mDisabled) {
@@ -2465,9 +2509,9 @@
}
private boolean setWakeLockDisabledStateLocked(WakeLock wakeLock) {
+ boolean disabled = false;
if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
== PowerManager.PARTIAL_WAKE_LOCK) {
- boolean disabled = false;
if (mDeviceIdleMode) {
final int appid = UserHandle.getAppId(wakeLock.mOwnerUid);
// If we are in idle mode, we will ignore all partial wake locks that are
@@ -2481,10 +2525,16 @@
disabled = true;
}
}
- if (wakeLock.mDisabled != disabled) {
- wakeLock.mDisabled = disabled;
- return true;
- }
+ } else if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+ == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK
+ && mUidState.get(wakeLock.mOwnerUid,
+ ActivityManager.PROCESS_STATE_CACHED_EMPTY)
+ > ActivityManager.PROCESS_STATE_TOP) {
+ disabled = true;
+ }
+ if (wakeLock.mDisabled != disabled) {
+ wakeLock.mDisabled = disabled;
+ return true;
}
return false;
}
@@ -2695,6 +2745,7 @@
pw.println(" mBatteryLevelLow=" + mBatteryLevelLow);
pw.println(" mLightDeviceIdleMode=" + mLightDeviceIdleMode);
pw.println(" mDeviceIdleMode=" + mDeviceIdleMode);
+ pw.println(" mSustainedPerformanceMode=" + mSustainedPerformanceMode);
pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
@@ -2809,6 +2860,14 @@
pw.println();
pw.println("Display Power: " + mDisplayPowerCallbacks);
+ pw.println();
+ pw.println("Sustained Performance UIDs:");
+ for (int i=0; i<mSustainedPerformanceUid.size(); i++) {
+ pw.print(" UID "); UserHandle.formatUid(pw, mSustainedPerformanceUid.keyAt(i));
+ pw.print(": "); pw.println(mSustainedPerformanceUid.valueAt(i));
+ }
+
+
wcd = mWirelessChargerDetector;
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 2833b35..f02e49e 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -587,6 +587,7 @@
outBounds.top = dockedBounds.bottom + dockDividerWidth;
}
}
+ DockedDividerUtils.sanitizeStackBounds(outBounds);
}
/** Resizes all non-docked stacks in the system to either fullscreen or the appropriate size
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e8de90c..c541b3f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2061,7 +2061,8 @@
Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig) throws RemoteException {
mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets,
- reportDraw, newConfig, getBackdropFrame(frame));
+ reportDraw, newConfig, getBackdropFrame(frame),
+ isDragResizeChanged() /* forceRelayout */);
}
public void registerFocusObserver(IWindowFocusObserver observer) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4fd8990..4bda7d9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -471,6 +471,7 @@
private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
+ private static final String TAG_FORCE_EPHEMERAL_USERS = "force_ephemeral_users";
private static final String TAG_ACCOUNT_TYPE = "account-type";
private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
= "permitted-accessiblity-services";
@@ -559,6 +560,7 @@
boolean disableBluetoothContactSharing = true;
boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
boolean requireAutoTime = false; // Can only be set by a device owner.
+ boolean forceEphemeralUsers = false; // Can only be set by a device owner.
ActiveAdmin parentAdmin;
final boolean isParent;
@@ -749,6 +751,11 @@
out.attribute(null, ATTR_VALUE, Boolean.toString(requireAutoTime));
out.endTag(null, TAG_REQUIRE_AUTO_TIME);
}
+ if (forceEphemeralUsers) {
+ out.startTag(null, TAG_FORCE_EPHEMERAL_USERS);
+ out.attribute(null, ATTR_VALUE, Boolean.toString(forceEphemeralUsers));
+ out.endTag(null, TAG_FORCE_EPHEMERAL_USERS);
+ }
if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures));
@@ -919,7 +926,10 @@
disableScreenCapture = Boolean.parseBoolean(
parser.getAttributeValue(null, ATTR_VALUE));
} else if (TAG_REQUIRE_AUTO_TIME.equals(tag)) {
- requireAutoTime= Boolean.parseBoolean(
+ requireAutoTime = Boolean.parseBoolean(
+ parser.getAttributeValue(null, ATTR_VALUE));
+ } else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
+ forceEphemeralUsers = Boolean.parseBoolean(
parser.getAttributeValue(null, ATTR_VALUE));
} else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
disabledKeyguardFeatures = Integer.parseInt(
@@ -1150,6 +1160,8 @@
pw.println(disableScreenCapture);
pw.print(prefix); pw.print("requireAutoTime=");
pw.println(requireAutoTime);
+ pw.print(prefix); pw.print("forceEphemeralUsers=");
+ pw.println(forceEphemeralUsers);
pw.print(prefix); pw.print("disabledKeyguardFeatures=");
pw.println(disabledKeyguardFeatures);
pw.print(prefix); pw.print("crossProfileWidgetProviders=");
@@ -2408,6 +2420,14 @@
if (packageList != null) {
mInjector.getPackageManagerInternal().setKeepUninstalledPackages(packageList);
}
+
+ synchronized (this) {
+ // push the force-ephemeral-users policy to the user manager.
+ ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
+ if (deviceOwner != null) {
+ mUserManagerInternal.setForceEphemeralUsers(deviceOwner.forceEphemeralUsers);
+ }
+ }
}
private void ensureDeviceOwnerUserStarted() {
@@ -4789,6 +4809,46 @@
}
}
+ @Override
+ public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) {
+ if (!mHasFeature) {
+ return;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ boolean removeAllUsers = false;
+ synchronized (this) {
+ final ActiveAdmin deviceOwner =
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ if (deviceOwner.forceEphemeralUsers != forceEphemeralUsers) {
+ deviceOwner.forceEphemeralUsers = forceEphemeralUsers;
+ saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+ mUserManagerInternal.setForceEphemeralUsers(forceEphemeralUsers);
+ removeAllUsers = forceEphemeralUsers;
+ }
+ }
+ if (removeAllUsers) {
+ long identitity = mInjector.binderClearCallingIdentity();
+ try {
+ mUserManagerInternal.removeAllUsers();
+ } finally {
+ mInjector.binderRestoreCallingIdentity(identitity);
+ }
+ }
+ }
+
+ @Override
+ public boolean getForceEphemeralUsers(ComponentName who) {
+ if (!mHasFeature) {
+ return false;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ synchronized (this) {
+ final ActiveAdmin deviceOwner =
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ return deviceOwner.forceEphemeralUsers;
+ }
+ }
+
private void ensureDeviceOwnerManagingSingleUser(ComponentName who) throws SecurityException {
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
@@ -5319,6 +5379,8 @@
if (admin != null) {
admin.disableCamera = false;
admin.userRestrictions = null;
+ admin.forceEphemeralUsers = false;
+ mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers);
}
clearUserPoliciesLocked(new UserHandle(UserHandle.USER_SYSTEM));
@@ -5361,7 +5423,9 @@
if (!mHasFeature) {
return;
}
- UserHandle callingUser = mInjector.binderGetCallingUserHandle();
+ final UserHandle callingUser = mInjector.binderGetCallingUserHandle();
+ final int userId = callingUser.getIdentifier();
+ enforceNotManagedProfile(userId, "clear profile owner");
// Check if this is the profile owner who is calling
final ActiveAdmin admin =
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -5369,7 +5433,6 @@
admin.disableCamera = false;
admin.userRestrictions = null;
clearUserPoliciesLocked(callingUser);
- final int userId = callingUser.getIdentifier();
mOwners.removeProfileOwner(userId);
mOwners.writeProfileOwner(userId);
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c186a12..361c251 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -84,6 +84,7 @@
import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
import com.android.server.restrictions.RestrictionsManagerService;
+import com.android.server.soundtrigger.SoundTriggerService;
import com.android.server.statusbar.StatusBarManagerService;
import com.android.server.storage.DeviceStorageMonitorService;
import com.android.server.telecom.TelecomLoaderService;
@@ -959,6 +960,8 @@
mSystemServiceManager.startService(JobSchedulerService.class);
+ mSystemServiceManager.startService(SoundTriggerService.class);
+
if (!disableNonCoreServices) {
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP)) {
mSystemServiceManager.startService(BACKUP_MANAGER_SERVICE_CLASS);
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java
new file mode 100644
index 0000000..18a5d59
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java
@@ -0,0 +1,144 @@
+/**
+ * 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.soundtrigger;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.util.Locale;
+import java.util.UUID;
+
+/**
+ * Helper to manage the database of the sound models that have been registered on the device.
+ *
+ * @hide
+ */
+public class SoundTriggerDbHelper extends SQLiteOpenHelper {
+ static final String TAG = "SoundTriggerDbHelper";
+ static final boolean DBG = false;
+
+ private static final String NAME = "st_sound_model.db";
+ private static final int VERSION = 1;
+
+ // Sound trigger-based sound models.
+ public static interface GenericSoundModelContract {
+ public static final String TABLE = "st_sound_model";
+ public static final String KEY_MODEL_UUID = "model_uuid";
+ public static final String KEY_VENDOR_UUID = "vendor_uuid";
+ public static final String KEY_DATA = "data";
+ }
+
+
+ // Table Create Statement for the sound trigger table
+ private static final String CREATE_TABLE_ST_SOUND_MODEL = "CREATE TABLE "
+ + GenericSoundModelContract.TABLE + "("
+ + GenericSoundModelContract.KEY_MODEL_UUID + " TEXT PRIMARY KEY,"
+ + GenericSoundModelContract.KEY_DATA + " BLOB" + " )";
+
+
+ public SoundTriggerDbHelper(Context context) {
+ super(context, NAME, null, VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // creating required tables
+ db.execSQL(CREATE_TABLE_ST_SOUND_MODEL);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // TODO: For now, drop older tables and recreate new ones.
+ db.execSQL("DROP TABLE IF EXISTS " + GenericSoundModelContract.TABLE);
+ onCreate(db);
+ }
+
+ /**
+ * Updates the given sound trigger model, adds it, if it doesn't already exist.
+ *
+ */
+ public boolean updateGenericSoundModel(GenericSoundModel soundModel) {
+ synchronized(this) {
+ SQLiteDatabase db = getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(GenericSoundModelContract.KEY_MODEL_UUID, soundModel.uuid.toString());
+ values.put(GenericSoundModelContract.KEY_VENDOR_UUID, soundModel.vendorUuid.toString());
+ values.put(GenericSoundModelContract.KEY_DATA, soundModel.data);
+
+ try {
+ return db.insertWithOnConflict(GenericSoundModelContract.TABLE, null, values,
+ SQLiteDatabase.CONFLICT_REPLACE) != -1;
+ } finally {
+ db.close();
+ }
+
+ }
+ }
+
+ public GenericSoundModel getGenericSoundModel(UUID model_uuid) {
+ synchronized(this) {
+
+ // Find the corresponding sound model ID for the keyphrase.
+ String selectQuery = "SELECT * FROM " + GenericSoundModelContract.TABLE
+ + " WHERE " + GenericSoundModelContract.KEY_MODEL_UUID + "= '" +
+ model_uuid + "'";
+ SQLiteDatabase db = getReadableDatabase();
+ Cursor c = db.rawQuery(selectQuery, null);
+ try {
+ if (c.moveToFirst()) {
+ do {
+ byte[] data = c.getBlob(c.getColumnIndex(
+ GenericSoundModelContract.KEY_DATA));
+ String vendor_uuid = c.getString(
+ c.getColumnIndex(GenericSoundModelContract.KEY_VENDOR_UUID));
+ return new GenericSoundModel(model_uuid, UUID.fromString(vendor_uuid),
+ data);
+ } while (c.moveToNext());
+ }
+ } finally {
+ c.close();
+ db.close();
+ }
+ }
+ return null;
+ }
+
+ public boolean deleteGenericSoundModel(UUID model_uuid) {
+ synchronized(this) {
+ GenericSoundModel soundModel = getGenericSoundModel(model_uuid);
+ if (soundModel == null) {
+ return false;
+ }
+ // Delete all sound models for the given keyphrase and specified user.
+ SQLiteDatabase db = getWritableDatabase();
+ String soundModelClause = GenericSoundModelContract.KEY_MODEL_UUID
+ + "='" + soundModel.uuid.toString() + "'";
+ try {
+ return db.delete(GenericSoundModelContract.TABLE, soundModelClause, null) != 0;
+ } finally {
+ db.close();
+ }
+ }
+ }
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
similarity index 99%
rename from services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
rename to services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 31d859f..597f915ec 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.voiceinteraction;
+package com.android.server.soundtrigger;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java
new file mode 100644
index 0000000..0a06bfa
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.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 com.android.server.soundtrigger;
+
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
+import android.hardware.soundtrigger.SoundTrigger.SoundModelEvent;
+import android.hardware.soundtrigger.SoundTriggerModule;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Provides a local service for managing voice-related recoginition models. This is primarily used
+ * by the {@link VoiceInteractionManagerService}.
+ */
+public abstract class SoundTriggerInternal {
+ /**
+ * Return codes for {@link #startRecognition(int, KeyphraseSoundModel,
+ * IRecognitionStatusCallback, RecognitionConfig)},
+ * {@link #stopRecognition(int, IRecognitionStatusCallback)}
+ */
+ public static final int STATUS_ERROR = SoundTrigger.STATUS_ERROR;
+ public static final int STATUS_OK = SoundTrigger.STATUS_OK;
+
+ /** The {@link ModuleProperties} for the system, or null if none exists. */
+ private ModuleProperties moduleProperties;
+
+ /**
+ * Starts recognition for the given keyphraseId.
+ *
+ * @param keyphraseId The identifier of the keyphrase for which
+ * the recognition is to be started.
+ * @param soundModel The sound model to use for recognition.
+ * @param listener The listener for the recognition events related to the given keyphrase.
+ * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
+ */
+ public abstract int startRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
+ IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig);
+
+ /**
+ * Stops recognition for the given {@link Keyphrase} if a recognition is
+ * currently active.
+ *
+ * @param keyphraseId The identifier of the keyphrase for which
+ * the recognition is to be stopped.
+ * @param listener The listener for the recognition events related to the given keyphrase.
+ *
+ * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
+ */
+ public abstract int stopRecognition(int keyphraseId, IRecognitionStatusCallback listener);
+
+ /**
+ * Stops all recognitions active currently and clears the internal state.
+ */
+ public abstract void stopAllRecognitions();
+
+ public ModuleProperties getModuleProperties() {
+ return moduleProperties;
+ }
+
+ public abstract void dump(FileDescriptor fd, PrintWriter pw, String[] args);
+}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
new file mode 100644
index 0000000..5e8fe9e
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -0,0 +1,194 @@
+/*
+ * 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.soundtrigger;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.Manifest;
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.SystemService;
+import com.android.internal.app.ISoundTriggerService;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.UUID;
+
+/**
+ * A single SystemService to manage all sound/voice-based sound models on the DSP.
+ * This services provides apis to manage sound trigger-based sound models via
+ * the ISoundTriggerService interface. This class also publishes a local interface encapsulating
+ * the functionality provided by {@link SoundTriggerHelper} for use by
+ * {@link VoiceInteractionManagerService}.
+ *
+ * @hide
+ */
+public class SoundTriggerService extends SystemService {
+ static final String TAG = "SoundTriggerService";
+ static final boolean DEBUG = false;
+
+ final Context mContext;
+ private final SoundTriggerServiceStub mServiceStub;
+ private final LocalSoundTriggerService mLocalSoundTriggerService;
+ private SoundTriggerDbHelper mDbHelper;
+
+ public SoundTriggerService(Context context) {
+ super(context);
+ mContext = context;
+ mServiceStub = new SoundTriggerServiceStub();
+ mLocalSoundTriggerService = new LocalSoundTriggerService(context);
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.SOUND_TRIGGER_SERVICE, mServiceStub);
+ publishLocalService(SoundTriggerInternal.class, mLocalSoundTriggerService);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (PHASE_SYSTEM_SERVICES_READY == phase) {
+ mLocalSoundTriggerService.initSoundTriggerHelper();
+ } else if (PHASE_THIRD_PARTY_APPS_CAN_START == phase) {
+ mDbHelper = new SoundTriggerDbHelper(mContext);
+ }
+ }
+
+ @Override
+ public void onStartUser(int userHandle) {
+ }
+
+ @Override
+ public void onSwitchUser(int userHandle) {
+ }
+
+ class SoundTriggerServiceStub extends ISoundTriggerService.Stub {
+ @Override
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ try {
+ return super.onTransact(code, data, reply, flags);
+ } catch (RuntimeException e) {
+ // The activity manager only throws security exceptions, so let's
+ // log all others.
+ if (!(e instanceof SecurityException)) {
+ Slog.wtf(TAG, "SoundTriggerService Crash", e);
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public void startRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "startRecognition(): Uuid : " + parcelUuid);
+ }
+ }
+
+ @Override
+ public void stopRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "stopRecognition(): Uuid : " + parcelUuid);
+ }
+ }
+
+ @Override
+ public SoundTrigger.GenericSoundModel getSoundModel(ParcelUuid soundModelId) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "getSoundModel(): id = " + soundModelId);
+ }
+ SoundTrigger.GenericSoundModel model = mDbHelper.getGenericSoundModel(soundModelId.getUuid());
+ if (model == null) {
+ Slog.e(TAG, "Null model in database.");
+ }
+ return model;
+ }
+
+ @Override
+ public void updateSoundModel(SoundTrigger.GenericSoundModel soundModel) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "updateSoundModel(): model = " + soundModel);
+ }
+ mDbHelper.updateGenericSoundModel(soundModel);
+ }
+
+ @Override
+ public void deleteSoundModel(ParcelUuid soundModelId) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "deleteSoundModel(): id = " + soundModelId);
+ }
+ mDbHelper.deleteGenericSoundModel(soundModelId.getUuid());
+ }
+ }
+
+ public final class LocalSoundTriggerService extends SoundTriggerInternal {
+ private final Context mContext;
+ private SoundTriggerHelper mSoundTriggerHelper;
+
+ LocalSoundTriggerService(Context context) {
+ mContext = context;
+ }
+
+ void initSoundTriggerHelper() {
+ if (mSoundTriggerHelper == null) {
+ mSoundTriggerHelper = new SoundTriggerHelper(mContext);
+ }
+ }
+
+ @Override
+ public int startRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
+ IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig) {
+ return mSoundTriggerHelper.startRecognition(keyphraseId, soundModel, listener,
+ recognitionConfig);
+ }
+
+ @Override
+ public int stopRecognition(int keyphraseId, IRecognitionStatusCallback listener) {
+ return mSoundTriggerHelper.stopRecognition(keyphraseId, listener);
+ }
+
+ @Override
+ public void stopAllRecognitions() {
+ mSoundTriggerHelper.stopAllRecognitions();
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mSoundTriggerHelper.dump(fd, pw, args);
+ }
+ }
+
+ private void enforceCallingPermission(String permission) {
+ if (mContext.checkCallingOrSelfPermission(permission)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Caller does not hold the permission " + permission);
+ }
+ }
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 2aef109..4a54643 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -62,6 +62,7 @@
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
+import com.android.server.soundtrigger.SoundTriggerInternal;
import com.android.server.SystemService;
import com.android.server.UiThread;
@@ -79,15 +80,14 @@
final Context mContext;
final ContentResolver mResolver;
final DatabaseHelper mDbHelper;
- final SoundTriggerHelper mSoundTriggerHelper;
final ActivityManagerInternal mAmInternal;
+ SoundTriggerInternal mSoundTriggerInternal;
public VoiceInteractionManagerService(Context context) {
super(context);
mContext = context;
mResolver = context.getContentResolver();
mDbHelper = new DatabaseHelper(context);
- mSoundTriggerHelper = new SoundTriggerHelper(context);
mServiceStub = new VoiceInteractionManagerServiceStub();
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
@@ -115,7 +115,9 @@
@Override
public void onBootPhase(int phase) {
- if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+ if (PHASE_SYSTEM_SERVICES_READY == phase) {
+ mSoundTriggerInternal = LocalServices.getService(SoundTriggerInternal.class);
+ } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
mServiceStub.systemRunning(isSafeMode());
}
}
@@ -380,7 +382,7 @@
if (force || mImpl == null || mImpl.mUser != mCurUser
|| !mImpl.mComponent.equals(serviceComponent)) {
- mSoundTriggerHelper.stopAllRecognitions();
+ mSoundTriggerInternal.stopAllRecognitions();
if (mImpl != null) {
mImpl.shutdownLocked();
}
@@ -736,9 +738,9 @@
mImpl.notifySoundModelsChangedLocked();
}
}
- return SoundTriggerHelper.STATUS_OK;
+ return SoundTriggerInternal.STATUS_OK;
} else {
- return SoundTriggerHelper.STATUS_ERROR;
+ return SoundTriggerInternal.STATUS_ERROR;
}
} finally {
Binder.restoreCallingIdentity(caller);
@@ -759,7 +761,7 @@
boolean deleted = false;
try {
deleted = mDbHelper.deleteKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
- return deleted ? SoundTriggerHelper.STATUS_OK : SoundTriggerHelper.STATUS_ERROR;
+ return deleted ? SoundTriggerInternal.STATUS_OK : SoundTriggerInternal.STATUS_ERROR;
} finally {
if (deleted) {
synchronized (this) {
@@ -812,7 +814,7 @@
final long caller = Binder.clearCallingIdentity();
try {
- return mSoundTriggerHelper.moduleProperties;
+ return mSoundTriggerInternal.getModuleProperties();
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -845,9 +847,9 @@
|| soundModel.uuid == null
|| soundModel.keyphrases == null) {
Slog.w(TAG, "No matching sound model found in startRecognition");
- return SoundTriggerHelper.STATUS_ERROR;
+ return SoundTriggerInternal.STATUS_ERROR;
} else {
- return mSoundTriggerHelper.startRecognition(
+ return mSoundTriggerInternal.startRecognition(
keyphraseId, soundModel, callback, recognitionConfig);
}
} finally {
@@ -869,7 +871,7 @@
final long caller = Binder.clearCallingIdentity();
try {
- return mSoundTriggerHelper.stopRecognition(keyphraseId, callback);
+ return mSoundTriggerInternal.stopRecognition(keyphraseId, callback);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -1011,7 +1013,7 @@
}
mImpl.dumpLocked(fd, pw, args);
}
- mSoundTriggerHelper.dump(fd, pw, args);
+ mSoundTriggerInternal.dump(fd, pw, args);
}
private void enforceCallingPermission(String permission) {
@@ -1060,7 +1062,7 @@
// The user is force stopping our current interactor/recognizer.
// Clear the current settings and restore default state.
synchronized (VoiceInteractionManagerService.this) {
- mSoundTriggerHelper.stopAllRecognitions();
+ mSoundTriggerInternal.stopAllRecognitions();
if (mImpl != null) {
mImpl.shutdownLocked();
mImpl = null;
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 3859294..de90202 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -265,6 +265,7 @@
// Next PROPERTY value: 0x00000040
//******************************************************************************************
+ private final String mTelecomCallId;
private final Uri mHandle;
private final int mHandlePresentation;
private final String mCallerDisplayName;
@@ -414,6 +415,11 @@
return builder.toString();
}
+ /** {@hide} */
+ public String getTelecomCallId() {
+ return mTelecomCallId;
+ }
+
/**
* @return The handle (e.g., phone number) to which the {@code Call} is currently
* connected.
@@ -567,6 +573,7 @@
/** {@hide} */
public Details(
+ String telecomCallId,
Uri handle,
int handlePresentation,
String callerDisplayName,
@@ -581,6 +588,7 @@
StatusHints statusHints,
Bundle extras,
Bundle intentExtras) {
+ mTelecomCallId = telecomCallId;
mHandle = handle;
mHandlePresentation = handlePresentation;
mCallerDisplayName = callerDisplayName;
@@ -596,6 +604,26 @@
mExtras = extras;
mIntentExtras = intentExtras;
}
+
+ /** {@hide} */
+ public static Details createFromParcelableCall(ParcelableCall parcelableCall) {
+ return new Details(
+ parcelableCall.getId(),
+ parcelableCall.getHandle(),
+ parcelableCall.getHandlePresentation(),
+ parcelableCall.getCallerDisplayName(),
+ parcelableCall.getCallerDisplayNamePresentation(),
+ parcelableCall.getAccountHandle(),
+ parcelableCall.getCapabilities(),
+ parcelableCall.getProperties(),
+ parcelableCall.getDisconnectCause(),
+ parcelableCall.getConnectTimeMillis(),
+ parcelableCall.getGatewayInfo(),
+ parcelableCall.getVideoState(),
+ parcelableCall.getStatusHints(),
+ parcelableCall.getExtras(),
+ parcelableCall.getIntentExtras());
+ }
}
public static abstract class Callback {
@@ -1022,21 +1050,7 @@
/** {@hide} */
final void internalUpdate(ParcelableCall parcelableCall, Map<String, Call> callIdMap) {
// First, we update the internal state as far as possible before firing any updates.
- Details details = new Details(
- parcelableCall.getHandle(),
- parcelableCall.getHandlePresentation(),
- parcelableCall.getCallerDisplayName(),
- parcelableCall.getCallerDisplayNamePresentation(),
- parcelableCall.getAccountHandle(),
- parcelableCall.getCapabilities(),
- parcelableCall.getProperties(),
- parcelableCall.getDisconnectCause(),
- parcelableCall.getConnectTimeMillis(),
- parcelableCall.getGatewayInfo(),
- parcelableCall.getVideoState(),
- parcelableCall.getStatusHints(),
- parcelableCall.getExtras(),
- parcelableCall.getIntentExtras());
+ Details details = Details.createFromParcelableCall(parcelableCall);
boolean detailsChanged = !Objects.equals(mDetails, details);
if (detailsChanged) {
mDetails = details;
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
new file mode 100644
index 0000000..1b6e162
--- /dev/null
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecom;
+
+import android.annotation.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecom.ICallScreeningService;
+import com.android.internal.telecom.ICallScreeningAdapter;
+
+/**
+ * This service can be implemented by the default dialer (see
+ * {@link TelecomManager#getDefaultDialerPackage()}) to allow or disallow incoming calls before
+ * they are shown to a user.
+ * <p>
+ * Below is an example manifest registration for a {@code CallScreeningService}.
+ * <pre>
+ * {@code
+ * <service android:name="your.package.YourCallScreeningServiceImplementation"
+ * android:permission="android.permission.BIND_SCREENING_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.telecom.CallScreeningService"/>
+ * </intent-filter>
+ * </service>
+ * }
+ * </pre>
+ */
+public abstract class CallScreeningService extends Service {
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE = "android.telecom.CallScreeningService";
+
+ private static final int MSG_SCREEN_CALL = 1;
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SCREEN_CALL:
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ mCallScreeningAdapter = (ICallScreeningAdapter) args.arg1;
+ onScreenCall(
+ Call.Details.createFromParcelableCall((ParcelableCall) args.arg2));
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ }
+ };
+
+ private final class CallScreeningBinder extends ICallScreeningService.Stub {
+ @Override
+ public void screenCall(ICallScreeningAdapter adapter, ParcelableCall call) {
+ Log.v(this, "screenCall");
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = adapter;
+ args.arg2 = call;
+ mHandler.obtainMessage(MSG_SCREEN_CALL, args).sendToTarget();
+ }
+ }
+
+ private ICallScreeningAdapter mCallScreeningAdapter;
+
+ /*
+ * Information about how to respond to an incoming call.
+ */
+ public class CallResponse {
+ private final boolean mShouldDisallowCall;
+ private final boolean mShouldRejectCall;
+ private final boolean mShouldSkipCallLog;
+ private final boolean mShouldSkipNotification;
+
+ private CallResponse(
+ boolean shouldDisallowCall,
+ boolean shouldRejectCall,
+ boolean shouldSkipCallLog,
+ boolean shouldSkipNotification) {
+ if (!shouldDisallowCall
+ && (shouldRejectCall || shouldSkipCallLog || shouldSkipNotification)) {
+ throw new IllegalStateException("Invalid response state for allowed call.");
+ }
+
+ mShouldDisallowCall = shouldDisallowCall;
+ mShouldRejectCall = shouldRejectCall;
+ mShouldSkipCallLog = shouldSkipCallLog;
+ mShouldSkipNotification = shouldSkipNotification;
+ }
+
+ /*
+ * @return Whether the incoming call should be blocked.
+ */
+ public boolean getDisallowCall() {
+ return mShouldDisallowCall;
+ }
+
+ /*
+ * @return Whether the incoming call should be disconnected as if the user had manually
+ * rejected it.
+ */
+ public boolean getRejectCall() {
+ return mShouldRejectCall;
+ }
+
+ /*
+ * @return Whether the incoming call should not be displayed in the call log.
+ */
+ public boolean getSkipCallLog() {
+ return mShouldSkipCallLog;
+ }
+
+ /*
+ * @return Whether a missed call notification should not be shown for the incoming call.
+ */
+ public boolean getSkipNotification() {
+ return mShouldSkipNotification;
+ }
+
+ public class Builder {
+ private boolean mShouldDisallowCall;
+ private boolean mShouldRejectCall;
+ private boolean mShouldSkipCallLog;
+ private boolean mShouldSkipNotification;
+
+ /*
+ * Sets whether the incoming call should be blocked.
+ */
+ public Builder setDisallowCall(boolean shouldDisallowCall) {
+ mShouldDisallowCall = shouldDisallowCall;
+ return this;
+ }
+
+ /*
+ * Sets whether the incoming call should be disconnected as if the user had manually
+ * rejected it. This property should only be set to true if the call is disallowed.
+ */
+ public Builder setRejectCall(boolean shouldRejectCall) {
+ mShouldRejectCall = shouldRejectCall;
+ return this;
+ }
+
+ /*
+ * Sets whether the incoming call should not be displayed in the call log. This property
+ * should only be set to true if the call is disallowed.
+ */
+ public Builder setSkipCallLog(boolean shouldSkipCallLog) {
+ mShouldSkipCallLog = shouldSkipCallLog;
+ return this;
+ }
+
+ /*
+ * Sets whether a missed call notification should not be shown for the incoming call.
+ * This property should only be set to true if the call is disallowed.
+ */
+ public Builder setSkipNotification(boolean shouldSkipNotification) {
+ mShouldSkipNotification = shouldSkipNotification;
+ return this;
+ }
+
+ public CallResponse build() {
+ return new CallResponse(
+ mShouldDisallowCall,
+ mShouldRejectCall,
+ mShouldSkipCallLog,
+ mShouldSkipNotification);
+ }
+ }
+ }
+
+ public CallScreeningService() {
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.v(this, "onBind");
+ return new CallScreeningBinder();
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ Log.v(this, "onUnbind");
+ return false;
+ }
+
+ /**
+ * Called when a new incoming call is added.
+ * {@link CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)}
+ * should be called to allow or disallow the call.
+ *
+ * @param callDetails Information about a new incoming call, see {@link Call.Details}.
+ */
+ public abstract void onScreenCall(Call.Details callDetails);
+
+ /**
+ * Responds to the given call, either allowing it or disallowing it.
+ *
+ * @param callDetails The call to allow.
+ * @param response The {@link CallScreeningService.CallResponse} which contains information
+ * about how to respond to a call.
+ */
+ public final void respondToCall(Call.Details callDetails, CallResponse response) {
+ try {
+ if (response.getDisallowCall()) {
+ mCallScreeningAdapter.disallowCall(
+ callDetails.getTelecomCallId(),
+ response.getRejectCall(),
+ !response.getSkipCallLog(),
+ !response.getSkipNotification());
+ } else {
+ mCallScreeningAdapter.allowCall(callDetails.getTelecomCallId());
+ }
+ } catch (RemoteException e) {
+ }
+ }
+}
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 426b240..671399b 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -73,6 +73,7 @@
private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 5;
private static final int MSG_BRING_TO_FOREGROUND = 6;
private static final int MSG_ON_CAN_ADD_CALL_CHANGED = 7;
+ private static final int MSG_SILENCE_RINGER = 8;
/** Default Handler used to consolidate binder method calls onto a single thread. */
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -114,6 +115,9 @@
case MSG_ON_CAN_ADD_CALL_CHANGED:
mPhone.internalSetCanAddCall(msg.arg1 == 1);
break;
+ case MSG_SILENCE_RINGER:
+ mPhone.internalSilenceRinger();
+ break;
default:
break;
}
@@ -165,6 +169,11 @@
mHandler.obtainMessage(MSG_ON_CAN_ADD_CALL_CHANGED, canAddCall ? 1 : 0, 0)
.sendToTarget();
}
+
+ @Override
+ public void silenceRinger() {
+ mHandler.obtainMessage(MSG_SILENCE_RINGER).sendToTarget();
+ }
}
private Phone.Listener mPhoneListener = new Phone.Listener() {
@@ -202,6 +211,12 @@
InCallService.this.onCanAddCallChanged(canAddCall);
}
+ /** ${inheritDoc} */
+ @Override
+ public void onSilenceRinger(Phone phone) {
+ InCallService.this.onSilenceRinger();
+ }
+
};
private Phone mPhone;
@@ -405,6 +420,12 @@
}
/**
+ * Called to silence the ringer if a ringing call exists.
+ */
+ public void onSilenceRinger() {
+ }
+
+ /**
* Used to issue commands to the {@link Connection.VideoProvider} associated with a
* {@link Call}.
*/
diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java
index 47154da..56eb7ec 100644
--- a/telecomm/java/android/telecom/Phone.java
+++ b/telecomm/java/android/telecom/Phone.java
@@ -97,6 +97,13 @@
* @param canAddCall Indicates whether an additional call can be added.
*/
public void onCanAddCallChanged(Phone phone, boolean canAddCall) { }
+
+ /**
+ * Called to silence the ringer if a ringing call exists.
+ *
+ * @param phone The {@code Phone} calling this method.
+ */
+ public void onSilenceRinger(Phone phone) { }
}
// A Map allows us to track each Call by its Telecom-specified call ID
@@ -179,6 +186,10 @@
}
}
+ final void internalSilenceRinger() {
+ fireSilenceRinger();
+ }
+
/**
* Called to destroy the phone and cleanup any lingering calls.
*/
@@ -330,6 +341,12 @@
}
}
+ private void fireSilenceRinger() {
+ for (Listener listener : mListeners) {
+ listener.onSilenceRinger(this);
+ }
+ }
+
private void checkCallTree(ParcelableCall parcelableCall) {
if (parcelableCall.getParentCallId() != null &&
!mCallByTelecomCallId.containsKey(parcelableCall.getParentCallId())) {
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 497864e..72ff272 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -308,6 +308,15 @@
"android.telecom.IN_CALL_SERVICE_CAR_MODE_UI";
/**
+ * A boolean meta-data value indicating whether an {@link InCallService} implements ringing.
+ * Dialer implementations (see {@link #getDefaultDialerPackage()}) which would also like to
+ * override the system provided ringing should set this meta-data to {@code true} in the
+ * manifest registration of their {@link InCallService}.
+ */
+ public static final String METADATA_IN_CALL_SERVICE_RINGING =
+ "android.telecom.IN_CALL_SERVICE_RINGING";
+
+ /**
* The dual tone multi-frequency signaling character sent to indicate the dialing system should
* pause for a predefined period.
*/
diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
new file mode 100644
index 0000000..2e0af27
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telecom;
+
+/**
+ * Internal remote callback interface for call screening services.
+ *
+ * @see android.telecom.CallScreeningService
+ *
+ * {@hide}
+ */
+oneway interface ICallScreeningAdapter {
+ void allowCall(String callId);
+
+ void disallowCall(
+ String callId,
+ boolean shouldReject,
+ boolean shouldAddToCallLog,
+ boolean shouldShowNotification);
+}
diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningService.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningService.aidl
new file mode 100644
index 0000000..c3fe1af
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecom/ICallScreeningService.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telecom;
+
+import android.telecom.ParcelableCall;
+
+import com.android.internal.telecom.ICallScreeningAdapter;
+
+/**
+ * Internal remote interface for a call screening service.
+ * @see android.telecom.CallScreeningService
+ * @hide
+ */
+oneway interface ICallScreeningService {
+ void screenCall(in ICallScreeningAdapter adapter, in ParcelableCall call);
+}
diff --git a/telecomm/java/com/android/internal/telecom/IInCallService.aidl b/telecomm/java/com/android/internal/telecom/IInCallService.aidl
index ded47d5..0088e0c 100644
--- a/telecomm/java/com/android/internal/telecom/IInCallService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IInCallService.aidl
@@ -45,4 +45,6 @@
void bringToForeground(boolean showDialpad);
void onCanAddCallChanged(boolean canAddCall);
+
+ void silenceRinger();
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 630dacc..4368b81 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -409,6 +409,11 @@
public static final String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN = "vvm_cellular_data_required";
/**
+ * Whether to prefetch audio data on new voicemail arrival, defaulted to true.
+ */
+ public static final String KEY_VVM_PREFETCH_BOOLEAN = "vvm_prefetch";
+
+ /**
* The package name of the carrier's visual voicemail app to ensure that dialer visual voicemail
* and carrier visual voicemail are not active at the same time.
*/
@@ -638,6 +643,7 @@
sDefaults.putInt(KEY_VVM_PORT_NUMBER_INT, 0);
sDefaults.putString(KEY_VVM_TYPE_STRING, "");
sDefaults.putBoolean(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN,false);
+ sDefaults.putBoolean(KEY_VVM_PREFETCH_BOOLEAN,true);
sDefaults.putString(KEY_CARRIER_VVM_PACKAGE_NAME_STRING, "");
sDefaults.putBoolean(KEY_CI_ACTION_ON_SYS_UPDATE_BOOL, false);
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING, "");
diff --git a/tests/SoundTriggerTestApp/Android.mk b/tests/SoundTriggerTestApp/Android.mk
new file mode 100644
index 0000000..7bcab5e
--- /dev/null
+++ b/tests/SoundTriggerTestApp/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := SoundTriggerTestApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRIVILEGED_MODULE := true
+
+include $(BUILD_PACKAGE)
diff --git a/tests/SoundTriggerTestApp/AndroidManifest.xml b/tests/SoundTriggerTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..40619da
--- /dev/null
+++ b/tests/SoundTriggerTestApp/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.test.soundtrigger">
+
+ <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" />
+ <application
+ android:permission="android.permission.MANAGE_SOUND_TRIGGER">
+ <activity
+ android:name="TestSoundTriggerActivity"
+ android:label="SoundTrigger Test Application"
+ android:theme="@android:style/Theme.Material.Light.Voice">
+ <intent-filter>
+ <action android:name="com.android.intent.action.MANAGE_SOUND_TRIGGER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/SoundTriggerTestApp/res/layout/main.xml b/tests/SoundTriggerTestApp/res/layout/main.xml
new file mode 100644
index 0000000..9d2b9d9
--- /dev/null
+++ b/tests/SoundTriggerTestApp/res/layout/main.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+
+ 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:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/enroll"
+ android:onClick="onEnrollButtonClicked"
+ android:padding="20dp" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/reenroll"
+ android:onClick="onReEnrollButtonClicked"
+ android:padding="20dp" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/unenroll"
+ android:onClick="onUnEnrollButtonClicked"
+ android:padding="20dp" />
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/SoundTriggerTestApp/res/values/strings.xml b/tests/SoundTriggerTestApp/res/values/strings.xml
new file mode 100644
index 0000000..07bac2a
--- /dev/null
+++ b/tests/SoundTriggerTestApp/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+
+ 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <string name="enroll">Enroll</string>
+ <string name="reenroll">Re-enroll</string>
+ <string name="unenroll">Un-enroll</string>
+</resources>
\ No newline at end of file
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java
new file mode 100644
index 0000000..4702835
--- /dev/null
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java
@@ -0,0 +1,115 @@
+/*
+ * 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.test.soundtrigger;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.media.soundtrigger.SoundTriggerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import com.android.internal.app.ISoundTriggerService;
+
+import java.util.UUID;
+
+/**
+ * Utility class for the managing sound trigger sound models.
+ */
+public class SoundTriggerUtil {
+ private static final String TAG = "TestSoundTriggerUtil:Hotsound";
+
+ private final ISoundTriggerService mSoundTriggerService;
+ private final SoundTriggerManager mSoundTriggerManager;
+ private final Context mContext;
+
+ public SoundTriggerUtil(Context context) {
+ mSoundTriggerService = ISoundTriggerService.Stub.asInterface(
+ ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE));
+ mSoundTriggerManager = (SoundTriggerManager) context.getSystemService(
+ Context.SOUND_TRIGGER_SERVICE);
+ mContext = context;
+ }
+
+ /**
+ * Adds/Updates a sound model.
+ * The sound model must contain a valid UUID.
+ *
+ * @param soundModel The sound model to add/update.
+ */
+ public boolean addOrUpdateSoundModel(GenericSoundModel soundModel) {
+ try {
+ mSoundTriggerService.updateSoundModel(soundModel);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in updateSoundModel", e);
+ }
+ return true;
+ }
+
+ public void addOrUpdateSoundModel(SoundTriggerManager.Model soundModel) {
+ mSoundTriggerManager.updateModel(soundModel);
+ }
+
+ /**
+ * Gets the sound model for the given keyphrase, null if none exists.
+ * If a sound model for a given keyphrase exists, and it needs to be updated,
+ * it should be obtained using this method, updated and then passed in to
+ * {@link #addOrUpdateSoundModel(GenericSoundModel)} without changing the IDs.
+ *
+ * @param modelId The model ID to look-up the sound model for.
+ * @return The sound model if one was found, null otherwise.
+ */
+ @Nullable
+ public GenericSoundModel getSoundModel(UUID modelId) {
+ GenericSoundModel model = null;
+ try {
+ model = mSoundTriggerService.getSoundModel(new ParcelUuid(modelId));
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in updateKeyphraseSoundModel");
+ }
+
+ if (model == null) {
+ Log.w(TAG, "No models present for the gien keyphrase ID");
+ return null;
+ } else {
+ return model;
+ }
+ }
+
+ /**
+ * Deletes the sound model for the given keyphrase id.
+ *
+ * @param modelId The model ID to look-up the sound model for.
+ * @return {@code true} if the call succeeds, {@code false} otherwise.
+ */
+ @Nullable
+ public boolean deleteSoundModel(UUID modelId) {
+ try {
+ mSoundTriggerService.deleteSoundModel(new ParcelUuid(modelId));
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in updateSoundModel");
+ }
+ return true;
+ }
+
+ public void deleteSoundModelUsingManager(UUID modelId) {
+ mSoundTriggerManager.deleteModel(modelId);
+ }
+}
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
new file mode 100644
index 0000000..966179b
--- /dev/null
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
@@ -0,0 +1,121 @@
+/*
+ * 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.test.soundtrigger;
+
+import java.util.Random;
+import java.util.UUID;
+
+import android.app.Activity;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.media.soundtrigger.SoundTriggerManager;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+public class TestSoundTriggerActivity extends Activity {
+ private static final String TAG = "TestSoundTriggerActivity";
+ private static final boolean DBG = true;
+
+ private SoundTriggerUtil mSoundTriggerUtil;
+ private Random mRandom;
+ private UUID mModelUuid = UUID.randomUUID();
+ private UUID mModelUuid2 = UUID.randomUUID();
+ private UUID mVendorUuid = UUID.randomUUID();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ if (DBG) Log.d(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ mSoundTriggerUtil = new SoundTriggerUtil(this);
+ mRandom = new Random();
+ }
+
+ /**
+ * Called when the user clicks the enroll button.
+ * Performs a fresh enrollment.
+ */
+ public void onEnrollButtonClicked(View v) {
+ // Generate a fake model to push.
+ byte[] data = new byte[1024];
+ mRandom.nextBytes(data);
+ GenericSoundModel model = new GenericSoundModel(mModelUuid, mVendorUuid, data);
+
+ boolean status = mSoundTriggerUtil.addOrUpdateSoundModel(model);
+ if (status) {
+ Toast.makeText(
+ this, "Successfully created sound trigger model UUID=" + mModelUuid, Toast.LENGTH_SHORT)
+ .show();
+ } else {
+ Toast.makeText(this, "Failed to enroll!!!" + mModelUuid, Toast.LENGTH_SHORT).show();
+ }
+
+ // Test the SoundManager API.
+ SoundTriggerManager.Model tmpModel = SoundTriggerManager.Model.create(mModelUuid2,
+ mVendorUuid, data);
+ mSoundTriggerUtil.addOrUpdateSoundModel(tmpModel);
+ }
+
+ /**
+ * Called when the user clicks the un-enroll button.
+ * Clears the enrollment information for the user.
+ */
+ public void onUnEnrollButtonClicked(View v) {
+ GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid);
+ if (soundModel == null) {
+ Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ boolean status = mSoundTriggerUtil.deleteSoundModel(mModelUuid);
+ if (status) {
+ Toast.makeText(this, "Successfully deleted model UUID=" + soundModel.uuid,
+ Toast.LENGTH_SHORT)
+ .show();
+ } else {
+ Toast.makeText(this, "Failed to delete sound model!!!", Toast.LENGTH_SHORT).show();
+ }
+ mSoundTriggerUtil.deleteSoundModelUsingManager(mModelUuid2);
+ }
+
+ /**
+ * Called when the user clicks the re-enroll button.
+ * Uses the previously enrolled sound model and makes changes to it before pushing it back.
+ */
+ public void onReEnrollButtonClicked(View v) {
+ GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid);
+ if (soundModel == null) {
+ Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ // Generate a fake model to push.
+ byte[] data = new byte[2048];
+ mRandom.nextBytes(data);
+ GenericSoundModel updated = new GenericSoundModel(soundModel.uuid,
+ soundModel.vendorUuid, data);
+ boolean status = mSoundTriggerUtil.addOrUpdateSoundModel(updated);
+ if (status) {
+ Toast.makeText(this, "Successfully re-enrolled, model UUID=" + updated.uuid,
+ Toast.LENGTH_SHORT)
+ .show();
+ } else {
+ Toast.makeText(this, "Failed to re-enroll!!!", Toast.LENGTH_SHORT).show();
+ }
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index a3f3821..2000fbc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -50,7 +50,7 @@
@Override
public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6,
- boolean b, Configuration configuration, Rect rect7) throws RemoteException {
+ boolean b, Configuration configuration, Rect rect7, boolean b2) throws RemoteException {
// pass for now.
}