Merge "Make ResolverDrawerLayout look like a ScrollView to accessibility" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 72e0447..68ecf96 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22704,7 +22704,7 @@
field public static final int KITKAT_WATCH = 20; // 0x14
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
- field public static final int MNC = 23; // 0x17
+ field public static final int M = 23; // 0x17
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -30122,6 +30122,9 @@
field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800
field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
+ field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
+ field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
+ field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
field public static final int STATE_ACTIVE = 4; // 0x4
field public static final int STATE_DIALING = 3; // 0x3
field public static final int STATE_DISCONNECTED = 6; // 0x6
@@ -30482,6 +30485,7 @@
field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+ field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
diff --git a/api/system-current.txt b/api/system-current.txt
index 37b1d7b..2e0613a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24650,7 +24650,7 @@
field public static final int KITKAT_WATCH = 20; // 0x14
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
- field public static final int MNC = 23; // 0x17
+ field public static final int M = 23; // 0x17
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -32307,6 +32307,9 @@
field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800
field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
+ field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
+ field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
+ field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
field public static final int STATE_ACTIVE = 4; // 0x4
field public static final int STATE_DIALING = 3; // 0x3
field public static final int STATE_DISCONNECTED = 6; // 0x6
@@ -32715,6 +32718,7 @@
field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+ field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE";
field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index dc83a01..330d730 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -720,7 +720,7 @@
}
// Reject this timezone if it isn't an Olson zone we recognize.
- if (mTargetSdkVersion >= Build.VERSION_CODES.MNC) {
+ if (mTargetSdkVersion >= Build.VERSION_CODES.M) {
boolean hasTimeZone = false;
try {
hasTimeZone = ZoneInfoDB.getInstance().hasTimeZone(timeZone);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 862d235..42ac67c 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1234,6 +1234,14 @@
}
/** @hide */
+ public void setUidMode(int code, int uid, int mode) {
+ try {
+ mService.setUidMode(code, uid, mode);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /** @hide */
public void setMode(int code, int uid, String packageName, int mode) {
try {
mService.setMode(code, uid, packageName, mode);
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 7fbb99a..4b670cd 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -240,7 +240,7 @@
getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
}
final boolean targetsM = decorView == null || decorView.getContext()
- .getApplicationInfo().targetSdkVersion >= VERSION_CODES.MNC;
+ .getApplicationInfo().targetSdkVersion >= VERSION_CODES.M;
ArrayList<String> sharedElementNames = targetsM ? mSharedElementNames :
mAllSharedElementNames;
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b2b1727..f21422e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -112,7 +112,7 @@
*
* In version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this intent must contain the
* extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
- * As of {@link android.os.Build.VERSION_CODES#MNC}, it should contain the extra
+ * As of {@link android.os.Build.VERSION_CODES#M}, it should contain the extra
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead, although specifying only
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported.
*
@@ -417,7 +417,7 @@
*
* <p><strong>Note:</strong> for devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP}
* and {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} only SHA-1 hash is supported.
- * Starting from {@link android.os.Build.VERSION_CODES#MNC}, this parameter accepts SHA-256 in
+ * Starting from {@link android.os.Build.VERSION_CODES#M}, this parameter accepts SHA-256 in
* addition to SHA-1. Support for SHA-1 is likely to be removed in future OS releases.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
@@ -590,7 +590,7 @@
* <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li></ul>
*
* <p>
- * As of {@link android.os.Build.VERSION_CODES#MNC}, the properties should contain
+ * As of {@link android.os.Build.VERSION_CODES#M}, the properties should contain
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead of
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, (although specifying only
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported).
@@ -603,7 +603,7 @@
* @hide
* This MIME type is used for starting the Device Owner provisioning that requires
* new provisioning features introduced in API version
- * {@link android.os.Build.VERSION_CODES#MNC} in addition to those supported in earlier
+ * {@link android.os.Build.VERSION_CODES#M} in addition to those supported in earlier
* versions.
*
* <p>During device owner provisioning a device admin app is set as the owner of the device.
@@ -2415,7 +2415,7 @@
* <p>The calling device admin must be a device or profile owner. If it is not, a
* security exception will be thrown.
*
- * <p>From version {@link android.os.Build.VERSION_CODES#MNC} disabling screen capture also
+ * <p>From version {@link android.os.Build.VERSION_CODES#M} disabling screen capture also
* blocks assist requests for all activities of the relevant user.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
@@ -2499,9 +2499,9 @@
* this method; if it has not, a security exception will be thrown.
*
* <p>Calling this from a managed profile before version
- * {@link android.os.Build.VERSION_CODES#MNC} will throw a security exception.
+ * {@link android.os.Build.VERSION_CODES#M} will throw a security exception.
*
- * <p>From version {@link android.os.Build.VERSION_CODES#MNC} a profile owner can set:
+ * <p>From version {@link android.os.Build.VERSION_CODES#M} a profile owner can set:
* <ul>
* <li>{@link #KEYGUARD_DISABLE_TRUST_AGENTS}, {@link #KEYGUARD_DISABLE_FINGERPRINT}
* these will affect the profile's parent user.
@@ -3623,7 +3623,7 @@
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
*
- * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
+ * @deprecated From {@link android.os.Build.VERSION_CODES#M}
*/
@Deprecated
public UserHandle createUser(@NonNull ComponentName admin, String name) {
@@ -3660,7 +3660,7 @@
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
*
- * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
+ * @deprecated From {@link android.os.Build.VERSION_CODES#M}
*/
@Deprecated
public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
@@ -3914,7 +3914,7 @@
* <p>Any packages that shares uid with an allowed package will also be allowed
* to activate lock task.
*
- * From {@link android.os.Build.VERSION_CODES#MNC} removing packages from the lock task
+ * From {@link android.os.Build.VERSION_CODES#M} removing packages from the lock task
* package list results in locked tasks belonging to those packages to be finished.
*
* This function can only be called by the device owner.
@@ -3982,14 +3982,14 @@
* <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
* <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
* <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
- * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
+ * This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards
* and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
* <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
- * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards.
+ * This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards.
* </li>
* </ul>
* <p>Changing the following settings has no effect as of
- * {@link android.os.Build.VERSION_CODES#MNC}:
+ * {@link android.os.Build.VERSION_CODES#M}:
* <ul>
* <li>{@link Settings.Global#BLUETOOTH_ON}.
* Use {@link android.bluetooth.BluetoothAdapter#enable()} and
@@ -4344,7 +4344,7 @@
* the permission grant state via {@link #setPermissionGrantState}.
*
* <p/>As this policy only acts on runtime permission requests, it only applies to applications
- * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later.
+ * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later.
*
* @param admin Which profile or device owner this request is associated with.
* @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT},
@@ -4388,7 +4388,7 @@
* revoke the permission. It retains the previous grant, if any.
*
* <p/>Permissions can be granted or revoked only for applications built with a
- * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later.
+ * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later.
*
* @param admin Which profile or device owner this request is associated with.
* @param packageName The application to grant or revoke a permission to.
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index e08686c..6b720c0 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1106,7 +1106,7 @@
@Override
public void setAssistBlocked(boolean state) {
mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED)
- | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED);
+ | (state ? ViewNode.FLAGS_ASSIST_BLOCKED : 0);
}
@Override
@@ -1412,6 +1412,9 @@
if (extras != null) {
Log.i(TAG, prefix + " Extras: " + extras);
}
+ if (node.isAssistBlocked()) {
+ Log.i(TAG, prefix + " BLOCKED");
+ }
final int NCHILDREN = node.getChildCount();
if (NCHILDREN > 0) {
Log.i(TAG, prefix + " Children:");
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index 4d2158f..954ccef 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -415,7 +415,7 @@
* if this method returns TRANSPORT_OK. To avoid storing such payloads the transport
* must recognize this case and return TRANSPORT_PACKAGE_REJECTED.
*
- * Added in MNC (API 23).
+ * Added in {@link android.os.Build.VERSION_CODES#M}.
*
* @param size The estimated size of the full-data payload for this app. This includes
* manifest and archive format overhead, but is not guaranteed to be precise.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f786d2f..aaaa745 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1021,7 +1021,7 @@
* numbers. Applications can <strong>dial</strong> emergency numbers using
* {@link #ACTION_DIAL}, however.
*
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC}
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M}
* and above and declares as using the {@link android.Manifest.permission#CALL_PHONE}
* permission which is not granted, then attempting to use this action will
* result in a {@link java.lang.SecurityException}.
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index d456b5e..5d405f9 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -19,7 +19,6 @@
import android.annotation.SystemApi;
import android.os.Build;
import android.os.Handler;
-import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
@@ -1632,7 +1631,7 @@
if (values == null) {
throw new IllegalArgumentException("sensor data cannot be null");
}
- int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.MNC);
+ int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.M);
if (values.length != expectedNumValues) {
throw new IllegalArgumentException ("Wrong number of values for sensor " +
sensor.getName() + " actual=" + values.length + " expected=" +
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index af1367c..c580083 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -173,6 +173,28 @@
}
}
+ ArrayList<TKey> vendorKeys = CameraMetadataNative.getAllVendorKeys(keyClass);
+
+ if (vendorKeys != null) {
+ for (TKey k : vendorKeys) {
+ String keyName;
+ if (k instanceof CaptureRequest.Key<?>) {
+ keyName = ((CaptureRequest.Key<?>) k).getName();
+ } else if (k instanceof CaptureResult.Key<?>) {
+ keyName = ((CaptureResult.Key<?>) k).getName();
+ } else if (k instanceof CameraCharacteristics.Key<?>) {
+ keyName = ((CameraCharacteristics.Key<?>) k).getName();
+ } else {
+ continue;
+ }
+
+ if (filterTags == null || Arrays.binarySearch(filterTags,
+ CameraMetadataNative.getTag(keyName)) >= 0) {
+ keyList.add(k);
+ }
+ }
+ }
+
return keyList;
}
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 7e50fd9..12a2910 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -1078,6 +1078,7 @@
private native synchronized void nativeWriteValues(int tag, byte[] src);
private native synchronized void nativeDump() throws IOException; // dump to ALOGD
+ private static native ArrayList nativeGetAllVendorKeys(Class keyClass);
private static native int nativeGetTagFromKey(String keyName)
throws IllegalArgumentException;
private static native int nativeGetTypeFromTag(int tag)
@@ -1113,6 +1114,19 @@
return nativeIsEmpty();
}
+
+ /**
+ * Return a list containing keys of the given key class for all defined vendor tags.
+ *
+ * @hide
+ */
+ public static <K> ArrayList<K> getAllVendorKeys(Class<K> keyClass) {
+ if (keyClass == null) {
+ throw new NullPointerException();
+ }
+ return (ArrayList<K>) nativeGetAllVendorKeys(keyClass);
+ }
+
/**
* Convert a key string into the equivalent native tag.
*
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 545e2fe..abed1f0 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -896,7 +896,7 @@
*
* @deprecated Deprecated in favor of the cleaner
* {@link #requestNetwork(NetworkRequest, NetworkCallback)} API.
- * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will
+ * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
* throw {@code UnsupportedOperationException} if called.
*/
public int startUsingNetworkFeature(int networkType, String feature) {
@@ -946,7 +946,7 @@
* always indicates failure.
*
* @deprecated Deprecated in favor of the cleaner {@link #unregisterNetworkCallback} API.
- * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will
+ * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
* throw {@code UnsupportedOperationException} if called.
*/
public int stopUsingNetworkFeature(int networkType, String feature) {
@@ -1228,7 +1228,7 @@
* @deprecated Deprecated in favor of the
* {@link #requestNetwork(NetworkRequest, NetworkCallback)},
* {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API.
- * In {@link VERSION_CODES#MNC}, and above, this method is unsupported and will
+ * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
* throw {@code UnsupportedOperationException} if called.
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
@@ -2742,7 +2742,7 @@
return;
}
- unsupportedStartingFrom(VERSION_CODES.MNC);
+ unsupportedStartingFrom(VERSION_CODES.M);
}
/**
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index b2ced7f..a0162f7 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -622,7 +622,7 @@
/**
* M comes after L.
*/
- public static final int MNC = 23;
+ public static final int M = 23;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 79fb805..83a1993 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -180,7 +180,7 @@
* Specifies if a user is disallowed from configuring VPN.
* The default value is <code>false</code>.
* This restriction has an effect in a managed profile only from
- * {@link android.os.Build.VERSION_CODES#MNC}
+ * {@link android.os.Build.VERSION_CODES#M}
*
* <p/>Key for user restrictions.
* <p/>Type: Boolean
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index e63fb04..9babf43 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -284,7 +284,7 @@
* If you don't set a ClipData, it will be copied there for you when calling
* {@link Context#startActivity(Intent)}.
*
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC} and above
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above
* and declares as using the {@link android.Manifest.permission#CAMERA} permission which
* is not granted, then atempting to use this action will result in a {@link
* java.lang.SecurityException}.
@@ -338,7 +338,7 @@
* If you don't set a ClipData, it will be copied there for you when calling
* {@link Context#startActivity(Intent)}.
*
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC} and above
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above
* and declares as using the {@link android.Manifest.permission#CAMERA} permission which
* is not granted, then atempting to use this action will result in a {@link
* java.lang.SecurityException}.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 10470aa..6f98788 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4434,7 +4434,7 @@
*
* @deprecated Use {@link android.app.KeyguardManager} to determine the state and security
* level of the keyguard. Accessing this setting from an app that is targeting
- * {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+ * {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
*/
@Deprecated
public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
@@ -4443,7 +4443,7 @@
* Whether lock pattern is visible as user enters (0 = false, 1 = true)
*
* @deprecated Accessing this setting from an app that is targeting
- * {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+ * {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
*/
@Deprecated
public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
@@ -4456,7 +4456,7 @@
* lockscreen uses
* {@link Settings.System#HAPTIC_FEEDBACK_ENABLED}.
* Accessing this setting from an app that is targeting
- * {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+ * {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
*/
@Deprecated
public static final String
@@ -8333,9 +8333,9 @@
return true;
case AppOpsManager.MODE_DEFAULT:
// this is the default operating mode after an app's installation
- if (!throwException) {
- return context.checkCallingOrSelfPermission(permissionName) ==
- PackageManager.PERMISSION_GRANTED;
+ if(context.checkCallingOrSelfPermission(permissionName) == PackageManager
+ .PERMISSION_GRANTED) {
+ return true;
}
default:
// this is for all other cases trickled down here...
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index de61c31..43c578f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -56,7 +56,6 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManagerGlobal;
-import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
@@ -3802,14 +3801,14 @@
// of whether a layout was requested on that View.
sIgnoreMeasureCache = targetSdkVersion < KITKAT;
- Canvas.sCompatibilityRestore = targetSdkVersion < MNC;
+ Canvas.sCompatibilityRestore = targetSdkVersion < M;
- // In MNC and newer, our widgets can pass a "hint" value in the size
+ // In M and newer, our widgets can pass a "hint" value in the size
// for UNSPECIFIED MeasureSpecs. This lets child views of scrolling containers
// know what the expected parent size is going to be, so e.g. list items can size
// themselves at 1/3 the size of their container. It breaks older apps though,
// specifically apps that use some popular open source libraries.
- sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < MNC;
+ sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < M;
sCompatibilityDone = true;
}
@@ -4277,27 +4276,27 @@
PROVIDER_BACKGROUND));
break;
case R.styleable.View_foreground:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
setForeground(a.getDrawable(attr));
}
break;
case R.styleable.View_foregroundGravity:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
}
break;
case R.styleable.View_foregroundTintMode:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
}
break;
case R.styleable.View_foregroundTint:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
setForegroundTintList(a.getColorStateList(attr));
}
break;
case R.styleable.View_foregroundInsidePadding:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
if (mForegroundInfo == null) {
mForegroundInfo = new ForegroundInfo();
}
@@ -11417,10 +11416,10 @@
* strongly recommended for performance reasons to either override
* {@link #hasOverlappingRendering()} to return <code>false</code> if appropriate, or setting a
* {@link #setLayerType(int, android.graphics.Paint) layer type} on the view for the duration
- * of the animation. On versions {@link android.os.Build.VERSION_CODES#MNC} and below,
+ * of the animation. On versions {@link android.os.Build.VERSION_CODES#M} and below,
* the default path for rendering an unlayered View with alpha could add multiple milliseconds
* of rendering cost, even for simple or small views. Starting with
- * {@link android.os.Build.VERSION_CODES#MNC}, {@link #LAYER_TYPE_HARDWARE} is automatically
+ * {@link android.os.Build.VERSION_CODES#M}, {@link #LAYER_TYPE_HARDWARE} is automatically
* applied to the view at the rendering level.</p>
*
* <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
@@ -11431,7 +11430,7 @@
* associated with a {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an
* alpha value less than 1.0 will supersede the alpha of the layer paint.</p>
*
- * <p>Starting with {@link android.os.Build.VERSION_CODES#MNC}, setting a translucent alpha
+ * <p>Starting with {@link android.os.Build.VERSION_CODES#M}, setting a translucent alpha
* value will clip a View to its bounds, unless the View returns <code>false</code> from
* {@link #hasOverlappingRendering}.</p>
*
@@ -18773,22 +18772,17 @@
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
- final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
- final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
- MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
- final boolean matchingSize = isExactly &&
- getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) &&
- getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
- if (forceLayout || !matchingSize &&
- (widthMeasureSpec != mOldWidthMeasureSpec ||
- heightMeasureSpec != mOldHeightMeasureSpec)) {
+ if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
+ widthMeasureSpec != mOldWidthMeasureSpec ||
+ heightMeasureSpec != mOldHeightMeasureSpec) {
// first clears the measured dimension flag
mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
resolveRtlPropertiesIfNeeded();
- int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
+ int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
+ mMeasureCache.indexOfKey(key);
if (cacheIndex < 0 || sIgnoreMeasureCache) {
// measure ourselves, this should set the measured dimension flag back
onMeasure(widthMeasureSpec, heightMeasureSpec);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 6dca26b..fab81a4 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5467,7 +5467,7 @@
* @see #setAnimationCacheEnabled(boolean)
* @see View#setDrawingCacheEnabled(boolean)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
*/
public boolean isAnimationCacheEnabled() {
@@ -5485,7 +5485,7 @@
* @see #isAnimationCacheEnabled()
* @see View#setDrawingCacheEnabled(boolean)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
*/
public void setAnimationCacheEnabled(boolean enabled) {
@@ -5502,7 +5502,7 @@
* @see #setChildrenDrawnWithCacheEnabled(boolean)
* @see View#setDrawingCacheEnabled(boolean)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Child views may no longer have their caching behavior disabled by parents.
*/
public boolean isAlwaysDrawnWithCacheEnabled() {
@@ -5526,7 +5526,7 @@
* @see View#setDrawingCacheEnabled(boolean)
* @see View#setDrawingCacheQuality(int)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Child views may no longer have their caching behavior disabled by parents.
*/
public void setAlwaysDrawnWithCacheEnabled(boolean always) {
@@ -5542,7 +5542,7 @@
* @see #setAlwaysDrawnWithCacheEnabled(boolean)
* @see #setChildrenDrawnWithCacheEnabled(boolean)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Child views may no longer be forced to cache their rendering state by their parents.
* Use {@link View#setLayerType(int, Paint)} on individual Views instead.
*/
@@ -5563,7 +5563,7 @@
* @see #setAlwaysDrawnWithCacheEnabled(boolean)
* @see #isChildrenDrawnWithCacheEnabled()
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Child views may no longer be forced to cache their rendering state by their parents.
* Use {@link View#setLayerType(int, Paint)} on individual Views instead.
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c22c0ef..928fe93 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -79,7 +79,6 @@
import com.android.internal.R;
import com.android.internal.os.SomeArgs;
import com.android.internal.policy.PhoneFallbackEventHandler;
-import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.RootViewSurfaceTaker;
@@ -5923,7 +5922,7 @@
}
private void adjustInputEventForCompatibility(InputEvent e) {
- if (mTargetSdkVersion < Build.VERSION_CODES.MNC && e instanceof MotionEvent) {
+ if (mTargetSdkVersion < Build.VERSION_CODES.M && e instanceof MotionEvent) {
MotionEvent motion = (MotionEvent) e;
final int mask =
MotionEvent.BUTTON_STYLUS_PRIMARY | MotionEvent.BUTTON_STYLUS_SECONDARY;
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index 76c8fbd..6130fd5 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -303,10 +303,12 @@
* {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and prior, do not trust this package
* name. The system had not verified the consistency between the package name here and
* application's uid. Consider to use {@link InputBinding#getUid()}, which is trustworthy.
- * Starting from Android MNC, the system verifies the consistency between this package name
- * and application uid before {@link EditorInfo} is passed to the input method.</p>
+ * Starting from {@link android.os.Build.VERSION_CODES#M}, the system verifies the consistency
+ * between this package name and application uid before {@link EditorInfo} is passed to the
+ * input method.</p>
*
- * <p><strong>Editor authors:</strong> Starting from Android MNC, the application is no longer
+ * <p><strong>Editor authors:</strong> Starting from {@link android.os.Build.VERSION_CODES#M},
+ * the application is no longer
* able to establish input connections if the package name provided here is inconsistent with
* application's uid.</p>
*/
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 47e894a..b5e08ca 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -686,7 +686,6 @@
int weightedMaxWidth = 0;
boolean allFillParent = true;
float totalWeight = 0;
- int usedExcessSpace = 0;
final int count = getVirtualChildCount();
@@ -722,10 +721,8 @@
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
totalWeight += lp.weight;
-
- final boolean fillExcessSpace = lp.weight > 0;
- final boolean hasZeroHeight = lp.height == 0;
- if (heightMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroHeight) {
+
+ if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
// Optimization: don't bother measuring children who are going to use
// leftover space. These views will get measured again down below if
// there is any leftover space.
@@ -733,12 +730,14 @@
mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
skippedMeasure = true;
} else {
- if (fillExcessSpace && hasZeroHeight) {
- // The LinearLayout's heightMode is either UNSPECIFIED or
- // AT_MOST, and this child wanted to stretch to fill
- // available space. Translate the explicit height of 0 to
- // WRAP_CONTENT so that we can measure the view's ideal
- // height.
+ int oldHeight = Integer.MIN_VALUE;
+
+ if (lp.height == 0 && lp.weight > 0) {
+ // heightMode is either UNSPECIFIED or AT_MOST, and this
+ // child wanted to stretch to fill available space.
+ // Translate that to WRAP_CONTENT so that it does not end up
+ // with a height of 0
+ oldHeight = 0;
lp.height = LayoutParams.WRAP_CONTENT;
}
@@ -750,16 +749,11 @@
child, i, widthMeasureSpec, 0, heightMeasureSpec,
totalWeight == 0 ? mTotalLength : 0);
- final int childHeight = child.getMeasuredHeight();
- if (fillExcessSpace) {
- usedExcessSpace += childHeight;
-
- // Restore original layout height.
- if (hasZeroHeight) {
- lp.height = 0;
- }
+ if (oldHeight != Integer.MIN_VALUE) {
+ lp.height = oldHeight;
}
+ final int childHeight = child.getMeasuredHeight();
final int totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin +
lp.bottomMargin + getNextLocationOffset(child));
@@ -863,7 +857,7 @@
// Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds. If we skipped
// measurement on any children, we need to measure them now.
- final int delta = heightSize - mTotalLength + usedExcessSpace;
+ int delta = heightSize - mTotalLength;
if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
@@ -880,14 +874,34 @@
float childExtra = lp.weight;
if (childExtra > 0) {
- // Distribute excess space to child.
- final int childHeight = Math.max(0, (int) (childExtra * delta / weightSum));
- final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight,
- MeasureSpec.EXACTLY);
+ // Child said it could absorb extra space -- give him his share
+ int share = (int) (childExtra * delta / weightSum);
+ weightSum -= childExtra;
+ delta -= share;
+
final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
- mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin,
- lp.width);
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ mPaddingLeft + mPaddingRight +
+ lp.leftMargin + lp.rightMargin, lp.width);
+
+ // TODO: Use a field like lp.isMeasured to figure out if this
+ // child has been previously measured
+ if ((lp.height != 0) || (heightMode != MeasureSpec.EXACTLY)) {
+ // child was measured once already above...
+ // base new measurement on stored values
+ int childHeight = child.getMeasuredHeight() + share;
+ if (childHeight < 0) {
+ childHeight = 0;
+ }
+
+ child.measure(childWidthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
+ } else {
+ // child was skipped in the loop above.
+ // Measure for this first time here
+ child.measure(childWidthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(share > 0 ? share : 0,
+ MeasureSpec.EXACTLY));
+ }
// Child may now not fit in vertical dimension.
childState = combineMeasuredStates(childState, child.getMeasuredState()
@@ -1003,7 +1017,6 @@
int weightedMaxHeight = 0;
boolean allFillParent = true;
float totalWeight = 0;
- int usedExcessSpace = 0;
final int count = getVirtualChildCount();
@@ -1053,10 +1066,8 @@
child.getLayoutParams();
totalWeight += lp.weight;
-
- final boolean fillExcessSpace = lp.weight > 0;
- final boolean hasZeroWidth = lp.width == 0;
- if (widthMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroWidth) {
+
+ if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) {
// Optimization: don't bother measuring children who are going to use
// leftover space. These views will get measured again down below if
// there is any leftover space.
@@ -1083,12 +1094,14 @@
skippedMeasure = true;
}
} else {
- if (fillExcessSpace && hasZeroWidth) {
- // The LinearLayout's widthMode is either UNSPECIFIED or
- // AT_MOST, and this child wanted to stretch to fill
- // available space. Translate the explicit height of 0 to
- // WRAP_CONTENT so that we can measure the view's ideal
- // width.
+ int oldWidth = Integer.MIN_VALUE;
+
+ if (lp.width == 0 && lp.weight > 0) {
+ // widthMode is either UNSPECIFIED or AT_MOST, and this
+ // child
+ // wanted to stretch to fill available space. Translate that to
+ // WRAP_CONTENT so that it does not end up with a width of 0
+ oldWidth = 0;
lp.width = LayoutParams.WRAP_CONTENT;
}
@@ -1100,16 +1113,11 @@
totalWeight == 0 ? mTotalLength : 0,
heightMeasureSpec, 0);
- final int childWidth = child.getMeasuredWidth();
- if (fillExcessSpace) {
- usedExcessSpace += childWidth;
-
- // Restore the original layout width.
- if (hasZeroWidth) {
- lp.width = 0;
- }
+ if (oldWidth != Integer.MIN_VALUE) {
+ lp.width = oldWidth;
}
+ final int childWidth = child.getMeasuredWidth();
if (isExactly) {
mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
getNextLocationOffset(child);
@@ -1234,7 +1242,7 @@
// Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds. If we skipped
// measurement on any children, we need to measure them now.
- final int delta = widthSize - mTotalLength + usedExcessSpace;
+ int delta = widthSize - mTotalLength;
if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
@@ -1257,13 +1265,34 @@
float childExtra = lp.weight;
if (childExtra > 0) {
// Child said it could absorb extra space -- give him his share
- final int childWidth = Math.max(0, (int) (childExtra * delta / weightSum));
- final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth,
- MeasureSpec.EXACTLY);
- final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+ int share = (int) (childExtra * delta / weightSum);
+ weightSum -= childExtra;
+ delta -= share;
+
+ final int childHeightMeasureSpec = getChildMeasureSpec(
+ heightMeasureSpec,
mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin,
lp.height);
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+
+ // TODO: Use a field like lp.isMeasured to figure out if this
+ // child has been previously measured
+ if ((lp.width != 0) || (widthMode != MeasureSpec.EXACTLY)) {
+ // child was measured once already above ... base new measurement
+ // on stored values
+ int childWidth = child.getMeasuredWidth() + share;
+ if (childWidth < 0) {
+ childWidth = 0;
+ }
+
+ child.measure(
+ MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
+ childHeightMeasureSpec);
+ } else {
+ // child was skipped in the loop above. Measure for this first time here
+ child.measure(MeasureSpec.makeMeasureSpec(
+ share > 0 ? share : 0, MeasureSpec.EXACTLY),
+ childHeightMeasureSpec);
+ }
// Child may now not fit in horizontal dimension.
childState = combineMeasuredStates(childState,
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 58a94b9..529d295 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -356,7 +356,7 @@
final int heightPadding;
final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
- if (targetSdkVersion >= VERSION_CODES.MNC) {
+ if (targetSdkVersion >= VERSION_CODES.M) {
widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin;
heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin;
} else {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 6af2e8b..d9faece 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -517,6 +517,7 @@
private final ResolveInfo mBackupResolveInfo;
private final ChooserTarget mChooserTarget;
private Drawable mBadgeIcon = null;
+ private CharSequence mBadgeContentDescription;
private Drawable mDisplayIcon;
private final Intent mFillInIntent;
private final int mFillInFlags;
@@ -532,7 +533,9 @@
if (ri != null) {
final ActivityInfo ai = ri.activityInfo;
if (ai != null && ai.applicationInfo != null) {
- mBadgeIcon = getPackageManager().getApplicationIcon(ai.applicationInfo);
+ final PackageManager pm = getPackageManager();
+ mBadgeIcon = pm.getApplicationIcon(ai.applicationInfo);
+ mBadgeContentDescription = pm.getApplicationLabel(ai.applicationInfo);
}
}
}
@@ -555,6 +558,7 @@
mBackupResolveInfo = other.mBackupResolveInfo;
mChooserTarget = other.mChooserTarget;
mBadgeIcon = other.mBadgeIcon;
+ mBadgeContentDescription = other.mBadgeContentDescription;
mDisplayIcon = other.mDisplayIcon;
mFillInIntent = fillInIntent;
mFillInFlags = flags;
@@ -647,6 +651,11 @@
}
@Override
+ public CharSequence getBadgeContentDescription() {
+ return mBadgeContentDescription;
+ }
+
+ @Override
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
return new ChooserTargetInfo(this, fillInIntent, flags);
}
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 73c4833..9fa2c23 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -38,6 +38,7 @@
int checkPackage(int uid, String packageName);
List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
+ void setUidMode(int code, int uid, int mode);
void setMode(int code, int uid, String packageName, int mode);
void resetAllModes(int reqUserId, String reqPackageName);
int checkAudioOperation(int code, int usage, int uid, String packageName);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 89599e0..7dd3bed 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -932,6 +932,11 @@
}
@Override
+ public CharSequence getBadgeContentDescription() {
+ return null;
+ }
+
+ @Override
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
return new DisplayResolveInfo(this, fillInIntent, flags);
}
@@ -1072,6 +1077,11 @@
public Drawable getBadgeIcon();
/**
+ * @return The content description for the badge icon
+ */
+ public CharSequence getBadgeContentDescription();
+
+ /**
* Clone this target with the given fill-in information.
*/
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags);
@@ -1542,6 +1552,7 @@
final Drawable badge = info.getBadgeIcon();
if (badge != null) {
holder.badge.setImageDrawable(badge);
+ holder.badge.setContentDescription(info.getBadgeContentDescription());
holder.badge.setVisibility(View.VISIBLE);
} else {
holder.badge.setVisibility(View.GONE);
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 9bd2eec..dd7ea45 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -32,7 +32,6 @@
import android.view.ActionMode;
import android.view.ContextThemeWrapper;
-import android.view.Display;
import android.view.Gravity;
import android.view.IRotationWatcher.Stub;
import android.view.IWindowManager;
@@ -3533,7 +3532,7 @@
public void onDestroyActionMode(ActionMode mode) {
mWrapped.onDestroyActionMode(mode);
final boolean isMncApp = mContext.getApplicationInfo().targetSdkVersion
- >= Build.VERSION_CODES.MNC;
+ >= Build.VERSION_CODES.M;
final boolean isPrimary;
final boolean isFloating;
if (isMncApp) {
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 7c8769d..fb22689 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -23,7 +23,9 @@
#include <utils/Vector.h>
#include <utils/SortedVector.h>
#include <utils/KeyedVector.h>
+#include <stdio.h>
#include <string.h>
+#include <vector>
#include "jni.h"
#include "JNIHelp.h"
@@ -45,9 +47,30 @@
// fully-qualified class name
#define CAMERA_METADATA_CLASS_NAME "android/hardware/camera2/impl/CameraMetadataNative"
+#define CHARACTERISTICS_KEY_CLASS_NAME "android/hardware/camera2/CameraCharacteristics$Key"
+#define REQUEST_KEY_CLASS_NAME "android/hardware/camera2/CaptureRequest$Key"
+#define RESULT_KEY_CLASS_NAME "android/hardware/camera2/CaptureResult$Key"
using namespace android;
+static struct metadata_java_key_offsets_t {
+ jclass mCharacteristicsKey;
+ jclass mResultKey;
+ jclass mRequestKey;
+ jmethodID mCharacteristicsConstr;
+ jmethodID mResultConstr;
+ jmethodID mRequestConstr;
+ jclass mByteArray;
+ jclass mInt32Array;
+ jclass mFloatArray;
+ jclass mInt64Array;
+ jclass mDoubleArray;
+ jclass mRationalArray;
+ jclass mArrayList;
+ jmethodID mArrayListConstr;
+ jmethodID mArrayListAdd;
+} gMetadataOffsets;
+
struct fields_t {
jfieldID metadata_ptr;
};
@@ -141,6 +164,7 @@
extern "C" {
static void CameraMetadata_classInit(JNIEnv *env, jobject thiz);
+static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType);
static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName);
static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag);
static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz);
@@ -510,6 +534,9 @@
{ "nativeClassInit",
"()V",
(void *)CameraMetadata_classInit },
+ { "nativeGetAllVendorKeys",
+ "(Ljava/lang/Class;)Ljava/util/ArrayList;",
+ (void *)CameraMetadata_getAllVendorKeys},
{ "nativeGetTagFromKey",
"(Ljava/lang/String;)I",
(void *)CameraMetadata_getTagFromKey },
@@ -588,6 +615,44 @@
// Get all the required offsets in java class and register native functions
int register_android_hardware_camera2_CameraMetadata(JNIEnv *env)
{
+
+ // Store global references to Key-related classes and methods used natively
+ jclass characteristicsKeyClazz = FindClassOrDie(env, CHARACTERISTICS_KEY_CLASS_NAME);
+ jclass requestKeyClazz = FindClassOrDie(env, REQUEST_KEY_CLASS_NAME);
+ jclass resultKeyClazz = FindClassOrDie(env, RESULT_KEY_CLASS_NAME);
+ gMetadataOffsets.mCharacteristicsKey = MakeGlobalRefOrDie(env, characteristicsKeyClazz);
+ gMetadataOffsets.mRequestKey = MakeGlobalRefOrDie(env, requestKeyClazz);
+ gMetadataOffsets.mResultKey = MakeGlobalRefOrDie(env, resultKeyClazz);
+ gMetadataOffsets.mCharacteristicsConstr = GetMethodIDOrDie(env,
+ gMetadataOffsets.mCharacteristicsKey, "<init>",
+ "(Ljava/lang/String;Ljava/lang/Class;)V");
+ gMetadataOffsets.mRequestConstr = GetMethodIDOrDie(env,
+ gMetadataOffsets.mRequestKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V");
+ gMetadataOffsets.mResultConstr = GetMethodIDOrDie(env,
+ gMetadataOffsets.mResultKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V");
+
+ // Store global references for primitive array types used by Keys
+ jclass byteClazz = FindClassOrDie(env, "[B");
+ jclass int32Clazz = FindClassOrDie(env, "[I");
+ jclass floatClazz = FindClassOrDie(env, "[F");
+ jclass int64Clazz = FindClassOrDie(env, "[J");
+ jclass doubleClazz = FindClassOrDie(env, "[D");
+ jclass rationalClazz = FindClassOrDie(env, "[Landroid/util/Rational;");
+ gMetadataOffsets.mByteArray = MakeGlobalRefOrDie(env, byteClazz);
+ gMetadataOffsets.mInt32Array = MakeGlobalRefOrDie(env, int32Clazz);
+ gMetadataOffsets.mFloatArray = MakeGlobalRefOrDie(env, floatClazz);
+ gMetadataOffsets.mInt64Array = MakeGlobalRefOrDie(env, int64Clazz);
+ gMetadataOffsets.mDoubleArray = MakeGlobalRefOrDie(env, doubleClazz);
+ gMetadataOffsets.mRationalArray = MakeGlobalRefOrDie(env, rationalClazz);
+
+ // Store global references for ArrayList methods used
+ jclass arrayListClazz = FindClassOrDie(env, "java/util/ArrayList");
+ gMetadataOffsets.mArrayList = MakeGlobalRefOrDie(env, arrayListClazz);
+ gMetadataOffsets.mArrayListConstr = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList,
+ "<init>", "(I)V");
+ gMetadataOffsets.mArrayListAdd = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList,
+ "add", "(Ljava/lang/Object;)Z");
+
// Register native functions
return RegisterMethodsOrDie(env,
CAMERA_METADATA_CLASS_NAME,
@@ -596,6 +661,7 @@
}
extern "C" {
+
static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) {
// XX: Why do this separately instead of doing it in the register function?
ALOGV("%s", __FUNCTION__);
@@ -612,6 +678,107 @@
env->FindClass(CAMERA_METADATA_CLASS_NAME);
}
+static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType) {
+
+ // Get all vendor tags
+ sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor();
+ if (vTags.get() == nullptr) {
+ // No vendor tags.
+ return NULL;
+ }
+
+ int count = vTags->getTagCount();
+ if (count <= 0) {
+ // No vendor tags.
+ return NULL;
+ }
+
+ std::vector<uint32_t> tagIds(count, /*initializer value*/0);
+ vTags->getTagArray(&tagIds[0]);
+
+ // Which key class/constructor should we use?
+ jclass keyClazz;
+ jmethodID keyConstr;
+ if (env->IsSameObject(keyType, gMetadataOffsets.mCharacteristicsKey)) {
+ keyClazz = gMetadataOffsets.mCharacteristicsKey;
+ keyConstr = gMetadataOffsets.mCharacteristicsConstr;
+ } else if (env->IsSameObject(keyType, gMetadataOffsets.mResultKey)) {
+ keyClazz = gMetadataOffsets.mResultKey;
+ keyConstr = gMetadataOffsets.mResultConstr;
+ } else if (env->IsSameObject(keyType, gMetadataOffsets.mRequestKey)) {
+ keyClazz = gMetadataOffsets.mRequestKey;
+ keyConstr = gMetadataOffsets.mRequestConstr;
+ } else {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "Invalid key class given as argument.");
+ return NULL;
+ }
+
+ // Allocate arrayList to return
+ jobject arrayList = env->NewObject(gMetadataOffsets.mArrayList,
+ gMetadataOffsets.mArrayListConstr, static_cast<jint>(count));
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ for (uint32_t id : tagIds) {
+ const char* section = vTags->getSectionName(id);
+ const char* tag = vTags->getTagName(id);
+ int type = vTags->getTagType(id);
+
+ size_t totalLen = strlen(section) + strlen(tag) + 2;
+ std::vector<char> fullName(totalLen, 0);
+ snprintf(&fullName[0], totalLen, "%s.%s", section, tag);
+
+ jstring name = env->NewStringUTF(&fullName[0]);
+
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ jclass valueClazz;
+ switch (type) {
+ case TYPE_BYTE:
+ valueClazz = gMetadataOffsets.mByteArray;
+ break;
+ case TYPE_INT32:
+ valueClazz = gMetadataOffsets.mInt32Array;
+ break;
+ case TYPE_FLOAT:
+ valueClazz = gMetadataOffsets.mFloatArray;
+ break;
+ case TYPE_INT64:
+ valueClazz = gMetadataOffsets.mInt64Array;
+ break;
+ case TYPE_DOUBLE:
+ valueClazz = gMetadataOffsets.mDoubleArray;
+ break;
+ case TYPE_RATIONAL:
+ valueClazz = gMetadataOffsets.mRationalArray;
+ break;
+ default:
+ jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+ "Invalid type %d given for key %s", type, &fullName[0]);
+ return NULL;
+ }
+
+ jobject key = env->NewObject(keyClazz, keyConstr, name, valueClazz);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ env->CallBooleanMethod(arrayList, gMetadataOffsets.mArrayListAdd, key);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ env->DeleteLocalRef(name);
+ env->DeleteLocalRef(key);
+ }
+
+ return arrayList;
+}
+
static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) {
ScopedUtfChars keyScoped(env, keyName);
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1515703..de16f20 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -219,7 +219,7 @@
<flag name="appop" value="0x40" />
<!-- Additional flag from base permission type: this permission can be automatically
granted to apps that target API levels below
- {@link android.os.Build.VERSION_CODES#MNC} (before runtime permissions
+ {@link android.os.Build.VERSION_CODES#M} (before runtime permissions
were introduced). -->
<flag name="pre23" value="0x80" />
<!-- Additional flag from base permission type: this permission can be automatically
@@ -1059,7 +1059,7 @@
at the same time.
<p>The default value is <code>false</code> for applications with
- <code>targetSdkVersion</code> lesser than {@link android.os.Build.VERSION_CODES#MNC} and
+ <code>targetSdkVersion</code> lesser than {@link android.os.Build.VERSION_CODES#M} and
<code>true</code> otherwise.
<p>NOTE: A task's root activity value is applied to all additional activities launched in
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 85b6c12..bc831da 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2604,7 +2604,7 @@
<public type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" />
<!-- ===============================================================
- Resources added in version MNC of the platform
+ Resources added in version M of the platform
=============================================================== -->
<eat-comment />
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index c29ec0d..bde3d19 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -54,7 +54,7 @@
* can be played on a device operating at a sample rate of 48000Hz; the sample rate conversion is
* automatically handled by the platform, it will not play at 6x speed.
*
- * <p>As of API {@link android.os.Build.VERSION_CODES#MNC},
+ * <p>As of API {@link android.os.Build.VERSION_CODES#M},
* sample rates up to 192kHz are supported
* for <code>AudioRecord</code> and <code>AudioTrack</code>, with sample rate conversion
* performed as needed.
@@ -99,7 +99,7 @@
* Floats are efficiently manipulated by modern CPUs,
* have greater precision than 24 bit signed integers,
* and have greater dynamic range than 32 bit signed integers.
- * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#MNC} and
+ * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#M} and
* <code>AudioTrack</code> as of API {@link android.os.Build.VERSION_CODES#LOLLIPOP}
* support <code>ENCODING_PCM_FLOAT</code>.
* </li>
@@ -123,7 +123,7 @@
* the samples and their arrangement in the audio frame. They are also used in the endpoint (e.g.
* a USB audio interface, a DAC connected to headphones) to specify allowable configurations of a
* particular device.
- * <br>As of API {@link android.os.Build.VERSION_CODES#MNC}, there are two types of channel masks:
+ * <br>As of API {@link android.os.Build.VERSION_CODES#M}, there are two types of channel masks:
* channel position masks and channel index masks.
*
* <h5 id="channelPositionMask">Channel position masks</h5>
@@ -152,7 +152,7 @@
* {@link #CHANNEL_OUT_FRONT_RIGHT}.
*
* <h5 id="channelIndexMask">Channel index masks</h5>
- * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#MNC}. They allow
+ * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#M}. They allow
* the selection of a particular channel from the source or sink endpoint by number, i.e. the first
* channel, the second channel, and so forth. This avoids problems with artificially assigning
* positions to channels of an endpoint, or figuring what the i<sup>th</sup> position bit is within
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 62810c6..8880dad 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -27,7 +27,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.content.Context;
@@ -1174,9 +1173,12 @@
* Poll for a timestamp on demand.
* <p>
* If you need to track timestamps during initial warmup or after a routing or mode change,
- * you should request a new timestamp once per second until the reported timestamps
- * show that the audio clock is stable.
- * Thereafter, query for a new timestamp approximately once every 10 seconds to once per minute.
+ * you should request a new timestamp periodically until the reported timestamps
+ * show that the frame position is advancing, or until it becomes clear that
+ * timestamps are unavailable for this route.
+ * <p>
+ * After the clock is advancing at a stable rate,
+ * query for a new timestamp approximately once every 10 seconds to once per minute.
* Calling this method more often is inefficient.
* It is also counter-productive to call this method more often than recommended,
* because the short-term differences between successive timestamp reports are not meaningful.
@@ -1199,6 +1201,11 @@
* In the case that no timestamp is available, any supplied instance is left unaltered.
* A timestamp may be temporarily unavailable while the audio clock is stabilizing,
* or during and immediately after a route change.
+ * A timestamp is permanently unavailable for a given route if the route does not support
+ * timestamps. In this case, the approximate frame position can be obtained
+ * using {@link #getPlaybackHeadPosition}.
+ * However, it may be useful to continue to query for
+ * timestamps occasionally, to recover after a route change.
*/
// Add this text when the "on new timestamp" API is added:
// Use if you need to get the most recent timestamp outside of the event callback handler.
@@ -1409,7 +1416,7 @@
* <br>
* If looping is currently enabled and the new position is greater than or equal to the
* loop end marker, the behavior varies by API level:
- * as of {@link android.os.Build.VERSION_CODES#MNC},
+ * as of {@link android.os.Build.VERSION_CODES#M},
* the looping is first disabled and then the position is set.
* For earlier API levels, the behavior is unspecified.
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
@@ -1446,7 +1453,7 @@
* {@link #ERROR_BAD_VALUE} is returned.
* The loop range is the interval [startInFrames, endInFrames).
* <br>
- * As of {@link android.os.Build.VERSION_CODES#MNC}, the position is left unchanged,
+ * As of {@link android.os.Build.VERSION_CODES#M}, the position is left unchanged,
* unless it is greater than or equal to the loop end marker, in which case
* it is forced to the loop start marker.
* For earlier API levels, the effect on position is unspecified.
@@ -2077,7 +2084,7 @@
* The track must be stopped or paused, and
* the track's creation mode must be {@link #MODE_STATIC}.
* <p>
- * As of {@link android.os.Build.VERSION_CODES#MNC}, also resets the value returned by
+ * As of {@link android.os.Build.VERSION_CODES#M}, also resets the value returned by
* {@link #getPlaybackHeadPosition()} to zero.
* For earlier API levels, the reset behavior is unspecified.
* <p>
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 5f60891..6c224e5 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -21,12 +21,8 @@
import android.annotation.Nullable;
import android.graphics.ImageFormat;
import android.graphics.Rect;
-import android.media.Image;
-import android.media.MediaCodecInfo;
+import android.graphics.SurfaceTexture;
import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecList;
-import android.media.MediaCrypto;
-import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -37,6 +33,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.nio.ReadOnlyBufferException;
import java.util.Arrays;
import java.util.HashMap;
@@ -233,8 +230,9 @@
data and submit it as a single codec-config buffer.
<p>
Android uses the following codec-specific data buffers. These are also required to be set in
- the track format for proper {@link MediaMuxer} track configuration. Each parameter set and
- codec-specific-data must start with a start code of {@code "\x00\x00\x00\x01"}.
+ the track format for proper {@link MediaMuxer} track configuration. Each parameter set and the
+ codec-specific-data sections marked with (<sup>*</sup>) must start with a start code of
+ {@code "\x00\x00\x00\x01"}.
<p>
<style>td.NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style>
<table>
@@ -242,28 +240,48 @@
<th>Format</th>
<th>CSD buffer #0</th>
<th>CSD buffer #1</th>
+ <th>CSD buffer #2</th>
</thead>
<tbody class=mid>
<tr>
<td>AAC</td>
- <td>Decoder-specific information from ESDS</td>
+ <td>Decoder-specific information from ESDS<sup>*</sup></td>
+ <td class=NA>Not Used</td>
<td class=NA>Not Used</td>
</tr>
<tr>
+ <td>VORBIS</td>
+ <td>Identification header</td>
+ <td>Setup header</td>
+ <td class=NA>Not Used</td>
+ </tr>
+ <tr>
+ <td>OPUS</td>
+ <td>Identification header</td>
+ <td>Pre-skip in nanosecs<br>
+ (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)<br>
+ This overrides the pre-skip value in the identification header.</td>
+ <td>Seek Pre-roll in nanosecs<br>
+ (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td>
+ </tr>
+ <tr>
<td>MPEG-4</td>
- <td>Decoder-specific information from ESDS</td>
+ <td>Decoder-specific information from ESDS<sup>*</sup></td>
+ <td class=NA>Not Used</td>
<td class=NA>Not Used</td>
</tr>
<tr>
<td>H.264 AVC</td>
- <td>SPS (Sequence Parameter Sets)</td>
- <td>PPS (Picture Parameter Sets)</td>
+ <td>SPS (Sequence Parameter Sets<sup>*</sup>)</td>
+ <td>PPS (Picture Parameter Sets<sup>*</sup>)</td>
+ <td class=NA>Not Used</td>
</tr>
<tr>
<td>H.265 HEVC</td>
- <td>VPS (Video Parameter Sets) +<br>
- SPS (Sequence Parameter Sets) +<br>
- PPS (Picture Parameter Sets)</td>
+ <td>VPS (Video Parameter Sets<sup>*</sup>) +<br>
+ SPS (Sequence Parameter Sets<sup>*</sup>) +<br>
+ PPS (Picture Parameter Sets<sup>*</sup>)</td>
+ <td class=NA>Not Used</td>
<td class=NA>Not Used</td>
</tr>
</tbody>
@@ -302,10 +320,10 @@
releaseOutputBuffer} methods to return the buffer to the codec.
<p>
While you are not required to resubmit/release buffers immediately to the codec, holding onto
- input and/or output buffers may stall the codec, and this behavior is device dependent. E.g. it
- is possible that a codec may hold off on generating output buffers until all outstanding buffers
- have been released/resubmitted. Therefore, try to hold onto to available buffers as little as
- possible.
+ input and/or output buffers may stall the codec, and this behavior is device dependent.
+ <strong>Specifically, it is possible that a codec may hold off on generating output buffers until
+ <em>all</em> outstanding buffers have been released/resubmitted.</strong> Therefore, try to
+ hold onto to available buffers as little as possible.
<p>
Depending on the API version, you can process data in three ways:
<table>
@@ -351,7 +369,7 @@
<p>
MediaCodec is typically used like this in asynchronous mode:
<pre class=prettyprint>
- MediaCodec codec = MediaCodec.createCodecByName(name);
+ MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
{@literal @Override}
@@ -408,7 +426,7 @@
<p>
MediaCodec is typically used like this in synchronous mode:
<pre>
- MediaCodec codec = MediaCodec.createCodecByName(name);
+ MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
MediaFormat outputFormat = codec.getOutputFormat(); // option B
codec.start();
@@ -447,7 +465,7 @@
between the size of the arrays and the number of input and output buffers used by the system,
although the array size provides an upper bound.
<pre>
- MediaCodec codec = MediaCodec.createCodecByName(name);
+ MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
@@ -510,11 +528,11 @@
#releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)}.</li>
</ul>
<p>
- Since {@link android.os.Build.VERSION_CODES#MNC}, the default timestamp is the {@linkplain
+ Since {@link android.os.Build.VERSION_CODES#M}, the default timestamp is the {@linkplain
BufferInfo#presentationTimeUs presentation timestamp} of the buffer (converted to nanoseconds).
It was not defined prior to that.
<p>
- Also since {@link android.os.Build.VERSION_CODES#MNC}, you can change the output Surface
+ Also since {@link android.os.Build.VERSION_CODES#M}, you can change the output Surface
dynamically using {@link #setOutputSurface setOutputSurface}.
<h4>Using an Input Surface</h4>
@@ -648,10 +666,10 @@
class. For API version numbers, see {@link android.os.Build.VERSION_CODES}.
<style>
- .api > tr > th, td { text-align: center; padding: 4px 4px; }
+ .api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; }
.api > tr > th { vertical-align: bottom; }
.api > tr > td { vertical-align: middle; }
- .sml > tr > th, td { text-align: center; padding: 2px 4px; }
+ .sml > tr > th, .sml > tr > td { text-align: center; padding: 2px 4px; }
.fn { text-align: left; }
.fn > code > a { font: 14px/19px Roboto Condensed, sans-serif; }
.deg45 {
@@ -1566,7 +1584,7 @@
private boolean mHasSurface = false;
/**
- * Instantiate a decoder supporting input data of the given mime type.
+ * Instantiate the preferred decoder supporting input data of the given mime type.
*
* The following is a partial list of defined mime types and their semantics:
* <ul>
@@ -1585,6 +1603,10 @@
* <li>"audio/g711-mlaw" - G.711 ulaw audio
* </ul>
*
+ * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findDecoderForFormat}
+ * and {@link #createByCodecName} to ensure that the resulting codec can handle a
+ * given format.
+ *
* @param type The mime type of the input data.
* @throws IOException if the codec cannot be created.
* @throws IllegalArgumentException if type is not a valid mime type.
@@ -1597,7 +1619,12 @@
}
/**
- * Instantiate an encoder supporting output data of the given mime type.
+ * Instantiate the preferred encoder supporting output data of the given mime type.
+ *
+ * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findEncoderForFormat}
+ * and {@link #createByCodecName} to ensure that the resulting codec can handle a
+ * given format.
+ *
* @param type The desired mime type of the output data.
* @throws IOException if the codec cannot be created.
* @throws IllegalArgumentException if type is not a valid mime type.
@@ -1666,6 +1693,8 @@
private native final void native_reset();
/**
+ * Free up resources used by the codec instance.
+ *
* Make sure you call this when you're done to free up any opened
* component instance instead of relying on the garbage collector
* to do this for you at some point in the future.
@@ -1886,17 +1915,25 @@
private native final void native_stop();
/**
- * Flush both input and output ports of the component, all indices
- * previously returned in calls to {@link #dequeueInputBuffer} and
- * {@link #dequeueOutputBuffer} become invalid.
+ * Flush both input and output ports of the component.
* <p>
- * If codec is configured in asynchronous mode, call {@link #start}
- * after {@code flush} has returned to resume codec operations. The
- * codec will not request input buffers until this has happened.
+ * Upon return, all indices previously returned in calls to {@link #dequeueInputBuffer
+ * dequeueInputBuffer} and {@link #dequeueOutputBuffer dequeueOutputBuffer} — or obtained
+ * via {@link Callback#onInputBufferAvailable onInputBufferAvailable} or
+ * {@link Callback#onOutputBufferAvailable onOutputBufferAvailable} callbacks — become
+ * invalid, and all buffers are owned by the codec.
* <p>
- * If codec is configured in synchronous mode, codec will resume
- * automatically if an input surface was created. Otherwise, it
- * will resume when {@link #dequeueInputBuffer} is called.
+ * If the codec is configured in asynchronous mode, call {@link #start}
+ * after {@code flush} has returned to resume codec operations. The codec
+ * will not request input buffers until this has happened.
+ * <strong>Note, however, that there may still be outstanding {@code onOutputBufferAvailable}
+ * callbacks that were not handled prior to calling {@code flush}.
+ * The indices returned via these callbacks also become invalid upon calling {@code flush} and
+ * should be discarded.</strong>
+ * <p>
+ * If the codec is configured in synchronous mode, codec will resume
+ * automatically if it is configured with an input surface. Otherwise, it
+ * will resume when {@link #dequeueInputBuffer dequeueInputBuffer} is called.
*
* @throws IllegalStateException if not in the Executing state.
* @throws MediaCodec.CodecException upon codec error.
@@ -2087,6 +2124,15 @@
* To indicate that this is the final piece of input data (or rather that
* no more input data follows unless the decoder is subsequently flushed)
* specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}.
+ * <p class=note>
+ * <strong>Note:</strong> Prior to {@link android.os.Build.VERSION_CODES#M},
+ * {@code presentationTimeUs} was not propagated to the frame timestamp of (rendered)
+ * Surface output buffers, and the resulting frame timestamp was undefined.
+ * Use {@link #releaseOutputBuffer(int, long)} to ensure a specific frame timestamp is set.
+ * Similarly, since frame timestamps can be used by the destination surface for rendering
+ * synchronization, <strong>care must be taken to normalize presentationTimeUs so as to not be
+ * mistaken for a system time. (See {@linkplain #releaseOutputBuffer(int, long)
+ * SurfaceView specifics}).</strong>
*
* @param index The index of a client-owned input buffer previously returned
* in a call to {@link #dequeueInputBuffer}.
@@ -2094,7 +2140,10 @@
* @param size The number of bytes of valid input data.
* @param presentationTimeUs The presentation timestamp in microseconds for this
* buffer. This is normally the media time at which this
- * buffer should be presented (rendered).
+ * buffer should be presented (rendered). When using an output
+ * surface, this will be propagated as the {@link
+ * SurfaceTexture#getTimestamp timestamp} for the frame (after
+ * conversion to nanoseconds).
* @param flags A bitmask of flags
* {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
* While not prohibited, most codecs do not use the
@@ -2207,8 +2256,10 @@
};
/**
- * Similar to {@link #queueInputBuffer} but submits a buffer that is
+ * Similar to {@link #queueInputBuffer queueInputBuffer} but submits a buffer that is
* potentially encrypted.
+ * <strong>Check out further notes at {@link #queueInputBuffer queueInputBuffer}.</strong>
+ *
* @param index The index of a client-owned input buffer previously returned
* in a call to {@link #dequeueInputBuffer}.
* @param offset The byte offset into the input buffer at which the data starts.
@@ -2315,7 +2366,7 @@
/**
* Dequeue an output buffer, block at most "timeoutUs" microseconds.
* Returns the index of an output buffer that has been successfully
- * decoded or one of the INFO_* constants below.
+ * decoded or one of the INFO_* constants.
* @param info Will be filled with buffer meta data.
* @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
* @throws IllegalStateException if not in the Executing state,
@@ -2343,9 +2394,11 @@
@NonNull BufferInfo info, long timeoutUs);
/**
- * If you are done with a buffer, use this call to return the buffer to
- * the codec. If you previously specified a surface when configuring this
- * video decoder you can optionally render the buffer.
+ * If you are done with a buffer, use this call to return the buffer to the codec
+ * or to render it on the output surface. If you configured the codec with an
+ * output surface, setting {@code render} to {@code true} will first send the buffer
+ * to that output surface. The surface will release the buffer back to the codec once
+ * it is no longer used/displayed.
*
* Once an output buffer is released to the codec, it MUST NOT
* be used until it is later retrieved by {@link #getOutputBuffer} in response
@@ -2679,6 +2732,8 @@
* <b>Note:</b> As of API 21, dequeued input buffers are
* automatically {@link java.nio.Buffer#clear cleared}.
*
+ * <em>Do not use this method if using an input surface.</em>
+ *
* @throws IllegalStateException if not in the Executing state,
* or codec is configured in asynchronous mode.
* @throws MediaCodec.CodecException upon codec error.
@@ -2708,6 +2763,8 @@
* buffers that are dequeued will be set to the valid data
* range.
*
+ * <em>Do not use this method if using an output surface.</em>
+ *
* @throws IllegalStateException if not in the Executing state,
* or codec is configured in asynchronous mode.
* @throws MediaCodec.CodecException upon codec error.
@@ -2993,6 +3050,10 @@
/**
* Called when an output frame has rendered on the output surface.
+ * <p>
+ * <strong>Note:</strong> This callback is for informational purposes only: to get precise
+ * render timing samples, and can be significantly delayed and batched. Some frames may have
+ * been rendered even if there was no callback generated.
*
* @param codec the MediaCodec instance
* @param presentationTimeUs the presentation time (media time) of the frame rendered.
@@ -3009,10 +3070,14 @@
}
/**
- * Register a callback to be invoked when an output frame is rendered on the output surface.
+ * Registers a callback to be invoked when an output frame is rendered on the output surface.
* <p>
* This method can be called in any codec state, but will only have an effect in the
* Executing state for codecs that render buffers to the output surface.
+ * <p>
+ * <strong>Note:</strong> This callback is for informational purposes only: to get precise
+ * render timing samples, and can be significantly delayed and batched. Some frames may have
+ * been rendered even if there was no callback generated.
*
* @param listener the callback that will be run
* @param handler the callback will be run on the handler's thread. If {@code null},
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 8243d40..4101935 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -525,6 +525,14 @@
/**
* Query whether codec supports a given {@link MediaFormat}.
+ *
+ * <p class=note>
+ * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+ * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+ * frame rate}. Use
+ * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+ * to clear any existing frame rate setting in the format.
+ *
* @param format media format with optional feature directives.
* @throws IllegalArgumentException if format is not a valid media format.
* @return whether the codec capabilities support the given format
@@ -1230,8 +1238,22 @@
* May return {@code null}, if the codec did not publish any measurement
* data.
* <p>
- * This is a performance estimate, based on full-speed decoding
- * and encoding measurements of common video sizes supported by the codec.
+ * This is a performance estimate provided by the device manufacturer
+ * based on full-speed decoding and encoding measurements in various configurations
+ * of common video sizes supported by the codec. As such it should only be used to
+ * compare individual codecs on the device. The value is not suitable for comparing
+ * different devices or even different android releases for the same device.
+ * <p>
+ * The returned range corresponds to the fastest frame rates achieved in the tested
+ * configurations. It is interpolated from the nearest frame size(s) tested. Codec
+ * performance is severely impacted by other activity on the device, and can vary
+ * significantly.
+ * <p class=note>
+ * Use this method in cases where only codec performance matters, e.g. to evaluate if
+ * a codec has any chance of meeting a performance target. Codecs are listed
+ * in {@link MediaCodecList} in the preferred order as defined by the device
+ * manufacturer. As such, applications should use the first suitable codec in the
+ * list to achieve the best balance between power use and performance.
*
* @param width the width of the video
* @param height the height of the video
diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java
index f44e048..cd7b3d3 100644
--- a/media/java/android/media/MediaCodecList.java
+++ b/media/java/android/media/MediaCodecList.java
@@ -190,6 +190,13 @@
* Find a decoder supporting a given {@link MediaFormat} in the list
* of media-codecs.
*
+ * <p class=note>
+ * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+ * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+ * frame rate}. Use
+ * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+ * to clear any existing frame rate setting in the format.
+ *
* @param format A decoder media format with optional feature directives.
* @throws IllegalArgumentException if format is not a valid media format.
* @throws NullPointerException if format is null.
@@ -204,6 +211,13 @@
* Find an encoder supporting a given {@link MediaFormat} in the list
* of media-codecs.
*
+ * <p class=note>
+ * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+ * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+ * frame rate}. Use
+ * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+ * to clear any existing frame rate setting in the format.
+ *
* @param format An encoder media format with optional feature directives.
* @throws IllegalArgumentException if format is not a valid media format.
* @throws NullPointerException if format is null.
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 49e6740..bafccae 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -46,6 +46,7 @@
import android.util.Slog;
import android.util.Xml;
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.HandlerCaller;
import com.android.internal.util.FastXmlSerializer;
import com.android.printspooler.R;
@@ -493,6 +494,7 @@
Slog.i(LOG_TAG, "[STATE CHANGED] " + printJob);
}
+ MetricsLogger.histogram(this, "print_job_state", state);
switch (state) {
case PrintJobInfo.STATE_COMPLETED:
case PrintJobInfo.STATE_CANCELED:
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 6baa4b3..e8a5e43 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -72,6 +72,7 @@
import android.widget.Spinner;
import android.widget.TextView;
+import com.android.internal.logging.MetricsLogger;
import com.android.printspooler.R;
import com.android.printspooler.model.MutexFileProvider;
import com.android.printspooler.model.PrintSpoolerProvider;
@@ -325,6 +326,7 @@
if (mState != STATE_INITIALIZING && mCurrentPrinter != null) {
mPrinterRegistry.setTrackedPrinter(mCurrentPrinter.getId());
}
+ MetricsLogger.count(this, "print_preview", 1);
}
@Override
@@ -1074,6 +1076,8 @@
private void confirmPrint() {
setState(STATE_PRINT_CONFIRMED);
+ MetricsLogger.count(this, "print_confirmed", 1);
+
updateOptionsUi();
addCurrentPrinterToHistory();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 17db471..298a1cc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -48,6 +48,8 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemProperties;
@@ -85,6 +87,15 @@
final static String TAG = "SystemServicesProxy";
final static BitmapFactory.Options sBitmapOptions;
+ final static HandlerThread sBgThread;
+
+ static {
+ sBgThread = new HandlerThread("Recents-SystemServicesProxy",
+ android.os.Process.THREAD_PRIORITY_BACKGROUND);
+ sBgThread.start();
+ sBitmapOptions = new BitmapFactory.Options();
+ sBitmapOptions.inMutable = true;
+ }
AccessibilityManager mAccm;
ActivityManager mAm;
@@ -98,17 +109,14 @@
String mRecentsPackage;
ComponentName mAssistComponent;
+ Handler mBgThreadHandler;
+
Bitmap mDummyIcon;
int mDummyThumbnailWidth;
int mDummyThumbnailHeight;
Paint mBgProtectionPaint;
Canvas mBgProtectionCanvas;
- static {
- sBitmapOptions = new BitmapFactory.Options();
- sBitmapOptions.inMutable = true;
- }
-
/** Private constructor */
public SystemServicesProxy(Context context) {
mAccm = AccessibilityManager.getInstance(context);
@@ -121,6 +129,7 @@
mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWm.getDefaultDisplay();
mRecentsPackage = context.getPackageName();
+ mBgThreadHandler = new Handler(sBgThread.getLooper());
// Get the dummy thumbnail width/heights
Resources res = context.getResources();
@@ -383,12 +392,17 @@
}
/** Removes the task */
- public void removeTask(int taskId) {
+ public void removeTask(final int taskId) {
if (mAm == null) return;
if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
// Remove the task.
- mAm.removeTask(taskId);
+ mBgThreadHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mAm.removeTask(taskId);
+ }
+ });
}
/**
@@ -656,22 +670,6 @@
return windowRect;
}
- /**
- * Takes a screenshot of the current surface.
- */
- public Bitmap takeScreenshot() {
- DisplayInfo di = new DisplayInfo();
- mDisplay.getDisplayInfo(di);
- return SurfaceControl.screenshot(di.getNaturalWidth(), di.getNaturalHeight());
- }
-
- /**
- * Takes a screenshot of the current app.
- */
- public Bitmap takeAppScreenshot() {
- return takeScreenshot();
- }
-
/** Starts an activity from recents. */
public boolean startActivityFromRecents(Context context, int taskId, String taskName,
ActivityOptions options) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index b2aa2b6..ad25c85 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -343,11 +343,14 @@
if (infoHandle.info != null) {
label = ssp.getActivityLabel(infoHandle.info);
mActivityLabelCache.put(taskKey, label);
+ return label;
} else {
Log.w(TAG, "Missing ActivityInfo for " + taskKey.baseIntent.getComponent()
+ " u=" + taskKey.userId);
}
- return label;
+ // If the activity info does not exist or fails to load, return an empty label for now,
+ // but do not cache it
+ return "";
}
/** Returns the content description using as many cached values as we can. */
@@ -358,14 +361,22 @@
if (label != null) {
return label;
}
+ // If the given activity label is empty, don't compute or cache the content description
+ if (activityLabel.isEmpty()) {
+ return "";
+ }
+
label = ssp.getContentDescription(taskKey.baseIntent, taskKey.userId, activityLabel, res);
if (label != null) {
mContentDescriptionCache.put(taskKey, label);
+ return label;
} else {
Log.w(TAG, "Missing content description for " + taskKey.baseIntent.getComponent()
+ " u=" + taskKey.userId);
}
- return label;
+ // If the content description does not exist, return an empty label for now, but do not
+ // cache it
+ return "";
}
/** Returns the activity icon using as many cached values as we can. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 78b3512..2e0b80a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -316,7 +316,7 @@
overscrollRange);
// Invalidate to kick off computeScroll
mSv.invalidate();
- } else if (mScroller.isScrollOutOfBounds()) {
+ } else if (mIsScrolling && mScroller.isScrollOutOfBounds()) {
// Animate the scroll back into bounds
mScroller.animateBoundScroll();
} else if (mActiveTaskView == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index ccec759..71baf57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -374,7 +374,11 @@
}
private void updateClipping() {
- mClipRect.set(0, mClipTopOptimization, getWidth(), getActualHeight());
+ int top = mClipTopOptimization;
+ if (top >= getActualHeight()) {
+ top = getActualHeight() - 1;
+ }
+ mClipRect.set(0, top, getWidth(), getActualHeight());
setClipBounds(mClipRect);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 13e9b16..ed1dca3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -51,7 +51,7 @@
@VisibleForTesting
final PhoneStateListener mPhoneStateListener;
// Save entire info for logging, we only use the id.
- private final SubscriptionInfo mSubscriptionInfo;
+ final SubscriptionInfo mSubscriptionInfo;
// @VisibleForDemoMode
final SparseArray<MobileIconGroup> mNetworkToIconLookup;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 57dfff5..2996808 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -66,6 +66,11 @@
// additional diagnostics, but not logspew
static final boolean CHATTY = Log.isLoggable(TAG + "Chat", Log.DEBUG);
+ private static final int EMERGENCY_NO_CONTROLLERS = 0;
+ private static final int EMERGENCY_FIRST_CONTROLLER = 100;
+ private static final int EMERGENCY_VOICE_CONTROLLER = 200;
+ private static final int EMERGENCY_NO_SUB = 300;
+
private final Context mContext;
private final TelephonyManager mPhone;
private final WifiManager mWifiManager;
@@ -118,6 +123,9 @@
// Handler that all callbacks are made on.
private final CallbackHandler mCallbackHandler;
+ private int mEmergencySource;
+ private boolean mIsEmergency;
+
@VisibleForTesting
ServiceState mLastServiceState;
@@ -267,6 +275,7 @@
if (mMobileSignalControllers.size() == 0) {
// When there are no active subscriptions, determine emengency state from last
// broadcast.
+ mEmergencySource = EMERGENCY_NO_CONTROLLERS;
return mLastServiceState != null && mLastServiceState.isEmergencyOnly();
}
int voiceSubId = mSubDefaults.getDefaultVoiceSubId();
@@ -274,16 +283,20 @@
for (MobileSignalController mobileSignalController :
mMobileSignalControllers.values()) {
if (!mobileSignalController.getState().isEmergency) {
+ mEmergencySource = EMERGENCY_FIRST_CONTROLLER
+ + mobileSignalController.mSubscriptionInfo.getSubscriptionId();
if (DEBUG) Log.d(TAG, "Found emergency " + mobileSignalController.mTag);
return false;
}
}
}
if (mMobileSignalControllers.containsKey(voiceSubId)) {
+ mEmergencySource = EMERGENCY_VOICE_CONTROLLER + voiceSubId;
if (DEBUG) Log.d(TAG, "Getting emergency from " + voiceSubId);
return mMobileSignalControllers.get(voiceSubId).getState().isEmergency;
}
if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
+ mEmergencySource = EMERGENCY_NO_SUB + voiceSubId;
// Something is wrong, better assume we can't make calls...
return true;
}
@@ -293,7 +306,8 @@
* so we should recheck and send out the state to listeners.
*/
void recalculateEmergency() {
- mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly());
+ mIsEmergency = isEmergencyOnly();
+ mCallbackHandler.setEmergencyCallsOnly(mIsEmergency);
}
public void addSignalCallback(SignalCallback cb) {
@@ -606,6 +620,10 @@
pw.println(mLocale);
pw.print(" mLastServiceState=");
pw.println(mLastServiceState);
+ pw.print(" mIsEmergency=");
+ pw.println(mIsEmergency);
+ pw.print(" mEmergencySource=");
+ pw.println(emergencyToString(mEmergencySource));
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
mobileSignalController.dump(pw);
@@ -617,6 +635,19 @@
mAccessPoints.dump(pw);
}
+ private static final String emergencyToString(int emergencySource) {
+ if (emergencySource > EMERGENCY_NO_SUB) {
+ return "NO_SUB(" + (emergencySource - EMERGENCY_NO_SUB) + ")";
+ } else if (emergencySource > EMERGENCY_VOICE_CONTROLLER) {
+ return "VOICE_CONTROLLER(" + (emergencySource - EMERGENCY_VOICE_CONTROLLER) + ")";
+ } else if (emergencySource > EMERGENCY_FIRST_CONTROLLER) {
+ return "FIRST_CONTROLLER(" + (emergencySource - EMERGENCY_FIRST_CONTROLLER) + ")";
+ } else if (emergencySource == EMERGENCY_NO_CONTROLLERS) {
+ return "NO_CONTROLLERS";
+ }
+ return "UNKNOWN_SOURCE";
+ }
+
private boolean mDemoMode;
private boolean mDemoInetCondition;
private WifiSignalController.WifiState mDemoWifiState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 5d2e5b7..82064a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -413,7 +413,9 @@
ExpandableNotificationRow topHeadsUpEntry = ambientState.getTopHeadsUpEntry();
int childCount = algorithmState.visibleChildren.size();
- int numberOfElementsCompletelyIn = (int) algorithmState.itemsInTopStack;
+ int numberOfElementsCompletelyIn = algorithmState.partialInTop == 1.0f
+ ? algorithmState.lastTopStackIndex
+ : (int) algorithmState.itemsInTopStack;
for (int i = 0; i < childCount; i++) {
ExpandableView child = algorithmState.visibleChildren.get(i);
StackViewState childViewState = resultState.getViewStateForView(child);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 417f18d..2a3492b 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -32,6 +32,7 @@
import android.app.ActivityManager;
import android.app.ActivityThread;
+import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -56,15 +57,18 @@
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.Xml;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.os.Zygote;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
+import libcore.util.EmptyArray;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -98,19 +102,38 @@
}
};
- final SparseArray<HashMap<String, Ops>> mUidOps
- = new SparseArray<HashMap<String, Ops>>();
+ final SparseArray<UidState> mUidStates = new SparseArray<>();
private final SparseArray<boolean[]> mOpRestrictions = new SparseArray<boolean[]>();
+ private static final class UidState {
+ public final int uid;
+ public ArrayMap<String, Ops> pkgOps;
+ public SparseIntArray opModes;
+
+ public UidState(int uid) {
+ this.uid = uid;
+ }
+
+ public void clear() {
+ pkgOps = null;
+ opModes = null;
+ }
+
+ public boolean isDefault() {
+ return (pkgOps == null || pkgOps.isEmpty())
+ && (opModes == null || opModes.size() <= 0);
+ }
+ }
+
public final static class Ops extends SparseArray<Op> {
public final String packageName;
- public final int uid;
+ public final UidState uidState;
public final boolean isPrivileged;
- public Ops(String _packageName, int _uid, boolean _isPrivileged) {
+ public Ops(String _packageName, UidState _uidState, boolean _isPrivileged) {
packageName = _packageName;
- uid = _uid;
+ uidState = _uidState;
isPrivileged = _isPrivileged;
}
}
@@ -220,27 +243,42 @@
public void systemReady() {
synchronized (this) {
boolean changed = false;
- for (int i=0; i<mUidOps.size(); i++) {
- HashMap<String, Ops> pkgs = mUidOps.valueAt(i);
+ for (int i = mUidStates.size() - 1; i >= 0; i--) {
+ UidState uidState = mUidStates.valueAt(i);
+
+ String[] packageNames = getPackagesForUid(uidState.uid);
+ if (ArrayUtils.isEmpty(packageNames)) {
+ uidState.clear();
+ mUidStates.removeAt(i);
+ changed = true;
+ continue;
+ }
+
+ ArrayMap<String, Ops> pkgs = uidState.pkgOps;
+ if (pkgs == null) {
+ continue;
+ }
+
Iterator<Ops> it = pkgs.values().iterator();
while (it.hasNext()) {
Ops ops = it.next();
int curUid;
try {
curUid = mContext.getPackageManager().getPackageUid(ops.packageName,
- UserHandle.getUserId(ops.uid));
+ UserHandle.getUserId(ops.uidState.uid));
} catch (NameNotFoundException e) {
curUid = -1;
}
- if (curUid != ops.uid) {
+ if (curUid != ops.uidState.uid) {
Slog.i(TAG, "Pruning old package " + ops.packageName
- + "/" + ops.uid + ": new uid=" + curUid);
+ + "/" + ops.uidState + ": new uid=" + curUid);
it.remove();
changed = true;
}
}
- if (pkgs.size() <= 0) {
- mUidOps.removeAt(i);
+
+ if (uidState.isDefault()) {
+ mUidStates.removeAt(i);
}
}
if (changed) {
@@ -279,22 +317,34 @@
public void packageRemoved(int uid, String packageName) {
synchronized (this) {
- HashMap<String, Ops> pkgs = mUidOps.get(uid);
- if (pkgs != null) {
- if (pkgs.remove(packageName) != null) {
- if (pkgs.size() <= 0) {
- mUidOps.remove(uid);
- }
- scheduleFastWriteLocked();
- }
+ UidState uidState = mUidStates.get(uid);
+ if (uidState == null) {
+ return;
+ }
+
+ boolean changed = false;
+
+ // Remove any package state if such.
+ if (uidState.pkgOps != null && uidState.pkgOps.remove(packageName) != null) {
+ changed = true;
+ }
+
+ // If we just nuked the last package state check if the UID is valid.
+ if (changed && uidState.pkgOps.isEmpty()
+ && getPackagesForUid(uid).length <= 0) {
+ mUidStates.remove(uid);
+ }
+
+ if (changed) {
+ scheduleFastWriteLocked();
}
}
}
public void uidRemoved(int uid) {
synchronized (this) {
- if (mUidOps.indexOfKey(uid) >= 0) {
- mUidOps.remove(uid);
+ if (mUidStates.indexOfKey(uid) >= 0) {
+ mUidStates.remove(uid);
scheduleFastWriteLocked();
}
}
@@ -346,16 +396,23 @@
Binder.getCallingPid(), Binder.getCallingUid(), null);
ArrayList<AppOpsManager.PackageOps> res = null;
synchronized (this) {
- for (int i=0; i<mUidOps.size(); i++) {
- HashMap<String, Ops> packages = mUidOps.valueAt(i);
- for (Ops pkgOps : packages.values()) {
+ final int uidStateCount = mUidStates.size();
+ for (int i = 0; i < uidStateCount; i++) {
+ UidState uidState = mUidStates.valueAt(i);
+ if (uidState.pkgOps == null || uidState.pkgOps.isEmpty()) {
+ continue;
+ }
+ ArrayMap<String, Ops> packages = uidState.pkgOps;
+ final int packageCount = packages.size();
+ for (int j = 0; j < packageCount; j++) {
+ Ops pkgOps = packages.valueAt(j);
ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops);
if (resOps != null) {
if (res == null) {
res = new ArrayList<AppOpsManager.PackageOps>();
}
AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
- pkgOps.packageName, pkgOps.uid, resOps);
+ pkgOps.packageName, pkgOps.uidState.uid, resOps);
res.add(resPackage);
}
}
@@ -380,7 +437,7 @@
}
ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>();
AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
- pkgOps.packageName, pkgOps.uid, resOps);
+ pkgOps.packageName, pkgOps.uidState.uid, resOps);
res.add(resPackage);
return res;
}
@@ -392,11 +449,15 @@
if (ops != null) {
ops.remove(op.op);
if (ops.size() <= 0) {
- HashMap<String, Ops> pkgOps = mUidOps.get(uid);
+ UidState uidState = ops.uidState;
+ ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
if (pkgOps != null) {
pkgOps.remove(ops.packageName);
- if (pkgOps.size() <= 0) {
- mUidOps.remove(uid);
+ if (pkgOps.isEmpty()) {
+ uidState.pkgOps = null;
+ }
+ if (uidState.isDefault()) {
+ mUidStates.remove(uid);
}
}
}
@@ -405,6 +466,113 @@
}
@Override
+ public void setUidMode(int code, int uid, int mode) {
+ if (Binder.getCallingPid() != Process.myPid()) {
+ mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+ Binder.getCallingPid(), Binder.getCallingUid(), null);
+ }
+ verifyIncomingOp(code);
+ code = AppOpsManager.opToSwitch(code);
+
+ synchronized (this) {
+ final int defaultMode = AppOpsManager.opToDefaultMode(code);
+
+ UidState uidState = getUidStateLocked(uid, false);
+ if (uidState == null) {
+ if (mode == defaultMode) {
+ return;
+ }
+ uidState = new UidState(uid);
+ uidState.opModes = new SparseIntArray();
+ uidState.opModes.put(code, mode);
+ mUidStates.put(uid, uidState);
+ scheduleWriteLocked();
+ } else if (uidState.opModes == null) {
+ if (mode != defaultMode) {
+ uidState.opModes = new SparseIntArray();
+ uidState.opModes.put(code, mode);
+ scheduleWriteLocked();
+ }
+ } else {
+ if (uidState.opModes.get(code) == mode) {
+ return;
+ }
+ if (mode == defaultMode) {
+ uidState.opModes.delete(code);
+ if (uidState.opModes.size() <= 0) {
+ uidState.opModes = null;
+ }
+ } else {
+ uidState.opModes.put(code, mode);
+ }
+ scheduleWriteLocked();
+ }
+ }
+
+ ArrayMap<Callback, ArraySet<String>> callbackSpecs = null;
+
+ ArrayList<Callback> callbacks = mOpModeWatchers.get(code);
+ if (callbacks != null) {
+ final int callbackCount = callbacks.size();
+ for (int i = 0; i < callbackCount; i++) {
+ Callback callback = callbacks.get(i);
+ callbackSpecs = new ArrayMap<>();
+ callbackSpecs.put(callback, null);
+ }
+ }
+
+ String[] uidPackageNames = getPackagesForUid(uid);
+ for (String uidPackageName : uidPackageNames) {
+ callbacks = mPackageModeWatchers.get(uidPackageName);
+ if (callbacks != null) {
+ if (callbackSpecs == null) {
+ callbackSpecs = new ArrayMap<>();
+ }
+ final int callbackCount = callbacks.size();
+ for (int i = 0; i < callbackCount; i++) {
+ Callback callback = callbacks.get(i);
+ ArraySet<String> changedPackages = callbackSpecs.get(callback);
+ if (changedPackages == null) {
+ changedPackages = new ArraySet<>();
+ callbackSpecs.put(callback, changedPackages);
+ }
+ changedPackages.add(uidPackageName);
+ }
+ }
+ }
+
+ if (callbackSpecs == null) {
+ return;
+ }
+
+ // There are components watching for mode changes such as window manager
+ // and location manager which are in our process. The callbacks in these
+ // components may require permissions our remote caller does not have.
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ for (int i = 0; i < callbackSpecs.size(); i++) {
+ Callback callback = callbackSpecs.keyAt(i);
+ ArraySet<String> reportedPackageNames = callbackSpecs.valueAt(i);
+ try {
+ if (reportedPackageNames == null) {
+ callback.mCallback.opChanged(code, null);
+ } else {
+ final int reportedPackageCount = reportedPackageNames.size();
+ for (int j = 0; j < reportedPackageCount; j++) {
+ String reportedPackageName = reportedPackageNames.valueAt(j);
+ callback.mCallback.opChanged(code, reportedPackageName);
+ }
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error dispatching op op change", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public void setMode(int code, int uid, String packageName, int mode) {
if (Binder.getCallingPid() != Process.myPid()) {
mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
@@ -414,6 +582,7 @@
ArrayList<Callback> repCbs = null;
code = AppOpsManager.opToSwitch(code);
synchronized (this) {
+ UidState uidState = getUidStateLocked(uid, false);
Op op = getOpLocked(code, uid, packageName, true);
if (op != null) {
if (op.mode != mode) {
@@ -468,14 +637,26 @@
if (callbacks == null) {
callbacks = new HashMap<Callback, ArrayList<Pair<String, Integer>>>();
}
+ boolean duplicate = false;
for (int i=0; i<cbs.size(); i++) {
Callback cb = cbs.get(i);
ArrayList<Pair<String, Integer>> reports = callbacks.get(cb);
if (reports == null) {
reports = new ArrayList<Pair<String, Integer>>();
callbacks.put(cb, reports);
+ } else {
+ final int reportCount = reports.size();
+ for (int j = 0; j < reportCount; j++) {
+ Pair<String, Integer> report = reports.get(j);
+ if (report.second == op && report.first.equals(packageName)) {
+ duplicate = true;
+ break;
+ }
+ }
}
- reports.add(new Pair<String, Integer>(packageName, op));
+ if (!duplicate) {
+ reports.add(new Pair<>(packageName, op));
+ }
}
return callbacks;
}
@@ -488,16 +669,54 @@
callingPid, callingUid, null);
reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId,
true, true, "resetAllModes", null);
+
+ int reqUid = -1;
+ if (reqPackageName != null) {
+ try {
+ reqUid = AppGlobals.getPackageManager().getPackageUid(
+ reqPackageName, reqUserId);
+ } catch (RemoteException e) {
+ /* ignore - local call */
+ }
+ }
+
HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null;
synchronized (this) {
boolean changed = false;
- for (int i=mUidOps.size()-1; i>=0; i--) {
- HashMap<String, Ops> packages = mUidOps.valueAt(i);
+ for (int i = mUidStates.size() - 1; i >= 0; i--) {
+ UidState uidState = mUidStates.valueAt(i);
+
+ SparseIntArray opModes = uidState.opModes;
+ if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) {
+ final int uidOpCount = opModes.size();
+ for (int j = uidOpCount - 1; j >= 0; j--) {
+ final int code = opModes.keyAt(j);
+ if (AppOpsManager.opAllowsReset(code)) {
+ opModes.removeAt(j);
+ if (opModes.size() <= 0) {
+ uidState.opModes = null;
+ }
+ for (String packageName : getPackagesForUid(uidState.uid)) {
+ callbacks = addCallbacks(callbacks, packageName, code,
+ mOpModeWatchers.get(code));
+ callbacks = addCallbacks(callbacks, packageName, code,
+ mPackageModeWatchers.get(packageName));
+ }
+ }
+ }
+ }
+
+ if (uidState.pkgOps == null) {
+ continue;
+ }
+
if (reqUserId != UserHandle.USER_ALL
- && reqUserId != UserHandle.getUserId(mUidOps.keyAt(i))) {
+ && reqUserId != UserHandle.getUserId(uidState.uid)) {
// Skip any ops for a different user
continue;
}
+
+ Map<String, Ops> packages = uidState.pkgOps;
Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Ops> ent = it.next();
@@ -526,10 +745,11 @@
it.remove();
}
}
- if (packages.size() == 0) {
- mUidOps.removeAt(i);
+ if (uidState.isDefault()) {
+ mUidStates.remove(uidState.uid);
}
}
+
if (changed) {
scheduleFastWriteLocked();
}
@@ -552,7 +772,7 @@
@Override
public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) {
synchronized (this) {
- op = AppOpsManager.opToSwitch(op);
+ op = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op;
Callback cb = mModeWatchers.get(callback.asBinder());
if (cb == null) {
cb = new Callback(callback);
@@ -621,7 +841,15 @@
if (isOpRestricted(uid, code, packageName)) {
return AppOpsManager.MODE_IGNORED;
}
- Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false);
+ code = AppOpsManager.opToSwitch(code);
+ UidState uidState = getUidStateLocked(uid, false);
+ if (uidState != null && uidState.opModes != null) {
+ final int uidMode = uidState.opModes.get(code);
+ if (uidMode != AppOpsManager.MODE_ALLOWED) {
+ return uidMode;
+ }
+ }
+ Op op = getOpLocked(code, uid, packageName, false);
if (op == null) {
return AppOpsManager.opToDefaultMode(code);
}
@@ -732,6 +960,17 @@
}
op.duration = 0;
final int switchCode = AppOpsManager.opToSwitch(code);
+ UidState uidState = ops.uidState;
+ if (uidState.opModes != null) {
+ final int uidMode = uidState.opModes.get(switchCode);
+ if (uidMode != AppOpsManager.MODE_ALLOWED) {
+ if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+ + switchCode + " (" + code + ") uid " + uid + " package "
+ + packageName);
+ op.rejectTime = System.currentTimeMillis();
+ return uidMode;
+ }
+ }
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
@@ -766,6 +1005,17 @@
return AppOpsManager.MODE_IGNORED;
}
final int switchCode = AppOpsManager.opToSwitch(code);
+ UidState uidState = ops.uidState;
+ if (uidState.opModes != null) {
+ final int uidMode = uidState.opModes.get(switchCode);
+ if (uidMode != AppOpsManager.MODE_ALLOWED) {
+ if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+ + switchCode + " (" + code + ") uid " + uid + " package "
+ + packageName);
+ op.rejectTime = System.currentTimeMillis();
+ return uidMode;
+ }
+ }
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code "
@@ -847,6 +1097,18 @@
throw new IllegalArgumentException("Bad operation #" + op);
}
+ private UidState getUidStateLocked(int uid, boolean edit) {
+ UidState uidState = mUidStates.get(uid);
+ if (uidState == null) {
+ if (!edit) {
+ return null;
+ }
+ uidState = new UidState(uid);
+ mUidStates.put(uid, uidState);
+ }
+ return uidState;
+ }
+
private Ops getOpsLocked(int uid, String packageName, boolean edit) {
if (uid == 0) {
packageName = "root";
@@ -857,15 +1119,19 @@
}
private Ops getOpsRawLocked(int uid, String packageName, boolean edit) {
- HashMap<String, Ops> pkgOps = mUidOps.get(uid);
- if (pkgOps == null) {
+ UidState uidState = getUidStateLocked(uid, edit);
+ if (uidState == null) {
+ return null;
+ }
+
+ if (uidState.pkgOps == null) {
if (!edit) {
return null;
}
- pkgOps = new HashMap<String, Ops>();
- mUidOps.put(uid, pkgOps);
+ uidState.pkgOps = new ArrayMap<>();
}
- Ops ops = pkgOps.get(packageName);
+
+ Ops ops = uidState.pkgOps.get(packageName);
if (ops == null) {
if (!edit) {
return null;
@@ -904,8 +1170,8 @@
Binder.restoreCallingIdentity(ident);
}
}
- ops = new Ops(packageName, uid, isPrivileged);
- pkgOps.put(packageName, ops);
+ ops = new Ops(packageName, uidState, isPrivileged);
+ uidState.pkgOps.put(packageName, ops);
}
return ops;
}
@@ -940,7 +1206,7 @@
if (!edit) {
return null;
}
- op = new Op(ops.uid, ops.packageName, code);
+ op = new Op(ops.uidState.uid, ops.packageName, code);
ops.put(code, op);
}
if (edit) {
@@ -1000,6 +1266,8 @@
String tagName = parser.getName();
if (tagName.equals("pkg")) {
readPackage(parser);
+ } if (tagName.equals("uid")) {
+ readUidOps(parser);
} else {
Slog.w(TAG, "Unknown element under <app-ops>: "
+ parser.getName());
@@ -1021,7 +1289,7 @@
Slog.w(TAG, "Failed parsing " + e);
} finally {
if (!success) {
- mUidOps.clear();
+ mUidStates.clear();
}
try {
stream.close();
@@ -1032,6 +1300,34 @@
}
}
+ void readUidOps(XmlPullParser parser) throws NumberFormatException,
+ XmlPullParserException, IOException {
+ final int uid = Integer.parseInt(parser.getAttributeValue(null, "n"));
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals("op")) {
+ final int code = Integer.parseInt(parser.getAttributeValue(null, "n"));
+ final int mode = Integer.parseInt(parser.getAttributeValue(null, "m"));
+ UidState uidState = getUidStateLocked(uid, true);
+ if (uidState.opModes == null) {
+ uidState.opModes = new SparseIntArray();
+ }
+ uidState.opModes.put(code, mode);
+ } else {
+ Slog.w(TAG, "Unknown element under <uid-ops>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ }
+
void readPackage(XmlPullParser parser) throws NumberFormatException,
XmlPullParserException, IOException {
String pkgName = parser.getAttributeValue(null, "n");
@@ -1114,15 +1410,16 @@
if (proxyPackageName != null) {
op.proxyPackageName = proxyPackageName;
}
- HashMap<String, Ops> pkgOps = mUidOps.get(uid);
- if (pkgOps == null) {
- pkgOps = new HashMap<String, Ops>();
- mUidOps.put(uid, pkgOps);
+
+ UidState uidState = getUidStateLocked(uid, true);
+ if (uidState.pkgOps == null) {
+ uidState.pkgOps = new ArrayMap<>();
}
- Ops ops = pkgOps.get(pkgName);
+
+ Ops ops = uidState.pkgOps.get(pkgName);
if (ops == null) {
- ops = new Ops(pkgName, uid, isPrivileged);
- pkgOps.put(pkgName, ops);
+ ops = new Ops(pkgName, uidState, isPrivileged);
+ uidState.pkgOps.put(pkgName, ops);
}
ops.put(op.op, op);
} else {
@@ -1149,7 +1446,27 @@
XmlSerializer out = new FastXmlSerializer();
out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
- out.startTag(null, "app-ops");
+ out.startTag(null, "app");
+
+ final int uidStateCount = mUidStates.size();
+ for (int i = 0; i < uidStateCount; i++) {
+ UidState uidState = mUidStates.valueAt(i);
+ if (uidState.opModes != null && uidState.opModes.size() > 0) {
+ out.startTag(null, "uid");
+ out.attribute(null, "n", Integer.toString(uidState.uid));
+ SparseIntArray uidOpModes = uidState.opModes;
+ final int opCount = uidOpModes.size();
+ for (int j = 0; j < opCount; j++) {
+ final int op = uidOpModes.keyAt(j);
+ final int mode = uidOpModes.valueAt(j);
+ out.startTag(null, "op");
+ out.attribute(null, "n", Integer.toString(op));
+ out.attribute(null, "m", Integer.toString(mode));
+ out.endTag(null, "op");
+ }
+ out.endTag(null, "uid");
+ }
+ }
if (allOps != null) {
String lastPkg = null;
@@ -1316,9 +1633,27 @@
if (needSep) {
pw.println();
}
- for (int i=0; i<mUidOps.size(); i++) {
- pw.print(" Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":");
- HashMap<String, Ops> pkgOps = mUidOps.valueAt(i);
+ for (int i=0; i<mUidStates.size(); i++) {
+ UidState uidState = mUidStates.valueAt(i);
+
+ pw.print(" Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":");
+
+ SparseIntArray opModes = uidState.opModes;
+ if (opModes != null) {
+ final int opModeCount = opModes.size();
+ for (int j = 0; j < opModeCount; j++) {
+ final int code = opModes.keyAt(j);
+ final int mode = opModes.valueAt(j);
+ pw.print(" "); pw.print(AppOpsManager.opToName(code));
+ pw.print(": mode="); pw.println(mode);
+ }
+ }
+
+ ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
+ if (pkgOps == null) {
+ continue;
+ }
+
for (Ops ops : pkgOps.values()) {
pw.print(" Package "); pw.print(ops.packageName); pw.println(":");
for (int j=0; j<ops.size(); j++) {
@@ -1382,4 +1717,16 @@
}
}
+ private static String[] getPackagesForUid(int uid) {
+ String[] packageNames = null;
+ try {
+ packageNames= AppGlobals.getPackageManager().getPackagesForUid(uid);
+ } catch (RemoteException e) {
+ /* ignore - local call */
+ }
+ if (packageNames == null) {
+ return EmptyArray.STRING;
+ }
+ return packageNames;
+ }
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 1223a00..094cb57 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1260,7 +1260,11 @@
}
for (int stream = 0; stream < mStreamStates.length; stream++) {
if (streamTypeAlias == mStreamVolumeAlias[stream]) {
- mStreamStates[stream].mute(state);
+ if (!(readCameraSoundForced()
+ && (mStreamStates[stream].getStreamType()
+ == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
+ mStreamStates[stream].mute(state);
+ }
}
}
} else if ((direction == AudioManager.ADJUST_RAISE) &&
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 669b8e5..3227ef8 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -696,7 +696,7 @@
List<PackageParser.Package> syncAdapterPackages = new ArrayList<>();
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
- homeIntent.addCategory(Intent.CATEGORY_HOME);
+ homeIntent.addCategory(Intent.CATEGORY_LAUNCHER);
for (String syncAdapterPackageName : syncAdapterPackageNames) {
homeIntent.setPackage(syncAdapterPackageName);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b65f0eb..26304ab 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8606,7 +8606,7 @@
if (!allowed) {
if (!allowed && (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_PRE23) != 0
- && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.MNC) {
+ && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
// If this was a previously normal/dangerous permission that got moved
// to a system permission as part of the runtime permission redesign, then
// we still want to blindly grant it to old apps.
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index a57463c..7bd0635 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -559,6 +559,7 @@
set.addAnimation(clipAnimTB);
set.addAnimation(translateY);
set.addAnimation(alpha);
+ set.setZAdjustment(Animation.ZORDER_TOP);
set.initialize(appWidth, appHeight, appWidth, appHeight);
anim = set;
} else {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d9828cc..26e75bd 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2658,6 +2658,16 @@
return disabled;
}
+ boolean isSecureLocked(WindowState w) {
+ if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ return true;
+ }
+ if (isScreenCaptureDisabledLocked(UserHandle.getUserId(w.mOwnerUid))) {
+ return true;
+ }
+ return false;
+ }
+
/**
* Set mScreenCaptureDisabled for specific user
*/
@@ -3169,6 +3179,9 @@
boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
&& (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
+ if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceControl != null) {
+ winAnimator.mSurfaceControl.setSecure(isSecureLocked(win));
+ }
win.mRelayoutCalled = true;
final int oldVisibility = win.mViewVisibility;
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3251a56..3ac6bba 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -788,11 +788,7 @@
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = w.mAttrs;
- if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
- flags |= SurfaceControl.SECURE;
- }
-
- if (mService.isScreenCaptureDisabledLocked(UserHandle.getUserId(mWin.mOwnerUid))) {
+ if (mService.isSecureLocked(w)) {
flags |= SurfaceControl.SECURE;
}
@@ -1277,6 +1273,7 @@
if (displayContent == null) {
return;
}
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
// Need to recompute a new system decor rect each time.
if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
@@ -1286,7 +1283,6 @@
} else if (!w.isDefaultDisplay()) {
// On a different display there is no system decor. Crop the window
// by the screen boundaries.
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
displayInfo.logicalWidth - w.mCompatFrame.left,
@@ -1308,9 +1304,11 @@
applyDecorRect(w.mDecorFrame);
}
- // By default, the clip rect is the system decor if the transformation doesn't specify one.
+ final boolean fullscreen = w.isFullscreen(displayInfo.appWidth, displayInfo.appHeight);
final Rect clipRect = mTmpClipRect;
- clipRect.set((mHasClipRect) ? mClipRect : w.mSystemDecorRect);
+ // We use the clip rect as provided by the tranformation for non-fullscreen windows to
+ // avoid premature clipping with the system decor rect.
+ clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect);
// Expand the clip rect for surface insets.
final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -1319,6 +1317,13 @@
clipRect.right += attrs.surfaceInsets.right;
clipRect.bottom += attrs.surfaceInsets.bottom;
+ if (mHasClipRect && fullscreen) {
+ // We intersect the clip rect specified by the transformation with the expanded system
+ // decor rect to prevent artifacts from drawing during animation if the transformation
+ // clip rect extends outside the system decor rect.
+ clipRect.intersect(mClipRect);
+ }
+
// The clip rect was generated assuming (0,0) as the window origin,
// so we need to translate to match the actual surface coordinates.
clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 1e833b1..cd2885b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -6436,7 +6436,7 @@
final ApplicationInfo ai = AppGlobals.getPackageManager()
.getApplicationInfo(packageName, 0, user.getIdentifier());
final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
- if (targetSdkVersion < android.os.Build.VERSION_CODES.MNC) {
+ if (targetSdkVersion < android.os.Build.VERSION_CODES.M) {
return false;
}
final PackageManager packageManager = mContext.getPackageManager();
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index bf78712..d663952 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -252,6 +252,29 @@
// Next CAPABILITY value: 0x00400000
//**********************************************************************************************
+ /**
+ * Connection extra key used to store the last forwarded number associated with the current
+ * connection. Used to communicate to the user interface that the connection was forwarded via
+ * the specified number.
+ */
+ public static final String EXTRA_LAST_FORWARDED_NUMBER =
+ "android.telecom.extra.LAST_FORWARDED_NUMBER";
+
+ /**
+ * Connection extra key used to store a child number associated with the current connection.
+ * Used to communicate to the user interface that the connection was received via
+ * a child address (i.e. phone number) associated with the {@link PhoneAccount}'s primary
+ * address.
+ */
+ public static final String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
+
+ /**
+ * Connection extra key used to store the subject for an incoming call. The user interface can
+ * query this extra and display its contents for incoming calls. Will only be used if the
+ * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}.
+ */
+ public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
+
// Flag controlling whether PII is emitted into the logs
private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 3b59f27d..067e734 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -177,6 +177,13 @@
"android.telecom.extra.PHONE_ACCOUNT_HANDLE";
/**
+ * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a string call
+ * subject which will be associated with an outgoing call. Should only be specified if the
+ * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}.
+ */
+ public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
+
+ /**
* The extra used by a {@link ConnectionService} to provide the handle of the caller that
* has initiated a new incoming call.
*/
diff --git a/tests/VoiceInteraction/res/layout/main.xml b/tests/VoiceInteraction/res/layout/main.xml
index 0f968eb..a83d02c 100644
--- a/tests/VoiceInteraction/res/layout/main.xml
+++ b/tests/VoiceInteraction/res/layout/main.xml
@@ -26,6 +26,12 @@
android:text="@string/start"
/>
+ <CheckBox android:id="@+id/secure"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/secure"
+ />
+
<com.android.test.voiceinteraction.AsyncStructure
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index ab39f99..29ffe21 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -17,6 +17,7 @@
<resources>
<string name="start">Start</string>
+ <string name="secure">Secure</string>
<string name="tree">Tree</string>
<string name="text">Text</string>
<string name="asyncStructure">(Async structure goes here)</string>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
index ee75f28..87fa91a 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
@@ -21,6 +21,8 @@
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
+import android.view.WindowManager;
+import android.widget.CheckBox;
public class VoiceInteractionMain extends Activity {
@@ -30,6 +32,7 @@
setContentView(R.layout.main);
findViewById(R.id.start).setOnClickListener(mStartListener);
+ findViewById(R.id.secure).setOnClickListener(mSecureListener);
}
@Override
@@ -52,4 +55,14 @@
showAssist(null);
}
};
+
+ View.OnClickListener mSecureListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ if (((CheckBox)v).isChecked()) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+ } else {
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
+ }
+ }
+ };
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index 645634f..09937bc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -74,7 +74,7 @@
}
public static String getTime(int platformVersion) {
- if (isGreaterOrEqual(platformVersion, MNC)) {
+ if (isGreaterOrEqual(platformVersion, M)) {
return "6:00";
}
if (platformVersion < GINGERBREAD) {
@@ -95,7 +95,7 @@
if (platformVersion < LOLLIPOP_MR1) {
return "5:00";
}
- if (platformVersion < MNC) {
+ if (platformVersion < M) {
return "5:10";
}
// Should never happen.
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index d915e5d..cf88df4 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -669,6 +669,7 @@
try {
return mService.getConfiguredNetworks();
} catch (RemoteException e) {
+ Log.w(TAG, "Caught RemoteException trying to get configured networks: " + e);
return null;
}
}
@@ -1589,6 +1590,7 @@
try {
return mService.buildWifiConfig(uriString, mimeType, data);
} catch (RemoteException e) {
+ Log.w(TAG, "Caught RemoteException trying to build wifi config: " + e);
return null;
}
}