summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt11
-rw-r--r--api/system-current.txt11
-rw-r--r--core/java/android/hardware/camera2/utils/CameraBinderDecorator.java4
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java2
-rw-r--r--core/java/android/widget/RelativeLayout.java18
-rw-r--r--core/java/android/widget/Toolbar.java18
-rw-r--r--core/res/res/drawable/spinner_background_material.xml14
-rw-r--r--core/res/res/values/attrs.xml10
-rw-r--r--core/res/res/values/public.xml3
-rw-r--r--core/res/res/values/strings.xml6
-rw-r--r--docs/html/training/articles/keystore.jd59
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java2
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java23
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/ShapeDrawable.java2
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java5
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSpi.java5
-rw-r--r--keystore/java/android/security/keystore/KeyGenParameterSpec.java127
-rw-r--r--keystore/java/android/security/keystore/KeyInfo.java20
-rw-r--r--keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java13
-rw-r--r--keystore/java/android/security/keystore/KeyProtection.java111
-rw-r--r--media/java/android/media/AudioRecord.java15
-rw-r--r--media/java/android/media/AudioTrack.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java18
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java14
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java33
-rw-r--r--telephony/java/android/telephony/DisconnectCause.java18
33 files changed, 431 insertions, 165 deletions
diff --git a/api/current.txt b/api/current.txt
index ca8cb8cba07e..b72730a8cb90 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -826,6 +826,7 @@ package android {
field public static final int listViewWhiteStyle = 16842869; // 0x1010075
field public static final int lockTaskMode = 16844015; // 0x10104ef
field public static final int logo = 16843454; // 0x10102be
+ field public static final int logoDescription = 16844026; // 0x10104fa
field public static final int longClickable = 16842982; // 0x10100e6
field public static final int loopViews = 16843527; // 0x1010307
field public static final int manageSpaceActivity = 16842756; // 0x1010004
@@ -1178,6 +1179,7 @@ package android {
field public static final int submitBackground = 16843912; // 0x1010488
field public static final int subtitle = 16843473; // 0x10102d1
field public static final int subtitleTextAppearance = 16843823; // 0x101042f
+ field public static final int subtitleTextColor = 16844028; // 0x10104fc
field public static final int subtitleTextStyle = 16843513; // 0x10102f9
field public static final int subtypeExtraValue = 16843674; // 0x101039a
field public static final int subtypeId = 16843713; // 0x10103c1
@@ -1308,6 +1310,7 @@ package android {
field public static final int title = 16843233; // 0x10101e1
field public static final int titleCondensed = 16843234; // 0x10101e2
field public static final int titleTextAppearance = 16843822; // 0x101042e
+ field public static final int titleTextColor = 16844027; // 0x10104fb
field public static final int titleTextStyle = 16843512; // 0x10102f8
field public static final int toAlpha = 16843211; // 0x10101cb
field public static final int toDegrees = 16843188; // 0x10101b4
@@ -12303,7 +12306,6 @@ package android.graphics.drawable {
method public android.graphics.drawable.Drawable.ConstantState getConstantState();
method public android.graphics.drawable.Drawable getCurrent();
method public android.graphics.Rect getDirtyBounds();
- method public boolean getDither();
method public void getHotspotBounds(android.graphics.Rect);
method public int getIntrinsicHeight();
method public int getIntrinsicWidth();
@@ -12320,6 +12322,7 @@ package android.graphics.drawable {
method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public void invalidateSelf();
method public boolean isAutoMirrored();
+ method public boolean isDither();
method public boolean isFilterBitmap();
method public boolean isStateful();
method public final boolean isVisible();
@@ -28910,6 +28913,7 @@ package android.service.voice {
method public void onDestroy();
method public boolean[] onGetSupportedCommands(java.lang.String[]);
method public void onHandleAssist(android.os.Bundle, android.app.assist.AssistStructure, android.app.assist.AssistContent);
+ method public void onHandleScreenshot(android.graphics.Bitmap);
method public void onHide();
method public boolean onKeyDown(int, android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
@@ -28932,6 +28936,7 @@ package android.service.voice {
method public void startVoiceActivity(android.content.Intent);
field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4
field public static final int SHOW_WITH_ASSIST = 1; // 0x1
+ field public static final int SHOW_WITH_SCREENSHOT = 2; // 0x2
}
public static final class VoiceInteractionSession.AbortVoiceRequest extends android.service.voice.VoiceInteractionSession.Request {
@@ -30620,10 +30625,14 @@ package android.telephony {
field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
+ field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
+ field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool";
+ field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
+ field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
diff --git a/api/system-current.txt b/api/system-current.txt
index fe8a21e4f3e2..e32892095991 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -901,6 +901,7 @@ package android {
field public static final int listViewWhiteStyle = 16842869; // 0x1010075
field public static final int lockTaskMode = 16844015; // 0x10104ef
field public static final int logo = 16843454; // 0x10102be
+ field public static final int logoDescription = 16844026; // 0x10104fa
field public static final int longClickable = 16842982; // 0x10100e6
field public static final int loopViews = 16843527; // 0x1010307
field public static final int manageSpaceActivity = 16842756; // 0x1010004
@@ -1257,6 +1258,7 @@ package android {
field public static final int submitBackground = 16843912; // 0x1010488
field public static final int subtitle = 16843473; // 0x10102d1
field public static final int subtitleTextAppearance = 16843823; // 0x101042f
+ field public static final int subtitleTextColor = 16844028; // 0x10104fc
field public static final int subtitleTextStyle = 16843513; // 0x10102f9
field public static final int subtypeExtraValue = 16843674; // 0x101039a
field public static final int subtypeId = 16843713; // 0x10103c1
@@ -1387,6 +1389,7 @@ package android {
field public static final int title = 16843233; // 0x10101e1
field public static final int titleCondensed = 16843234; // 0x10101e2
field public static final int titleTextAppearance = 16843822; // 0x101042e
+ field public static final int titleTextColor = 16844027; // 0x10104fb
field public static final int titleTextStyle = 16843512; // 0x10102f8
field public static final int toAlpha = 16843211; // 0x10101cb
field public static final int toDegrees = 16843188; // 0x10101b4
@@ -12628,7 +12631,6 @@ package android.graphics.drawable {
method public android.graphics.drawable.Drawable.ConstantState getConstantState();
method public android.graphics.drawable.Drawable getCurrent();
method public android.graphics.Rect getDirtyBounds();
- method public boolean getDither();
method public void getHotspotBounds(android.graphics.Rect);
method public int getIntrinsicHeight();
method public int getIntrinsicWidth();
@@ -12645,6 +12647,7 @@ package android.graphics.drawable {
method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public void invalidateSelf();
method public boolean isAutoMirrored();
+ method public boolean isDither();
method public boolean isFilterBitmap();
method public boolean isStateful();
method public final boolean isVisible();
@@ -31057,6 +31060,7 @@ package android.service.voice {
method public void onDestroy();
method public boolean[] onGetSupportedCommands(java.lang.String[]);
method public void onHandleAssist(android.os.Bundle, android.app.assist.AssistStructure, android.app.assist.AssistContent);
+ method public void onHandleScreenshot(android.graphics.Bitmap);
method public void onHide();
method public boolean onKeyDown(int, android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
@@ -31079,6 +31083,7 @@ package android.service.voice {
method public void startVoiceActivity(android.content.Intent);
field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4
field public static final int SHOW_WITH_ASSIST = 1; // 0x1
+ field public static final int SHOW_WITH_SCREENSHOT = 2; // 0x2
}
public static final class VoiceInteractionSession.AbortVoiceRequest extends android.service.voice.VoiceInteractionSession.Request {
@@ -32850,10 +32855,14 @@ package android.telephony {
field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
+ field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
+ field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool";
+ field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
+ field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index d461bca532e1..1aee79477e3f 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -138,8 +138,8 @@ public class CameraBinderDecorator {
* errors, then add them to the top switch statement
*/
if (errorFlag < 0) {
- throw new UnsupportedOperationException(String.format("Unknown error %d",
- errorFlag));
+ throw new CameraRuntimeException(CAMERA_ERROR,
+ String.format("Unknown camera device error %d", errorFlag));
}
}
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index d5ee7e7304cc..0367cfcefe0c 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -80,7 +80,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
public static final int SHOW_WITH_ASSIST = 1<<0;
/**
- * @hide
* Flag received in {@link #onShow}: originator requested that the session be started with
* a screen shot of the currently focused activity.
*/
@@ -1162,7 +1161,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
onHandleAssist(data);
}
- /** @hide */
public void onHandleScreenshot(Bitmap screenshot) {
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index affc5daa35f7..339038eddf3f 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -522,7 +522,7 @@ public class RelativeLayout extends ViewGroup {
View baselineView = null;
LayoutParams baselineParams = null;
for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
if (baselineView == null || baselineParams == null
@@ -548,9 +548,9 @@ public class RelativeLayout extends ViewGroup {
if (offsetHorizontalAxis) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
final int[] rules = params.getRules(layoutDirection);
if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) {
centerHorizontal(child, params, width);
@@ -578,9 +578,9 @@ public class RelativeLayout extends ViewGroup {
if (offsetVerticalAxis) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
final int[] rules = params.getRules(layoutDirection);
if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) {
centerVertical(child, params, height);
@@ -607,9 +607,9 @@ public class RelativeLayout extends ViewGroup {
final int verticalOffset = contentBounds.top - top;
if (horizontalOffset != 0 || verticalOffset != 0) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE && child != ignore) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
if (horizontalGravity) {
params.mLeft += horizontalOffset;
params.mRight += horizontalOffset;
@@ -626,9 +626,9 @@ public class RelativeLayout extends ViewGroup {
if (isLayoutRtl()) {
final int offsetWidth = myWidth - width;
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
params.mLeft -= offsetWidth;
params.mRight -= offsetWidth;
}
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 2ea2667f3591..471ea9b0031e 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -273,6 +273,24 @@ public class Toolbar extends ViewGroup {
if (!TextUtils.isEmpty(navDesc)) {
setNavigationContentDescription(navDesc);
}
+
+ final Drawable logo = a.getDrawable(R.styleable.Toolbar_logo);
+ if (logo != null) {
+ setLogo(logo);
+ }
+
+ final CharSequence logoDesc = a.getText(R.styleable.Toolbar_logoDescription);
+ if (!TextUtils.isEmpty(logoDesc)) {
+ setLogoDescription(logoDesc);
+ }
+
+ if (a.hasValue(R.styleable.Toolbar_titleTextColor)) {
+ setTitleTextColor(a.getColor(R.styleable.Toolbar_titleTextColor, 0xffffffff));
+ }
+
+ if (a.hasValue(R.styleable.Toolbar_subtitleTextColor)) {
+ setSubtitleTextColor(a.getColor(R.styleable.Toolbar_subtitleTextColor, 0xffffffff));
+ }
a.recycle();
}
diff --git a/core/res/res/drawable/spinner_background_material.xml b/core/res/res/drawable/spinner_background_material.xml
index 892dbc5eb4c3..d37f5b78a4c0 100644
--- a/core/res/res/drawable/spinner_background_material.xml
+++ b/core/res/res/drawable/spinner_background_material.xml
@@ -17,22 +17,18 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingMode="stack"
android:paddingStart="0dp"
- android:paddingEnd="48dp"
+ android:paddingEnd="24dp"
android:paddingLeft="0dp"
android:paddingRight="0dp">
<item
android:gravity="end|center_vertical"
- android:width="48dp"
- android:height="48dp">
- <ripple
- android:color="?attr/colorControlHighlight"
- android:radius="24dp" />
- </item>
+ android:width="24dp"
+ android:height="24dp"
+ android:drawable="@drawable/control_background_40dp_material" />
<item
android:drawable="@drawable/ic_spinner_caret"
android:gravity="end|center_vertical"
android:width="24dp"
- android:height="24dp"
- android:end="12dp" />
+ android:height="24dp" />
</layer-list>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c08d511a15a1..647dde778792 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7775,6 +7775,16 @@ i
<!-- Text to set as the content description for the navigation button
located at the start of the toolbar. -->
<attr name="navigationContentDescription" format="string" />
+ <!-- Drawable to set as the logo that appears at the starting side of
+ the Toolbar, just after the navigation button. -->
+ <attr name="logo" />
+ <!-- A content description string to describe the appearance of the
+ associated logo image. -->
+ <attr name="logoDescription" format="string" />
+ <!-- A color to apply to the title string. -->
+ <attr name="titleTextColor" format="color" />
+ <!-- A color to apply to the subtitle string. -->
+ <attr name="subtitleTextColor" format="color" />
</declare-styleable>
<declare-styleable name="Toolbar_LayoutParams">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index bbe27a4bdf90..b7f47245c4eb 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2699,4 +2699,7 @@
<public type="attr" name="scrollIndicators" />
<public type="attr" name="hyphenationFrequency" />
<public type="attr" name="fingerprintAuthDrawable" />
+ <public type="attr" name="logoDescription" />
+ <public type="attr" name="titleTextColor" />
+ <public type="attr" name="subtitleTextColor" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 510f6a590c3c..ea0d349ccd76 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -537,10 +537,10 @@
<!-- Label for the Android system components when they are shown to the user. -->
<string name="android_system_label">Android System</string>
- <!-- Label for the user owner in the intent forwarding app. -->
- <string name="user_owner_label">Personal apps</string>
+ <!-- Label for the user owner in the intent forwarding app. [CHAR LIMIT=15] -->
+ <string name="user_owner_label">Personal</string>
- <!-- Label for a corporate profile in the intent forwarding app. -->
+ <!-- Label for a corporate profile in the intent forwarding app. [CHAR LIMIT=15] -->
<string name="managed_profile_label">Work</string>
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/docs/html/training/articles/keystore.jd b/docs/html/training/articles/keystore.jd
index fca958e0620d..52cb13eb5a03 100644
--- a/docs/html/training/articles/keystore.jd
+++ b/docs/html/training/articles/keystore.jd
@@ -32,7 +32,7 @@ page.title=Android Keystore System
keystore, they can be used for cryptographic operations with the key material
remaining non-exportable. Moreover, it offers facilities to restrict when and
how keys can be used, such as requiring user authentication for key use or
- restricting encryption keys to be used only in certain block modes. See
+ restricting keys to be used only in certain cryptographic modes. See
<a href="#SecurityFeatures">Security Features</a> section for more information.</p>
<p>The Keystore system is used by the {@link
@@ -48,7 +48,8 @@ Android Keystore system protects key material from unauthorized use. Firstly, An
mitigates unauthorized use of key material outside of the Android device by preventing extraction of
the key material from application processes and from the Android device as a whole. Secondly,
Android KeyStore mitigates unauthorized use of key material on the Android device by making apps
-specify authorized uses of their keys and then enforcing these restrictions.
+specify authorized uses of their keys and then enforcing these restrictions outside of the apps'
+processes.
<h3 id="ExtractionPrevention">Extraction Prevention</h3>
@@ -78,14 +79,16 @@ Key material of Android Keystore keys is protected from extraction using two sec
To mitigate unauthorized use of keys on the Android device, Android Keystore lets apps specify
authorized uses of their keys when generating or importing the keys. Once a key is generated or
imported, its authorizations can not be changed. Authorizations are then enforced by the Android
-Keystore whenever the key is used.
+Keystore whenever the key is used. This is an advanced security feature which is generally useful
+only if your requirements are that a compromise of your application process after key
+generation/import (but not before or during) cannot lead to unauthorized uses of the key.
<p>Supported key use authorizations fall into the following categories:
<ul>
<li><em>cryptography</em>: authorized key algorithm, operations or purposes (encrypt, decrypt, sign,
- verify), padding schemes, block modes, digests with which the key can be used</li>
+ verify), padding schemes, block modes, digests with which the key can be used;</li>
<li><em>temporal validity interval</em>: interval of time during which the key is authorized for
- use</li>
+ use;</li>
<li><em>user authentication</em>: the key can only be used if the user has been authenticated
recently enough. See <a href="#UserAuthentication">Requiring User Authentication For Key Use</a>.
</li>
@@ -181,23 +184,33 @@ and {@link java.security.KeyPairGenerator} or
<h3 id="UserAuthentication">Requiring User Authentication For Key Use</h3>
<p>When generating or importing a key into the {@code AndroidKeyStore} you can specify that the key
-can only be used if user has been authenticated. The user is authenticated using a subset of their
-secure lock screen credentials. This is a security measure which makes it possible to generate
-cryptographic assertions about the user having been authenticated.
+is only authorized to be used if the user has been authenticated. The user is authenticated using a
+subset of their secure lock screen credentials (pattern/PIN/password, fingerprint).
-<p>When a key is configured to require user authentication, it is also configured to operate in one
-of the two modes:
+<p>This is an advanced security feature which is generally useful only if your requirements are that
+a compromise of your application process after key generation/import (but not before or during)
+cannot bypass the requirement for the user to be authenticated to use the key.
+
+<p>When a key is authorized to be used only if the user has been authenticated, it is configured to
+operate in one of the two modes:
<ul>
-<li>User authentication is valid for a duration of time. All keys in this mode are authorized
- for use as soon as the user unlocks the secure lock screen or confirms their secure lock screen
- credentials using the {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence) KeyguardManager.createConfirmDeviceCredentialIntent}
- flow. Each key specifies for how long the authorization remains valid for that key. Such keys
- can only be generated or imported if the secure lock screen is enabled (see {@link android.app.KeyguardManager#isDeviceSecure() KeyguardManager.isDeviceSecure()}).
- These keys become permanently invalidated once the secure lock screen is disabled or forcibly
- reset (e.g. by a Device Admin).</li>
-<li>User authentication is required for every use of the key. In this mode, a specific operation
- involving a specific key is authorized by the user. Currently, the only means of such
- authorization is fingerprint authentication: {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler) FingerprintManager.authenticate}.
- Such keys can only be generated or imported if at least one fingerprint is enrolled (see {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}).
- These keys become permanently invalidated once all fingerprints are unenrolled.</li>
-</ul>
+<li>User authentication authorizes the use of keys for a duration of time. All keys in this mode are
+ authorized for use as soon as the user unlocks the secure lock screen or confirms their secure
+ lock screen credential using the
+ {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence) KeyguardManager.createConfirmDeviceCredentialIntent}
+ flow. The duration for which the authorization remains valid is specific to each key, as specified
+ using {@code setUserAuthenticationValidityDurationSeconds} during key generation or import. Such
+ keys can only be generated or imported if the secure lock screen is enabled (see
+ {@link android.app.KeyguardManager#isDeviceSecure() KeyguardManager.isDeviceSecure()}). These keys
+ become permanently invalidated once the secure lock screen is disabled (reconfigured to None,
+ Swipe or other mode which does not authenticate the user) or forcibly reset (e.g. by a Device
+ Administrator).</li>
+<li>User authentication authorizes a specific cryptographic operation associated with one key. In
+ this mode, each operation involving such a key must be individually authorized by the user.
+ Currently, the only means of such authorization is fingerprint authentication:
+ {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler) FingerprintManager.authenticate}.
+ Such keys can only be generated or imported if at least one fingerprint is enrolled (see
+ {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}).
+ These keys become permanently invalidated once a new fingerprint is enrolled or all fingerprints
+ are unenrolled.</li>
+</ul> \ No newline at end of file
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index a0c407f0334d..f059727cb806 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -363,7 +363,7 @@ public class BitmapDrawable extends Drawable {
}
@Override
- public boolean getDither() {
+ public boolean isDither() {
return mBitmapState.mPaint.isDither();
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 415af0d6bc4a..6090cf0b8add 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -279,7 +279,7 @@ public abstract class Drawable {
* @return whether this drawable dithers its colors
* @see #setDither(boolean)
*/
- public boolean getDither() {
+ public boolean isDither() {
return false;
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 8b801c38c2c2..1759f53da604 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -167,7 +167,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
@Override
- public boolean getDither() {
+ public boolean isDither() {
return mDrawableContainerState.mDither;
}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index ed47eede651b..626991d19b6b 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -826,7 +826,7 @@ public class GradientDrawable extends Drawable {
}
@Override
- public boolean getDither() {
+ public boolean isDither() {
return mGradientState.mDither;
}
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 5c00a23b9918..90891f606f24 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1248,12 +1248,12 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
@Override
- public boolean getDither() {
+ public boolean isDither() {
final Drawable dr = getFirstNonNullDrawable();
if (dr != null) {
- return dr.getDither();
+ return dr.isDither();
} else {
- return super.getDither();
+ return super.isDither();
}
}
@@ -1537,8 +1537,23 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
continue;
}
+ // Take the resolved layout direction into account. If start / end
+ // padding are defined, they will be resolved (hence overriding) to
+ // left / right or right / left depending on the resolved layout
+ // direction. If start / end padding are not defined, use the
+ // left / right ones.
+ final int insetL, insetR;
+ final int layoutDirection = getLayoutDirection();
+ if (layoutDirection == LayoutDirection.RTL) {
+ insetL = r.mInsetE == UNDEFINED_INSET ? r.mInsetL : r.mInsetE;
+ insetR = r.mInsetS == UNDEFINED_INSET ? r.mInsetR : r.mInsetS;
+ } else {
+ insetL = r.mInsetS == UNDEFINED_INSET ? r.mInsetL : r.mInsetS;
+ insetR = r.mInsetE == UNDEFINED_INSET ? r.mInsetR : r.mInsetE;
+ }
+
final int minWidth = r.mWidth < 0 ? r.mDrawable.getIntrinsicWidth() : r.mWidth;
- final int w = minWidth + r.mInsetL + r.mInsetR + padL + padR;
+ final int w = minWidth + insetL + insetR + padL + padR;
if (w > width) {
width = w;
}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 0b7869bc243f..adf53e3e6a2f 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -374,7 +374,7 @@ public class NinePatchDrawable extends Drawable {
}
@Override
- public boolean getDither() {
+ public boolean isDither() {
return mPaint == null ? DEFAULT_DITHER : mPaint.isDither();
}
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 334b3bd366db..a669d3c8667a 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -328,7 +328,7 @@ public class ShapeDrawable extends Drawable {
}
@Override
- public boolean getDither() {
+ public boolean isDither() {
return mShapeState.mPaint.isDither();
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index af05578535a5..2055cdb144e5 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -226,9 +226,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
| KeyProperties.PURPOSE_VERIFY);
// Authorized to be used with any digest (including no digest).
specBuilder.setDigests(KeyProperties.DIGEST_NONE);
- specBuilder.setSignaturePaddings(
- KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
- // Authorized to be used with any padding (including no padding).
+ // Authorized to be used with any encryption and signature padding
+ // scheme (including no padding).
specBuilder.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_NONE);
// Disable randomized encryption requirement to support encryption
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 3bd9d1de57b2..5fb589e80a8c 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -258,9 +258,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
| KeyProperties.PURPOSE_VERIFY);
// Authorized to be used with any digest (including no digest).
specBuilder.setDigests(KeyProperties.DIGEST_NONE);
- specBuilder.setSignaturePaddings(
- KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
- // Authorized to be used with any padding (including no padding).
+ // Authorized to be used with any encryption and signature padding scheme (including no
+ // padding).
specBuilder.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_NONE);
// Disable randomized encryption requirement to support encryption padding NONE
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 8d4bfcd0cc83..1732db9ae335 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -19,16 +19,20 @@ package android.security.keystore;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.KeyguardManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.text.TextUtils;
import java.math.BigInteger;
import java.security.KeyPairGenerator;
+import java.security.Signature;
import java.security.cert.Certificate;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
import javax.security.auth.x500.X500Principal;
/**
@@ -62,10 +66,15 @@ import javax.security.auth.x500.X500Principal;
* <p>NOTE: If a private key is not authorized to sign the self-signed certificate, then the
* certificate will be created with an invalid signature which will not verify. Such a certificate
* is still useful because it provides access to the public key. To generate a valid
- * signature for the certificate the key needs to be authorized for
- * {@link KeyProperties#PURPOSE_SIGN}, a suitable digest or {@link KeyProperties#DIGEST_NONE}, and
- * {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
- * {@link KeyProperties#ENCRYPTION_PADDING_NONE}.
+ * signature for the certificate the key needs to be authorized for all of the following:
+ * <ul>
+ * <li>{@link KeyProperties#PURPOSE_SIGN},</li>
+ * <li>operation without requiring the user to be authenticated (see
+ * {@link Builder#setUserAuthenticationRequired(boolean)}),</li>
+ * <li>suitable digest or {@link KeyProperties#DIGEST_NONE},</li>
+ * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
+ * {@link KeyProperties#ENCRYPTION_PADDING_NONE}.</li>
+ * </ul>
*
* <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key
* material of the public keys is accessible.
@@ -103,7 +112,7 @@ import javax.security.auth.x500.X500Principal;
*
* <p><h3>Example: Symmetric key</h3>
* The following example illustrates how to generate an AES key in the Android KeyStore system under
- * alias {@code key2} authorized to be used only for encryption/decryption in CBC mode with PKCS#7
+ * alias {@code key2} authorized to be used only for encryption/decryption in GCM mode with no
* padding.
* <pre> {@code
* KeyGenerator keyGenerator = KeyGenerator.getInstance(
@@ -112,8 +121,8 @@ import javax.security.auth.x500.X500Principal;
* keyGenerator.initialize(
* new KeyGenParameterSpec.Builder("key2",
* KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
- * .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
- * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+ * .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+ * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
* .build());
* SecretKey key = keyGenerator.generateKey();
*
@@ -368,7 +377,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
}
/**
- * Gets the set of block modes (e.g., {@code CBC}, {@code CTR}) with which the key can be used
+ * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used
* when encrypting/decrypting. Attempts to use the key with any other block modes will be
* rejected.
*
@@ -393,28 +402,32 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
}
/**
- * Returns {@code true} if user authentication is required for this key to be used.
+ * Returns {@code true} if the key is authorized to be used only if the user has been
+ * authenticated.
*
- * <p>This restriction applies only to private key operations. Public key operations are not
- * restricted.
+ * <p>This authorization applies only to secret key and private key operations. Public key
+ * operations are not restricted.
*
* @see #getUserAuthenticationValidityDurationSeconds()
+ * @see Builder#setUserAuthenticationRequired(boolean)
*/
public boolean isUserAuthenticationRequired() {
return mUserAuthenticationRequired;
}
/**
- * Gets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
+ * Gets the duration of time (seconds) for which this key is authorized to be used after the
+ * user is successfully authenticated. This has effect only if user authentication is required
+ * (see {@link #isUserAuthenticationRequired()}).
*
- * <p>This restriction applies only to private key operations. Public key operations are not
- * restricted.
+ * <p>This authorization applies only to secret key and private key operations. Public key
+ * operations are not restricted.
*
* @return duration in seconds or {@code -1} if authentication is required for every use of the
- * key.
+ * key.
*
* @see #isUserAuthenticationRequired()
+ * @see Builder#setUserAuthenticationValidityDurationSeconds(int)
*/
public int getUserAuthenticationValidityDurationSeconds() {
return mUserAuthenticationValidityDurationSeconds;
@@ -681,11 +694,11 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
}
/**
- * Sets the set of block modes (e.g., {@code CBC}, {@code CTR}, {@code ECB}) with which the
- * key can be used when encrypting/decrypting. Attempts to use the key with any other block
- * modes will be rejected.
+ * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be
+ * used when encrypting/decrypting. Attempts to use the key with any other block modes will
+ * be rejected.
*
- * <p>This must be specified for encryption/decryption keys.
+ * <p>This must be specified for symmetric encryption/decryption keys.
*
* <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
*/
@@ -711,7 +724,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
* <li>encryption/decryption transformation which do not offer {@code IND-CPA}, such as
* {@code ECB} with a symmetric encryption algorithm, or RSA encryption/decryption without
* padding, are prohibited;</li>
- * <li>in block modes which use an IV, such as {@code CBC}, {@code CTR}, and {@code GCM},
+ * <li>in block modes which use an IV, such as {@code GCM}, {@code CBC}, and {@code CTR},
* caller-provided IVs are rejected when encrypting, to ensure that only random IVs are
* used.</li>
* </ul>
@@ -738,22 +751,38 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
}
/**
- * Sets whether user authentication is required to use this key.
+ * Sets whether this key is authorized to be used only if the user has been authenticated.
*
- * <p>By default, the key can be used without user authentication.
+ * <p>By default, the key is authorized to be used regardless of whether the user has been
+ * authenticated.
*
- * <p>When user authentication is required, the user authorizes the use of the key by
- * authenticating to this Android device using a subset of their secure lock screen
- * credentials. Different authentication methods are used depending on whether the every
- * use of the key must be authenticated (as specified by
- * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+ * <p>When user authentication is required:
+ * <ul>
+ * <li>The key can only be generated if secure lock screen is set up (see
+ * {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
+ * authentication takes place for every use of the key (see
+ * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
+ * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
+ * <li>The use of the key must be authorized by the user by authenticating to this Android
+ * device using a subset of their secure lock screen credentials such as
+ * password/PIN/pattern or fingerprint.
* <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
* information</a>.
+ * <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
+ * disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
+ * or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
+ * Additionally, if the key requires that user authentication takes place for every use of
+ * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
+ * no more fingerprints are enrolled. Attempts to initialize cryptographic operations using
+ * such keys will throw {@link KeyPermanentlyInvalidatedException}.</li>
+ * </ul>
*
- * <p>This restriction applies only to private key operations. Public key operations are not
- * restricted.
+ * <p>This authorization applies only to secret key and private key operations. Public key
+ * operations are not restricted.
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
+ * @see KeyguardManager#isDeviceSecure()
+ * @see FingerprintManager#hasEnrolledFingerprints()
*/
@NonNull
public Builder setUserAuthenticationRequired(boolean required) {
@@ -762,15 +791,39 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
}
/**
- * Sets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
- *
- * <p>By default, the user needs to authenticate for every use of the key.
- *
- * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
- * every use of the key.
+ * Sets the duration of time (seconds) for which this key is authorized to be used after the
+ * user is successfully authenticated. This has effect if the key requires user
+ * authentication for its use (see {@link #setUserAuthenticationRequired(boolean)}).
+ *
+ * <p>By default, if user authentication is required, it must take place for every use of
+ * the key.
+ *
+ * <p>Cryptographic operations involving keys which require user authentication to take
+ * place for every operation can only use fingerprint authentication. This is achieved by
+ * initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
+ * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
+ * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
+ * the cryptographic operation only if the authentication flow succeeds.
+ *
+ * <p>Cryptographic operations involving keys which are authorized to be used for a duration
+ * of time after a successful user authentication event can only use secure lock screen
+ * authentication. These cryptographic operations will throw
+ * {@link UserNotAuthenticatedException} during initialization if the user needs to be
+ * authenticated to proceed. This situation can be resolved by the user unlocking the secure
+ * lock screen of the Android or by going through the confirm credential flow initiated by
+ * {@link KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence)}.
+ * Once resolved, initializing a new cryptographic operation using this key (or any other
+ * key which is authorized to be used for a fixed duration of time after user
+ * authentication) should succeed provided the user authentication flow completed
+ * successfully.
+ *
+ * @param seconds duration in seconds or {@code -1} if user authentication must take place
+ * for every use of the key.
*
* @see #setUserAuthenticationRequired(boolean)
+ * @see FingerprintManager
+ * @see FingerprintManager.CryptoObject
+ * @see KeyguardManager
*/
@NonNull
public Builder setUserAuthenticationValidityDurationSeconds(
diff --git a/keystore/java/android/security/keystore/KeyInfo.java b/keystore/java/android/security/keystore/KeyInfo.java
index 03b41002ee95..785ec1528b94 100644
--- a/keystore/java/android/security/keystore/KeyInfo.java
+++ b/keystore/java/android/security/keystore/KeyInfo.java
@@ -30,7 +30,7 @@ import javax.crypto.SecretKey;
* Keystore system</a>. This class describes whether the key material is available in
* plaintext outside of secure hardware, whether user authentication is required for using the key
* and whether this requirement is enforced by secure hardware, the key's origin, what uses the key
- * is authorized for (e.g., only in {@code CBC} mode, or signing only), whether the key should be
+ * is authorized for (e.g., only in {@code GCM} mode, or signing only), whether the key should be
* encrypted at rest, the key's and validity start and end dates.
*
* <p>Instances of this class are immutable.
@@ -191,7 +191,7 @@ public class KeyInfo implements KeySpec {
}
/**
- * Gets the set of block modes (e.g., {@code CBC}, {@code CTR}) with which the key can be used
+ * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used
* when encrypting/decrypting. Attempts to use the key with any other block modes will be
* rejected.
*
@@ -238,17 +238,27 @@ public class KeyInfo implements KeySpec {
}
/**
- * Returns {@code true} if user authentication is required for this key to be used.
+ * Returns {@code true} if the key is authorized to be used only if the user has been
+ * authenticated.
+ *
+ * <p>This authorization applies only to secret key and private key operations. Public key
+ * operations are not restricted.
*
* @see #getUserAuthenticationValidityDurationSeconds()
+ * @see KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)
+ * @see KeyProtection.Builder#setUserAuthenticationRequired(boolean)
*/
public boolean isUserAuthenticationRequired() {
return mUserAuthenticationRequired;
}
/**
- * Gets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
+ * Gets the duration of time (seconds) for which this key is authorized to be used after the
+ * user is successfully authenticated. This has effect only if user authentication is required
+ * (see {@link #isUserAuthenticationRequired()}).
+ *
+ * <p>This authorization applies only to secret key and private key operations. Public key
+ * operations are not restricted.
*
* @return duration in seconds or {@code -1} if authentication is required for every use of the
* key.
diff --git a/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java b/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
index e320c9cbc290..9e82fc0205c8 100644
--- a/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
+++ b/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
@@ -21,12 +21,13 @@ import java.security.InvalidKeyException;
/**
* Indicates that the key can no longer be used because it has been permanently invalidated.
*
- * <p>This can currently occur only for keys that require user authentication. Such keys are
- * permanently invalidated once the secure lock screen is disabled (i.e., reconfigured to None,
- * Swipe or other mode which does not authenticate the user) or when the secure lock screen is
- * forcibly reset (e.g., by Device Admin). Additionally, keys configured to require user
- * authentication for every use of the key are also permanently invalidated once a new fingerprint
- * is enrolled or once no more fingerprints are enrolled.
+ * <p>This only occurs for keys which are authorized to be used only if the user has been
+ * authenticated. Such keys are permanently and irreversibly invalidated once the secure lock screen
+ * is disabled (i.e., reconfigured to None, Swipe or other mode which does not authenticate the
+ * user) or when the secure lock screen is forcibly reset (e.g., by Device Admin). Additionally,
+ * keys configured to require user authentication to take place for every of the keys, are also
+ * permanently invalidated once a new fingerprint is enrolled or once no more fingerprints are
+ * enrolled.
*/
public class KeyPermanentlyInvalidatedException extends InvalidKeyException {
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index 1e0611c80be8..b7a2a0b25032 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -19,19 +19,23 @@ package android.security.keystore;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.KeyguardManager;
+import android.hardware.fingerprint.FingerprintManager;
import java.security.Key;
+import java.security.Signature;
import java.security.KeyStore.ProtectionParameter;
import java.security.cert.Certificate;
import java.util.Date;
import javax.crypto.Cipher;
+import javax.crypto.Mac;
/**
* Specification of how a key or key pair is secured when imported into the
* <a href="{@docRoot}training/articles/keystore.html">Android KeyStore facility</a>. This class
* specifies parameters such as whether user authentication is required for using the key, what uses
- * the key is authorized for (e.g., only in {@code CTR} mode, or only for signing -- decryption not
+ * the key is authorized for (e.g., only in {@code GCM} mode, or only for signing -- decryption not
* permitted), the key's and validity start and end dates.
*
* <p>To import a key or key pair into the Android KeyStore, create an instance of this class using
@@ -51,8 +55,8 @@ import javax.crypto.Cipher;
*
* <p><h3>Example: Symmetric Key</h3>
* The following example illustrates how to import an AES key into the Android KeyStore under alias
- * {@code key1} authorized to be used only for encryption/decryption in CBC mode with PKCS#7
- * padding. The key must export its key material via {@link Key#getEncoded()} in {@code RAW} format.
+ * {@code key1} authorized to be used only for encryption/decryption in GCM mode with no padding.
+ * The key must export its key material via {@link Key#getEncoded()} in {@code RAW} format.
* <pre> {@code
* SecretKey key = ...; // AES key
*
@@ -62,8 +66,8 @@ import javax.crypto.Cipher;
* "key1",
* new KeyStore.SecretKeyEntry(key),
* new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
- * .setBlockMode(KeyProperties.BLOCK_MODE_CBC)
- * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+ * .setBlockMode(KeyProperties.BLOCK_MODE_GCM)
+ * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
* .build());
* // Key imported, obtain a reference to it.
* SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
@@ -232,7 +236,7 @@ public final class KeyProtection implements ProtectionParameter {
}
/**
- * Gets the set of block modes (e.g., {@code CBC}, {@code CTR}) with which the key can be used
+ * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used
* when encrypting/decrypting. Attempts to use the key with any other block modes will be
* rejected.
*
@@ -257,22 +261,32 @@ public final class KeyProtection implements ProtectionParameter {
}
/**
- * Returns {@code true} if user authentication is required for this key to be used.
+ * Returns {@code true} if the key is authorized to be used only if the user has been
+ * authenticated.
+ *
+ * <p>This authorization applies only to secret key and private key operations. Public key
+ * operations are not restricted.
*
* @see #getUserAuthenticationValidityDurationSeconds()
+ * @see Builder#setUserAuthenticationRequired(boolean)
*/
public boolean isUserAuthenticationRequired() {
return mUserAuthenticationRequired;
}
/**
- * Gets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
+ * Gets the duration of time (seconds) for which this key is authorized to be used after the
+ * user is successfully authenticated. This has effect only if user authentication is required
+ * (see {@link #isUserAuthenticationRequired()}).
+ *
+ * <p>This authorization applies only to secret key and private key operations. Public key
+ * operations are not restricted.
*
* @return duration in seconds or {@code -1} if authentication is required for every use of the
* key.
*
* @see #isUserAuthenticationRequired()
+ * @see Builder#setUserAuthenticationValidityDurationSeconds(int)
*/
public int getUserAuthenticationValidityDurationSeconds() {
return mUserAuthenticationValidityDurationSeconds;
@@ -424,11 +438,11 @@ public final class KeyProtection implements ProtectionParameter {
}
/**
- * Sets the set of block modes (e.g., {@code CBC}, {@code CTR}, {@code ECB}) with which the
- * key can be used when encrypting/decrypting. Attempts to use the key with any other block
- * modes will be rejected.
+ * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be
+ * used when encrypting/decrypting. Attempts to use the key with any other block modes will
+ * be rejected.
*
- * <p>This must be specified for encryption/decryption keys.
+ * <p>This must be specified for symmetric encryption/decryption keys.
*
* <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
*/
@@ -453,8 +467,8 @@ public final class KeyProtection implements ProtectionParameter {
* <ul>
* <li>transformation which do not offer {@code IND-CPA}, such as symmetric ciphers using
* {@code ECB} mode or RSA encryption without padding, are prohibited;</li>
- * <li>in transformations which use an IV, such as symmetric ciphers in {@code CBC},
- * {@code CTR}, and {@code GCM} block modes, caller-provided IVs are rejected when
+ * <li>in transformations which use an IV, such as symmetric ciphers in {@code GCM},
+ * {@code CBC}, and {@code CTR} block modes, caller-provided IVs are rejected when
* encrypting, to ensure that only random IVs are used.</li>
*
* <p>Before disabling this requirement, consider the following approaches instead:
@@ -479,19 +493,38 @@ public final class KeyProtection implements ProtectionParameter {
}
/**
- * Sets whether user authentication is required to use this key.
+ * Sets whether this key is authorized to be used only if the user has been authenticated.
*
- * <p>By default, the key can be used without user authentication.
+ * <p>By default, the key is authorized to be used regardless of whether the user has been
+ * authenticated.
*
- * <p>When user authentication is required, the user authorizes the use of the key by
- * authenticating to this Android device using a subset of their secure lock screen
- * credentials. Different authentication methods are used depending on whether the every
- * use of the key must be authenticated (as specified by
- * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+ * <p>When user authentication is required:
+ * <ul>
+ * <li>The key can only be import if secure lock screen is set up (see
+ * {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
+ * authentication takes place for every use of the key (see
+ * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
+ * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
+ * <li>The use of the key must be authorized by the user by authenticating to this Android
+ * device using a subset of their secure lock screen credentials such as
+ * password/PIN/pattern or fingerprint.
* <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
* information</a>.
+ * <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
+ * disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
+ * or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
+ * Additionally, if the key requires that user authentication takes place for every use of
+ * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
+ * no more fingerprints are enrolled. Attempts to initialize cryptographic operations using
+ * such keys will throw {@link KeyPermanentlyInvalidatedException}.</li>
+ * </ul>
+ *
+ * <p>This authorization applies only to secret key and private key operations. Public key
+ * operations are not restricted.
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
+ * @see KeyguardManager#isDeviceSecure()
+ * @see FingerprintManager#hasEnrolledFingerprints()
*/
@NonNull
public Builder setUserAuthenticationRequired(boolean required) {
@@ -500,15 +533,39 @@ public final class KeyProtection implements ProtectionParameter {
}
/**
- * Sets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
+ * Sets the duration of time (seconds) for which this key is authorized to be used after the
+ * user is successfully authenticated. This has effect if the key requires user
+ * authentication for its use (see {@link #setUserAuthenticationRequired(boolean)}).
+ *
+ * <p>By default, if user authentication is required, it must take place for every use of
+ * the key.
+ *
+ * <p>Cryptographic operations involving keys which require user authentication to take
+ * place for every operation can only use fingerprint authentication. This is achieved by
+ * initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
+ * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
+ * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
+ * the cryptographic operation only if the authentication flow succeeds.
*
- * <p>By default, the user needs to authenticate for every use of the key.
+ * <p>Cryptographic operations involving keys which are authorized to be used for a duration
+ * of time after a successful user authentication event can only use secure lock screen
+ * authentication. These cryptographic operations will throw
+ * {@link UserNotAuthenticatedException} during initialization if the user needs to be
+ * authenticated to proceed. This situation can be resolved by the user unlocking the secure
+ * lock screen of the Android or by going through the confirm credential flow initiated by
+ * {@link KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence)}.
+ * Once resolved, initializing a new cryptographic operation using this key (or any other
+ * key which is authorized to be used for a fixed duration of time after user
+ * authentication) should succeed provided the user authentication flow completed
+ * successfully.
*
- * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
- * every use of the key.
+ * @param seconds duration in seconds or {@code -1} if user authentication must take place
+ * for every use of the key.
*
* @see #setUserAuthenticationRequired(boolean)
+ * @see FingerprintManager
+ * @see FingerprintManager.CryptoObject
+ * @see KeyguardManager
*/
@NonNull
public Builder setUserAuthenticationValidityDurationSeconds(
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 3cbc405e4741..974b62e117b6 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -527,10 +527,11 @@ public class AudioRecord
}
/**
- * @return a new {@link AudioRecord} instance initialized with all the parameters set
- * on this <code>Builder</code>
+ * @return a new {@link AudioRecord} instance successfully initialized with all
+ * the parameters set on this <code>Builder</code>.
* @throws UnsupportedOperationException if the parameters set on the <code>Builder</code>
- * were incompatible, or if they are not supported by the device.
+ * were incompatible, or if they are not supported by the device,
+ * or if the device was not available.
*/
public AudioRecord build() throws UnsupportedOperationException {
if (mFormat == null) {
@@ -564,7 +565,13 @@ public class AudioRecord
mBufferSizeInBytes = mFormat.getChannelCount()
* mFormat.getBytesPerSample(mFormat.getEncoding());
}
- return new AudioRecord(mAttributes, mFormat, mBufferSizeInBytes, mSessionId);
+ final AudioRecord record = new AudioRecord(
+ mAttributes, mFormat, mBufferSizeInBytes, mSessionId);
+ if (record.getState() == STATE_UNINITIALIZED) {
+ // release is not necessary
+ throw new UnsupportedOperationException("Cannot create AudioRecord");
+ }
+ return record;
} catch (IllegalArgumentException e) {
throw new UnsupportedOperationException(e.getMessage());
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index f395cb340f92..62810c6f8b5a 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -661,9 +661,10 @@ public class AudioTrack
/**
* Builds an {@link AudioTrack} instance initialized with all the parameters set
* on this <code>Builder</code>.
- * @return a new {@link AudioTrack} instance.
+ * @return a new successfully initialized {@link AudioTrack} instance.
* @throws UnsupportedOperationException if the parameters set on the <code>Builder</code>
- * were incompatible, or if they are not supported by the device.
+ * were incompatible, or if they are not supported by the device,
+ * or if the device was not available.
*/
public @NonNull AudioTrack build() throws UnsupportedOperationException {
if (mAttributes == null) {
@@ -686,7 +687,13 @@ public class AudioTrack
mBufferSizeInBytes = mFormat.getChannelCount()
* mFormat.getBytesPerSample(mFormat.getEncoding());
}
- return new AudioTrack(mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId);
+ final AudioTrack track = new AudioTrack(
+ mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId);
+ if (track.getState() == STATE_UNINITIALIZED) {
+ // release is not necessary
+ throw new UnsupportedOperationException("Cannot create AudioTrack");
+ }
+ return track;
} catch (IllegalArgumentException e) {
throw new UnsupportedOperationException(e.getMessage());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index f57575de8675..10c35af1cfb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -110,6 +110,8 @@ public class HeadsUpTouchHelper implements Gefingerpoken {
mInitialTouchX = x;
mInitialTouchY = y;
int expandedHeight = mPickedChild.getActualHeight();
+ mPanel.setPanelScrimMinFraction((float) expandedHeight
+ / mPanel.getMaxPanelHeight());
mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight
+ mNotificationsTopPadding);
mHeadsUpManager.unpinAll();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 5ac436ae55ec..495f0fda8007 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1767,6 +1767,7 @@ public class NotificationPanelView extends PanelView implements
mIsExpansionFromHeadsUp = false;
mNotificationStackScroller.setTrackingHeadsUp(false);
mExpandingFromHeadsUp = false;
+ setPanelScrimMinFraction(0.0f);
}
private void setListening(boolean listening) {
@@ -2317,7 +2318,7 @@ public class NotificationPanelView extends PanelView implements
}
x = Math.min(rightMost, Math.max(leftMost, x));
setVerticalPanelTranslation(x -
- (mNotificationStackScroller.getLeft() + mNotificationStackScroller.getWidth()/2));
+ (mNotificationStackScroller.getLeft() + mNotificationStackScroller.getWidth() / 2));
}
private void resetVerticalPanelPosition() {
@@ -2334,4 +2335,8 @@ public class NotificationPanelView extends PanelView implements
mNotificationStackScroller.setStackHeight(stackHeight);
updateKeyguardBottomAreaAlpha();
}
+
+ public void setPanelScrimMinFraction(float minFraction) {
+ mBar.panelScrimMinFractionChanged(minFraction);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 552a0b21dbd0..cf553ec4521f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -25,7 +25,7 @@ import android.widget.FrameLayout;
import java.util.ArrayList;
-public class PanelBar extends FrameLayout {
+public abstract class PanelBar extends FrameLayout {
public static final boolean DEBUG = false;
public static final String TAG = PanelBar.class.getSimpleName();
public static final void LOG(String fmt, Object... args) {
@@ -156,6 +156,8 @@ public class PanelBar extends FrameLayout {
}
}
+ public abstract void panelScrimMinFractionChanged(float minFraction);
+
/**
* @param panel the panel which changed its expansion state
* @param frac the fraction from the expansion in [0, 1]
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index b7e675d5c476..dfd280aa09b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -40,6 +40,8 @@ public class PhoneStatusBarView extends PanelBar {
PanelView mNotificationPanel;
private final PhoneStatusBarTransitions mBarTransitions;
private ScrimController mScrimController;
+ private float mMinFraction;
+ private float mPanelFraction;
public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -180,8 +182,22 @@ public class PhoneStatusBarView extends PanelBar {
}
@Override
+ public void panelScrimMinFractionChanged(float minFraction) {
+ if (mMinFraction != minFraction) {
+ mMinFraction = minFraction;
+ updateScrimFraction();
+ }
+ }
+
+ @Override
public void panelExpansionChanged(PanelView panel, float frac, boolean expanded) {
super.panelExpansionChanged(panel, frac, expanded);
- mScrimController.setPanelExpansion(frac);
+ mPanelFraction = frac;
+ updateScrimFraction();
+ }
+
+ private void updateScrimFraction() {
+ float scrimFraction = Math.max(mPanelFraction - mMinFraction / (1.0f - mMinFraction), 0);
+ mScrimController.setPanelExpansion(scrimFraction);
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 0b430ca0d08a..47a230afb72a 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -180,8 +180,6 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
public boolean showLocked(Bundle args, int flags,
IVoiceInteractionSessionShowCallback showCallback) {
- // For now we never allow screenshots.
- flags &= ~VoiceInteractionSession.SHOW_WITH_SCREENSHOT;
if (mBound) {
if (!mFullyBound) {
mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
@@ -190,13 +188,15 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
new UserHandle(mUser));
}
mShown = true;
+ boolean allDataEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0;
mShowArgs = args;
mShowFlags = flags;
mHaveAssistData = false;
if ((flags& VoiceInteractionSession.SHOW_WITH_ASSIST) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_STRUCTURE, mCallingUid,
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
- && isStructureEnabled()) {
+ && allDataEnabled) {
try {
mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
mAssistReceiver);
@@ -212,7 +212,8 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mHaveScreenshot = false;
if ((flags& VoiceInteractionSession.SHOW_WITH_SCREENSHOT) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_SCREENSHOT, mCallingUid,
- mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED) {
+ mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
+ && allDataEnabled) {
try {
mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
} catch (RemoteException e) {
@@ -466,11 +467,6 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mService = null;
}
- private boolean isStructureEnabled() {
- return Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0;
- }
-
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix); pw.print("mToken="); pw.println(mToken);
pw.print(prefix); pw.print("mShown="); pw.println(mShown);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 3f78497eef78..0eb94b8c1e30 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -182,6 +182,34 @@ public class CarrierConfigManager {
public static final String
KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
+ /**
+ * Override the platform's notion of a network operator being considered roaming.
+ * Value is string array of MCCMNCs to be considered roaming for 3GPP RATs.
+ */
+ public static final String
+ KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
+
+ /**
+ * Override the platform's notion of a network operator being considered not roaming.
+ * Value is string array of MCCMNCs to be considered not roaming for 3GPP RATs.
+ */
+ public static final String
+ KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
+
+ /**
+ * Override the platform's notion of a network operator being considered roaming.
+ * Value is string array of SIDs to be considered roaming for 3GPP2 RATs.
+ */
+ public static final String
+ KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+
+ /**
+ * Override the platform's notion of a network operator being considered non roaming.
+ * Value is string array of SIDs to be considered not roaming for 3GPP2 RATs.
+ */
+ public static final String
+ KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
+
/**
* Flag specifying whether VoLTE should be available for carrier, independent of carrier
* provisioning. If false: hard disabled. If true: then depends on carrier provisioning,
@@ -358,6 +386,11 @@ public class CarrierConfigManager {
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, "");
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, "");
+ sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY, null);
+
// MMS defaults
sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL, true);
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 674777ec328f..8443490feb00 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -153,17 +153,17 @@ public class DisconnectCause {
/**
* The outgoing call failed with an unknown cause.
*/
- public static final int OUTGOING_FAILURE = 43;
+ public static final int OUTGOING_FAILURE = 43;
/**
* The outgoing call was canceled by the {@link android.telecom.ConnectionService}.
*/
- public static final int OUTGOING_CANCELED = 44;
+ public static final int OUTGOING_CANCELED = 44;
/**
* The call, which was an IMS call, disconnected because it merged with another call.
*/
- public static final int IMS_MERGED_SUCCESSFULLY = 45;
+ public static final int IMS_MERGED_SUCCESSFULLY = 45;
/**
* Stk Call Control modified DIAL request to USSD request.
@@ -181,6 +181,12 @@ public class DisconnectCause {
*/
public static final int DIAL_MODIFIED_TO_DIAL = 48;
+ /**
+ * The call was terminated because CDMA phone service and roaming have already been activated.
+ * {@hide}
+ */
+ public static final int CDMA_ALREADY_ACTIVATED = 49;
+
//*********************************************************************************************
// When adding a disconnect type:
// 1) Please assign the new type the next id value below.
@@ -189,14 +195,14 @@ public class DisconnectCause {
// 4) Update toString() with the newly added disconnect type.
// 5) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
//
- // NextId: 49
+ // NextId: 50
//*********************************************************************************************
/** Smallest valid value for call disconnect codes. */
public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
/** Largest valid value for call disconnect codes. */
- public static final int MAXIMUM_VALID_VALUE = DIAL_MODIFIED_TO_DIAL;
+ public static final int MAXIMUM_VALID_VALUE = CDMA_ALREADY_ACTIVATED;
/** Private constructor to avoid class instantiation. */
private DisconnectCause() {
@@ -302,6 +308,8 @@ public class DisconnectCause {
return "OUTGOING_CANCELED";
case IMS_MERGED_SUCCESSFULLY:
return "IMS_MERGED_SUCCESSFULLY";
+ case CDMA_ALREADY_ACTIVATED:
+ return "CDMA_ALREADY_ACTIVATED";
default:
return "INVALID: " + cause;
}