Merge "Add more APIs to hidden API greylist"
diff --git a/api/current.txt b/api/current.txt
index b4c84b1..54f0e15 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23371,6 +23371,7 @@
method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
method public int getMaxHdcpLevel();
+ method public static int getMaxSecurityLevel();
method public int getMaxSessionCount();
method public android.os.PersistableBundle getMetrics();
method public int getOpenSessionCount();
@@ -23384,6 +23385,7 @@
method public static boolean isCryptoSchemeSupported(java.util.UUID);
method public static boolean isCryptoSchemeSupported(java.util.UUID, java.lang.String);
method public byte[] openSession() throws android.media.NotProvisionedException, android.media.ResourceBusyException;
+ method public byte[] openSession(int) throws android.media.NotProvisionedException, android.media.ResourceBusyException;
method public byte[] provideKeyResponse(byte[], byte[]) throws android.media.DeniedByServerException, android.media.NotProvisionedException;
method public void provideProvisionResponse(byte[]) throws android.media.DeniedByServerException;
method public java.util.HashMap<java.lang.String, java.lang.String> queryKeyStatus(byte[]);
@@ -23399,7 +23401,6 @@
method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
method public void setPropertyByteArray(java.lang.String, byte[]);
method public void setPropertyString(java.lang.String, java.lang.String);
- method public void setSecurityLevel(byte[], int);
field public static final deprecated int EVENT_KEY_EXPIRED = 3; // 0x3
field public static final int EVENT_KEY_REQUIRED = 2; // 0x2
field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 90fcaab..279e05f 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -634,8 +634,39 @@
* @throws ResourceBusyException if required resources are in use
*/
@NonNull
- public native byte[] openSession() throws NotProvisionedException,
- ResourceBusyException;
+ public byte[] openSession() throws NotProvisionedException,
+ ResourceBusyException {
+ return openSession(getMaxSecurityLevel());
+ }
+
+ /**
+ * Open a new session at a requested security level. The security level
+ * represents the robustness of the device's DRM implementation. By default,
+ * sessions are opened at the native security level of the device.
+ * Overriding the security level is necessary when the decrypted frames need
+ * to be manipulated, such as for image compositing. The security level
+ * parameter must be lower than the native level. Reducing the security
+ * level will typically limit the content to lower resolutions, as
+ * determined by the license policy. If the requested level is not
+ * supported, the next lower supported security level will be set. The level
+ * can be queried using {@link #getSecurityLevel}. A session
+ * ID is returned.
+ *
+ * @param level the new security level, one of
+ * {@link #SW_SECURE_CRYPTO}, {@link #SW_SECURE_DECODE},
+ * {@link #HW_SECURE_CRYPTO}, {@link #HW_SECURE_DECODE} or
+ * {@link #HW_SECURE_ALL}.
+ *
+ * @throws NotProvisionedException if provisioning is needed
+ * @throws ResourceBusyException if required resources are in use
+ * @throws IllegalArgumentException if the requested security level is
+ * higher than the native level or lower than the lowest supported level or
+ * if the device does not support specifying the security level when opening
+ * a session
+ */
+ @NonNull
+ public native byte[] openSession(@SecurityLevel int level) throws
+ NotProvisionedException, ResourceBusyException;
/**
* Close a session on the MediaDrm object that was previously opened
@@ -1109,7 +1140,7 @@
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({SECURITY_LEVEL_UNKNOWN, SW_SECURE_CRYPTO, SW_SECURE_DECODE,
- HW_SECURE_CRYPTO, HW_SECURE_DECODE, HW_SECURE_ALL})
+ HW_SECURE_CRYPTO, HW_SECURE_DECODE, HW_SECURE_ALL})
public @interface SecurityLevel {}
/**
@@ -1119,39 +1150,55 @@
public static final int SECURITY_LEVEL_UNKNOWN = 0;
/**
- * Software-based whitebox crypto
+ * DRM key management uses software-based whitebox crypto.
*/
public static final int SW_SECURE_CRYPTO = 1;
/**
- * Software-based whitebox crypto and an obfuscated decoder
+ * DRM key management and decoding use software-based whitebox crypto.
*/
- public static final int SW_SECURE_DECODE = 2;
+ public static final int SW_SECURE_DECODE = 2;
/**
- * DRM key management and crypto operations are performed within a
- * hardware backed trusted execution environment
+ * DRM key management and crypto operations are performed within a hardware
+ * backed trusted execution environment.
*/
public static final int HW_SECURE_CRYPTO = 3;
/**
- * DRM key management, crypto operations and decoding of content
- * are performed within a hardware backed trusted execution environment
+ * DRM key management, crypto operations and decoding of content are
+ * performed within a hardware backed trusted execution environment.
*/
- public static final int HW_SECURE_DECODE = 4;
+ public static final int HW_SECURE_DECODE = 4;
/**
* DRM key management, crypto operations, decoding of content and all
- * handling of the media (compressed and uncompressed) is handled within
- * a hardware backed trusted execution environment.
+ * handling of the media (compressed and uncompressed) is handled within a
+ * hardware backed trusted execution environment.
*/
public static final int HW_SECURE_ALL = 5;
/**
- * Return the current security level of a session. A session
- * has an initial security level determined by the robustness of
- * the DRM system's implementation on the device. The security
- * level may be adjusted using {@link #setSecurityLevel}.
+ * The maximum security level supported by the device. This is the default
+ * security level when a session is opened.
+ * @hide
+ */
+ public static final int SECURITY_LEVEL_MAX = 6;
+
+ /**
+ * The maximum security level supported by the device. This is the default
+ * security level when a session is opened.
+ */
+ @SecurityLevel
+ public static final int getMaxSecurityLevel() {
+ return SECURITY_LEVEL_MAX;
+ }
+
+ /**
+ * Return the current security level of a session. A session has an initial
+ * security level determined by the robustness of the DRM system's
+ * implementation on the device. The security level may be changed at the
+ * time a session is opened using {@link #openSession}.
* @param sessionId the session to query.
* <p>
* @return one of {@link #SECURITY_LEVEL_UNKNOWN},
@@ -1163,21 +1210,6 @@
public native int getSecurityLevel(@NonNull byte[] sessionId);
/**
- * Set the security level of a session. This can be useful if specific
- * attributes of a lower security level are needed by an application,
- * such as image manipulation or compositing. Reducing the security
- * level will typically limit decryption to lower content resolutions,
- * depending on the license policy.
- * @param sessionId the session to set the security level on.
- * @param level the new security level, one of
- * {@link #SW_SECURE_CRYPTO}, {@link #SW_SECURE_DECODE},
- * {@link #HW_SECURE_CRYPTO}, {@link #HW_SECURE_DECODE} or
- * {@link #HW_SECURE_ALL}.
- */
- public native void setSecurityLevel(@NonNull byte[] sessionId,
- @SecurityLevel int level);
-
- /**
* String property name: identifies the maker of the DRM plugin
*/
public static final String PROPERTY_VENDOR = "vendor";
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 4f06caa..d7f51d4 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -145,6 +145,7 @@
struct SecurityLevels {
jint kSecurityLevelUnknown;
+ jint kSecurityLevelMax;
jint kSecurityLevelSwSecureCrypto;
jint kSecurityLevelSwSecureDecode;
jint kSecurityLevelHwSecureCrypto;
@@ -683,6 +684,10 @@
GET_STATIC_FIELD_ID(field, clazz, "HW_SECURE_ALL", "I");
gSecurityLevels.kSecurityLevelHwSecureAll = env->GetStaticIntField(clazz, field);
+ jmethodID getMaxSecurityLevel;
+ GET_STATIC_METHOD_ID(getMaxSecurityLevel, clazz, "getMaxSecurityLevel", "()I");
+ gSecurityLevels.kSecurityLevelMax = env->CallStaticIntMethod(clazz, getMaxSecurityLevel);
+
FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
GET_FIELD_ID(gFields.keyRequest.data, clazz, "mData", "[B");
GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
@@ -813,7 +818,7 @@
}
static jbyteArray android_media_MediaDrm_openSession(
- JNIEnv *env, jobject thiz) {
+ JNIEnv *env, jobject thiz, jint jlevel) {
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
@@ -823,7 +828,26 @@
}
Vector<uint8_t> sessionId;
- status_t err = drm->openSession(sessionId);
+ DrmPlugin::SecurityLevel level;
+
+ if (jlevel == gSecurityLevels.kSecurityLevelMax) {
+ level = DrmPlugin::kSecurityLevelMax;
+ } else if (jlevel == gSecurityLevels.kSecurityLevelSwSecureCrypto) {
+ level = DrmPlugin::kSecurityLevelSwSecureCrypto;
+ } else if (jlevel == gSecurityLevels.kSecurityLevelSwSecureDecode) {
+ level = DrmPlugin::kSecurityLevelSwSecureDecode;
+ } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureCrypto) {
+ level = DrmPlugin::kSecurityLevelHwSecureCrypto;
+ } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureDecode) {
+ level = DrmPlugin::kSecurityLevelHwSecureDecode;
+ } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureAll) {
+ level = DrmPlugin::kSecurityLevelHwSecureAll;
+ } else {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid security level");
+ return NULL;
+ }
+
+ status_t err = drm->openSession(level, sessionId);
if (throwExceptionAsNecessary(env, err, "Failed to open session")) {
return NULL;
@@ -1345,40 +1369,6 @@
}
-static void android_media_MediaDrm_setSecurityLevel(JNIEnv *env,
- jobject thiz, jbyteArray jsessionId, jint jlevel) {
- sp<IDrm> drm = GetDrm(env, thiz);
-
- if (!CheckSession(env, drm, jsessionId)) {
- return;
- }
-
- Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
- DrmPlugin::SecurityLevel level;
-
- if (jlevel == gSecurityLevels.kSecurityLevelSwSecureCrypto) {
- level = DrmPlugin::kSecurityLevelSwSecureCrypto;
- } else if (jlevel == gSecurityLevels.kSecurityLevelSwSecureDecode) {
- level = DrmPlugin::kSecurityLevelSwSecureDecode;
- } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureCrypto) {
- level = DrmPlugin::kSecurityLevelHwSecureCrypto;
- } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureDecode) {
- level = DrmPlugin::kSecurityLevelHwSecureDecode;
- } else if (jlevel == gSecurityLevels.kSecurityLevelHwSecureAll) {
- level = DrmPlugin::kSecurityLevelHwSecureAll;
- } else {
- jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid security level");
- return;
- }
-
- status_t err = drm->setSecurityLevel(sessionId, level);
-
- if (throwExceptionAsNecessary(env, err, "Failed to set security level")) {
- return;
- }
-}
-
-
static jstring android_media_MediaDrm_getPropertyString(
JNIEnv *env, jobject thiz, jstring jname) {
sp<IDrm> drm = GetDrm(env, thiz);
@@ -1724,7 +1714,7 @@
{ "isCryptoSchemeSupportedNative", "([BLjava/lang/String;)Z",
(void *)android_media_MediaDrm_isCryptoSchemeSupportedNative },
- { "openSession", "()[B",
+ { "openSession", "(I)[B",
(void *)android_media_MediaDrm_openSession },
{ "closeSession", "([B)V",
@@ -1785,9 +1775,6 @@
{ "getSecurityLevel", "([B)I",
(void *)android_media_MediaDrm_getSecurityLevel },
- { "setSecurityLevel", "([BI)V",
- (void *)android_media_MediaDrm_setSecurityLevel },
-
{ "getPropertyString", "(Ljava/lang/String;)Ljava/lang/String;",
(void *)android_media_MediaDrm_getPropertyString },
diff --git a/packages/SystemUI/res/color/accent_tint_color_selector.xml b/packages/SystemUI/res/color/accent_tint_color_selector.xml
new file mode 100644
index 0000000..85af186
--- /dev/null
+++ b/packages/SystemUI/res/color/accent_tint_color_selector.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false"
+ android:color="?android:attr/colorButtonNormal"/>
+
+ <item android:color="?android:attr/colorAccent"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index bab4eba7..803659f 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -38,59 +38,64 @@
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
- android:paddingTop="10dp"
- android:paddingBottom="10dp"
android:background="@drawable/rounded_bg_full"
android:translationZ="@dimen/volume_panel_elevation"
android:orientation="horizontal" >
<!-- volume rows added and removed here! :-) -->
</LinearLayout>
- <LinearLayout
+ <FrameLayout
android:id="@+id/footer"
android:layout_width="@dimen/volume_dialog_panel_width"
android:layout_height="@dimen/volume_dialog_panel_width"
- android:clipChildren="false"
- android:clipToPadding="false"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:layout_below="@id/volume_dialog_rows"
- android:background="@drawable/rounded_bg_full"
- android:gravity="center"
- android:layout_gravity="end"
- android:translationZ="@dimen/volume_panel_elevation"
- android:clickable="true"
- android:orientation="vertical" >
+ android:background="@drawable/rounded_bg_full">
- <TextView
- android:id="@+id/ringer_title"
- android:text="@string/ring_toggle_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:maxLines="1"
- android:layout_centerVertical="true"
- android:textColor="?android:attr/colorControlNormal"
- android:textAppearance="@style/TextAppearance.Volume.Header" />
+ <LinearLayout
+ android:id="@+id/footer_linear_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:gravity="center"
+ android:layout_gravity="end"
+ android:translationZ="@dimen/volume_panel_elevation"
+ android:clickable="true"
+ android:orientation="vertical" >
- <com.android.keyguard.AlphaOptimizedImageButton
- android:id="@+id/ringer_icon"
- style="@style/VolumeButtons"
- android:background="?android:selectableItemBackgroundBorderless"
- android:layout_width="@dimen/volume_dialog_panel_width"
- android:layout_height="@dimen/volume_button_size"
- android:tint="?android:attr/colorAccent"
- android:soundEffectsEnabled="false" />
+ <TextView
+ android:id="@+id/ringer_title"
+ android:text="@string/ring_toggle_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:layout_centerVertical="true"
+ android:textColor="?android:attr/colorControlNormal"
+ android:textAppearance="@style/TextAppearance.Volume.Header" />
- <TextView
- android:id="@+id/ringer_status"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:maxLines="1"
- android:textColor="?android:attr/colorControlNormal"
- android:textAppearance="@style/TextAppearance.Volume.Header.Secondary" />
+ <com.android.keyguard.AlphaOptimizedImageButton
+ android:id="@+id/ringer_icon"
+ style="@style/VolumeButtons"
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_button_size"
+ android:tint="@color/accent_tint_color_selector"
+ android:soundEffectsEnabled="false" />
- </LinearLayout>
+ <TextView
+ android:id="@+id/ringer_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:textColor="?android:attr/colorControlNormal"
+ android:textAppearance="@style/TextAppearance.Volume.Header.Secondary" />
+ </LinearLayout>
+
+ <include layout="@layout/volume_dnd_icon"/>
+ </FrameLayout>
</LinearLayout>
</com.android.systemui.volume.VolumeUiLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index 70654a8..fb9355a 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -13,89 +13,98 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:tag="row"
android:layout_height="wrap_content"
android:layout_width="@dimen/volume_dialog_panel_width"
android:clipChildren="true"
android:clipToPadding="true"
- android:theme="@style/qs_theme"
- android:gravity="center"
- android:orientation="vertical" >
+ android:theme="@style/qs_theme">
<LinearLayout
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:layout_marginTop="10dp"
+ android:layout_marginBottom="10dp"
android:gravity="center"
- android:padding="5dp">
- <TextView
- android:id="@+id/volume_row_header"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:maxLength="10"
- android:maxLines="1"
- android:textColor="?android:attr/colorControlNormal"
- android:textAppearance="@style/TextAppearance.Volume.Header" />
+ android:orientation="vertical" >
+
<LinearLayout
- android:id="@+id/output_chooser"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:minWidth="48dp"
- android:minHeight="48dp"
- android:paddingTop="10dp"
- android:background="?android:selectableItemBackgroundBorderless"
- android:gravity="center">
+ android:gravity="center"
+ android:padding="5dp">
<TextView
- android:id="@+id/volume_row_connected_device"
- android:visibility="gone"
+ android:id="@+id/volume_row_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:maxLength="10"
android:ellipsize="end"
+ android:maxLength="10"
android:maxLines="1"
- android:textAppearance="@style/TextAppearance.Volume.Header.Secondary" />
- <com.android.keyguard.AlphaOptimizedImageButton
- android:id="@+id/output_chooser_button"
- android:layout_width="24dp"
- android:layout_height="24dp"
+ android:textColor="?android:attr/colorControlNormal"
+ android:textAppearance="@style/TextAppearance.Volume.Header" />
+ <LinearLayout
+ android:id="@+id/output_chooser"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minWidth="48dp"
+ android:minHeight="48dp"
+ android:paddingTop="10dp"
android:background="?android:selectableItemBackgroundBorderless"
- android:contentDescription="@string/accessibility_output_chooser"
- style="@style/VolumeButtons"
- android:clickable="false"
- android:layout_centerVertical="true"
- android:src="@drawable/ic_swap"
- android:soundEffectsEnabled="false" />
+ android:gravity="center">
+ <TextView
+ android:id="@+id/volume_row_connected_device"
+ android:visibility="gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLength="10"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:textAppearance="@style/TextAppearance.Volume.Header.Secondary" />
+ <com.android.keyguard.AlphaOptimizedImageButton
+ android:id="@+id/output_chooser_button"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:contentDescription="@string/accessibility_output_chooser"
+ style="@style/VolumeButtons"
+ android:clickable="false"
+ android:layout_centerVertical="true"
+ android:src="@drawable/ic_swap"
+ android:soundEffectsEnabled="false"/>
+ </LinearLayout>
</LinearLayout>
- </LinearLayout>
- <FrameLayout
- android:id="@+id/volume_row_slider_frame"
- android:padding="0dp"
- android:layout_width="@dimen/volume_dialog_panel_width"
- android:layoutDirection="rtl"
- android:layout_height="@dimen/volume_dialog_panel_width">
- <SeekBar
- android:id="@+id/volume_row_slider"
- android:clickable="true"
+ <FrameLayout
+ android:id="@+id/volume_row_slider_frame"
android:padding="0dp"
- android:layout_margin="0dp"
android:layout_width="@dimen/volume_dialog_panel_width"
- android:layout_height="@dimen/volume_dialog_panel_width"
android:layoutDirection="rtl"
- android:layout_gravity="center"
- android:rotation="90" />
- </FrameLayout>
+ android:layout_height="@dimen/volume_dialog_panel_width">
+ <SeekBar
+ android:id="@+id/volume_row_slider"
+ android:clickable="true"
+ android:padding="0dp"
+ android:layout_margin="0dp"
+ android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_height="@dimen/volume_dialog_panel_width"
+ android:layoutDirection="rtl"
+ android:layout_gravity="center"
+ android:rotation="90" />
+ </FrameLayout>
- <com.android.keyguard.AlphaOptimizedImageButton
- android:id="@+id/volume_row_icon"
- style="@style/VolumeButtons"
- android:padding="10dp"
- android:layout_width="@dimen/volume_button_size"
- android:layout_height="@dimen/volume_button_size"
- android:background="?android:selectableItemBackgroundBorderless"
- android:soundEffectsEnabled="false" />
+ <com.android.keyguard.AlphaOptimizedImageButton
+ android:id="@+id/volume_row_icon"
+ style="@style/VolumeButtons"
+ android:padding="10dp"
+ android:layout_width="@dimen/volume_button_size"
+ android:layout_height="@dimen/volume_button_size"
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:soundEffectsEnabled="false" />
+ </LinearLayout>
-</LinearLayout>
\ No newline at end of file
+ <include layout="@layout/volume_dnd_icon"/>
+
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/volume_dnd_icon.xml b/packages/SystemUI/res/layout/volume_dnd_icon.xml
new file mode 100644
index 0000000..215b230
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_dnd_icon.xml
@@ -0,0 +1,30 @@
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="14dp"
+ android:layout_height="14dp"
+ android:layout_marginTop="6dp"
+ android:layout_marginRight="6dp"
+ android:layout_gravity="right|top">
+
+ <ImageView
+ android:id="@+id/dnd_icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_dnd"
+ android:tint="?android:attr/textColorTertiary"/>
+</FrameLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index fb5c447..8881ee9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -68,6 +68,7 @@
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageButton;
+import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
@@ -109,7 +110,9 @@
private ViewGroup mDialogRowsView;
private ViewGroup mFooter;
private ImageButton mRingerIcon;
+ private ImageView mZenIcon;
private TextView mRingerStatus;
+ private TextView mRingerTitle;
private final List<VolumeRow> mRows = new ArrayList<>();
private ConfigurableTexts mConfigurableTexts;
private final SparseBooleanArray mDynamic = new SparseBooleanArray();
@@ -216,6 +219,8 @@
mFooter = mDialog.findViewById(R.id.footer);
mRingerIcon = mFooter.findViewById(R.id.ringer_icon);
mRingerStatus = mFooter.findViewById(R.id.ringer_status);
+ mRingerTitle = mFooter.findViewById(R.id.ringer_title);
+ mZenIcon = mFooter.findViewById(R.id.dnd_icon);
if (mRows.isEmpty()) {
addRow(AudioManager.STREAM_MUSIC,
@@ -349,6 +354,7 @@
if (stream == STREAM_ACCESSIBILITY) {
row.header.setFilters(new InputFilter[] {new InputFilter.LengthFilter(13)});
}
+ row.dndIcon = row.view.findViewById(R.id.dnd_icon);
row.slider = row.view.findViewById(R.id.volume_row_slider);
row.slider.setOnSeekBarChangeListener(new VolumeSeekBarChangeListener(row));
row.anim = null;
@@ -559,6 +565,8 @@
if (ss == null) {
return;
}
+
+ enableRingerViewsH(mState.zenMode == Global.ZEN_MODE_OFF || !mState.disallowRinger);
switch (mState.ringerModeInternal) {
case AudioManager.RINGER_MODE_VIBRATE:
mRingerStatus.setText(R.string.volume_ringer_status_vibrate);
@@ -603,6 +611,28 @@
}
}
+ /**
+ * Toggles enable state of views in a VolumeRow (not including seekbar, outputChooser or icon)
+ * Hides/shows zen icon
+ * @param enable whether to enable volume row views and hide dnd icon
+ */
+ private void enableVolumeRowViewsH(VolumeRow row, boolean enable) {
+ row.header.setEnabled(enable);
+ row.dndIcon.setVisibility(enable ? View.GONE : View.VISIBLE);
+ }
+
+ /**
+ * Toggles enable state of footer/ringer views
+ * Hides/shows zen icon
+ * @param enable whether to enable ringer views and hide dnd icon
+ */
+ private void enableRingerViewsH(boolean enable) {
+ mRingerTitle.setEnabled(enable);
+ mRingerStatus.setEnabled(enable);
+ mRingerIcon.setEnabled(enable);
+ mZenIcon.setVisibility(enable ? View.GONE : View.VISIBLE);
+ }
+
private void trimObsoleteH() {
if (D.BUG) Log.d(TAG, "trimObsoleteH");
for (int i = mRows.size() - 1; i >= 0; i--) {
@@ -748,6 +778,7 @@
if (zenMuted) {
row.tracking = false;
}
+ enableVolumeRowViewsH(row, !zenMuted);
// update slider
final boolean enableSlider = !zenMuted;
@@ -1178,5 +1209,6 @@
private int lastAudibleLevel = 1;
private View outputChooser;
private TextView connectedDevice;
+ private ImageView dndIcon;
}
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 55c0f5a..3e43d8e 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -206,7 +206,7 @@
private static final int UPDATE_NETWORK_STATE = 4;
private static final int INJECT_NTP_TIME = 5;
private static final int DOWNLOAD_XTRA_DATA = 6;
- private static final int UPDATE_LOCATION = 7;
+ private static final int UPDATE_LOCATION = 7; // Handle external location from network listener
private static final int ADD_LISTENER = 8;
private static final int REMOVE_LISTENER = 9;
private static final int INJECT_NTP_TIME_FINISHED = 10;
@@ -259,6 +259,42 @@
}
}
+ // Simple class to hold stats reported in the Extras Bundle
+ private static class LocationExtras {
+ private int mSvCount;
+ private int mMeanCn0;
+ private int mMaxCn0;
+ private final Bundle mBundle;
+
+ public LocationExtras() {
+ mBundle = new Bundle();
+ }
+
+ public void set(int svCount, int meanCn0, int maxCn0) {
+ mSvCount = svCount;
+ mMeanCn0 = meanCn0;
+ mMaxCn0 = maxCn0;
+ setBundle(mBundle);
+ }
+
+ public void reset() {
+ set(0,0,0);
+ }
+
+ // Also used by outside methods to add to other bundles
+ public void setBundle(Bundle extras) {
+ if (extras != null) {
+ extras.putInt("satellites", mSvCount);
+ extras.putInt("meanCn0", mMeanCn0);
+ extras.putInt("maxCn0", mMaxCn0);
+ }
+ }
+
+ public Bundle getBundle() {
+ return mBundle;
+ }
+ }
+
private Object mLock = new Object();
// current status
@@ -369,7 +405,7 @@
private final NtpTrustedTime mNtpTime;
private final ILocationManager mILocationManager;
private Location mLocation = new Location(LocationManager.GPS_PROVIDER);
- private Bundle mLocationExtras = new Bundle();
+ private final LocationExtras mLocationExtras = new LocationExtras();
private final GnssStatusListenerHelper mListenerHelper;
private final GnssMeasurementsProvider mGnssMeasurementsProvider;
private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
@@ -713,7 +749,7 @@
mNtpTime = NtpTrustedTime.getInstance(context);
mILocationManager = ilocationManager;
- mLocation.setExtras(mLocationExtras);
+ mLocation.setExtras(mLocationExtras.getBundle());
// Create a wake lock
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -1245,29 +1281,17 @@
@Override
public int getStatus(Bundle extras) {
- setLocationExtras(extras);
+ mLocationExtras.setBundle(extras);
return mStatus;
}
- private void updateStatus(int status, int svCount, int meanCn0, int maxCn0) {
- if (status != mStatus || svCount != mSvCount || meanCn0 != mMeanCn0 || maxCn0 != mMaxCn0) {
+ private void updateStatus(int status) {
+ if (status != mStatus) {
mStatus = status;
- mSvCount = svCount;
- mMeanCn0 = meanCn0;
- mMaxCn0 = maxCn0;
- setLocationExtras(mLocationExtras);
mStatusUpdateTime = SystemClock.elapsedRealtime();
}
}
- private void setLocationExtras(Bundle extras) {
- if (extras != null) {
- extras.putInt("satellites", mSvCount);
- extras.putInt("meanCn0", mMeanCn0);
- extras.putInt("maxCn0", mMaxCn0);
- }
- }
-
@Override
public long getStatusUpdateTime() {
return mStatusUpdateTime;
@@ -1563,7 +1587,8 @@
}
// reset SV count to zero
- updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
+ updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
+ mLocationExtras.reset();
mFixRequestTime = SystemClock.elapsedRealtime();
if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
// set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
@@ -1586,7 +1611,8 @@
mLastFixTime = 0;
// reset SV count to zero
- updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
+ updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
+ mLocationExtras.reset();
}
}
@@ -1626,7 +1652,7 @@
// It would be nice to push the elapsed real-time timestamp
// further down the stack, but this is still useful
mLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
- mLocation.setExtras(mLocationExtras);
+ mLocation.setExtras(mLocationExtras.getBundle());
try {
mILocationManager.reportLocation(mLocation, false);
@@ -1662,8 +1688,9 @@
}
if (mStarted && mStatus != LocationProvider.AVAILABLE) {
- // we want to time out if we do not receive a fix
- // within the time out and we are requesting infrequent fixes
+ // For devices that use framework scheduling, a timer may be set to ensure we don't
+ // spend too much power searching for a location, when the requested update rate is slow.
+ // As we just recievied a location, we'll cancel that timer.
if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
mAlarmManager.cancel(mTimeoutIntent);
}
@@ -1672,7 +1699,7 @@
Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
- updateStatus(LocationProvider.AVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
+ updateStatus(LocationProvider.AVAILABLE);
}
if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
@@ -1771,7 +1798,7 @@
meanCn0 /= usedInFixCount;
}
// return number of sats used in fix instead of total reported
- updateStatus(mStatus, usedInFixCount, meanCn0, maxCn0);
+ mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
@@ -1779,7 +1806,7 @@
Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
- updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
+ updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
}
}
@@ -2726,9 +2753,6 @@
private float mSvElevations[] = new float[MAX_SVS];
private float mSvAzimuths[] = new float[MAX_SVS];
private float mSvCarrierFreqs[] = new float[MAX_SVS];
- private int mSvCount;
- private int mMeanCn0;
- private int mMaxCn0;
// preallocated to avoid memory allocation in reportNmea()
private byte[] mNmeaBuffer = new byte[120];
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 1b2f954..98fcb0b 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -169,7 +169,12 @@
anim.addUpdateListener(animation -> {
synchronized (mCancelLock) {
if (!a.mCancelled) {
- applyTransformation(a, mFrameTransaction, anim.getCurrentPlayTime());
+ final long duration = anim.getDuration();
+ long currentPlayTime = anim.getCurrentPlayTime();
+ if (currentPlayTime > duration) {
+ currentPlayTime = duration;
+ }
+ applyTransformation(a, mFrameTransaction, currentPlayTime);
}
}