Merge "Added the new RIL request to set SIM power state"
diff --git a/Android.mk b/Android.mk
index 28adbca..7a8b1b7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -295,9 +295,9 @@
core/java/android/printservice/IPrintService.aidl \
core/java/android/printservice/IPrintServiceClient.aidl \
core/java/android/companion/ICompanionDeviceManager.aidl \
- core/java/android/companion/ICompanionDeviceManagerService.aidl \
- core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl \
- core/java/android/companion/IOnAssociateCallback.aidl \
+ core/java/android/companion/ICompanionDeviceDiscoveryService.aidl \
+ core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl \
+ core/java/android/companion/IFindDeviceCallback.aidl \
core/java/android/service/dreams/IDreamManager.aidl \
core/java/android/service/dreams/IDreamService.aidl \
core/java/android/service/persistentdata/IPersistentDataBlockService.aidl \
diff --git a/api/current.txt b/api/current.txt
index c8e84c3..48857e9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -121,6 +121,7 @@
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
+ field public static final java.lang.String RUN_IN_BACKGROUND = "android.permission.RUN_IN_BACKGROUND";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
@@ -139,6 +140,7 @@
field public static final java.lang.String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
field public static final java.lang.String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
+ field public static final java.lang.String USE_DATA_IN_BACKGROUND = "android.permission.USE_DATA_IN_BACKGROUND";
field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
@@ -6572,6 +6574,7 @@
method public int getTextStyle();
method public int getTop();
method public android.graphics.Matrix getTransformation();
+ method public java.lang.String getUrl();
method public int getVisibility();
method public int getWidth();
method public boolean isAccessibilityFocused();
@@ -9224,7 +9227,7 @@
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
- field public static final java.lang.String EXTRA_QUICK_VIEW_PLAIN = "android.intent.extra.QUICK_VIEW_PLAIN";
+ field public static final java.lang.String EXTRA_QUICK_VIEW_ADVANCED = "android.intent.extra.QUICK_VIEW_ADVANCED";
field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
@@ -24022,6 +24025,7 @@
field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
@@ -39330,6 +39334,8 @@
method public boolean setOperatorBrandOverride(java.lang.String);
method public boolean setPreferredNetworkTypeToGlobal();
method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
+ method public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
+ method public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -44649,7 +44655,7 @@
method public java.lang.Object getTag(int);
method public int getTextAlignment();
method public int getTextDirection();
- method public final java.lang.CharSequence getTooltipText();
+ method public java.lang.CharSequence getTooltipText();
method public final int getTop();
method protected float getTopFadingEdgeStrength();
method protected int getTopPaddingOffset();
@@ -44955,7 +44961,7 @@
method public void setTag(int, java.lang.Object);
method public void setTextAlignment(int);
method public void setTextDirection(int);
- method public final void setTooltipText(java.lang.CharSequence);
+ method public void setTooltipText(java.lang.CharSequence);
method public final void setTop(int);
method public void setTouchDelegate(android.view.TouchDelegate);
method public final void setTransitionName(java.lang.String);
@@ -45662,6 +45668,7 @@
method public abstract void setTextLines(int[], int[]);
method public abstract void setTextStyle(float, int, int, int);
method public abstract void setTransformation(android.graphics.Matrix);
+ method public abstract void setUrl(java.lang.String);
method public abstract void setVisibility(int);
field public static final int AUTO_FILL_FLAG_SANITIZED = 1; // 0x1
}
@@ -47338,7 +47345,7 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
}
public final class TextClassificationResult {
@@ -54465,7 +54472,6 @@
method public java.lang.Class<?> lookupClass();
method public int lookupModes();
method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
- method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectGetter(java.lang.reflect.Field) throws java.lang.IllegalAccessException;
diff --git a/api/system-current.txt b/api/system-current.txt
index fd84e83..fc78b4b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -211,6 +211,7 @@
field public static final java.lang.String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
field public static final java.lang.String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
+ field public static final java.lang.String RUN_IN_BACKGROUND = "android.permission.RUN_IN_BACKGROUND";
field public static final java.lang.String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
@@ -248,6 +249,7 @@
field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
+ field public static final java.lang.String USE_DATA_IN_BACKGROUND = "android.permission.USE_DATA_IN_BACKGROUND";
field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
@@ -6578,6 +6580,8 @@
method public void uninstallAllUserCaCerts(android.content.ComponentName);
method public void uninstallCaCert(android.content.ComponentName, byte[]);
method public void wipeData(int);
+ field public static final java.lang.String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
+ field public static final java.lang.String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
field public static final java.lang.String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
field public static final java.lang.String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
@@ -6809,6 +6813,7 @@
method public int getTextStyle();
method public int getTop();
method public android.graphics.Matrix getTransformation();
+ method public java.lang.String getUrl();
method public int getVisibility();
method public int getWidth();
method public boolean isAccessibilityFocused();
@@ -9668,7 +9673,7 @@
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
- field public static final java.lang.String EXTRA_QUICK_VIEW_PLAIN = "android.intent.extra.QUICK_VIEW_PLAIN";
+ field public static final java.lang.String EXTRA_QUICK_VIEW_ADVANCED = "android.intent.extra.QUICK_VIEW_ADVANCED";
field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
@@ -25808,6 +25813,7 @@
field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
@@ -42729,6 +42735,8 @@
method public boolean setRadioPower(boolean);
method public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
+ method public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
+ method public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
method public void silenceRinger();
method public boolean supplyPin(java.lang.String);
method public int[] supplyPinReportResult(java.lang.String);
@@ -48087,7 +48095,7 @@
method public java.lang.Object getTag(int);
method public int getTextAlignment();
method public int getTextDirection();
- method public final java.lang.CharSequence getTooltipText();
+ method public java.lang.CharSequence getTooltipText();
method public final int getTop();
method protected float getTopFadingEdgeStrength();
method protected int getTopPaddingOffset();
@@ -48393,7 +48401,7 @@
method public void setTag(int, java.lang.Object);
method public void setTextAlignment(int);
method public void setTextDirection(int);
- method public final void setTooltipText(java.lang.CharSequence);
+ method public void setTooltipText(java.lang.CharSequence);
method public final void setTop(int);
method public void setTouchDelegate(android.view.TouchDelegate);
method public final void setTransitionName(java.lang.String);
@@ -49100,6 +49108,7 @@
method public abstract void setTextLines(int[], int[]);
method public abstract void setTextStyle(float, int, int, int);
method public abstract void setTransformation(android.graphics.Matrix);
+ method public abstract void setUrl(java.lang.String);
method public abstract void setVisibility(int);
field public static final int AUTO_FILL_FLAG_SANITIZED = 1; // 0x1
}
@@ -50779,7 +50788,7 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
}
public final class TextClassificationResult {
@@ -58267,7 +58276,6 @@
method public java.lang.Class<?> lookupClass();
method public int lookupModes();
method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
- method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectGetter(java.lang.reflect.Field) throws java.lang.IllegalAccessException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 752986c..72ffe48 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -121,6 +121,7 @@
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
+ field public static final java.lang.String RUN_IN_BACKGROUND = "android.permission.RUN_IN_BACKGROUND";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
@@ -139,6 +140,7 @@
field public static final java.lang.String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
field public static final java.lang.String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
+ field public static final java.lang.String USE_DATA_IN_BACKGROUND = "android.permission.USE_DATA_IN_BACKGROUND";
field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
@@ -6376,6 +6378,8 @@
method public void uninstallAllUserCaCerts(android.content.ComponentName);
method public void uninstallCaCert(android.content.ComponentName, byte[]);
method public void wipeData(int);
+ field public static final java.lang.String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
+ field public static final java.lang.String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
field public static final java.lang.String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
field public static final java.lang.String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
@@ -6595,6 +6599,7 @@
method public int getTextStyle();
method public int getTop();
method public android.graphics.Matrix getTransformation();
+ method public java.lang.String getUrl();
method public int getVisibility();
method public int getWidth();
method public boolean isAccessibilityFocused();
@@ -9250,7 +9255,7 @@
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
- field public static final java.lang.String EXTRA_QUICK_VIEW_PLAIN = "android.intent.extra.QUICK_VIEW_PLAIN";
+ field public static final java.lang.String EXTRA_QUICK_VIEW_ADVANCED = "android.intent.extra.QUICK_VIEW_ADVANCED";
field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
@@ -24115,6 +24120,7 @@
field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
@@ -39466,6 +39472,8 @@
method public boolean setOperatorBrandOverride(java.lang.String);
method public boolean setPreferredNetworkTypeToGlobal();
method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
+ method public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
+ method public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -44956,7 +44964,7 @@
method public java.lang.Object getTag(int);
method public int getTextAlignment();
method public int getTextDirection();
- method public final java.lang.CharSequence getTooltipText();
+ method public java.lang.CharSequence getTooltipText();
method public android.view.View getTooltipView();
method public final int getTop();
method protected float getTopFadingEdgeStrength();
@@ -45263,7 +45271,7 @@
method public void setTag(int, java.lang.Object);
method public void setTextAlignment(int);
method public void setTextDirection(int);
- method public final void setTooltipText(java.lang.CharSequence);
+ method public void setTooltipText(java.lang.CharSequence);
method public final void setTop(int);
method public void setTouchDelegate(android.view.TouchDelegate);
method public final void setTransitionName(java.lang.String);
@@ -45974,6 +45982,7 @@
method public abstract void setTextLines(int[], int[]);
method public abstract void setTextStyle(float, int, int, int);
method public abstract void setTransformation(android.graphics.Matrix);
+ method public abstract void setUrl(java.lang.String);
method public abstract void setVisibility(int);
field public static final int AUTO_FILL_FLAG_SANITIZED = 1; // 0x1
}
@@ -47652,7 +47661,7 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
}
public final class TextClassificationResult {
@@ -54794,7 +54803,6 @@
method public java.lang.Class<?> lookupClass();
method public int lookupModes();
method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
- method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectGetter(java.lang.reflect.Field) throws java.lang.IllegalAccessException;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index fb927e9..6dd31a8 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -357,7 +357,8 @@
public static final String OPSTR_INSTANT_APP_START_FOREGROUND
= "android:instant_app_start_foreground";
- private static final int[] RUNTIME_PERMISSIONS_OPS = {
+ private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
+ // RUNTIME PERMISSIONS
// Contacts
OP_READ_CONTACTS,
OP_WRITE_CONTACTS,
@@ -392,7 +393,13 @@
// Camera
OP_CAMERA,
// Body sensors
- OP_BODY_SENSORS
+ OP_BODY_SENSORS,
+
+ // APPOP PERMISSIONS
+ OP_ACCESS_NOTIFICATIONS,
+ OP_SYSTEM_ALERT_WINDOW,
+ OP_WRITE_SETTINGS,
+ OP_REQUEST_INSTALL_PACKAGES,
};
/**
@@ -926,9 +933,9 @@
AppOpsManager.MODE_ALLOWED, // OP_RUN_IN_BACKGROUND
AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ACCESSIBILITY_VOLUME
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_DEFAULT, // OP_REQUEST_INSTALL_PACKAGES
+ AppOpsManager.MODE_DEFAULT, // OP_REQUEST_INSTALL_PACKAGES
AppOpsManager.MODE_ALLOWED, // OP_ENTER_PICTURE_IN_PICTURE_ON_HIDE
- AppOpsManager.MODE_DEFAULT, // OP_INSTANT_APP_START_FOREGROUND
+ AppOpsManager.MODE_DEFAULT, // OP_INSTANT_APP_START_FOREGROUND
};
/**
@@ -1018,7 +1025,7 @@
/**
* Mapping from a permission to the corresponding app op.
*/
- private static HashMap<String, Integer> sRuntimePermToOp = new HashMap<>();
+ private static HashMap<String, Integer> sPermToOp = new HashMap<>();
static {
if (sOpToSwitch.length != _NUM_OP) {
@@ -1058,9 +1065,9 @@
sOpStrToOp.put(sOpToString[i], i);
}
}
- for (int op : RUNTIME_PERMISSIONS_OPS) {
+ for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
if (sOpPerms[op] != null) {
- sRuntimePermToOp.put(sOpPerms[op], op);
+ sPermToOp.put(sOpPerms[op], op);
}
}
}
@@ -1112,12 +1119,12 @@
/**
* Retrieve the app op code for a permission, or null if there is not one.
- * This API is intended to be used for mapping runtime permissions to the
- * corresponding app op.
+ * This API is intended to be used for mapping runtime or appop permissions
+ * to the corresponding app op.
* @hide
*/
public static int permissionToOpCode(String permission) {
- Integer boxedOpCode = sRuntimePermToOp.get(permission);
+ Integer boxedOpCode = sPermToOp.get(permission);
return boxedOpCode != null ? boxedOpCode : OP_NONE;
}
@@ -1462,7 +1469,7 @@
* @return The app op associated with the permission or null.
*/
public static String permissionToOp(String permission) {
- final Integer opCode = sRuntimePermToOp.get(permission);
+ final Integer opCode = sPermToOp.get(permission);
if (opCode == null) {
return null;
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 0eb47a3..3b2562d 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1774,10 +1774,14 @@
* if any of the accounts have it.
* </ul>
*/
+ @SystemApi
+ @TestApi
public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED =
"android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
/** @hide See {@link #ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED} */
+ @SystemApi
+ @TestApi
public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED =
"android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 6591fc9..8d385db 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -17,13 +17,13 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
-import android.view.ViewStructure;
import android.view.ViewRootImpl;
+import android.view.ViewStructure;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.view.autofill.AutoFillId;
import android.view.autofill.AutoFillType;
import android.view.autofill.AutoFillValue;
-import android.view.autofill.AutoFillId;
import java.util.ArrayList;
@@ -579,6 +579,7 @@
static final int FLAGS_HAS_EXTRAS = 0x00400000;
static final int FLAGS_HAS_ID = 0x00200000;
static final int FLAGS_HAS_CHILDREN = 0x00100000;
+ static final int FLAGS_HAS_URL = 0x00080000;
static final int FLAGS_ALL_CONTROL = 0xfff00000;
int mFlags;
@@ -587,6 +588,7 @@
CharSequence mContentDescription;
ViewNodeText mText;
+ String mUrl;
Bundle mExtras;
ViewNode[] mChildren;
@@ -651,6 +653,9 @@
if ((flags&FLAGS_HAS_TEXT) != 0) {
mText = new ViewNodeText(in, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0);
}
+ if ((flags&FLAGS_HAS_URL) != 0) {
+ mUrl = in.readString();
+ }
if ((flags&FLAGS_HAS_EXTRAS) != 0) {
mExtras = in.readBundle();
}
@@ -704,6 +709,9 @@
flags |= FLAGS_HAS_COMPLEX_TEXT;
}
}
+ if (mUrl != null) {
+ flags |= FLAGS_HAS_URL;
+ }
if (mExtras != null) {
flags |= FLAGS_HAS_EXTRAS;
}
@@ -760,6 +768,9 @@
if ((flags&FLAGS_HAS_TEXT) != 0) {
mText.writeToParcel(out, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0, writeSensitive);
}
+ if ((flags&FLAGS_HAS_URL) != 0) {
+ out.writeString(mUrl);
+ }
if ((flags&FLAGS_HAS_EXTRAS) != 0) {
out.writeBundle(mExtras);
}
@@ -1040,6 +1051,20 @@
}
/**
+ * Returns the URL represented by this node.
+ *
+ * <p>Typically used in 2 categories of nodes:
+ *
+ * <ol>
+ * <li>Root node (containing the URL of the HTML page)
+ * <li>Child nodes that represent hyperlinks (contains the hyperlink URL).
+ * </ol>
+ */
+ public String getUrl() {
+ return mUrl;
+ }
+
+ /**
* Returns any text associated with the node that is displayed to the user, or null
* if there is none.
*/
@@ -1486,6 +1511,11 @@
public void setSanitized(boolean sanitized) {
mNode.mSanitized = sanitized;
}
+
+ @Override
+ public void setUrl(String url) {
+ mNode.mUrl = url;
+ }
}
/** @hide */
@@ -1583,6 +1613,10 @@
Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor())
+ ", bg: #" + Integer.toHexString(node.getTextBackgroundColor()));
}
+ CharSequence url = node.getUrl();
+ if (url != null) {
+ Log.i(TAG, prefix + " URL: " + url);
+ }
String hint = node.getHint();
if (hint != null) {
Log.i(TAG, prefix + " Hint: " + hint);
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index b379c7c..c0c1a4d 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -29,12 +29,10 @@
/**
* System level service for managing companion devices
*
- * Usage:
- * To obtain an instance call
- * {@link Context#getSystemService}({@link Context#COMPANION_DEVICE_SERVICE})
- *
- * Then, call {@link #associate} to initiate the flow of associating current package
- * with a device selected by user
+ * <p>To obtain an instance call {@link Context#getSystemService}({@link
+ * Context#COMPANION_DEVICE_SERVICE}) Then, call {@link #associate(AssociationRequest,
+ * Callback, Handler)} to initiate the flow of associating current package with a
+ * device selected by user.</p>
*
* @see AssociationRequest
*/
@@ -47,6 +45,14 @@
public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
/**
+ * The package name of the companion device discovery component.
+ *
+ * @hide
+ */
+ public static final String COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME =
+ "com.android.companiondevicemanager";
+
+ /**
* A callback to receive once at least one suitable device is found, or the search failed
* (e.g. timed out)
*/
@@ -81,13 +87,20 @@
/**
* Associate this app with a companion device, selected by user
*
- * Once at least one appropriate device is found, {@code callback} will be called with a
+ * <p>Once at least one appropriate device is found, {@code callback} will be called with a
* {@link PendingIntent} that can be used to show the list of available devices for the user
* to select.
* It should be started for result (i.e. using
* {@link android.app.Activity#startIntentSenderForResult}), as the resulting
* {@link android.content.Intent} will contain extra {@link #EXTRA_DEVICE}, with the selected
- * device. (e.g. {@link android.bluetooth.BluetoothDevice})
+ * device. (e.g. {@link android.bluetooth.BluetoothDevice})</p>
+ *
+ * <p>If your app needs to be excluded from battery optimizations (run in the background)
+ * or to have unrestricted data access (use data in the background) you can declare that
+ * you use the {@link android.Manifest.permission#RUN_IN_BACKGROUND} and {@link
+ * android.Manifest.permission#USE_DATA_IN_BACKGROUND} respectively. Note that these
+ * special capabilities have a negative effect on the device's battery and user's data
+ * usage, therefore you should requested them when absolutely necessary.</p>
*
* @param request specific details about this request
* @param callback will be called once there's at least one device found for user to choose from
@@ -106,17 +119,16 @@
try {
mService.associate(
request,
- new IOnAssociateCallback.Stub() {
-
+ new IFindDeviceCallback.Stub() {
@Override
- public void onSuccess(PendingIntent launcher) throws RemoteException {
+ public void onSuccess(PendingIntent launcher) {
finalHandler.post(() -> {
callback.onDeviceFound(launcher.getIntentSender());
});
}
@Override
- public void onFailure(CharSequence reason) throws RemoteException {
+ public void onFailure(CharSequence reason) {
finalHandler.post(() -> callback.onFailure(reason));
}
},
diff --git a/core/java/android/companion/ICompanionDeviceManagerService.aidl b/core/java/android/companion/ICompanionDeviceDiscoveryService.aidl
similarity index 71%
rename from core/java/android/companion/ICompanionDeviceManagerService.aidl
rename to core/java/android/companion/ICompanionDeviceDiscoveryService.aidl
index ff2a7eb..4d77963 100644
--- a/core/java/android/companion/ICompanionDeviceManagerService.aidl
+++ b/core/java/android/companion/ICompanionDeviceDiscoveryService.aidl
@@ -17,13 +17,14 @@
package android.companion;
import android.companion.AssociationRequest;
-import android.companion.IOnAssociateCallback;
-
+import android.companion.ICompanionDeviceDiscoveryServiceCallback;
+import android.companion.IFindDeviceCallback;
/** @hide */
-interface ICompanionDeviceManagerService {
+interface ICompanionDeviceDiscoveryService {
void startDiscovery(
in AssociationRequest request,
- in IOnAssociateCallback callback,
- in String callingPackage);
+ in String callingPackage,
+ in IFindDeviceCallback findCallback,
+ in ICompanionDeviceDiscoveryServiceCallback serviceCallback);
}
diff --git a/core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl b/core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl
similarity index 81%
rename from core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
rename to core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl
index c9dd345..7af708e 100644
--- a/core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
+++ b/core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl
@@ -16,9 +16,7 @@
package android.companion;
-import android.bluetooth.BluetoothDevice;
-
/** @hide */
-interface ICompanionDeviceManagerServiceCallback {
- void onDeviceSelected(in BluetoothDevice device);
+interface ICompanionDeviceDiscoveryServiceCallback {
+ void onDeviceSelected(String packageName, int userId);
}
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 065e31b..1d30ada 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -16,7 +16,7 @@
package android.companion;
-import android.companion.IOnAssociateCallback;
+import android.companion.IFindDeviceCallback;
import android.companion.AssociationRequest;
/**
@@ -26,8 +26,8 @@
*/
interface ICompanionDeviceManager {
void associate(in AssociationRequest request,
- in IOnAssociateCallback callback,
- in String callingPackage); //TODO int userId?
+ in IFindDeviceCallback callback,
+ in String callingPackage);
//TODO add these
// boolean haveNotificationAccess(String packageName);
diff --git a/core/java/android/companion/IOnAssociateCallback.aidl b/core/java/android/companion/IFindDeviceCallback.aidl
similarity index 95%
rename from core/java/android/companion/IOnAssociateCallback.aidl
rename to core/java/android/companion/IFindDeviceCallback.aidl
index 4867eadd..919e1519 100644
--- a/core/java/android/companion/IOnAssociateCallback.aidl
+++ b/core/java/android/companion/IFindDeviceCallback.aidl
@@ -19,7 +19,7 @@
import android.app.PendingIntent;
/** @hide */
-interface IOnAssociateCallback {
+interface IFindDeviceCallback {
void onSuccess(in PendingIntent launcher);
void onFailure(in CharSequence reason);
}
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 7096771..6703bd4 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -17,6 +17,9 @@
package android.content;
import static android.content.ContentProvider.maybeAddUserId;
+import static android.content.ContentResolver.SCHEME_ANDROID_RESOURCE;
+import static android.content.ContentResolver.SCHEME_CONTENT;
+import static android.content.ContentResolver.SCHEME_FILE;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
@@ -353,6 +356,9 @@
}
return builder.toString();
+ } catch (SecurityException e) {
+ Log.w("ClipData", "Failure opening stream", e);
+
} catch (FileNotFoundException e) {
// Unable to open content URI as text... not really an
// error, just something to ignore.
@@ -371,8 +377,14 @@
}
}
- // If we couldn't open the URI as a stream, then the URI itself
- // probably serves fairly well as a textual representation.
+ // If we couldn't open the URI as a stream, use the URI itself as a textual
+ // representation (but not for "content", "android.resource" or "file" schemes).
+ final String scheme = uri.getScheme();
+ if (SCHEME_CONTENT.equals(scheme)
+ || SCHEME_ANDROID_RESOURCE.equals(scheme)
+ || SCHEME_FILE.equals(scheme)) {
+ return "";
+ }
return uri.toString();
}
@@ -536,6 +548,9 @@
return Html.escapeHtml(text);
}
+ } catch (SecurityException e) {
+ Log.w("ClipData", "Failure opening stream", e);
+
} catch (FileNotFoundException e) {
// Unable to open content URI as text... not really an
// error, just something to ignore.
@@ -555,9 +570,15 @@
}
}
- // If we couldn't open the URI as a stream, then we can build
- // some HTML text with the URI itself.
- // probably serves fairly well as a textual representation.
+ // If we couldn't open the URI as a stream, use the URI itself as a textual
+ // representation (but not for "content", "android.resource" or "file" schemes).
+ final String scheme = mUri.getScheme();
+ if (SCHEME_CONTENT.equals(scheme)
+ || SCHEME_ANDROID_RESOURCE.equals(scheme)
+ || SCHEME_FILE.equals(scheme)) {
+ return "";
+ }
+
if (styled) {
return uriToStyledText(mUri.toString());
} else {
@@ -777,7 +798,7 @@
*/
private static String[] getMimeTypes(ContentResolver resolver, Uri uri) {
String[] mimeTypes = null;
- if ("content".equals(uri.getScheme())) {
+ if (SCHEME_CONTENT.equals(uri.getScheme())) {
String realType = resolver.getType(uri);
mimeTypes = resolver.getStreamTypes(uri, "*/*");
if (realType != null) {
diff --git a/core/java/android/content/DialogInterface.java b/core/java/android/content/DialogInterface.java
index 947eac6..511f356 100644
--- a/core/java/android/content/DialogInterface.java
+++ b/core/java/android/content/DialogInterface.java
@@ -19,45 +19,43 @@
import android.view.KeyEvent;
/**
- *
+ * Interface that defines a dialog-type class that can be shown, dismissed, or
+ * canceled, and may have buttons that can be clicked.
*/
-public interface DialogInterface {
- /**
- * The identifier for the positive button.
- */
- public static final int BUTTON_POSITIVE = -1;
+public interface DialogInterface {
+ /** The identifier for the positive button. */
+ int BUTTON_POSITIVE = -1;
- /**
- * The identifier for the negative button.
- */
- public static final int BUTTON_NEGATIVE = -2;
+ /** The identifier for the negative button. */
+ int BUTTON_NEGATIVE = -2;
- /**
- * The identifier for the neutral button.
- */
- public static final int BUTTON_NEUTRAL = -3;
+ /** The identifier for the neutral button. */
+ int BUTTON_NEUTRAL = -3;
- /**
- * @deprecated Use {@link #BUTTON_POSITIVE}
- */
+ /** @deprecated Use {@link #BUTTON_POSITIVE} */
@Deprecated
- public static final int BUTTON1 = BUTTON_POSITIVE;
+ int BUTTON1 = BUTTON_POSITIVE;
+
+ /** @deprecated Use {@link #BUTTON_NEGATIVE} */
+ @Deprecated
+ int BUTTON2 = BUTTON_NEGATIVE;
+
+ /** @deprecated Use {@link #BUTTON_NEUTRAL} */
+ @Deprecated
+ int BUTTON3 = BUTTON_NEUTRAL;
/**
- * @deprecated Use {@link #BUTTON_NEGATIVE}
+ * Cancels the dialog, invoking the {@link OnCancelListener}.
+ * <p>
+ * The {@link OnDismissListener} may also be called if cancellation
+ * dismisses the dialog.
*/
- @Deprecated
- public static final int BUTTON2 = BUTTON_NEGATIVE;
+ void cancel();
/**
- * @deprecated Use {@link #BUTTON_NEUTRAL}
+ * Dismisses the dialog, invoking the {@link OnDismissListener}.
*/
- @Deprecated
- public static final int BUTTON3 = BUTTON_NEUTRAL;
-
- public void cancel();
-
- public void dismiss();
+ void dismiss();
/**
* Interface used to allow the creator of a dialog to run some code when the
@@ -70,11 +68,11 @@
interface OnCancelListener {
/**
* This method will be invoked when the dialog is canceled.
- *
- * @param dialog The dialog that was canceled will be passed into the
- * method.
+ *
+ * @param dialog the dialog that was canceled will be passed into the
+ * method
*/
- public void onCancel(DialogInterface dialog);
+ void onCancel(DialogInterface dialog);
}
/**
@@ -84,11 +82,11 @@
interface OnDismissListener {
/**
* This method will be invoked when the dialog is dismissed.
- *
- * @param dialog The dialog that was dismissed will be passed into the
- * method.
+ *
+ * @param dialog the dialog that was dismissed will be passed into the
+ * method
*/
- public void onDismiss(DialogInterface dialog);
+ void onDismiss(DialogInterface dialog);
}
/**
@@ -99,29 +97,28 @@
/**
* This method will be invoked when the dialog is shown.
*
- * @param dialog The dialog that was shown will be passed into the
- * method.
+ * @param dialog the dialog that was shown will be passed into the
+ * method
*/
- public void onShow(DialogInterface dialog);
+ void onShow(DialogInterface dialog);
}
/**
* Interface used to allow the creator of a dialog to run some code when an
- * item on the dialog is clicked..
+ * item on the dialog is clicked.
*/
interface OnClickListener {
/**
* This method will be invoked when a button in the dialog is clicked.
- *
- * @param dialog The dialog that received the click.
- * @param which The button that was clicked (e.g.
- * {@link DialogInterface#BUTTON1}) or the position
- * of the item clicked.
+ *
+ * @param dialog the dialog that received the click
+ * @param which the button that was clicked (ex.
+ * {@link DialogInterface#BUTTON_POSITIVE}) or the position
+ * of the item clicked
*/
- /* TODO: Change to use BUTTON_POSITIVE after API council */
- public void onClick(DialogInterface dialog, int which);
+ void onClick(DialogInterface dialog, int which);
}
-
+
/**
* Interface used to allow the creator of a dialog to run some code when an
* item in a multi-choice dialog is clicked.
@@ -129,14 +126,15 @@
interface OnMultiChoiceClickListener {
/**
* This method will be invoked when an item in the dialog is clicked.
- *
- * @param dialog The dialog where the selection was made.
- * @param which The position of the item in the list that was clicked.
- * @param isChecked True if the click checked the item, else false.
+ *
+ * @param dialog the dialog where the selection was made
+ * @param which the position of the item in the list that was clicked
+ * @param isChecked {@code true} if the click checked the item, else
+ * {@code false}
*/
- public void onClick(DialogInterface dialog, int which, boolean isChecked);
+ void onClick(DialogInterface dialog, int which, boolean isChecked);
}
-
+
/**
* Interface definition for a callback to be invoked when a key event is
* dispatched to this dialog. The callback will be invoked before the key
@@ -146,13 +144,14 @@
/**
* Called when a key is dispatched to a dialog. This allows listeners to
* get a chance to respond before the dialog.
- *
- * @param dialog The dialog the key has been dispatched to.
- * @param keyCode The code for the physical key that was pressed
- * @param event The KeyEvent object containing full information about
- * the event.
- * @return True if the listener has consumed the event, false otherwise.
+ *
+ * @param dialog the dialog the key has been dispatched to
+ * @param keyCode the code for the physical key that was pressed
+ * @param event the KeyEvent object containing full information about
+ * the event
+ * @return {@code true} if the listener has consumed the event,
+ * {@code false} otherwise
*/
- public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event);
+ boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event);
}
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 028a7bcf..b0505ac 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -669,13 +669,14 @@
* preview. {@link #getClipData} contains an optional list of content URIs
* if there is more than one item to preview. {@link #EXTRA_INDEX} is an
* optional index of the URI in the clip data to show first.
- * If {@link #EXTRA_QUICK_VIEW_PLAIN} is true, then the quick viewer should show
- * basic UI without any extra features other than quick viewing the passed items.
- * Especially, the quick viewer should not let users open the passed files
- * in other apps, which includes sharing, opening, editing, printing, etc in the
- * plain mode.
+ * <p>By default quick viewers are supposed to be lightweight and focus on
+ * previewing the content only. They should not expose features such as printing,
+ * opening in an external app, deleting, rotating, casting, etc.
+ * However, if {@link #EXTRA_QUICK_VIEW_ADVANCED} is true, then the quick viewer
+ * may show advanced UI which includes convenience actions suitable for the passed
+ * Uris.
* <p>Output: nothing.
- * @see #EXTRA_QUICK_VIEW_HIDE_DEFAULT_ACTIONS
+ * @see #EXTRA_QUICK_VIEW_ADVANCED
* @see #EXTRA_INDEX
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@@ -4413,19 +4414,15 @@
public static final String EXTRA_INDEX = "android.intent.extra.INDEX";
/**
- * Shows a plain quick viewer UI which doesn't provide any extra features other than
- * quick viewing the items.
- *
- * <p>Especially, the quick viewer should not let users open the quick viewed files
- * in other apps, which includes sharing, opening, editing, printing, etc.
- *
- * <p>This feature is optional, and may not be handled by all quick viewers.
+ * Tells the quick viewer to show additional UI actions suitable for the passed Uris,
+ * such as opening in other apps, sharing, opening, editing, printing, deleting,
+ * casting, etc.
*
* <p>The value is boolean. By default false.
* @see ACTION_QUICK_VIEW
*/
- public static final String EXTRA_QUICK_VIEW_PLAIN =
- "android.intent.extra.QUICK_VIEW_PLAIN";
+ public static final String EXTRA_QUICK_VIEW_ADVANCED =
+ "android.intent.extra.QUICK_VIEW_ADVANCED";
/**
* Optional boolean extra indicating whether quiet mode has been switched on or off.
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index bb0a042..5423ca9 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -646,7 +646,7 @@
// Special case where the only scene mode listed is AUTO => no scene mode
if (sceneModes != null && sceneModes.size() == 1 &&
- sceneModes.get(0) == Parameters.SCENE_MODE_AUTO) {
+ sceneModes.get(0).equals(Parameters.SCENE_MODE_AUTO)) {
supportedSceneModes = null;
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index acb1d07..719a957 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2998,8 +2998,8 @@
*
* This function behaves identically to the non-timedout version, but if a suitable
* network is not found within the given time (in milliseconds) the
- * {@link NetworkCallback#unavailable} callback is called. The request must
- * still be released normally by calling {@link unregisterNetworkCallback(NetworkCallback)}.
+ * {@link NetworkCallback#onUnavailable()} callback is called. The request must
+ * still be released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)}.
*
* <p>This method requires the caller to hold either the
* {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
@@ -3011,10 +3011,7 @@
* the callbacks must not be shared - they uniquely specify
* this request.
* @param timeoutMs The time in milliseconds to attempt looking for a suitable network
- * before {@link NetworkCallback#unavailable} is called.
- *
- * TODO: Make timeouts work and then unhide this method.
- *
+ * before {@link NetworkCallback#onUnavailable()} is called.
* @hide
*/
public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
@@ -3024,13 +3021,6 @@
}
/**
- * The maximum number of milliseconds the framework will look for a suitable network
- * during a timeout-equiped call to {@link requestNetwork}.
- * {@hide}
- */
- public final static int MAX_NETWORK_REQUEST_TIMEOUT_MS = 100 * 60 * 1000;
-
- /**
* The lookup key for a {@link Network} object included with the intent after
* successfully finding a network for the applications request. Retrieve it with
* {@link android.content.Intent#getParcelableExtra(String)}.
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 11b9606..ee8eed1 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -348,8 +348,8 @@
if (msg.what == UPDATE_SLIDER) {
if (mSeekBar != null) {
mLastProgress = msg.arg1;
- mLastAudibleStreamVolume = Math.abs(msg.arg2);
- final boolean muted = msg.arg2 < 0;
+ mLastAudibleStreamVolume = msg.arg2;
+ final boolean muted = ((Boolean)msg.obj).booleanValue();
if (muted != mMuted) {
mMuted = muted;
if (mCallback != null) {
@@ -362,8 +362,7 @@
}
public void postUpdateSlider(int volume, int lastAudibleVolume, boolean mute) {
- final int arg2 = lastAudibleVolume * (mute ? -1 : 1);
- obtainMessage(UPDATE_SLIDER, volume, arg2).sendToTarget();
+ obtainMessage(UPDATE_SLIDER, volume, lastAudibleVolume, new Boolean(mute)).sendToTarget();
}
}
diff --git a/core/java/android/text/Emoji.java b/core/java/android/text/Emoji.java
index b6d720d..83810b0 100644
--- a/core/java/android/text/Emoji.java
+++ b/core/java/android/text/Emoji.java
@@ -164,6 +164,8 @@
public static int VARIATION_SELECTOR_16 = 0xFE0F;
+ public static int CANCEL_TAG = 0xE007F;
+
// Returns true if the given code point is regional indicator symbol.
public static boolean isRegionalIndicatorSymbol(int codepoint) {
return 0x1F1E6 <= codepoint && codepoint <= 0x1F1FF;
@@ -188,4 +190,13 @@
public static boolean isKeycapBase(int codePoint) {
return ('0' <= codePoint && codePoint <= '9') || codePoint == '#' || codePoint == '*';
}
+
+ /**
+ * Returns true if the character can be a part of tag_spec in emoji tag sequence.
+ *
+ * Note that 0xE007F (CANCEL TAG) is not included.
+ */
+ public static boolean isTagSpecChar(int codePoint) {
+ return 0xE0020 <= codePoint && codePoint <= 0xE007E;
+ }
}
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 90559dc..5f0a46d 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -145,8 +145,11 @@
// The number of following RIS code points is even.
final int STATE_EVEN_NUMBERED_RIS = 11;
+ // The offset is in emoji tag sequence.
+ final int STATE_IN_TAG_SEQUENCE = 12;
+
// The state machine has been stopped.
- final int STATE_FINISHED = 12;
+ final int STATE_FINISHED = 13;
int deleteCharCount = 0; // Char count to be deleted by backspace.
int lastSeenVSCharCount = 0; // Char count of previous variation selector.
@@ -173,6 +176,8 @@
state = STATE_BEFORE_KEYCAP;
} else if (Emoji.isEmoji(codePoint)) {
state = STATE_BEFORE_EMOJI;
+ } else if (codePoint == Emoji.CANCEL_TAG) {
+ state = STATE_IN_TAG_SEQUENCE;
} else {
state = STATE_FINISHED;
}
@@ -275,6 +280,20 @@
state = STATE_FINISHED;
}
break;
+ case STATE_IN_TAG_SEQUENCE:
+ if (Emoji.isTagSpecChar(codePoint)) {
+ deleteCharCount += 2; /* Char count of emoji tag spec character. */
+ // Keep the same state.
+ } else if (Emoji.isEmoji(codePoint)) {
+ deleteCharCount += Character.charCount(codePoint);
+ state = STATE_FINISHED;
+ } else {
+ // Couldn't find tag_base character. Delete the last tag_term character.
+ deleteCharCount = 2; // for U+E007F
+ state = STATE_FINISHED;
+ }
+ // TODO: Need handle emoji variation selectors. Issue 35224297
+ break;
default:
throw new IllegalArgumentException("state " + state + " is unknown");
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0c6d9e3..ef5dc33 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24899,13 +24899,20 @@
* Sets the tooltip text which will be displayed in a small popup next to the view.
* <p>
* The tooltip will be displayed:
+ * <ul>
* <li>On long click, unless is not handled otherwise (by OnLongClickListener or a context
* menu). </li>
* <li>On hover, after a brief delay since the pointer has stopped moving </li>
+ * </ul>
+ * <p>
+ * <strong>Note:</strong> Do not override this method, as it will have no
+ * effect on the text displayed in the tooltip.
*
* @param tooltipText the tooltip text, or null if no tooltip is required
+ * @see #getTooltipText()
+ * @attr ref android.R.styleable#View_tooltipText
*/
- public final void setTooltipText(@Nullable CharSequence tooltipText) {
+ public void setTooltipText(@Nullable CharSequence tooltipText) {
if (TextUtils.isEmpty(tooltipText)) {
setFlags(0, TOOLTIP);
hideTooltip();
@@ -24934,10 +24941,16 @@
/**
* Returns the view's tooltip text.
*
+ * <strong>Note:</strong> Do not override this method, as it will have no
+ * effect on the text displayed in the tooltip. You must call
+ * {@link #setTooltipText(CharSequence)} to modify the tooltip text.
+ *
* @return the tooltip text
+ * @see #setTooltipText(CharSequence)
+ * @attr ref android.R.styleable#View_tooltipText
*/
@Nullable
- public final CharSequence getTooltipText() {
+ public CharSequence getTooltipText() {
return mTooltipInfo != null ? mTooltipInfo.mTooltipText : null;
}
@@ -24950,21 +24963,20 @@
}
private boolean showTooltip(int x, int y, boolean fromLongClick) {
- if (mAttachInfo == null) {
+ if (mAttachInfo == null || mTooltipInfo == null) {
return false;
}
if ((mViewFlags & ENABLED_MASK) != ENABLED) {
return false;
}
- final CharSequence tooltipText = getTooltipText();
- if (TextUtils.isEmpty(tooltipText)) {
+ if (TextUtils.isEmpty(mTooltipInfo.mTooltipText)) {
return false;
}
hideTooltip();
mTooltipInfo.mTooltipFromLongClick = fromLongClick;
mTooltipInfo.mTooltipPopup = new TooltipPopup(getContext());
final boolean fromTouch = (mPrivateFlags3 & PFLAG3_FINGER_DOWN) == PFLAG3_FINGER_DOWN;
- mTooltipInfo.mTooltipPopup.show(this, x, y, fromTouch, tooltipText);
+ mTooltipInfo.mTooltipPopup.show(this, x, y, fromTouch, mTooltipInfo.mTooltipText);
mAttachInfo.mTooltipHost = this;
return true;
}
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 9e3467a..9ce23e6 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -338,4 +338,17 @@
/** @hide */
public abstract AutoFillId getAutoFillId();
+
+ /**
+ * Sets the URL represented by this node.
+ *
+ * <p>Typically used in the following situations:
+ *
+ * <ol>
+ * <li>In a {@link android.app.assist.AssistStructure.WindowNode#getRootViewNode()}, to set up
+ * the main URL of an HTML page.
+ * <li>On child nodes represening hyperlinks.
+ * </ol>
+ */
+ public abstract void setUrl(String url);
}
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index fc6448a..c7e8dee 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -167,8 +167,10 @@
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
try {
- sWindowManagerService = getWindowManagerService();
- ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());
+ if (sWindowManagerService != null) {
+ ValueAnimator.setDurationScale(
+ sWindowManagerService.getCurrentAnimatorScale());
+ }
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 7a5e670..a541a4c 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -296,9 +296,12 @@
* to corresponding API calls. Note that this state is not guaranteed
* to be synchronized with state in WindowManagerService.
* @param targetWindowToken token to identify the target window that the IME is associated with.
+ * {@code null} when application, system, or the IME itself decided to
+ * change its window visibility before being associated with any target
+ * window.
*/
- public abstract void updateInputMethodWindowStatus(IBinder imeToken, boolean imeWindowVisible,
- IBinder targetWindowToken);
+ public abstract void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
+ boolean imeWindowVisible, @Nullable IBinder targetWindowToken);
/**
* Returns true when the hardware keyboard is available.
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4c9a866..1937187 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -54,6 +54,7 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
+import android.view.PointerIcon;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
@@ -4402,6 +4403,17 @@
}
@Override
+ public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
+ if (mFastScroll != null) {
+ PointerIcon pointerIcon = mFastScroll.onResolvePointerIcon(event, pointerIndex);
+ if (pointerIcon != null) {
+ return pointerIcon;
+ }
+ }
+ return super.onResolvePointerIcon(event, pointerIndex);
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int actionMasked = ev.getActionMasked();
View v;
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 559181b..198bf27 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -38,6 +38,7 @@
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
+import android.view.PointerIcon;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
@@ -1441,6 +1442,13 @@
return false;
}
+ public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
+ if (mState == STATE_DRAGGING || isPointInside(event.getX(), event.getY())) {
+ return PointerIcon.getSystemIcon(mList.getContext(), PointerIcon.TYPE_ARROW);
+ }
+ return null;
+ }
+
public boolean onTouchEvent(MotionEvent me) {
if (!isEnabled()) {
return false;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 3c1a180..2d0ddef 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -123,6 +123,13 @@
bindProfileView();
}
}
+
+ @Override
+ public boolean onPackageChanged(String packageName, int uid, String[] components) {
+ // We care about all package changes, not just the whole package itself which is
+ // default behavior.
+ return true;
+ }
};
/**
@@ -1555,7 +1562,15 @@
}
public void onListRebuilt() {
- // This space for rent
+ int count = getUnfilteredCount();
+ if (count == 1 && getOtherProfile() == null) {
+ // Only one target, so we're a candidate to auto-launch!
+ final TargetInfo target = targetInfoForPosition(0, false);
+ if (shouldAutoLaunchSingleChoice(target)) {
+ safelyStartActivity(target);
+ finish();
+ }
+ }
}
public boolean shouldGetResolvedFilter() {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 0b5a1b7..310cbc7 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -584,6 +584,7 @@
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
+ OsConstants.CAP_SYS_PTRACE,
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cd02fbb..97fbfa5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1813,6 +1813,22 @@
android:description="@string/permdesc_systemAlertWindow"
android:protectionLevel="signature|preinstalled|appop|pre23|development" />
+ <!-- Allows an app to run in the background.
+ <p>Protection level: signature
+ -->
+ <permission android:name="android.permission.RUN_IN_BACKGROUND"
+ android:label="@string/permlab_runInBackground"
+ android:description="@string/permdesc_runInBackground"
+ android:protectionLevel="signature" />
+
+ <!-- Allows an app to use data in the background.
+ <p>Protection level: signature
+ -->
+ <permission android:name="android.permission.USE_DATA_IN_BACKGROUND"
+ android:label="@string/permlab_useDataInBackground"
+ android:description="@string/permdesc_useDataInBackground"
+ android:protectionLevel="signature" />
+
<!-- ================================== -->
<!-- Permissions affecting the system wallpaper -->
<!-- ================================== -->
@@ -2996,7 +3012,7 @@
any metadata and intents attached.
@hide -->
<permission android:name="android.permission.ACCESS_NOTIFICATIONS"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature|privileged|appop" />
<!-- Marker permission for applications that wish to access notification policy.
<p>Protection level: normal
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2309866..8faa76c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -816,6 +816,16 @@
<string name="permdesc_systemAlertWindow">This app can appear on top of other apps or other parts of the screen. This may interfere with normal app usage and change the way that other apps appear.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_runInBackground">run in the background</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_runInBackground">This app can run in the background. This may drain battery faster.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_useDataInBackground">use data in the background</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_useDataInBackground">This app can use data in the background. This may increase data usage.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_persistentActivity">make app always run</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_persistentActivity" product="tablet">Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the tablet.</string>
diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
index a260e94..864b48a 100644
--- a/core/tests/coretests/src/android/text/method/BackspaceTest.java
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -37,23 +37,12 @@
// Sync the state to the TextView and call onKeyDown with KEYCODE_DEL key event.
// Then update the state to the result of TextView.
private void backspace(final EditorState state, int modifiers) {
- mActivity.runOnUiThread(new Runnable() {
- public void run() {
- mTextView.setText(state.mText, BufferType.EDITABLE);
- mTextView.setKeyListener(mKeyListener);
- mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
- }
- });
- mInstrumentation.waitForIdleSync();
- assertTrue(mTextView.hasWindowFocus());
+ mTextView.setText(state.mText, BufferType.EDITABLE);
+ mTextView.setKeyListener(mKeyListener);
+ mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_DEL, modifiers);
- mActivity.runOnUiThread(new Runnable() {
- public void run() {
- mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
- }
- });
- mInstrumentation.waitForIdleSync();
+ mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
state.mText = mTextView.getText();
state.mSelectionStart = mTextView.getSelectionStart();
@@ -247,6 +236,51 @@
state.assertEquals("U+1F1FA U+1F1F8 |");
backspace(state, 0);
state.assertEquals("|");
+
+ // Incomplete sequence. (no tag_term: U+E007E)
+ state.setByString("'a' U+1F3F4 U+E0067 'b' |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+1F3F4 U+E0067 |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+1F3F4 |");
+ backspace(state, 0);
+ state.assertEquals("'a' |");
+
+ // No tag_base
+ state.setByString("'a' U+E0067 U+E007F 'b' |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+E0067 U+E007F |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+E0067 |");
+ backspace(state, 0);
+ state.assertEquals("'a' |");
+
+ // Isolated tag chars
+ state.setByString("'a' U+E0067 U+E0067 'b' |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+E0067 U+E0067 |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+E0067 |");
+ backspace(state, 0);
+ state.assertEquals("'a' |");
+
+ // Isolated tab term.
+ state.setByString("'a' U+E007F U+E007F 'b' |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+E007F U+E007F |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+E007F |");
+ backspace(state, 0);
+ state.assertEquals("'a' |");
+
+ // Immediate tag_term after tag_base
+ state.setByString("'a' U+1F3F4 U+E007F U+1F3F4 U+E007F 'b' |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+1F3F4 U+E007F U+1F3F4 U+E007F |");
+ backspace(state, 0);
+ state.assertEquals("'a' U+1F3F4 U+E007F |");
+ backspace(state, 0);
+ state.assertEquals("'a' |");
}
@SmallTest
diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
index 1990fd0..839d380 100644
--- a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
+++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
@@ -37,23 +37,12 @@
// Sync the state to the TextView and call onKeyDown with KEYCODE_FORWARD_DEL key event.
// Then update the state to the result of TextView.
private void forwardDelete(final EditorState state, int modifiers) {
- mActivity.runOnUiThread(new Runnable() {
- public void run() {
- mTextView.setText(state.mText, BufferType.EDITABLE);
- mTextView.setKeyListener(mKeyListener);
- mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
- }
- });
- mInstrumentation.waitForIdleSync();
- assertTrue(mTextView.hasWindowFocus());
+ mTextView.setText(state.mText, BufferType.EDITABLE);
+ mTextView.setKeyListener(mKeyListener);
+ mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_FORWARD_DEL, modifiers);
- mActivity.runOnUiThread(new Runnable() {
- public void run() {
- mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
- }
- });
- mInstrumentation.waitForIdleSync();
+ mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
state.mText = mTextView.getText();
state.mSelectionStart = mTextView.getSelectionStart();
@@ -186,6 +175,46 @@
state.assertEquals("| U+1F1FA");
forwardDelete(state, 0);
state.assertEquals("|");
+
+ // Incomplete sequence. (no tag_term:U+E007E)
+ state.setByString("| 'a' U+1F3F4 U+E0067 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3F4 U+E0067 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'b'");
+
+ // No tag_base
+ state.setByString("| 'a' U+E0067 U+E007F 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'b'");
+
+ // Isolated tag chars
+ state.setByString("| 'a' U+E0067 U+E0067 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'b'");
+
+ // Isolated tag base.
+ state.setByString("| 'a' U+1F3F4 U+1F3F4 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3F4 U+1F3F4 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3F4 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'b'");
+
+ // Isolated tab term.
+ state.setByString("| 'a' U+E007F U+E007F 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'b'");
+
+ // Immediate tag_term after tag_base
+ state.setByString("| 'a' U+1F3F4 U+E007F U+1F3F4 U+E007F 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3F4 U+E007F U+1F3F4 U+E007F 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3F4 U+E007F 'b'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'b'");
}
@SmallTest
diff --git a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java b/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
index 4b4e7af..f005d7b 100644
--- a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
+++ b/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
@@ -17,41 +17,26 @@
package android.text.method;
import android.app.Instrumentation;
-import android.test.ActivityInstrumentationTestCase2;
-import android.text.format.DateUtils;
+import android.test.InstrumentationTestCase;
import android.view.KeyEvent;
import android.widget.EditText;
-import android.widget.TextViewActivity;
import com.android.frameworks.coretests.R;
-public abstract class KeyListenerTestCase extends
- ActivityInstrumentationTestCase2<TextViewActivity> {
+public abstract class KeyListenerTestCase extends InstrumentationTestCase {
- protected TextViewActivity mActivity;
protected Instrumentation mInstrumentation;
protected EditText mTextView;
public KeyListenerTestCase() {
- super(TextViewActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
- mActivity = getActivity();
mInstrumentation = getInstrumentation();
- mTextView = (EditText) mActivity.findViewById(R.id.textview);
-
- mActivity.runOnUiThread(new Runnable() {
- public void run() {
- // Ensure that the screen is on for this test.
- mTextView.setKeepScreenOn(true);
- }
- });
-
- assertTrue(mActivity.waitForWindowFocus(5 * DateUtils.SECOND_IN_MILLIS));
+ mTextView = new EditText(mInstrumentation.getContext());
}
protected static KeyEvent getKey(int keycode, int metaState) {
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 80832f8..aacce91 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -32,9 +32,8 @@
import java.util.Map;
/**
- * MediaMuxer facilitates muxing elementary streams. Currently supports mp4 or
- * webm file as the output and at most one audio and/or one video elementary
- * stream. MediaMuxer does not support muxing B-frames.
+ * MediaMuxer facilitates muxing elementary streams. Currently MediaMuxer supports MP4, Webm
+ * and 3GP file as the output. It also supports muxing B-frames in MP4 since Android Nougat.
* <p>
* It is generally used like this:
*
@@ -65,6 +64,182 @@
* muxer.stop();
* muxer.release();
* </pre>
+ *
+
+ <h4>Metadata Track</h4>
+ <p>
+ Metadata is usefule in carrying extra information that correlated with video or audio to
+ facilate offline processing, e.g. gyro signals from the sensor. Meatadata track is only
+ supported in MP4 format. When adding a metadata track, track's mime format must start with
+ prefix "application/", e.g. "applicaton/gyro". Metadata's format/layout will be defined by
+ the application. The generated MP4 file uses TextMetaDataSampleEntry defined in section 12.3.3.2
+ of the ISOBMFF to signal the metadata's mime format. When using {@link android.media.MediaExtractor}
+ to extract the file with metadata track, the mime format of the metadata will be extracted into
+ {@link android.media.MediaFormat}.
+
+ <pre class=prettyprint>
+ MediaMuxer muxer = new MediaMuxer("temp.mp4", OutputFormat.MUXER_OUTPUT_MPEG_4);
+ // More often, the MediaFormat will be retrieved from MediaCodec.getOutputFormat()
+ // or MediaExtractor.getTrackFormat().
+ MediaFormat audioFormat = new MediaFormat(...);
+ MediaFormat videoFormat = new MediaFormat(...);
+
+ // Setup Metadata Track
+ MediaFormat metadataFormat = new MediaFormat(...);
+ metadataFormat.setString(KEY_MIME, "application/gyro");
+
+ int audioTrackIndex = muxer.addTrack(audioFormat);
+ int videoTrackIndex = muxer.addTrack(videoFormat);
+ int metadataTrackIndex = muxer.addTrack(metadataFormat);
+ ByteBuffer inputBuffer = ByteBuffer.allocate(bufferSize);
+ boolean finished = false;
+ BufferInfo bufferInfo = new BufferInfo();
+
+ muxer.start();
+ while(!finished) {
+ // getInputBuffer() will fill the inputBuffer with one frame of encoded
+ // sample from either MediaCodec or MediaExtractor, set isAudioSample to
+ // true when the sample is audio data, set up all the fields of bufferInfo,
+ // and return true if there are no more samples.
+ finished = getInputBuffer(inputBuffer, sampleType, bufferInfo);
+ if (!finished) {
+ int currentTrackIndex = getTrackIndex(sampleType);
+ muxer.writeSampleData(currentTrackIndex, inputBuffer, bufferInfo);
+ }
+ };
+ muxer.stop();
+ muxer.release();
+ }</pre>
+
+ <h2 id=History><a name="History"></a>Features and API History</h2>
+ <p>
+ The following table summarizes the feature support in different API version and containers.
+ For API version numbers, see {@link android.os.Build.VERSION_CODES}.
+
+ <style>
+ .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, .sml > tr > td { text-align: center; padding: 2px 4px; }
+ .fn { text-align: center; }
+ </style>
+
+ <table align="right" style="width: 0%">
+ <thead>
+ <tbody class=api>
+ <tr><th>Symbol</th>
+ <th>Meaning</th></tr>
+ </tbody>
+ </thead>
+ <tbody class=sml>
+ <tr><td>●</td><td>Supported</td></tr>
+ <tr><td>○</td><td>Not supported</td></tr>
+ <tr><td>▧</td><td>Supported in MP4/WebM/3GP</td></tr>
+ <tr><td>⁕</td><td>Only Supported in MP4</td></tr>
+ </tbody>
+ </table>
+<table align="center" style="width: 100%;">
+ <thead class=api>
+ <tr>
+ <th rowspan=2>Feature</th>
+ <th colspan="24">SDK Version</th>
+ </tr>
+ <tr>
+ <th>18</th>
+ <th>19</th>
+ <th>20</th>
+ <th>21</th>
+ <th>22</th>
+ <th>23</th>
+ <th>24</th>
+ <th>25</th>
+ <th>26+</th>
+ </tr>
+ </thead>
+ <tbody class=api>
+ <tr>
+ <td align="center">MP4 container</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ </tr>
+ <td align="center">WebM container</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ <td>●</td>
+ </tr>
+ <td align="center">3GP container</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>●</td>
+ </tr>
+ <td align="center">Muxing B-Frames(bi-directional predicted frames)</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>⁕</td>
+ <td>⁕</td>
+ <td>⁕</td>
+ </tr>
+ </tr>
+ <td align="center">Muxing Single Video/Audio Track</td>
+ <td>▧</td>
+ <td>▧</td>
+ <td>▧</td>
+ <td>▧</td>
+ <td>▧</td>
+ <td>▧</td>
+ <td>▧</td>
+ <td>▧</td>
+ <td>▧</td>
+ </tr>
+ </tr>
+ <td align="center">Muxing Multiple Video/Audio Tracks</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>⁕</td>
+ </tr>
+ </tr>
+ <td align="center">Muxing Metadata Tracks</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>○</td>
+ <td>⁕</td>
+ </tr>
+ </tbody>
+ </table>
*/
final public class MediaMuxer {
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 45f88f3..efb1ed7 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1300,6 +1300,18 @@
public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
/**
+ * The internal ID used by individual TV input services.
+ *
+ * <p>This is internal to the provider that inserted it, and should not be decoded by other
+ * apps.
+ *
+ * <p>Can be empty.
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+
+ /**
* Internal data used by individual TV input services.
*
* <p>This is internal to the provider that inserted it, and should not be decoded by other
diff --git a/obex/javax/obex/ServerSession.java b/obex/javax/obex/ServerSession.java
index acee5dd..3831cf7 100644
--- a/obex/javax/obex/ServerSession.java
+++ b/obex/javax/obex/ServerSession.java
@@ -658,6 +658,11 @@
*/
byte[] sendData = new byte[totalLength];
int maxRxLength = ObexHelper.getMaxRxPacketSize(mTransport);
+ if (maxRxLength > mMaxPacketLength) {
+ if(V) Log.v(TAG,"Set maxRxLength to min of maxRxServrLen:" + maxRxLength +
+ " and MaxNegotiated from Client: " + mMaxPacketLength);
+ maxRxLength = mMaxPacketLength;
+ }
sendData[0] = (byte)code;
sendData[1] = length[2];
sendData[2] = length[3];
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index 8a970da..25127ef 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -33,7 +33,6 @@
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import android.widget.Toast;
public class DeviceChooserActivity extends Activity {
@@ -129,12 +128,9 @@
}
protected void onPairTapped(BluetoothDevice selectedDevice) {
+ getService().onDeviceSelected();
setResult(RESULT_OK,
new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice));
finish();
}
-
- private void toast(String msg) {
- Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
- }
}
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index ccbee2a..11c722d 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -32,16 +32,15 @@
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.companion.AssociationRequest;
-import android.companion.BluetoothDeviceFilterUtils;
import android.companion.BluetoothLEDeviceFilter;
-import android.companion.ICompanionDeviceManagerService;
-import android.companion.IOnAssociateCallback;
+import android.companion.ICompanionDeviceDiscoveryService;
+import android.companion.ICompanionDeviceDiscoveryServiceCallback;
+import android.companion.IFindDeviceCallback;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
-import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.os.RemoteException;
@@ -70,21 +69,25 @@
List<BluetoothDevice> mDevicesFound;
BluetoothDevice mSelectedDevice;
DevicesAdapter mDevicesAdapter;
- IOnAssociateCallback mCallback;
+ IFindDeviceCallback mFindCallback;
+ ICompanionDeviceDiscoveryServiceCallback mServiceCallback;
String mCallingPackage;
- private final ICompanionDeviceManagerService mBinder =
- new ICompanionDeviceManagerService.Stub() {
+ private final ICompanionDeviceDiscoveryService mBinder =
+ new ICompanionDeviceDiscoveryService.Stub() {
@Override
public void startDiscovery(AssociationRequest request,
- IOnAssociateCallback callback,
- String callingPackage) throws RemoteException {
+ String callingPackage,
+ IFindDeviceCallback findCallback,
+ ICompanionDeviceDiscoveryServiceCallback serviceCallback) {
if (DEBUG) {
Log.i(LOG_TAG,
- "startDiscovery() called with: filter = [" + request + "], callback = ["
- + callback + "]");
+ "startDiscovery() called with: filter = [" + request
+ + "], findCallback = [" + findCallback + "]"
+ + "], serviceCallback = [" + serviceCallback + "]");
}
- mCallback = callback;
+ mFindCallback = findCallback;
+ mServiceCallback = serviceCallback;
mCallingPackage = callingPackage;
DeviceDiscoveryService.this.startDiscovery(request);
}
@@ -171,6 +174,14 @@
return super.onUnbind(intent);
}
+ public void onDeviceSelected() {
+ try {
+ mServiceCallback.onDeviceSelected(mCallingPackage, getUserId());
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Error reporting selected device");
+ }
+ }
+
private void stopScan() {
if (DEBUG) Log.i(LOG_TAG, "stopScan() called");
mBluetoothAdapter.cancelDiscovery();
@@ -205,7 +216,7 @@
//TODO also, on timeout -> call onFailure
private void onReadyToShowUI() {
try {
- mCallback.onSuccess(PendingIntent.getActivity(
+ mFindCallback.onSuccess(PendingIntent.getActivity(
this, 0,
new Intent(this, DeviceChooserActivity.class),
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index d4c7c7a..2e115ab 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -154,8 +154,8 @@
android:name=".BugreportReceiver"
android:permission="android.permission.DUMP">
<intent-filter>
- <action android:name="android.intent.action.BUGREPORT_STARTED" />
- <action android:name="android.intent.action.BUGREPORT_FINISHED" />
+ <action android:name="com.android.internal.intent.action.BUGREPORT_STARTED" />
+ <action android:name="com.android.internal.intent.action.BUGREPORT_FINISHED" />
</intent-filter>
</receiver>
@@ -163,7 +163,7 @@
android:name=".RemoteBugreportReceiver"
android:permission="android.permission.DUMP">
<intent-filter>
- <action android:name="android.intent.action.REMOTE_BUGREPORT_FINISHED" />
+ <action android:name="com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED" />
</intent-filter>
</receiver>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 17d0a09..12d0c03 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -133,10 +133,12 @@
private static final String AUTHORITY = "com.android.shell";
// External intents sent by dumpstate.
- static final String INTENT_BUGREPORT_STARTED = "android.intent.action.BUGREPORT_STARTED";
- static final String INTENT_BUGREPORT_FINISHED = "android.intent.action.BUGREPORT_FINISHED";
+ static final String INTENT_BUGREPORT_STARTED =
+ "com.android.internal.intent.action.BUGREPORT_STARTED";
+ static final String INTENT_BUGREPORT_FINISHED =
+ "com.android.internal.intent.action.BUGREPORT_FINISHED";
static final String INTENT_REMOTE_BUGREPORT_FINISHED =
- "android.intent.action.REMOTE_BUGREPORT_FINISHED";
+ "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
// Internal intents used on notification actions.
static final String INTENT_BUGREPORT_CANCEL = "android.intent.action.BUGREPORT_CANCEL";
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java
index bc98c8e..529c421 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java
@@ -43,6 +43,8 @@
public View getContentView();
public boolean handleCloseControls(boolean save);
+
+ public boolean willBeRemoved();
}
public interface SnoozeGutsContent extends GutsContent {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index cb4306f..bfe4bb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -902,6 +902,9 @@
* @return whether the notification is currently showing a view with an icon.
*/
public boolean isShowingIcon() {
+ if (areGutsExposed()) {
+ return false;
+ }
if (mIsSummaryWithChildren) {
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index b36cfdc..fd1317e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -244,6 +244,10 @@
}
}
+ public boolean willBeRemoved() {
+ return mGutsContent != null ? mGutsContent.willBeRemoved() : false;
+ }
+
public boolean isExposed() {
return mExposed;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 5d13e61..9703235 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -274,6 +274,11 @@
}
@Override
+ public boolean willBeRemoved() {
+ return !mChannelEnabledSwitch.isChecked();
+ }
+
+ @Override
public View getContentView() {
return this;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index d4ed1dc..1cd909ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -380,11 +380,12 @@
: 0.0f;
row.setContentTransformationAmount(contentTransformationAmount, isLastChild);
setIconTransformationAmount(row, transitionAmount, iconTransformDistance,
- clampedAmount != transitionAmount);
+ clampedAmount != transitionAmount, isLastChild);
}
private void setIconTransformationAmount(ExpandableNotificationRow row,
- float transitionAmount, float iconTransformDistance, boolean usingLinearInterpolation) {
+ float transitionAmount, float iconTransformDistance, boolean usingLinearInterpolation,
+ boolean isLastChild) {
StatusBarIconView icon = row.getEntry().expandedIcon;
NotificationIconContainer.IconState iconState = getIconState(icon);
@@ -437,7 +438,7 @@
iconState.scaleY = 1.0f;
iconState.hidden = false;
}
- if (row.isAboveShelf()) {
+ if (row.isAboveShelf() || (!row.isInShelf() && isLastChild && row.areGutsExposed())) {
iconState.hidden = true;
}
int shelfColor = icon.getStaticDrawableColor();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index 0657dc1..6b1e62d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -56,6 +56,7 @@
private TextView mUndoButton;
private ViewGroup mSnoozeOptionView;
private List<SnoozeOption> mSnoozeOptions;
+ private boolean mSnoozing;
private SnoozeOption mSelectedOption;
@@ -175,6 +176,11 @@
}
@Override
+ public boolean willBeRemoved() {
+ return mSnoozing;
+ }
+
+ @Override
public View getContentView() {
return this;
}
@@ -199,6 +205,7 @@
// When snooze is closed (i.e. there was interaction outside of the notification)
// then we commit the snooze action.
if (mSnoozeListener != null && mSelectedOption != null) {
+ mSnoozing = true;
mSnoozeListener.snoozeNotification(mSbn, mSelectedOption);
return true;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 3d6e4b3..dd04741 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -5760,7 +5760,7 @@
row.setTag(sbn.getPackageName());
final NotificationGuts guts = row.getGuts();
guts.setClosedListener((NotificationGuts g) -> {
- if (!row.isRemoved()) {
+ if (!g.willBeRemoved() && !row.isRemoved()) {
mStackScroller.onHeightChanged(row, !isPanelFullyCollapsed() /* needsAnimation */);
}
mNotificationGutsExposed = null;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/leak/LeakReporterTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/leak/LeakReporterTest.java
index 96a9bee..1194849 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/leak/LeakReporterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/leak/LeakReporterTest.java
@@ -30,6 +30,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -71,18 +72,21 @@
mLeakDir.delete();
}
+ @Ignore("slow")
@Test
public void testDump_postsNotification() {
mLeakReporter.dumpLeak(5);
verify(mNotificationManager).notify(any(), anyInt(), any());
}
+ @Ignore("slow")
@Test
public void testDump_Repeated() {
mLeakReporter.dumpLeak(1);
mLeakReporter.dumpLeak(2);
}
+ @Ignore("slow")
@Test
public void testDump_ProducesNonZeroFiles() {
mLeakReporter.dumpLeak(5);
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 36dee49..8d2f0c3 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3416,6 +3416,19 @@
// ACTION: Settings advanced button is expanded
ACTION_SETTINGS_ADVANCED_BUTTON_EXPAND = 834;
+ // ACTION: Logs the number of times the saved network evaluator was used to
+ // recommend a wifi network
+ WIFI_NETWORK_RECOMMENDATION_SAVED_NETWORK_EVALUATOR = 835;
+
+ // ACTION: Logs the number of times the recommended network evaluator was
+ // used to recommend a wifi network
+ WIFI_NETWORK_RECOMMENDATION_RECOMMENDED_NETWORK_EVALUATOR = 836;
+
+ // ACTION: Logs the number of times a recommended network was resulted in a
+ // successful connection
+ // VALUE: true if the connection was successful, false if the connection failed
+ WIFI_NETWORK_RECOMMENDATION_CONNECTION_SUCCESS = 837;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index 85bf5c2..a697a8e 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -737,29 +737,7 @@
private void callSaveLocked() {
if (DEBUG) Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
- // TODO(b/33197203): hookup extras and make sure they're tested by CTS
- final Bundle extras = null;
-// // TODO(b/33197203): make sure the extras are tested by CTS
-// final Bundle responseExtras = mCurrentResponse == null ? null
-// : mCurrentResponse.getExtras();
-// final Bundle datasetExtras = mAutoFilledDataset == null ? null
-// : mAutoFilledDataset.getExtras();
-// final Bundle extras = (responseExtras == null && datasetExtras == null)
-// ? null : new Bundle();
-// if (responseExtras != null) {
-// if (DEBUG) {
-// Slog.d(TAG, "response extras on save extras: "
-// + bundleToString(responseExtras));
-// }
-// extras.putBundle(AutoFillService.EXTRA_RESPONSE_EXTRAS, responseExtras);
-// }
-// if (datasetExtras != null) {
-// if (DEBUG) {
-// Slog.d(TAG, "dataset extras on save extras: " + bundleToString(datasetExtras));
-// }
-// extras.putBundle(AutoFillService.EXTRA_DATASET_EXTRAS, datasetExtras);
-// }
-
+ final Bundle extras = this.mCurrentResponse.getExtras();
for (Entry<AutoFillId, ViewState> entry : mViewStates.entrySet()) {
final AutoFillValue value = entry.getValue().mAutoFillValue;
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 767fb46..c469718 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -191,7 +191,7 @@
ensureBound();
} else {
if (DEBUG) {
- Slog.d(LOG_TAG, "[user: " + mUserId + "] handleOnFillRequest()");
+ Slog.d(LOG_TAG, "[user: " + mUserId + "] handlePendingRequest()");
}
pendingRequest.run();
}
@@ -235,8 +235,19 @@
}
mBinding = false;
if (isBound()) {
- mAutoFillService.asBinder().unlinkToDeath(this, 0);
- mAutoFillService = null;
+ // TODO(b/33197203, b/35395043): synchronize access instead
+ // Need to double check if it's null, since it could be set on onServiceDisconnected()
+ if (mAutoFillService != null) {
+ try {
+ mAutoFillService.onDisconnected();
+ } catch (Exception e) {
+ Slog.w(LOG_TAG, "Exception calling onDisconnected(): " + e);
+ }
+ }
+ if (mAutoFillService != null) {
+ mAutoFillService.asBinder().unlinkToDeath(this, 0);
+ mAutoFillService = null;
+ }
}
mContext.unbindService(mServiceConnection);
}
@@ -305,6 +316,18 @@
return;
}
+ try {
+ // TODO(b/33197203, b/35395043): synchronize access instead
+ // Need to double check if it's null, since it could be set on
+ // onServiceDisconnected()
+ if (mAutoFillService != null) {
+ mAutoFillService.onConnected();
+ }
+ } catch (RemoteException e) {
+ Slog.w(LOG_TAG, "Exception calling onConnected(): " + e);
+ }
+
+
if (mPendingRequest != null) {
handlePendingRequest(mPendingRequest);
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 13e6ae0..4c22da3 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -2400,14 +2400,19 @@
}
final long oldToken = Binder.clearCallingIdentity();
try {
+ List<Integer> operationsToCancel = new ArrayList<>();
synchronized (mCurrentOpLock) {
for (int i = 0; i < mCurrentOperations.size(); i++) {
Operation op = mCurrentOperations.valueAt(i);
int token = mCurrentOperations.keyAt(i);
if (op.type == OP_TYPE_BACKUP) {
- handleCancel(token, true /* cancelAll */);
+ operationsToCancel.add(token);
}
}
+
+ for (Integer token : operationsToCancel) {
+ handleCancel(token, true /* cancelAll */);
+ }
}
// We don't want the backup jobs to kick in any time soon.
@@ -2607,6 +2612,7 @@
boolean userInitiated, boolean nonIncremental) {
mTransport = transport;
mOriginalQueue = queue;
+ mQueue = new ArrayList<>();
mJournal = journal;
mObserver = observer;
mMonitor = monitor;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 719a64e..fe0b840 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4166,7 +4166,7 @@
}
ensureRequestableCapabilities(networkCapabilities);
- if (timeoutMs < 0 || timeoutMs > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS) {
+ if (timeoutMs < 0) {
throw new IllegalArgumentException("Bad timeout specified");
}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index e6f6e57..8442c11 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -2033,10 +2033,6 @@
@Override
public void setImeWindowStatus(IBinder token, IBinder startInputToken, int vis,
int backDisposition) {
- if (startInputToken == null) {
- throw new InvalidParameterException("startInputToken cannot be null");
- }
-
if (!calledWithValidToken(token)) {
return;
}
@@ -2044,15 +2040,13 @@
final StartInputInfo info;
synchronized (mMethodMap) {
info = mStartInputMap.get(startInputToken);
- if (info == null) {
- throw new InvalidParameterException("Unknown startInputToken=" + startInputToken);
- }
mImeWindowVis = vis;
mBackDisposition = backDisposition;
updateSystemUiLocked(token, vis, backDisposition);
}
- mWindowManagerInternal.updateInputMethodWindowStatus(info.mImeToken,
- (vis & InputMethodService.IME_VISIBLE) != 0, info.mTargetWindow);
+ mWindowManagerInternal.updateInputMethodWindowStatus(token,
+ (vis & InputMethodService.IME_VISIBLE) != 0,
+ token != null ? info.mTargetWindow : null);
}
private void updateSystemUi(IBinder token, int vis, int backDisposition) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a73eb18..35c2462 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -241,6 +241,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.location.LocationManager;
+import android.media.audiofx.AudioEffect;
import android.metrics.LogMaker;
import android.net.Proxy;
import android.net.ProxyInfo;
@@ -556,7 +557,7 @@
// Intent sent when remote bugreport collection has been completed
private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
- "android.intent.action.REMOTE_BUGREPORT_FINISHED";
+ "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
// Used to indicate that an app transition should be animated.
static final boolean ANIMATE = true;
@@ -18257,7 +18258,9 @@
|| AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
|| LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
|| TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
- || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
+ || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
+ || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
+ || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
// Broadcast is either protected, or it's a public action that
// we've relaxed, so it's fine for system internals to send.
return;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 1b19382..082b6b5 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -22,7 +22,6 @@
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.AppOpsManager.MODE_ALLOWED;
@@ -47,7 +46,6 @@
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Build.VERSION_CODES.O;
@@ -85,7 +83,6 @@
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Rect;
-import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
@@ -290,8 +287,8 @@
/**
* Temp configs used in {@link #ensureActivityConfigurationLocked(int, boolean)}
*/
- private final Configuration mTmpGlobalConfig = new Configuration();
- private final Configuration mTmpTaskConfig = new Configuration();
+ private final Configuration mTmpConfig1 = new Configuration();
+ private final Configuration mTmpConfig2 = new Configuration();
private static String startingWindowStateToString(int state) {
switch (state) {
@@ -1975,13 +1972,13 @@
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Ensuring correct configuration: " + this);
- // Short circuit: if the two configurations are equal (the common case), then there is
- // nothing to do.
- final Configuration newGlobalConfig = service.getGlobalConfiguration();
- final Configuration newTaskMergedOverrideConfig = task.getMergedOverrideConfiguration();
- if (mLastReportedConfiguration.equals(newGlobalConfig)
- && mLastReportedOverrideConfiguration.equals(newTaskMergedOverrideConfig)
- && !forceNewConfig) {
+ // Short circuit: if the two full configurations are equal (the common case), then there is
+ // nothing to do. We test the full configuration instead of the global and merged override
+ // configurations because there are cases (like moving a task to the pinned stack) where
+ // the combine configurations are equal, but would otherwise differ in the override config
+ mTmpConfig1.setTo(mLastReportedConfiguration);
+ mTmpConfig1.updateFrom(mLastReportedOverrideConfiguration);
+ if (task.getConfiguration().equals(mTmpConfig1) && !forceNewConfig) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Configuration unchanged in " + this);
return true;
@@ -1997,14 +1994,16 @@
// Okay we now are going to make this activity have the new config.
// But then we need to figure out how it needs to deal with that.
- mTmpGlobalConfig.setTo(mLastReportedConfiguration);
- mTmpTaskConfig.setTo(mLastReportedOverrideConfiguration);
+ final Configuration newGlobalConfig = service.getGlobalConfiguration();
+ final Configuration newTaskMergedOverrideConfig = task.getMergedOverrideConfiguration();
+ mTmpConfig1.setTo(mLastReportedConfiguration);
+ mTmpConfig2.setTo(mLastReportedOverrideConfiguration);
mLastReportedConfiguration.setTo(newGlobalConfig);
mLastReportedOverrideConfiguration.setTo(newTaskMergedOverrideConfig);
int taskChanges = getTaskConfigurationChanges(this, newTaskMergedOverrideConfig,
- mTmpTaskConfig);
- final int changes = mTmpGlobalConfig.diff(newGlobalConfig) | taskChanges;
+ mTmpConfig2);
+ final int changes = mTmpConfig1.diff(newGlobalConfig) | taskChanges;
if (changes == 0 && !forceNewConfig) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Configuration no differences in " + this);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 7c24604..f75ce25 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2507,7 +2507,7 @@
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
- mStackSupervisor.isFrontStack(lastStack)) {
+ mStackSupervisor.isFrontStackOnDisplay(lastStack)) {
next.showStartingWindow(null /* prev */, false /* newTask */,
false /* taskSwitch */);
}
@@ -4354,7 +4354,7 @@
// If we have a watcher, preflight the move before committing to it. First check
// for *other* available tasks, but if none are available, then try again allowing the
// current task to be selected.
- if (mStackSupervisor.isFrontStack(this) && mService.mController != null) {
+ if (mStackSupervisor.isFrontStackOnDisplay(this) && mService.mController != null) {
ActivityRecord next = topRunningActivityLocked(null, taskId);
if (next == null) {
next = topRunningActivityLocked(null, 0);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 95734a4..4a29872 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -624,11 +624,6 @@
return stack == mFocusedStack;
}
- /** The top most stack. */
- boolean isFrontStack(ActivityStack stack) {
- return isFrontOfStackList(stack, mHomeStack.mStacks);
- }
-
/** The top most stack on its display. */
boolean isFrontStackOnDisplay(ActivityStack stack) {
return isFrontOfStackList(stack, stack.mActivityContainer.mActivityDisplay.mStacks);
@@ -1103,13 +1098,21 @@
}
// Look in other non-focused and non-home stacks.
- final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = stacks.get(stackNdx);
- if (stack != focusedStack && isFrontStack(stack) && stack.isFocusable()) {
- r = stack.topRunningActivityLocked();
- if (r != null) {
- return r;
+ mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
+
+ for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
+ final int displayId = mTmpOrderedDisplayIds.get(i);
+ final List<ActivityStack> stacks = mActivityDisplays.get(displayId).mStacks;
+ if (stacks == null) {
+ continue;
+ }
+ for (int j = stacks.size() - 1; j >= 0; --j) {
+ final ActivityStack stack = stacks.get(j);
+ if (stack != focusedStack && isFrontStackOnDisplay(stack) && stack.isFocusable()) {
+ r = stack.topRunningActivityLocked();
+ if (r != null) {
+ return r;
+ }
}
}
}
@@ -2676,7 +2679,7 @@
// In some cases the focused stack isn't the front stack. E.g. pinned stack.
// Whenever we are moving the top activity from the front stack we want to make sure to move
// the stack to the front.
- final boolean wasFront = isFrontStack(prevStack)
+ final boolean wasFront = isFrontStackOnDisplay(prevStack)
&& (prevStack.topRunningActivityLocked() == r);
if (stackId == DOCKED_STACK_ID && !task.isResizeable()) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 520d4ee..f8645d6 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -35,7 +35,6 @@
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
-import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Debug;
@@ -52,6 +51,7 @@
import com.android.internal.util.XmlUtils;
import com.android.server.wm.AppWindowContainerController;
+import com.android.server.wm.StackWindowController;
import com.android.server.wm.TaskWindowContainerController;
import com.android.server.wm.TaskWindowContainerListener;
@@ -278,7 +278,6 @@
private final Rect mTmpStableBounds = new Rect();
private final Rect mTmpNonDecorBounds = new Rect();
private final Rect mTmpRect = new Rect();
- private final Rect mTmpRect2 = new Rect();
// Last non-fullscreen bounds the task was launched in or resized to.
// The information is persisted and used to determine the appropriate stack to launch the
@@ -1838,66 +1837,38 @@
return !mTmpConfig.equals(newConfig);
}
- private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds,
- boolean overrideWidth, boolean overrideHeight) {
- mTmpRect2.set(inInsetBounds);
- mService.mWindowManager.subtractNonDecorInsets(mTmpRect2);
- int leftInset = mTmpRect2.left - inInsetBounds.left;
- int topInset = mTmpRect2.top - inInsetBounds.top;
- int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right;
- int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom;
- inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
- }
-
- private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds,
- boolean overrideWidth, boolean overrideHeight) {
- mTmpRect2.set(inInsetBounds);
- mService.mWindowManager.subtractStableInsets(mTmpRect2);
- int leftInset = mTmpRect2.left - inInsetBounds.left;
- int topInset = mTmpRect2.top - inInsetBounds.top;
- int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right;
- int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom;
- inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
- }
-
/** Clears passed config and fills it with new override values. */
private void calculateOverrideConfig(Configuration config, Rect bounds, Rect insetBounds,
boolean overrideWidth, boolean overrideHeight) {
mTmpNonDecorBounds.set(bounds);
mTmpStableBounds.set(bounds);
- final Configuration parentConfig = getParent().getConfiguration();
config.unset();
+ final Configuration parentConfig = getParent().getConfiguration();
final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
- final boolean isFloatingTask = mStack != null && StackId.tasksAreFloating(mStack.mStackId);
- if (isFloatingTask) {
- // Floating tasks should not be resized to the screen's bounds.
- config.screenWidthDp = (int) (mTmpStableBounds.width() / density);
- config.screenHeightDp = (int) (mTmpStableBounds.height() / density);
- } else {
- // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen area,
- // i.e. the screen area without the system bars.
- // Additionally task dimensions should not be bigger than its parents dimensions.
- subtractNonDecorInsets(mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds,
- overrideWidth, overrideHeight);
- subtractStableInsets(mTmpStableBounds, insetBounds != null ? insetBounds : bounds,
- overrideWidth, overrideHeight);
- config.screenWidthDp = Math.min(
- (int) (mTmpStableBounds.width() / density), parentConfig.screenWidthDp);
- config.screenHeightDp = Math.min(
- (int) (mTmpStableBounds.height() / density), parentConfig.screenHeightDp);
- }
// TODO: Orientation?
config.orientation = (config.screenWidthDp <= config.screenHeightDp)
? Configuration.ORIENTATION_PORTRAIT
: Configuration.ORIENTATION_LANDSCAPE;
+ if (mStack != null) {
+ final StackWindowController stackController = mStack.getWindowContainerController();
+ stackController.adjustConfigurationForBounds(bounds, insetBounds,
+ mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
+ config, parentConfig);
+ } else {
+ // No stack, give some default values
+ config.smallestScreenWidthDp =
+ mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
+ config.screenWidthDp = config.screenHeightDp = config.smallestScreenWidthDp;
+ Slog.wtf(TAG, "Expected stack when caclulating override config");
+ }
// For calculating screen layout, we need to use the non-decor inset screen area for the
// calculation for compatibility reasons, i.e. screen area without system bars that could
// never go away in Honeycomb.
- final int compatScreenWidthDp = (int)(mTmpNonDecorBounds.width() / density);
- final int compatScreenHeightDp = (int)(mTmpNonDecorBounds.height() / density);
+ final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
+ final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
// We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override
// calculation with partial default.
final int sl = Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_XLARGE;
@@ -1905,8 +1876,6 @@
final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
- config.smallestScreenWidthDp = mService.mWindowManager.getSmallestWidthForTaskBounds(
- insetBounds != null ? insetBounds : bounds);
}
/**
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 8d0111b..5b3495f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -43,6 +43,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -72,6 +73,7 @@
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.media.VolumePolicy;
+import android.media.audiofx.AudioEffect;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.PlayerBase;
@@ -723,6 +725,9 @@
RotationHelper.init(mContext, mAudioHandler);
}
+ intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
+ intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
+
context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
@@ -5462,6 +5467,9 @@
state == BluetoothAdapter.STATE_TURNING_OFF) {
disconnectAllBluetoothProfiles();
}
+ } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
+ action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
+ handleAudioEffectBroadcast(context, intent);
}
}
} // end class AudioServiceBroadcastReceiver
@@ -5497,6 +5505,27 @@
}
} // end class AudioServiceUserRestrictionsListener
+ private void handleAudioEffectBroadcast(Context context, Intent intent) {
+ String target = intent.getPackage();
+ if (target != null) {
+ Log.w(TAG, "effect broadcast already targeted to " + target);
+ return;
+ }
+ intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
+ // TODO this should target a user-selected panel
+ List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers(
+ intent, 0 /* flags */);
+ if (ril != null && ril.size() != 0) {
+ ResolveInfo ri = ril.get(0);
+ if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) {
+ intent.setPackage(ri.activityInfo.packageName);
+ context.sendBroadcastAsUser(intent, UserHandle.ALL);
+ return;
+ }
+ }
+ Log.w(TAG, "couldn't find receiver package for effect intent");
+ }
+
private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
PackageManager pm = mContext.getPackageManager();
// Find the home activity of the user. It should not be killed to avoid expensive restart,
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 17b005d..8bc72de 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -481,12 +481,6 @@
public void onLost(Network network) {
releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
}
-
- @Override
- public void onUnavailable() {
- // timeout, it was not possible to establish the required connection
- releaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
- }
};
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -877,8 +871,7 @@
NetworkRequest request = requestBuilder.build();
mConnMgr.requestNetwork(
request,
- mSuplConnectivityCallback,
- ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS);
+ mSuplConnectivityCallback);
}
private void handleReleaseSuplConnection(int agpsDataConnStatus) {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 98177fe..407262b 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -93,7 +93,6 @@
private final SessionManagerImpl mSessionManagerImpl;
private final MediaSessionStack mPriorityStack;
- private final ArrayList<MediaSessionRecord> mAllSessions = new ArrayList<MediaSessionRecord>();
private final SparseArray<UserRecord> mUserRecords = new SparseArray<UserRecord>();
private final ArrayList<SessionsListenerRecord> mSessionsListeners
= new ArrayList<SessionsListenerRecord>();
@@ -145,7 +144,8 @@
public void updateSession(MediaSessionRecord record) {
synchronized (mLock) {
- if (!mAllSessions.contains(record)) {
+ UserRecord user = mUserRecords.get(record.getUserId());
+ if (user == null || !user.mSessions.contains(record)) {
Log.d(TAG, "Unknown session updated. Ignoring.");
return;
}
@@ -171,7 +171,8 @@
public void onSessionPlaystateChange(MediaSessionRecord record, int oldState, int newState) {
boolean updateSessions = false;
synchronized (mLock) {
- if (!mAllSessions.contains(record)) {
+ UserRecord user = mUserRecords.get(record.getUserId());
+ if (user == null || !user.mSessions.contains(record)) {
Log.d(TAG, "Unknown session changed playback state. Ignoring.");
return;
}
@@ -184,7 +185,8 @@
public void onSessionPlaybackTypeChanged(MediaSessionRecord record) {
synchronized (mLock) {
- if (!mAllSessions.contains(record)) {
+ UserRecord user = mUserRecords.get(record.getUserId());
+ if (user == null || !user.mSessions.contains(record)) {
Log.d(TAG, "Unknown session changed playback type. Ignoring.");
return;
}
@@ -318,7 +320,6 @@
}
mPriorityStack.removeSession(session);
- mAllSessions.remove(session);
try {
session.getCallback().asBinder().unlinkToDeath(session, 0);
@@ -455,7 +456,6 @@
throw new RuntimeException("Media Session owner died prematurely.", e);
}
- mAllSessions.add(session);
mPriorityStack.addSession(session, mCurrentUserIdList.contains(userId));
user.addSessionLocked(session);
@@ -1087,16 +1087,10 @@
synchronized (mLock) {
pw.println(mSessionsListeners.size() + " sessions listeners.");
- int count = mAllSessions.size();
- pw.println(count + " Sessions:");
- for (int i = 0; i < count; i++) {
- mAllSessions.get(i).dump(pw, "");
- pw.println();
- }
mPriorityStack.dump(pw, "");
pw.println("User Records:");
- count = mUserRecords.size();
+ int count = mUserRecords.size();
for (int i = 0; i < count; i++) {
UserRecord user = mUserRecords.get(mUserRecords.keyAt(i));
user.dumpLocked(pw, "");
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 9da94b3..06b6f66 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.app.DownloadManager;
import android.app.admin.DevicePolicyManager;
+import android.companion.CompanionDeviceManager;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -673,6 +674,16 @@
&& doesPackageSupportRuntimePermissions(storageManagerPckg)) {
grantRuntimePermissionsLPw(storageManagerPckg, STORAGE_PERMISSIONS, true, userId);
}
+
+ // Companion devices
+ PackageParser.Package companionDeviceDiscoveryPackage = getSystemPackageLPr(
+ CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME);
+ if (companionDeviceDiscoveryPackage != null
+ && doesPackageSupportRuntimePermissions(companionDeviceDiscoveryPackage)) {
+ grantRuntimePermissionsLPw(companionDeviceDiscoveryPackage,
+ LOCATION_PERMISSIONS, true, userId);
+ }
+
mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3e05157..477bb7f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5736,7 +5736,7 @@
mScreenshotChordVolumeDownKeyConsumed = false;
cancelPendingPowerKeyAction();
interceptScreenshotChord();
- if (!keyguardActive) {
+ if (!isKeyguardLocked()) {
interceptAccessibilityShortcutChord();
}
}
@@ -5754,7 +5754,7 @@
mA11yShortcutChordVolumeUpKeyConsumed = false;
cancelPendingPowerKeyAction();
cancelPendingScreenshotChordAction();
- if (!keyguardActive) {
+ if (!isKeyguardLocked()) {
interceptAccessibilityShortcutChord();
}
}
diff --git a/services/core/java/com/android/server/updates/TzDataInstallReceiver.java b/services/core/java/com/android/server/updates/TzDataInstallReceiver.java
index b704eb1..3c73c88 100644
--- a/services/core/java/com/android/server/updates/TzDataInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/TzDataInstallReceiver.java
@@ -20,7 +20,7 @@
import java.io.File;
import java.io.IOException;
-import libcore.tzdata.update2.TimeZoneBundleInstaller;
+import libcore.tzdata.update2.TimeZoneDistroInstaller;
/**
* An install receiver responsible for installing timezone data updates.
@@ -34,14 +34,14 @@
private static final String UPDATE_DIR_NAME = TZ_DATA_DIR.getPath() + "/updates/";
private static final String UPDATE_METADATA_DIR_NAME = "metadata/";
private static final String UPDATE_VERSION_FILE_NAME = "version";
- private static final String UPDATE_CONTENT_FILE_NAME = "tzdata_bundle.zip";
+ private static final String UPDATE_CONTENT_FILE_NAME = "tzdata_distro.zip";
- private final TimeZoneBundleInstaller installer;
+ private final TimeZoneDistroInstaller installer;
public TzDataInstallReceiver() {
super(UPDATE_DIR_NAME, UPDATE_CONTENT_FILE_NAME, UPDATE_METADATA_DIR_NAME,
UPDATE_VERSION_FILE_NAME);
- installer = new TimeZoneBundleInstaller(TAG, SYSTEM_TZ_DATA_FILE, TZ_DATA_DIR);
+ installer = new TimeZoneDistroInstaller(TAG, SYSTEM_TZ_DATA_FILE, TZ_DATA_DIR);
}
@Override
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 0a92a81..75a79fd 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -152,11 +152,6 @@
int getSmallestWidthDpForBounds(Rect bounds) {
final DisplayInfo di = mDisplayContent.getDisplayInfo();
- // If the bounds are fullscreen, return the value of the fullscreen configuration
- if (bounds == null || (bounds.left == 0 && bounds.top == 0
- && bounds.right == di.logicalWidth && bounds.bottom == di.logicalHeight)) {
- return mDisplayContent.getConfiguration().smallestScreenWidthDp;
- }
final int baseDisplayWidth = mDisplayContent.mBaseDisplayWidth;
final int baseDisplayHeight = mDisplayContent.mBaseDisplayHeight;
int minWidth = Integer.MAX_VALUE;
@@ -185,7 +180,7 @@
mTmpRect2.width(), mTmpRect2.height(), getContentWidth());
mService.mPolicy.getStableInsetsLw(rotation, mTmpRect2.width(), mTmpRect2.height(),
mTmpRect3);
- mService.subtractInsets(mTmpRect2, mTmpRect3, mTmpRect);
+ mService.intersectDisplayInsetBounds(mTmpRect2, mTmpRect3, mTmpRect);
minWidth = Math.min(mTmpRect.width(), minWidth);
}
return (int) (minWidth / mDisplayContent.getDisplayMetrics().density);
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 36d07e0..142f69a 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+
+import android.app.ActivityManager.StackId;
import android.app.RemoteAction;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -24,6 +27,8 @@
import android.os.Message;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.DisplayInfo;
+
import com.android.server.UiThread;
import com.android.internal.annotations.VisibleForTesting;
@@ -48,6 +53,12 @@
private final H mHandler;
+ // Temp bounds only used in adjustConfigurationForBounds()
+ private final Rect mTmpRect = new Rect();
+ private final Rect mTmpStableInsets = new Rect();
+ private final Rect mTmpNonDecorInsets = new Rect();
+ private final Rect mTmpDisplayBounds = new Rect();
+
public StackWindowController(int stackId, StackWindowListener listener,
int displayId, boolean onTop, Rect outBounds) {
this(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance());
@@ -289,6 +300,107 @@
}
}
+ /**
+ * Adjusts the screen size in dp's for the {@param config} for the given params.
+ */
+ public void adjustConfigurationForBounds(Rect bounds, Rect insetBounds,
+ Rect nonDecorBounds, Rect stableBounds, boolean overrideWidth,
+ boolean overrideHeight, float density, Configuration config,
+ Configuration parentConfig) {
+ synchronized (mWindowMap) {
+ final TaskStack stack = mContainer;
+ final DisplayContent displayContent = stack.getDisplayContent();
+ final DisplayInfo di = displayContent.getDisplayInfo();
+
+ // Get the insets and display bounds
+ mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+ mTmpStableInsets);
+ mService.mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+ mTmpNonDecorInsets);
+ mTmpDisplayBounds.set(0, 0, di.logicalWidth, di.logicalHeight);
+
+ int width;
+ int height;
+ if (StackId.tasksAreFloating(mStackId)) {
+ // Floating tasks should not be resized to the screen's bounds.
+
+ if (bounds.width() == mTmpDisplayBounds.width() &&
+ bounds.height() == mTmpDisplayBounds.height()) {
+ // If the bounds we are animating is the same as the fullscreen stack
+ // dimensions, then apply the same inset calculations that we normally do for
+ // the fullscreen stack, without intersecting it with the display bounds
+ stableBounds.inset(mTmpStableInsets);
+ nonDecorBounds.inset(mTmpNonDecorInsets);
+ }
+ width = (int) (stableBounds.width() / density);
+ height = (int) (stableBounds.height() / density);
+ } else {
+ // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen
+ // area, i.e. the screen area without the system bars.
+ // Additionally task dimensions should not be bigger than its parents dimensions.
+ // The non decor inset are areas that could never be removed in Honeycomb. See
+ // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
+ intersectDisplayBoundsExcludeInsets(nonDecorBounds,
+ insetBounds != null ? insetBounds : bounds, mTmpNonDecorInsets,
+ mTmpDisplayBounds, overrideWidth, overrideHeight);
+ intersectDisplayBoundsExcludeInsets(stableBounds,
+ insetBounds != null ? insetBounds : bounds, mTmpStableInsets,
+ mTmpDisplayBounds, overrideWidth, overrideHeight);
+ width = Math.min((int) (stableBounds.width() / density),
+ parentConfig.screenWidthDp);
+ height = Math.min((int) (stableBounds.height() / density),
+ parentConfig.screenHeightDp);
+ }
+
+ config.screenWidthDp = width;
+ config.screenHeightDp = height;
+ config.smallestScreenWidthDp = getSmallestWidthForTaskBounds(
+ insetBounds != null ? insetBounds : bounds, density);
+ }
+ }
+
+ /**
+ * Intersects the specified {@code inOutBounds} with the display frame that excludes the stable
+ * inset areas.
+ *
+ * @param inOutBounds The inOutBounds to subtract the stable inset areas from.
+ */
+ private void intersectDisplayBoundsExcludeInsets(Rect inOutBounds, Rect inInsetBounds,
+ Rect stableInsets, Rect displayBounds, boolean overrideWidth, boolean overrideHeight) {
+ mTmpRect.set(inInsetBounds);
+ mService.intersectDisplayInsetBounds(displayBounds, stableInsets, mTmpRect);
+ int leftInset = mTmpRect.left - inInsetBounds.left;
+ int topInset = mTmpRect.top - inInsetBounds.top;
+ int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect.right;
+ int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect.bottom;
+ inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
+ }
+
+ /**
+ * Calculates the smallest width for a task given the {@param bounds}.
+ *
+ * @return the smallest width to be used in the Configuration, in dips
+ */
+ private int getSmallestWidthForTaskBounds(Rect bounds, float density) {
+ final DisplayContent displayContent = mContainer.getDisplayContent();
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+
+ if (bounds == null || (bounds.width() == displayInfo.logicalWidth &&
+ bounds.height() == displayInfo.logicalHeight)) {
+ // If the bounds are fullscreen, return the value of the fullscreen configuration
+ return displayContent.getConfiguration().smallestScreenWidthDp;
+ } else if (StackId.tasksAreFloating(mStackId)) {
+ // For floating tasks, calculate the smallest width from the bounds of the task
+ return (int) (Math.min(bounds.width(), bounds.height()) / density);
+ } else {
+ // Iterating across all screen orientations, and return the minimum of the task
+ // width taking into account that the bounds might change because the snap algorithm
+ // snaps to a different value
+ return displayContent.getDockedDividerController()
+ .getSmallestWidthDpForBounds(bounds);
+ }
+ }
+
void requestResize(Rect bounds) {
mHandler.obtainMessage(H.REQUEST_RESIZE, bounds).sendToTarget();
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index b09d699..b9429f4 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1476,7 +1476,10 @@
@Override
public void getFullScreenBounds(Rect bounds) {
- getDisplayContent().getContentRect(bounds);
+ // This is currently only used for the pinned stack animation when leaving PiP
+ // (see {@link BoundsAnimationController}), and in that case we need to animate this back
+ // to the full bounds to match the fullscreen stack
+ getDisplayContent().getLogicalDisplayRect(bounds);
}
public boolean hasMovementAnimations() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a53102f..5653113 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6146,6 +6146,7 @@
* Get an array with display ids ordered by focus priority - last items should be given
* focus first. Sparse array just maps position to displayId.
*/
+ // TODO: Maintain display list in focus order in ActivityManager and remove this call.
public void getDisplaysInFocusOrder(SparseIntArray displaysInFocusOrder) {
synchronized(mWindowMap) {
mRoot.getDisplaysInFocusOrder(displaysInFocusOrder);
@@ -7543,63 +7544,12 @@
}
}
- private void getNonDecorInsetsLocked(Rect outInsets) {
- final DisplayInfo di = getDefaultDisplayInfoLocked();
- mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, outInsets);
- }
-
- /**
- * Intersects the specified {@code inOutBounds} with the display frame that excludes the stable
- * inset areas.
- *
- * @param inOutBounds The inOutBounds to subtract the stable inset areas from.
- */
- public void subtractStableInsets(Rect inOutBounds) {
- synchronized (mWindowMap) {
- getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect2);
- final DisplayInfo di = getDefaultDisplayInfoLocked();
- mTmpRect.set(0, 0, di.logicalWidth, di.logicalHeight);
- subtractInsets(mTmpRect, mTmpRect2, inOutBounds);
- }
- }
-
- /**
- * Intersects the specified {@code inOutBounds} with the display frame that excludes
- * areas that could never be removed in Honeycomb. See
- * {@link WindowManagerPolicy#getNonDecorInsetsLw}.
- *
- * @param inOutBounds The inOutBounds to subtract the inset areas from.
- */
- public void subtractNonDecorInsets(Rect inOutBounds) {
- synchronized (mWindowMap) {
- getNonDecorInsetsLocked(mTmpRect2);
- final DisplayInfo di = getDefaultDisplayInfoLocked();
- mTmpRect.set(0, 0, di.logicalWidth, di.logicalHeight);
- subtractInsets(mTmpRect, mTmpRect2, inOutBounds);
- }
- }
-
- void subtractInsets(Rect display, Rect insets, Rect inOutBounds) {
+ void intersectDisplayInsetBounds(Rect display, Rect insets, Rect inOutBounds) {
mTmpRect3.set(display);
mTmpRect3.inset(insets);
inOutBounds.intersect(mTmpRect3);
}
- /**
- * Calculates the smallest width for a task given the {@param bounds}. It does that by iterating
- * across all screen orientations, and returns the minimum of the task width taking into account
- * that the bounds might change because the snap algorithm snaps to a different value.
- *
- * @return the smallest width to be used in the Configuration, in dips
- */
- public int getSmallestWidthForTaskBounds(Rect bounds) {
- synchronized (mWindowMap) {
- // TODO(multi-display): Use correct display content here
- return getDefaultDisplayContentLocked().getDockedDividerController()
- .getSmallestWidthDpForBounds(bounds);
- }
- }
-
MousePositionTracker mMousePositionTracker = new MousePositionTracker();
private static class MousePositionTracker implements PointerEventListener {
@@ -7914,8 +7864,8 @@
}
@Override
- public void updateInputMethodWindowStatus(IBinder imeToken, boolean imeWindowVisible,
- IBinder targetWindowToken) {
+ public void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
+ boolean imeWindowVisible, @Nullable IBinder targetWindowToken) {
// TODO (b/34628091): Use this method to address the window animation issue.
if (DEBUG_INPUT_METHOD) {
Slog.w(TAG_WM, "updateInputMethodWindowStatus: imeToken=" + imeToken
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index dd44aa0..2b5a06d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3192,7 +3192,6 @@
// If admin is a device or profile owner tidy that up first.
if (isDeviceOwner(adminReceiver, userHandle)) {
clearDeviceOwnerLocked(getDeviceOwnerAdminLocked(), userHandle);
- clearDeviceOwnerUserRestrictionLocked(UserHandle.of(userHandle));
}
if (isProfileOwner(adminReceiver, userHandle)) {
final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver,
@@ -3208,10 +3207,8 @@
}
}
- // It's temporary solution to clear DISALLOW_ADD_USER after CTS
- // STOPSHIP(b/31952368) when the restriction is moved from system to the device owner,
- // it can be removed.
private void clearDeviceOwnerUserRestrictionLocked(UserHandle userHandle) {
+ // ManagedProvisioning/DPC sets DISALLOW_ADD_USER. Clear to recover to the original state
if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER, userHandle)) {
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, false, userHandle);
}
@@ -6573,6 +6570,7 @@
mOwners.writeDeviceOwner();
updateDeviceOwnerLocked();
+ clearDeviceOwnerUserRestrictionLocked(UserHandle.of(userId));
mInjector.securityLogSetLoggingEnabledProperty(false);
mSecurityLogMonitor.stop();
setNetworkLoggingActiveInternal(false);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 83e209d..31c8261 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -35,6 +35,7 @@
import android.os.IIncidentManager;
import android.os.Looper;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StrictMode;
@@ -236,6 +237,8 @@
private static final String START_SENSOR_SERVICE = "StartSensorService";
private Future<?> mSensorServiceStart;
+ private Future<?> mZygotePreload;
+
/**
* Start the sensor service. This is a blocking call and can take time.
@@ -688,6 +691,26 @@
}
try {
+ final String SECONDARY_ZYGOTE_PRELOAD = "SecondaryZygotePreload";
+ // We start the preload ~1s before the webview factory preparation, to
+ // ensure that it completes before the 32 bit relro process is forked
+ // from the zygote. In the event that it takes too long, the webview
+ // RELRO process will block, but it will do so without holding any locks.
+ mZygotePreload = SystemServerInitThreadPool.get().submit(() -> {
+ try {
+ Slog.i(TAG, SECONDARY_ZYGOTE_PRELOAD);
+ BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
+ SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ traceLog.traceBegin(SECONDARY_ZYGOTE_PRELOAD);
+ if (!Process.zygoteProcess.preloadDefault(Build.SUPPORTED_32_BIT_ABIS[0])) {
+ Slog.e(TAG, "Unable to preload default resources");
+ }
+ traceLog.traceEnd();
+ } catch (Exception ex) {
+ Slog.e(TAG, "Exception preloading default resources", ex);
+ }
+ }, SECONDARY_ZYGOTE_PRELOAD);
+
traceBeginAndSlog("StartKeyAttestationApplicationIdProviderService");
ServiceManager.addService("sec_key_att_app_id_provider",
new KeyAttestationApplicationIdProviderService(context));
@@ -1615,6 +1638,8 @@
BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(WEBVIEW_PREPARATION);
+ ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");
+ mZygotePreload = null;
mWebViewUpdateService.prepareWebViewInSystemServer();
traceLog.traceEnd();
}, WEBVIEW_PREPARATION);
diff --git a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
index 9824c1d..9ac8295 100644
--- a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
+++ b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
@@ -19,20 +19,28 @@
import static com.android.internal.util.Preconditions.checkNotNull;
-import android.app.PendingIntent;
+import android.Manifest;
import android.companion.AssociationRequest;
+import android.companion.CompanionDeviceManager;
+import android.companion.ICompanionDeviceDiscoveryService;
+import android.companion.ICompanionDeviceDiscoveryServiceCallback;
import android.companion.ICompanionDeviceManager;
-import android.companion.ICompanionDeviceManagerService;
-import android.companion.IOnAssociateCallback;
+import android.companion.IFindDeviceCallback;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.NetworkPolicyManager;
import android.os.Binder;
import android.os.IBinder;
+import android.os.IDeviceIdleController;
import android.os.RemoteException;
-import android.util.Log;
+import android.os.ServiceManager;
+import android.util.Slog;
+import com.android.internal.util.ArrayUtils;
import com.android.server.SystemService;
//TODO move to own package!
@@ -40,7 +48,8 @@
public class CompanionDeviceManagerService extends SystemService {
private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
- "com.android.companiondevicemanager", ".DeviceDiscoveryService");
+ CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
+ ".DeviceDiscoveryService");
private static final boolean DEBUG = false;
private static final String LOG_TAG = "CompanionDeviceManagerService";
@@ -58,14 +67,13 @@
}
class CompanionDeviceManagerImpl extends ICompanionDeviceManager.Stub {
-
@Override
public void associate(
AssociationRequest request,
- IOnAssociateCallback callback,
- String callingPackage) throws RemoteException {
+ IFindDeviceCallback callback,
+ String callingPackage) {
if (DEBUG) {
- Log.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback
+ Slog.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback
+ ", callingPackage = " + callingPackage + ")");
}
checkNotNull(request);
@@ -85,23 +93,24 @@
private ServiceConnection getServiceConnection(
final AssociationRequest<?> request,
- final IOnAssociateCallback callback,
+ final IFindDeviceCallback findDeviceCallback,
final String callingPackage) {
return new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) {
- Log.i(LOG_TAG,
+ Slog.i(LOG_TAG,
"onServiceConnected(name = " + name + ", service = "
+ service + ")");
}
try {
- ICompanionDeviceManagerService.Stub
+ ICompanionDeviceDiscoveryService.Stub
.asInterface(service)
.startDiscovery(
request,
- getCallback(callingPackage, callback),
- callingPackage);
+ callingPackage,
+ findDeviceCallback,
+ getServiceCallback());
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -109,39 +118,50 @@
@Override
public void onServiceDisconnected(ComponentName name) {
- if (DEBUG) Log.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")");
+ if (DEBUG) Slog.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")");
}
};
}
- private IOnAssociateCallback.Stub getCallback(
- String callingPackage,
- IOnAssociateCallback propagateTo) {
- return new IOnAssociateCallback.Stub() {
-
+ private ICompanionDeviceDiscoveryServiceCallback.Stub getServiceCallback() {
+ return new ICompanionDeviceDiscoveryServiceCallback.Stub() {
@Override
- public void onSuccess(PendingIntent launcher)
- throws RemoteException {
- if (DEBUG) Log.i(LOG_TAG, "onSuccess(launcher = " + launcher + ")");
- recordSpecialPriviledgesForPackage(callingPackage);
- propagateTo.onSuccess(launcher);
- }
-
- @Override
- public void onFailure(CharSequence reason) throws RemoteException {
- if (DEBUG) Log.i(LOG_TAG, "onFailure()");
- propagateTo.onFailure(reason);
+ public void onDeviceSelected(String packageName, int userId) {
+ grantSpecialAccessPermissionsIfNeeded(packageName, userId);
}
};
}
- void recordSpecialPriviledgesForPackage(String priviledgedPackage) {
- //TODO Show dialog before recording notification access
-// final SettingStringHelper setting =
-// new SettingStringHelper(
-// getContext().getContentResolver(),
-// Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
-// Binder.getCallingUid());
-// setting.write(ColonDelimitedSet.OfStrings.add(setting.read(), priviledgedPackage));
+ private void grantSpecialAccessPermissionsIfNeeded(String packageName, int userId) {
+ final long identity = Binder.clearCallingIdentity();
+ final PackageInfo packageInfo;
+ try {
+ packageInfo = getContext().getPackageManager().getPackageInfoAsUser(
+ packageName, PackageManager.GET_PERMISSIONS, userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(LOG_TAG, "Error granting special access permissions to package:"
+ + packageName, e);
+ return;
+ }
+ try {
+ if (ArrayUtils.contains(packageInfo.requestedPermissions,
+ Manifest.permission.RUN_IN_BACKGROUND)) {
+ IDeviceIdleController idleController = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ try {
+ idleController.addPowerSaveWhitelistApp(packageName);
+ } catch (RemoteException e) {
+ /* ignore - local call */
+ }
+ }
+ if (ArrayUtils.contains(packageInfo.requestedPermissions,
+ Manifest.permission.USE_DATA_IN_BACKGROUND)) {
+ NetworkPolicyManager.from(getContext()).addUidPolicy(
+ packageInfo.applicationInfo.uid,
+ NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 23a1bb4..d0e5159 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -918,6 +918,8 @@
assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
+ when(mContext.userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
+ MockUtils.checkUserHandle(UserHandle.USER_SYSTEM))).thenReturn(true);
assertTrue(dpm.isAdminActive(admin1));
assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM));
@@ -947,6 +949,10 @@
// Now DO shouldn't be set.
assertNull(dpm.getDeviceOwnerComponentOnAnyUser());
+ verify(mContext.userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
+ eq(false),
+ MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
+
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
eq(UserHandle.USER_SYSTEM),
eq(null),
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 2e99b6e..caf9ec6 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -16,6 +16,8 @@
package com.android.server.usb;
+import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ActivityNotFoundException;
@@ -41,6 +43,8 @@
import android.util.AtomicFile;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
@@ -50,6 +54,8 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.XmlUtils;
+import libcore.io.IoUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -66,10 +72,6 @@
import java.util.List;
import java.util.Map;
-import libcore.io.IoUtils;
-
-import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
-
class UsbProfileGroupSettingsManager {
private static final String TAG = UsbProfileGroupSettingsManager.class.getSimpleName();
private static final boolean DEBUG = false;
@@ -873,6 +875,56 @@
return resolveInfos;
}
+ /**
+ * Only return those matches with the highest priority.
+ *
+ * @param matches All matches, some might have lower priority
+ *
+ * @return The matches with the highest priority
+ */
+ @NonNull
+ private ArrayList<ResolveInfo> preferHighPriority(
+ @NonNull ArrayList<ResolveInfo> matches) {
+ SparseArray<ArrayList<ResolveInfo>> highestPriorityMatchesByUserId = new SparseArray<>();
+ SparseIntArray highestPriorityByUserId = new SparseIntArray();
+
+ // Create list of highest priority matches per user in highestPriorityMatchesByUserId
+ int numMatches = matches.size();
+ for (int matchNum = 0; matchNum < numMatches; matchNum++) {
+ ResolveInfo match = matches.get(matchNum);
+
+ // If this a previously unknown user?
+ if (highestPriorityByUserId.indexOfKey(match.targetUserId) < 0) {
+ highestPriorityByUserId.put(match.targetUserId, Integer.MIN_VALUE);
+ highestPriorityMatchesByUserId.put(match.targetUserId, new ArrayList<>());
+ }
+
+ // Find current highest priority matches for the current user
+ int highestPriority = highestPriorityByUserId.get(match.targetUserId);
+ ArrayList<ResolveInfo> highestPriorityMatches = highestPriorityMatchesByUserId.get(
+ match.targetUserId);
+
+ if (match.priority == highestPriority) {
+ highestPriorityMatches.add(match);
+ } else if (match.priority > highestPriority) {
+ highestPriorityByUserId.put(match.targetUserId, match.priority);
+
+ highestPriorityMatches.clear();
+ highestPriorityMatches.add(match);
+ }
+ }
+
+ // Combine all users back together. This means that all matches have the same priority for a
+ // user. Matches for different users might have different priority.
+ ArrayList<ResolveInfo> combinedMatches = new ArrayList<>();
+ int numMatchArrays = highestPriorityMatchesByUserId.size();
+ for (int matchArrayNum = 0; matchArrayNum < numMatchArrays; matchArrayNum++) {
+ combinedMatches.addAll(highestPriorityMatchesByUserId.valueAt(matchArrayNum));
+ }
+
+ return combinedMatches;
+ }
+
private final ArrayList<ResolveInfo> getDeviceMatchesLocked(UsbDevice device, Intent intent) {
ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>();
List<ResolveInfo> resolveInfos = queryIntentActivitiesForAllProfiles(intent);
@@ -883,7 +935,7 @@
matches.add(resolveInfo);
}
}
- return matches;
+ return preferHighPriority(matches);
}
private final ArrayList<ResolveInfo> getAccessoryMatchesLocked(
@@ -897,7 +949,7 @@
matches.add(resolveInfo);
}
}
- return matches;
+ return preferHighPriority(matches);
}
public void deviceAttached(UsbDevice device) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 3b15f1c..70df69c 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -417,6 +417,21 @@
public static final String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL
= "carrier_volte_provisioning_required_bool";
+ /**
+ * Flag specifying if WFC provisioning depends on VoLTE provisioning.
+ *
+ * {@code false}: default value; honor actual WFC provisioning state.
+ * {@code true}: when VoLTE is not provisioned, treat WFC as not provisioned; when VoLTE is
+ * provisioned, honor actual WFC provisioning state.
+ *
+ * As of now, Verizon is the only carrier enforcing this dependency in their
+ * WFC awareness and activation requirements.
+ *
+ * @hide
+ * */
+ public static final String KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL
+ = "carrier_volte_override_wfc_provisioning_bool";
+
/** Flag specifying whether VoLTE TTY is supported. */
public static final String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
= "carrier_volte_tty_supported_bool";
@@ -1316,6 +1331,7 @@
sDefaults.putInt(KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT, 2);
sDefaults.putBoolean(KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
+ sDefaults.putBoolean(KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true);
sDefaults.putBoolean(KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, true);
sDefaults.putBoolean(KEY_CARRIER_IMS_GBA_REQUIRED_BOOL, false);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4ff4d80..c2c724f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5907,6 +5907,29 @@
}
/**
+ * Sets the per-account voicemail ringtone.
+ *
+ * <p>Requires that the calling app is the default dialer, or has carrier privileges, or has
+ * permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+ *
+ * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
+ * voicemail ringtone.
+ * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
+ * PhoneAccount.
+ * @see #hasCarrierPrivileges
+ */
+ public void setVoicemailRingtoneUri(PhoneAccountHandle phoneAccountHandle, Uri uri) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ service.setVoicemailRingtoneUri(getOpPackageName(), phoneAccountHandle, uri);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#setVoicemailRingtoneUri", e);
+ }
+ }
+
+ /**
* Returns whether vibration is set for voicemail notification in Phone settings.
*
* @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
@@ -5926,6 +5949,31 @@
}
/**
+ * Sets the per-account preference whether vibration is enabled for voicemail notifications.
+ *
+ * <p>Requires that the calling app is the default dialer, or has carrier privileges, or has
+ * permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+ *
+ * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
+ * voicemail vibration setting.
+ * @param enabled Whether to enable or disable vibration for voicemail notifications from a
+ * specific PhoneAccount.
+ * @see #hasCarrierPrivileges
+ */
+ public void setVoicemailVibrationEnabled(PhoneAccountHandle phoneAccountHandle,
+ boolean enabled) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ service.setVoicemailVibrationEnabled(getOpPackageName(), phoneAccountHandle,
+ enabled);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#isVoicemailVibrationEnabled", e);
+ }
+ }
+
+ /**
* Return the application ID for the app type like {@link APPTYPE_CSIM}.
*
* Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d90a33e..e6a6178 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1146,6 +1146,20 @@
Uri getVoicemailRingtoneUri(in PhoneAccountHandle accountHandle);
/**
+ * Sets the per-account voicemail ringtone.
+ *
+ * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
+ * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+ *
+ * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
+ * voicemail ringtone.
+ * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
+ * PhoneAccount.
+ */
+ void setVoicemailRingtoneUri(String callingPackage,
+ in PhoneAccountHandle phoneAccountHandle, in Uri uri);
+
+ /**
* Returns whether vibration is set for voicemail notification in Phone settings.
*
* @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
@@ -1155,6 +1169,20 @@
boolean isVoicemailVibrationEnabled(in PhoneAccountHandle accountHandle);
/**
+ * Sets the per-account preference whether vibration is enabled for voicemail notifications.
+ *
+ * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
+ * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+ *
+ * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
+ * voicemail vibration setting.
+ * @param enabled Whether to enable or disable vibration for voicemail notifications from a
+ * specific PhoneAccount.
+ */
+ void setVoicemailVibrationEnabled(String callingPackage,
+ in PhoneAccountHandle phoneAccountHandle, boolean enabled);
+
+ /**
* Returns a list of packages that have carrier privileges.
*/
List<String> getPackagesWithCarrierPrivileges();
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
index d71cc6f..6e3a8e8 100644
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
@@ -50,6 +50,7 @@
import android.util.DisplayMetrics;
import android.util.LruCache;
import android.util.TypedValue;
+import android.view.DisplayAdjustments;
import android.view.ViewGroup.LayoutParams;
import java.io.File;
@@ -71,7 +72,8 @@
DisplayMetrics metrics,
Configuration config,
LayoutlibCallback layoutlibCallback) {
- Resources resources = new Resources(assets, metrics, config);
+ Resources resources = new Resources(Resources_Delegate.class.getClassLoader());
+ resources.setImpl(new ResourcesImpl(assets, metrics, config, new DisplayAdjustments()));
resources.mContext = context;
resources.mLayoutlibCallback = layoutlibCallback;
return Resources.mSystem = resources;
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index ded52a7..b15ee95 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -25,13 +25,15 @@
import org.junit.runners.Suite.SuiteClasses;
import android.graphics.Matrix_DelegateTest;
+import android.util.BridgeXmlPullAttributesTest;
/**
* Suite used by the layoutlib build system
*/
@RunWith(Suite.class)
@SuiteClasses({
- RenderTests.class, LayoutParserWrapperTest.class, BridgeXmlBlockParserTest.class,
+ RenderTests.class, LayoutParserWrapperTest.class,
+ BridgeXmlBlockParserTest.class, BridgeXmlPullAttributesTest.class,
Matrix_DelegateTest.class, TestDelegates.class
})
public class Main {
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index bae2dc0c..8ebfc65 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -132,7 +132,11 @@
@Override
public Integer getResourceId(ResourceType type, String name) {
- return mResources.get(type).get(name);
+ Map<String, Integer> resName2Id = mResources.get(type);
+ if (resName2Id == null) {
+ return null;
+ }
+ return resName2Id.get(name);
}
@Override
diff --git a/tools/layoutlib/create/create.iml b/tools/layoutlib/create/create.iml
index 368b46b..ac97502 100644
--- a/tools/layoutlib/create/create.iml
+++ b/tools/layoutlib/create/create.iml
@@ -12,9 +12,9 @@
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
- <library name="asm-5.0">
+ <library name="asm-5.2">
<CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-5.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-5.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>