summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/accounts/AbstractAccountAuthenticator.java5
-rw-r--r--core/java/android/app/Activity.java4
-rw-r--r--core/java/android/app/Instrumentation.java2
-rw-r--r--core/java/android/app/Service.java10
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java4
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java8
-rw-r--r--core/java/android/bluetooth/BluetoothServerSocket.java2
-rw-r--r--core/java/android/hardware/GeomagneticField.java4
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java4
-rw-r--r--core/java/android/inputmethodservice/SoftInputWindow.java6
-rw-r--r--core/java/android/net/NetworkMisc.java2
-rw-r--r--core/java/android/net/UrlQuerySanitizer.java12
-rw-r--r--core/java/android/util/FeatureFlagUtils.java3
-rw-r--r--core/java/android/util/JsonReader.java6
-rw-r--r--core/java/android/view/KeyCharacterMap.java4
-rw-r--r--core/java/android/view/KeyEvent.java4
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/android/view/accessibility/AccessibilityCache.java14
-rw-r--r--core/res/AndroidManifest.xml8
-rw-r--r--core/res/res/drawable/emergency_icon.xml2
-rw-r--r--core/res/res/drawable/ic_faster_emergency.xml31
-rw-r--r--core/res/res/values/attrs.xml6
-rw-r--r--core/res/res/values/config.xml2
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java20
-rw-r--r--location/java/android/location/Criteria.java6
-rw-r--r--media/java/android/media/AudioManager.java2
-rw-r--r--media/java/android/media/AudioRecord.java2
-rw-r--r--media/java/android/media/MediaPlayer.java2
-rw-r--r--media/java/android/media/MediaPlayer2Impl.java2
-rw-r--r--media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java23
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java16
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java38
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java16
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java52
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java30
-rw-r--r--packages/SystemUI/res/layout/global_actions_wrapped.xml18
-rw-r--r--packages/SystemUI/res/values/dimens.xml4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/EmergencyButton.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java156
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java76
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java38
-rw-r--r--proto/src/metrics_constants.proto63
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java13
-rw-r--r--services/core/java/com/android/server/am/MemoryStatUtil.java19
-rw-r--r--services/core/java/com/android/server/am/UserController.java14
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java26
-rw-r--r--services/core/java/com/android/server/notification/RankingConfig.java2
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java13
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java5
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java37
-rw-r--r--telecomm/java/android/telecom/ParcelableCallAnalytics.java38
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java12
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java24
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java27
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java84
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java4
58 files changed, 823 insertions, 215 deletions
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index a3b3a9f21954..79d1361192e3 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -17,7 +17,6 @@
package android.accounts;
import android.Manifest;
-import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -32,8 +31,8 @@ import java.util.Arrays;
/**
* Abstract base class for creating AccountAuthenticators.
- * In order to be an authenticator one must extend this class, provider implementations for the
- * abstract methods and write a service that returns the result of {@link #getIBinder()}
+ * In order to be an authenticator one must extend this class, provide implementations for the
+ * abstract methods, and write a service that returns the result of {@link #getIBinder()}
* in the service's {@link android.app.Service#onBind(android.content.Intent)} when invoked
* with an intent with action {@link AccountManager#ACTION_AUTHENTICATOR_INTENT}. This service
* must specify the following intent filter and metadata tags in its AndroidManifest.xml file
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0fb85d25cf1a..1925f431b3b6 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -393,7 +393,7 @@ import java.util.List;
* <td>The final call you receive before your
* activity is destroyed. This can happen either because the
* activity is finishing (someone called {@link Activity#finish} on
- * it, or because the system is temporarily destroying this
+ * it), or because the system is temporarily destroying this
* instance of the activity to save space. You can distinguish
* between these two scenarios with the {@link
* Activity#isFinishing} method.</td>
@@ -1937,7 +1937,7 @@ public class Activity extends ContextThemeWrapper
/**
* Perform any final cleanup before an activity is destroyed. This can
* happen either because the activity is finishing (someone called
- * {@link #finish} on it, or because the system is temporarily destroying
+ * {@link #finish} on it), or because the system is temporarily destroying
* this instance of the activity to save space. You can distinguish
* between these two scenarios with the {@link #isFinishing} method.
*
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index c7618fe62c87..d4385549da02 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1749,7 +1749,7 @@ public class Instrumentation {
/**
* Like {@link #execStartActivity(android.content.Context, android.os.IBinder,
* android.os.IBinder, String, android.content.Intent, int, android.os.Bundle)},
- * but for calls from a {#link Fragment}.
+ * but for calls from a {@link Fragment}.
*
* @param who The Context from which the activity is being started.
* @param contextThread The main thread of the Context from which the activity
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index ea0fd75bec90..6cee2da5762e 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -20,13 +20,13 @@ import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
-import android.content.Intent;
-import android.content.ContextWrapper;
import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
-import android.os.RemoteException;
import android.os.IBinder;
+import android.os.RemoteException;
import android.util.Log;
import java.io.FileDescriptor;
@@ -390,7 +390,7 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
* don't recreate until a future explicit call to
* {@link Context#startService Context.startService(Intent)}. The
* service will not receive a {@link #onStartCommand(Intent, int, int)}
- * call with a null Intent because it will not be re-started if there
+ * call with a null Intent because it will not be restarted if there
* are no pending Intents to deliver.
*
* <p>This mode makes sense for things that want to do some work as a
@@ -415,7 +415,7 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
* redelivery until the service calls {@link #stopSelf(int)} with the
* start ID provided to {@link #onStartCommand}. The
* service will not receive a {@link #onStartCommand(Intent, int, int)}
- * call with a null Intent because it will will only be re-started if
+ * call with a null Intent because it will only be restarted if
* it is not finished processing all Intents sent to it (and any such
* pending events will be delivered at the point of restart).
*/
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 1b6b5a01ec7e..44051081b595 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2797,7 +2797,7 @@ public final class BluetoothAdapter {
* socket will be encrypted.
* <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
* {@link BluetoothServerSocket}.
- * <p>The system will assign a dynamic PSM value. This PSM value can be read from the {#link
+ * <p>The system will assign a dynamic PSM value. This PSM value can be read from the {@link
* BluetoothServerSocket#getPsm()} and this value will be released when this server socket is
* closed, Bluetooth is turned off, or the application exits unexpectedly.
* <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
@@ -2847,7 +2847,7 @@ public final class BluetoothAdapter {
* <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
* {@link BluetoothServerSocket}.
* <p>The system will assign a dynamic protocol/service multiplexer (PSM) value. This PSM value
- * can be read from the {#link BluetoothServerSocket#getPsm()} and this value will be released
+ * can be read from the {@link BluetoothServerSocket#getPsm()} and this value will be released
* when this server socket is closed, Bluetooth is turned off, or the application exits
* unexpectedly.
* <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 7a6b72e980f5..f4b7d7c700c5 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1567,7 +1567,7 @@ public final class BluetoothDevice implements Parcelable {
* For example, for Bluetooth 2.1 devices, if any of the devices does not
* have an input and output capability or just has the ability to
* display a numeric key, a secure socket connection is not possible.
- * In such a case, use {#link createInsecureRfcommSocket}.
+ * In such a case, use {@link createInsecureRfcommSocket}.
* For more details, refer to the Security Model section 5.2 (vol 3) of
* Bluetooth Core Specification version 2.1 + EDR.
* <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
@@ -1601,7 +1601,7 @@ public final class BluetoothDevice implements Parcelable {
* For example, for Bluetooth 2.1 devices, if any of the devices does not
* have an input and output capability or just has the ability to
* display a numeric key, a secure socket connection is not possible.
- * In such a case, use {#link createInsecureRfcommSocket}.
+ * In such a case, use {@link createInsecureRfcommSocket}.
* For more details, refer to the Security Model section 5.2 (vol 3) of
* Bluetooth Core Specification version 2.1 + EDR.
* <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
@@ -1658,7 +1658,7 @@ public final class BluetoothDevice implements Parcelable {
* For example, for Bluetooth 2.1 devices, if any of the devices does not
* have an input and output capability or just has the ability to
* display a numeric key, a secure socket connection is not possible.
- * In such a case, use {#link createInsecureRfcommSocketToServiceRecord}.
+ * In such a case, use {@link #createInsecureRfcommSocketToServiceRecord}.
* For more details, refer to the Security Model section 5.2 (vol 3) of
* Bluetooth Core Specification version 2.1 + EDR.
* <p>Hint: If you are connecting to a Bluetooth serial board then try
@@ -1938,7 +1938,7 @@ public final class BluetoothDevice implements Parcelable {
* encrypted.
* <p> Use this socket if an authenticated socket link is possible. Authentication refers
* to the authentication of the link key to prevent man-in-the-middle type of attacks. When a
- * secure socket connection is not possible, use {#link createInsecureLeL2capCocSocket(int,
+ * secure socket connection is not possible, use {@link createInsecureLeL2capCocSocket(int,
* int)}.
*
* @param transport Bluetooth transport to use, must be {@link #TRANSPORT_LE}
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index ebb7f187aea5..ca29ef37a228 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -201,7 +201,7 @@ public final class BluetoothServerSocket implements Closeable {
/**
* Returns the assigned dynamic protocol/service multiplexer (PSM) value for the listening L2CAP
* Connection-oriented Channel (CoC) server socket. This server socket must be returned by the
- * {#link BluetoothAdapter.listenUsingL2capCoc(int)} or {#link
+ * {@link BluetoothAdapter.listenUsingL2capCoc(int)} or {@link
* BluetoothAdapter.listenUsingInsecureL2capCoc(int)}. The returned value is undefined if this
* method is called on non-L2CAP server sockets.
*
diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java
index 94f2ac085965..0d7b695d7f1d 100644
--- a/core/java/android/hardware/GeomagneticField.java
+++ b/core/java/android/hardware/GeomagneticField.java
@@ -31,7 +31,7 @@ import java.util.GregorianCalendar;
* Android may use a newer version of the model.
*/
public class GeomagneticField {
- // The magnetic field at a given point, in nonoteslas in geodetic
+ // The magnetic field at a given point, in nanoteslas in geodetic
// coordinates.
private float mX;
private float mY;
@@ -278,7 +278,7 @@ public class GeomagneticField {
}
/**
- * @return Horizontal component of the field strength in nonoteslas.
+ * @return Horizontal component of the field strength in nanoteslas.
*/
public float getHorizontalStrength() {
return (float) Math.hypot(mX, mY);
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index b4c8a5e504bc..d26c51628e22 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2110,7 +2110,7 @@ public class InputMethodService extends AbstractInputMethodService {
* Called when the application has reported a new location of its text
* cursor. This is only called if explicitly requested by the input method.
* The default implementation does nothing.
- * @deprecated Use {#link onUpdateCursorAnchorInfo(CursorAnchorInfo)} instead.
+ * @deprecated Use {@link #onUpdateCursorAnchorInfo(CursorAnchorInfo)} instead.
*/
@Deprecated
public void onUpdateCursor(Rect newCursor) {
@@ -2177,7 +2177,7 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
- * @return {#link ExtractEditText} if it is considered to be visible and active. Otherwise
+ * @return {@link ExtractEditText} if it is considered to be visible and active. Otherwise
* {@code null} is returned.
*/
private ExtractEditText getExtractEditTextIfVisible() {
diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java
index 795117e493b6..bf579a703567 100644
--- a/core/java/android/inputmethodservice/SoftInputWindow.java
+++ b/core/java/android/inputmethodservice/SoftInputWindow.java
@@ -103,9 +103,9 @@ public class SoftInputWindow extends Dialog {
/**
* Set which boundary of the screen the DockWindow sticks to.
*
- * @param gravity The boundary of the screen to stick. See {#link
- * android.view.Gravity.LEFT}, {#link android.view.Gravity.TOP},
- * {#link android.view.Gravity.BOTTOM}, {#link
+ * @param gravity The boundary of the screen to stick. See {@link
+ * android.view.Gravity.LEFT}, {@link android.view.Gravity.TOP},
+ * {@link android.view.Gravity.BOTTOM}, {@link
* android.view.Gravity.RIGHT}.
*/
public void setGravity(int gravity) {
diff --git a/core/java/android/net/NetworkMisc.java b/core/java/android/net/NetworkMisc.java
index 69f50a272af0..a2da6eaa4922 100644
--- a/core/java/android/net/NetworkMisc.java
+++ b/core/java/android/net/NetworkMisc.java
@@ -46,7 +46,7 @@ public class NetworkMisc implements Parcelable {
/**
* Set if the user desires to use this network even if it is unvalidated. This field has meaning
- * only if {#link explicitlySelected} is true. If it is, this field must also be set to the
+ * only if {@link explicitlySelected} is true. If it is, this field must also be set to the
* appropriate value based on previous user choice.
*/
public boolean acceptUnvalidated;
diff --git a/core/java/android/net/UrlQuerySanitizer.java b/core/java/android/net/UrlQuerySanitizer.java
index d2073b4dfd3a..5b674067192e 100644
--- a/core/java/android/net/UrlQuerySanitizer.java
+++ b/core/java/android/net/UrlQuerySanitizer.java
@@ -287,7 +287,7 @@ public class UrlQuerySanitizer {
/**
* Sanitize a value.
* <ol>
- * <li>If script URLs are not OK, the will be removed.
+ * <li>If script URLs are not OK, they will be removed.
* <li>If neither spaces nor other white space is OK, then
* white space will be trimmed from the beginning and end of
* the URL. (Just the actual white space characters are trimmed, not
@@ -563,7 +563,7 @@ public class UrlQuerySanitizer {
}
/**
- * Constructs a UrlQuerySanitizer and parse a URL.
+ * Constructs a UrlQuerySanitizer and parses a URL.
* This constructor is provided for convenience when the
* default parsing behavior is acceptable.
* <p>
@@ -644,7 +644,7 @@ public class UrlQuerySanitizer {
}
/**
- * An array list of all of the parameter value pairs in the sanitized
+ * An array list of all of the parameter-value pairs in the sanitized
* query, in the order they appeared in the query. May contain duplicate
* parameters.
* <p class="note"><b>Note:</b> Do not modify this list. Treat it as a read-only list.</p>
@@ -656,7 +656,7 @@ public class UrlQuerySanitizer {
/**
* Check if a parameter exists in the current sanitized query.
* @param parameter the unencoded name of a parameter.
- * @return true if the paramater exists in the current sanitized queary.
+ * @return true if the parameter exists in the current sanitized queary.
*/
public boolean hasParameter(String parameter) {
return mEntries.containsKey(parameter);
@@ -766,7 +766,7 @@ public class UrlQuerySanitizer {
* the value. If all goes well then addSanitizedValue is called with
* the unescaped parameter and the sanitized unescaped value.
* @param parameter an escaped parameter
- * @param value an unsanitzied escaped value
+ * @param value an unsanitized escaped value
*/
protected void parseEntry(String parameter, String value) {
String unescapedParameter = unescape(parameter);
@@ -812,7 +812,7 @@ public class UrlQuerySanitizer {
/**
* Get the effective value sanitizer for a parameter. Like getValueSanitizer,
* except if there is no value sanitizer registered for a parameter, and
- * unregistered paramaters are allowed, then the default value sanitizer is
+ * unregistered parameters are allowed, then the default value sanitizer is
* returned.
* @param parameter an unescaped parameter
* @return the effective value sanitizer for a parameter.
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index c86149907323..01e2db2e3939 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -33,6 +33,8 @@ public class FeatureFlagUtils {
public static final String FFLAG_PREFIX = "sys.fflag.";
public static final String FFLAG_OVERRIDE_PREFIX = FFLAG_PREFIX + "override.";
+ public static final String PERSIST_PREFIX = "persist." + FFLAG_OVERRIDE_PREFIX;
+ public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
private static final Map<String, String> DEFAULT_FLAGS;
static {
@@ -44,6 +46,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put("settings_data_usage_v2", "true");
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
+ DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "true");
}
/**
diff --git a/core/java/android/util/JsonReader.java b/core/java/android/util/JsonReader.java
index 7d1c6c4918db..50f63f8db304 100644
--- a/core/java/android/util/JsonReader.java
+++ b/core/java/android/util/JsonReader.java
@@ -16,13 +16,15 @@
package android.util;
+import libcore.internal.StringPool;
+
import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
-import libcore.internal.StringPool;
+
/**
* Reads a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
@@ -295,7 +297,7 @@ public final class JsonReader implements Closeable {
/**
* Consumes the next token from the JSON stream and asserts that it is the
- * end of the current array.
+ * end of the current object.
*/
public void endObject() throws IOException {
expect(JsonToken.END_OBJECT);
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 02202db52fac..503eb9738362 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -123,7 +123,7 @@ public class KeyCharacterMap implements Parcelable {
/**
* Modifier keys may be chorded with character keys.
*
- * @see {#link #getModifierBehavior()} for more details.
+ * @see {@link #getModifierBehavior()} for more details.
*/
public static final int MODIFIER_BEHAVIOR_CHORDED = 0;
@@ -131,7 +131,7 @@ public class KeyCharacterMap implements Parcelable {
* Modifier keys may be chorded with character keys or they may toggle
* into latched or locked states when pressed independently.
*
- * @see {#link #getModifierBehavior()} for more details.
+ * @see {@link #getModifierBehavior()} for more details.
*/
public static final int MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED = 1;
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index a59740563ceb..86554fee04b9 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -883,8 +883,8 @@ public class KeyEvent extends InputEvent implements Parcelable {
/**
* {@link #getAction} value: multiple duplicate key events have
* occurred in a row, or a complex string is being delivered. If the
- * key code is not {#link {@link #KEYCODE_UNKNOWN} then the
- * {#link {@link #getRepeatCount()} method returns the number of times
+ * key code is not {@link #KEYCODE_UNKNOWN} then the
+ * {@link #getRepeatCount()} method returns the number of times
* the given key code should be executed.
* Otherwise, if the key code is {@link #KEYCODE_UNKNOWN}, then
* this is a sequence of characters as returned by {@link #getCharacters}.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2c9e543c3abd..04e818247e39 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -15493,7 +15493,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Sets the visual z position of this view, in pixels. This is equivalent to setting the
* {@link #setTranslationZ(float) translationZ} property to be the difference between
- * the x value passed in and the current {@link #getElevation() elevation} property.
+ * the z value passed in and the current {@link #getElevation() elevation} property.
*
* @param z The visual z position of this view, in pixels.
*/
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index da5a1cd67922..0e1e379d610a 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -418,20 +418,28 @@ public class AccessibilityCache {
*
* @param nodes The nodes in the hosting window.
* @param rootNodeId The id of the root to evict.
+ *
+ * @return {@code true} if the cache was cleared
*/
- private void clearSubTreeRecursiveLocked(LongSparseArray<AccessibilityNodeInfo> nodes,
+ private boolean clearSubTreeRecursiveLocked(LongSparseArray<AccessibilityNodeInfo> nodes,
long rootNodeId) {
AccessibilityNodeInfo current = nodes.get(rootNodeId);
if (current == null) {
- return;
+ // The node isn't in the cache, but its descendents might be.
+ clear();
+ return true;
}
nodes.remove(rootNodeId);
final int childCount = current.getChildCount();
for (int i = 0; i < childCount; i++) {
final long childNodeId = current.getChildId(i);
- clearSubTreeRecursiveLocked(nodes, childNodeId);
+ if (clearSubTreeRecursiveLocked(nodes, childNodeId)) {
+ current.recycle();
+ return true;
+ }
}
current.recycle();
+ return false;
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cda1293e93c7..42bbe20a1cab 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -995,7 +995,7 @@
<!-- Allows a calling application which manages it own calls through the self-managed
{@link android.telecom.ConnectionService} APIs. See
- {@link android.telecom.PhoneAccount#CAPABILITY_SELF_MANAGED for more information on the
+ {@link android.telecom.PhoneAccount#CAPABILITY_SELF_MANAGED} for more information on the
self-managed ConnectionService APIs.
<p>Protection level: normal
-->
@@ -1080,9 +1080,9 @@
android:priority="700" />
<!-- Required to be able to access the camera device.
- <p>This will automatically enforce the <a
- href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
- <uses-feature>}</a> manifest element for <em>all</em> camera features.
+ <p>This will automatically enforce the
+ <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
+ uses-feature</a> manifest element for <em>all</em> camera features.
If you do not require all camera features or can properly operate if a camera
is not available, then you must modify your manifest as appropriate in order to
install on devices that don't support all camera features.</p>
diff --git a/core/res/res/drawable/emergency_icon.xml b/core/res/res/drawable/emergency_icon.xml
index b2ffa2b4481c..c142be356a2b 100644
--- a/core/res/res/drawable/emergency_icon.xml
+++ b/core/res/res/drawable/emergency_icon.xml
@@ -18,7 +18,7 @@ Copyright (C) 2014 The Android Open Source Project
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
- android:tint="?attr/colorControlNormal">
+ android:tint="?attr/colorError">
<path
android:fillColor="#FF000000"
android:pathData="M6.8,17.3C5.3,15.9 4.5,14.0 4.5,12.0c0.0,-2.0 0.8,-3.8 2.1,-5.2l1.4,1.4c-1.0,1.0 -1.6,2.4 -1.6,3.8c0.0,1.5 0.6,2.9 1.6,3.9L6.8,17.3z"/>
diff --git a/core/res/res/drawable/ic_faster_emergency.xml b/core/res/res/drawable/ic_faster_emergency.xml
new file mode 100644
index 000000000000..680dfce5d632
--- /dev/null
+++ b/core/res/res/drawable/ic_faster_emergency.xml
@@ -0,0 +1,31 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?attr/colorError">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19,3H5C3.9,3,3.01,3.9,3.01,5L3,19c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19L5,19V5h14V19z" />
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M 10.5 17 L 13.5 17 L 13.5 13.5 L 17 13.5 L 17 10.5 L 13.5 10.5 L 13.5 7 L 10.5 7 L 10.5 10.5 L 7 10.5 L 7 13.5 L 10.5 13.5 Z" />
+ <path
+ android:pathData="M0,0h24v24H0V0z" />
+
+</vector>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 21c10ce89c1a..6b5a91489697 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1423,7 +1423,7 @@
at {@link android.view.inputmethod.InputConnection#performEditorAction(int)
InputConnection.performEditorAction(int)}.
<p>Corresponds to
- {@link android.view.inputmethod.EditorInfo#IME_FLAG_NO_FULLSCREEN}. -->
+ {@link android.view.inputmethod.EditorInfo#IME_FLAG_NAVIGATE_PREVIOUS}. -->
<flag name="flagNavigatePrevious" value="0x4000000" />
<!-- Used to specify that there is something
interesting that a forward navigation can focus on. This is like using
@@ -4166,9 +4166,9 @@
row is full. The rowCount attribute may be used similarly in the vertical case.
The default is horizontal. -->
<attr name="orientation" />
- <!-- The maxmimum number of rows to create when automatically positioning children. -->
+ <!-- The maximum number of rows to create when automatically positioning children. -->
<attr name="rowCount" format="integer" />
- <!-- The maxmimum number of columns to create when automatically positioning children. -->
+ <!-- The maximum number of columns to create when automatically positioning children. -->
<attr name="columnCount" format="integer" />
<!-- When set to true, tells GridLayout to use default margins when none are specified
in a view's layout parameters.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a10c1975339d..db03eee26630 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2613,6 +2613,7 @@
"silent" = silent mode
"users" = list of users
"restart" = restart device
+ "emergency" = Launch emergency dialer
"lockdown" = Lock down device until the user authenticates
"logout" = Logout the current user
-->
@@ -2623,6 +2624,7 @@
<item>logout</item>
<item>bugreport</item>
<item>screenshot</item>
+ <item>emergency</item>
</string-array>
<!-- Number of milliseconds to hold a wake lock to ensure that drawing is fully
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 95af9a602577..eaaa86610f75 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2989,7 +2989,7 @@
<!-- Global actions icons -->
<java-symbol type="drawable" name="ic_restart" />
<java-symbol type="drawable" name="ic_screenshot" />
-
+ <java-symbol type="drawable" name="ic_faster_emergency" />
<java-symbol type="drawable" name="emergency_icon" />
<java-symbol type="array" name="config_convert_to_emergency_number_map" />
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
index 4de8155663f5..993378d8a4d0 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
@@ -300,6 +300,26 @@ public class AccessibilityCacheTest {
}
@Test
+ public void subTreeChangeEventFromUncachedNode_clearsNodeInCache() {
+ AccessibilityNodeInfo nodeInfo = getNodeWithA11yAndWindowId(CHILD_VIEW_ID, WINDOW_ID_1);
+ long id = nodeInfo.getSourceNodeId();
+ mAccessibilityCache.add(nodeInfo);
+ nodeInfo.recycle();
+
+ AccessibilityEvent event = AccessibilityEvent
+ .obtain(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+ event.setContentChangeTypes(AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
+ event.setSource(getMockViewWithA11yAndWindowIds(PARENT_VIEW_ID, WINDOW_ID_1));
+
+ mAccessibilityCache.onAccessibilityEvent(event);
+ AccessibilityNodeInfo shouldBeNull = mAccessibilityCache.getNode(WINDOW_ID_1, id);
+ if (shouldBeNull != null) {
+ shouldBeNull.recycle();
+ }
+ assertNull(shouldBeNull);
+ }
+
+ @Test
public void scrollEvent_clearsNodeAndChild() {
AccessibilityEvent event = AccessibilityEvent
.obtain(AccessibilityEvent.TYPE_VIEW_SCROLLED);
diff --git a/location/java/android/location/Criteria.java b/location/java/android/location/Criteria.java
index a6099be60875..74eb4450d42c 100644
--- a/location/java/android/location/Criteria.java
+++ b/location/java/android/location/Criteria.java
@@ -21,9 +21,9 @@ import android.os.Parcelable;
/**
* A class indicating the application criteria for selecting a
- * location provider. Providers maybe ordered according to accuracy,
- * power usage, ability to report altitude, speed,
- * and bearing, and monetary cost.
+ * location provider. Providers may be ordered according to accuracy,
+ * power usage, ability to report altitude, speed, bearing, and monetary
+ * cost.
*/
public class Criteria implements Parcelable {
/**
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 0c38c38e88ff..8686253506f4 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4552,7 +4552,7 @@ public class AudioManager {
/**
* The message sent to apps when the contents of the device list changes if they provide
- * a {#link Handler} object to addOnAudioDeviceConnectionListener().
+ * a {@link Handler} object to addOnAudioDeviceConnectionListener().
*/
private final static int MSG_DEVICES_CALLBACK_REGISTERED = 0;
private final static int MSG_DEVICES_DEVICES_ADDED = 1;
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 54800ae213cd..2c67f3205eb1 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -467,7 +467,7 @@ public class AudioRecord implements AudioRouting
* .setSampleRate(32000)
* .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
* .build())
- * .setBufferSize(2*minBuffSize)
+ * .setBufferSizeInBytes(2*minBuffSize)
* .build();
* </pre>
* <p>
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 97d0a6ecd6a3..3151c2818d71 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -226,7 +226,7 @@ import java.util.Vector;
* transfers the object to the <em>Prepared</em> state once the method call
* returns, or a call to {@link #prepareAsync()} (asynchronous) which
* first transfers the object to the <em>Preparing</em> state after the
- * call returns (which occurs almost right way) while the internal
+ * call returns (which occurs almost right away) while the internal
* player engine continues working on the rest of preparation work
* until the preparation work completes. When the preparation completes or when {@link #prepare()} call returns,
* the internal player engine then calls a user supplied callback method,
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index 56423fda0404..828c673944cc 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -4781,7 +4781,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private void sendCompleteNotification(int status) {
// In {@link #notifyWhenCommandLabelReached} case, a separate callback
- // {#link #onCommandLabelReached} is already called in {@code process()}.
+ // {@link #onCommandLabelReached} is already called in {@code process()}.
if (mMediaCallType == CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED) {
return;
}
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
index 6595baa594d2..7919723b80a8 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
@@ -38,7 +38,7 @@ import android.util.Log;
* <p>To use, connect up the sourceListener callback, and then when executing
* the graph, use the SurfaceTexture object passed to the callback to feed
* frames into the filter graph. For example, pass the SurfaceTexture into
- * {#link
+ * {@link
* android.hardware.Camera.setPreviewTexture(android.graphics.SurfaceTexture)}.
* This filter is intended for applications that need for flexibility than the
* CameraSource and MediaSource provide. Note that the application needs to
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index bb8fbe2da9c9..1a8e24f46d48 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -143,8 +143,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
void onProfileStateChanged(LocalBluetoothProfile profile, int newProfileState) {
if (Utils.D) {
- Log.d(TAG, "onProfileStateChanged: profile " + profile +
- " newProfileState " + newProfileState);
+ Log.d(TAG, "onProfileStateChanged: profile " + profile + ", device=" + mDevice
+ + ", newProfileState " + newProfileState);
}
if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_TURNING_OFF)
{
@@ -224,6 +224,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
connectWithoutResettingTimer(connectAllProfiles);
}
+ public boolean isHearingAidDevice() {
+ return mHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID;
+ }
+
void onBondingDockConnect() {
// Attempt to connect if UUIDs are available. Otherwise,
// we will connect when the ACTION_UUID intent arrives.
@@ -1189,7 +1193,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
* @return {@code true} if {@code cachedBluetoothDevice} is a2dp device
*/
public boolean isA2dpDevice() {
- return mProfileManager.getA2dpProfile().getConnectionStatus(mDevice) ==
+ A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ return a2dpProfile != null && a2dpProfile.getConnectionStatus(mDevice) ==
BluetoothProfile.STATE_CONNECTED;
}
@@ -1197,7 +1202,17 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
* @return {@code true} if {@code cachedBluetoothDevice} is HFP device
*/
public boolean isHfpDevice() {
- return mProfileManager.getHeadsetProfile().getConnectionStatus(mDevice) ==
+ HeadsetProfile headsetProfile = mProfileManager.getHeadsetProfile();
+ return headsetProfile != null && headsetProfile.getConnectionStatus(mDevice) ==
+ BluetoothProfile.STATE_CONNECTED;
+ }
+
+ /**
+ * @return {@code true} if {@code cachedBluetoothDevice} is Hearing Aid device
+ */
+ public boolean isConnectedHearingAidDevice() {
+ HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
+ return hearingAidProfile != null && hearingAidProfile.getConnectionStatus(mDevice) ==
BluetoothProfile.STATE_CONNECTED;
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index e9d96ae0310f..1bfcf9ade8a5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -162,14 +162,14 @@ public class CachedBluetoothDeviceManager {
*/
public synchronized String getHearingAidPairDeviceSummary(CachedBluetoothDevice device) {
String pairDeviceSummary = null;
- if (device.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
- for (CachedBluetoothDevice hearingAidDevice : mHearingAidDevicesNotAddedInCache) {
- if (hearingAidDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID
- && hearingAidDevice.getHiSyncId() == device.getHiSyncId()) {
- pairDeviceSummary = hearingAidDevice.getConnectionSummary();
- }
- }
+ CachedBluetoothDevice otherHearingAidDevice =
+ getHearingAidOtherDevice(device, device.getHiSyncId());
+ if (otherHearingAidDevice != null) {
+ pairDeviceSummary = otherHearingAidDevice.getConnectionSummary();
}
+ log("getHearingAidPairDeviceSummary: pairDeviceSummary=" + pairDeviceSummary
+ + ", otherHearingAidDevice=" + otherHearingAidDevice);
+
return pairDeviceSummary;
}
@@ -358,7 +358,7 @@ public class CachedBluetoothDeviceManager {
}
}
- private CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice,
+ public CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice,
long hiSyncId) {
if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
return null;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 62f8724870e3..7ff5448ba766 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -123,6 +123,14 @@ public class LocalBluetoothProfileManager {
ParcelUuid[] uuids = adapter.getUuids();
+ List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
+ if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
+ mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
+ this);
+ addProfile(mHearingAidProfile, HearingAidProfile.NAME,
+ BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ }
+
// uuids may be null if Bluetooth is turned off
if (uuids != null) {
updateLocalProfiles(uuids);
@@ -159,13 +167,6 @@ public class LocalBluetoothProfileManager {
addProfile(mPbapProfile, PbapServerProfile.NAME,
BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED);
- List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
- if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
- mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
- this);
- addProfile(mHearingAidProfile, HearingAidProfile.NAME,
- BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
- }
if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
}
@@ -360,9 +361,10 @@ public class LocalBluetoothProfileManager {
Log.i(TAG, "Failed to connect " + mProfile + " device");
}
- if (getHearingAidProfile() != null &&
- mProfile instanceof HearingAidProfile &&
- (newState == BluetoothProfile.STATE_CONNECTED)) {
+ boolean isHearingAidProfile = (getHearingAidProfile() != null) &&
+ (mProfile instanceof HearingAidProfile);
+
+ if (isHearingAidProfile && (newState == BluetoothProfile.STATE_CONNECTED)) {
// Check if the HiSyncID has being initialized
if (cachedDevice.getHiSyncId() == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
@@ -375,10 +377,22 @@ public class LocalBluetoothProfileManager {
}
}
- mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
- mProfile.getProfileId());
cachedDevice.onProfileStateChanged(mProfile, newState);
cachedDevice.refresh();
+
+ if (isHearingAidProfile) {
+ CachedBluetoothDevice otherDevice =
+ mDeviceManager.getHearingAidOtherDevice(cachedDevice, cachedDevice.getHiSyncId());
+ if (otherDevice != null) {
+ if (DEBUG) {
+ Log.d(TAG, "Refreshing other hearing aid=" + otherDevice
+ + ", newState=" + newState);
+ }
+ otherDevice.refresh();
+ }
+ }
+ mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
+ mProfile.getProfileId());
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 16ed85cf5afa..db9b44f2c132 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -835,4 +835,20 @@ public class CachedBluetoothDeviceManagerTest {
assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
}
+
+ /**
+ * Test to verify getHearingAidOtherDevice() for hearing aid devices with same HiSyncId.
+ */
+ @Test
+ public void testGetHearingAidOtherDevice_bothHearingAidsPaired_returnsOtherDevice() {
+ mCachedDevice1.setHiSyncId(HISYNCID1);
+ mCachedDevice2.setHiSyncId(HISYNCID1);
+ mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+ mCachedDeviceManager.mHearingAidDevicesNotAddedInCache.add(mCachedDevice2);
+ doAnswer((invocation) -> DEVICE_SUMMARY_1).when(mCachedDevice1).getConnectionSummary();
+ doAnswer((invocation) -> DEVICE_SUMMARY_2).when(mCachedDevice2).getConnectionSummary();
+
+ assertThat(mCachedDeviceManager.getHearingAidOtherDevice(mCachedDevice1, HISYNCID1))
+ .isEqualTo(mCachedDevice2);
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 927a94f6b017..30da88245913 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -28,6 +28,7 @@ import static org.robolectric.Shadows.shadowOf;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.media.AudioManager;
@@ -572,4 +573,55 @@ public class CachedBluetoothDeviceTest {
assertThat(mCachedDevice.isHfpDevice()).isFalse();
}
+
+ @Test
+ public void isConnectedHearingAidDevice_connected_returnTrue() {
+ when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+ when(mHearingAidProfile.getConnectionStatus(mDevice)).
+ thenReturn(BluetoothProfile.STATE_CONNECTED);
+
+ assertThat(mCachedDevice.isConnectedHearingAidDevice()).isTrue();
+ }
+
+ @Test
+ public void isConnectedHearingAidDevice_disconnected_returnFalse() {
+ when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+ when(mHearingAidProfile.getConnectionStatus(mDevice)).
+ thenReturn(BluetoothProfile.STATE_DISCONNECTED);
+
+ assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse();
+ }
+
+ @Test
+ public void isConnectedHfpDevice_profileIsNull_returnFalse() {
+ when(mProfileManager.getHeadsetProfile()).thenReturn(null);
+
+ assertThat(mCachedDevice.isHfpDevice()).isFalse();
+ }
+
+ @Test
+ public void isConnectedA2dpDevice_profileIsNull_returnFalse() {
+ when(mProfileManager.getA2dpProfile()).thenReturn(null);
+
+ assertThat(mCachedDevice.isA2dpDevice()).isFalse();
+ }
+
+ @Test
+ public void isConnectedHearingAidDevice_profileIsNull_returnFalse() {
+ when(mProfileManager.getHearingAidProfile()).thenReturn(null);
+
+ assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse();
+ }
+
+ @Test
+ public void testIsHearingAidDevice_isHearingAidDevice() {
+ mCachedDevice.setHiSyncId(0x1234);
+ assertThat(mCachedDevice.isHearingAidDevice()).isTrue();
+ }
+
+ @Test
+ public void testIsHearingAidDevice_isNotHearingAidDevice() {
+ mCachedDevice.setHiSyncId(BluetoothHearingAid.HI_SYNC_ID_INVALID);
+ assertThat(mCachedDevice.isHearingAidDevice()).isFalse();
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
index d342bc878477..d7b651b876d3 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -52,6 +53,7 @@ import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(resourceDir = "../../res")
public class LocalBluetoothProfileManagerTest {
+ private final static long HI_SYNC_ID = 0x1234;
@Mock
private CachedBluetoothDeviceManager mDeviceManager;
@Mock
@@ -62,6 +64,8 @@ public class LocalBluetoothProfileManagerTest {
private BluetoothDevice mDevice;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock
+ private CachedBluetoothDevice mHearingAidOtherDevice;
private Context mContext;
private LocalBluetoothProfileManager mProfileManager;
@@ -200,6 +204,32 @@ public class LocalBluetoothProfileManagerTest {
}
/**
+ * Verify BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
+ * refresh both sides devices.
+ */
+ @Test
+ public void stateChangedHandler_receiveHAPConnectionStateChanged_shouldRefreshBothSides() {
+ ArrayList<Integer> supportProfiles = new ArrayList<>();
+ supportProfiles.add(BluetoothProfile.HEARING_AID);
+ when(mAdapter.getSupportedProfiles()).thenReturn(supportProfiles);
+ when(mCachedBluetoothDevice.getHiSyncId()).thenReturn(HI_SYNC_ID);
+ when(mDeviceManager.getHearingAidOtherDevice(mCachedBluetoothDevice, HI_SYNC_ID))
+ .thenReturn(mHearingAidOtherDevice);
+
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+ mEventManager);
+ mIntent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+ mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+ mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mCachedBluetoothDevice).refresh();
+ verify(mHearingAidOtherDevice).refresh();
+ }
+
+ /**
* Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuid will dispatch to
* profile connection state changed callback
*/
diff --git a/packages/SystemUI/res/layout/global_actions_wrapped.xml b/packages/SystemUI/res/layout/global_actions_wrapped.xml
index b715def73294..7f4e0d21078f 100644
--- a/packages/SystemUI/res/layout/global_actions_wrapped.xml
+++ b/packages/SystemUI/res/layout/global_actions_wrapped.xml
@@ -3,7 +3,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_gravity="top|right"
android:layout_marginBottom="0dp"
+ android:orientation="vertical"
android:paddingTop="@dimen/global_actions_top_padding"
android:clipToPadding="false"
android:theme="@style/qs_theme"
@@ -17,7 +19,19 @@
android:layout_gravity="top|right"
android:gravity="center"
android:orientation="vertical"
- android:padding="12dp"
- android:translationZ="9dp" />
+ android:padding="@dimen/global_actions_padding"
+ android:translationZ="@dimen/global_actions_translate" />
+
+ <!-- For separated button-->
+ <FrameLayout
+ android:id="@+id/separated_button"
+ android:layout_width="@dimen/global_actions_panel_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|right"
+ android:layout_marginTop="6dp"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:padding="@dimen/global_actions_padding"
+ android:translationZ="@dimen/global_actions_translate" />
</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 7d90e02d0f2f..79e1fae98c21 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -922,6 +922,10 @@
<dimen name="global_actions_top_padding">120dp</dimen>
+ <dimen name="global_actions_padding">12dp</dimen>
+
+ <dimen name="global_actions_translate">9dp</dimen>
+
<!-- The maximum offset in either direction that elements are moved horizontally to prevent
burn-in on AOD. -->
<dimen name="burn_in_prevention_offset_x">8dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index 943558943821..f4f2ebce4f53 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -38,6 +38,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.IccCardConstants.State;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.util.EmergencyAffordanceManager;
+import com.android.systemui.util.EmergencyDialerConstants;
/**
* This class implements a smart emergency button that updates itself based
@@ -47,11 +48,13 @@ import com.android.internal.util.EmergencyAffordanceManager;
*/
public class EmergencyButton extends Button {
private static final Intent INTENT_EMERGENCY_DIAL = new Intent()
- .setAction("com.android.phone.EmergencyDialer.DIAL")
+ .setAction(EmergencyDialerConstants.ACTION_DIAL)
.setPackage("com.android.phone")
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
+ EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
private static final String LOG_TAG = "EmergencyButton";
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
index 98dc3219acc6..198a4e6cedb8 100644
--- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -27,32 +27,33 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
-import android.widget.FrameLayout;
import android.widget.LinearLayout;
+
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.leak.RotationUtils;
-import java.util.ArrayList;
-
import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
-public class HardwareUiLayout extends FrameLayout implements Tunable {
+public class HardwareUiLayout extends LinearLayout implements Tunable {
private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
private final int[] mTmp2 = new int[2];
- private View mChild;
+ private View mList;
+ private View mSeparatedView;
private int mOldHeight;
private boolean mAnimating;
private AnimatorSet mAnimation;
private View mDivision;
private boolean mHasOutsideTouch;
- private HardwareBgDrawable mBackground;
+ private HardwareBgDrawable mListBackground;
+ private HardwareBgDrawable mSeparatedViewBackground;
private Animator mAnimator;
private boolean mCollapse;
+ private boolean mHasSeparatedButton;
private int mEndPoint;
private boolean mEdgeBleed;
private boolean mRoundedDivider;
@@ -91,16 +92,19 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
mRoundedDivider = Settings.Secure.getInt(getContext().getContentResolver(),
ROUNDED_DIVIDER, 0) != 0;
updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
- mBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
- if (mChild != null) {
- mChild.setBackground(mBackground);
+ mListBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
+ mSeparatedViewBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed,
+ getContext());
+ if (mList != null) {
+ mList.setBackground(mListBackground);
+ mSeparatedView.setBackground(mSeparatedViewBackground);
requestLayout();
}
}
private void updateEdgeMargin(int edge) {
- if (mChild != null) {
- MarginLayoutParams params = (MarginLayoutParams) mChild.getLayoutParams();
+ if (mList != null) {
+ MarginLayoutParams params = (MarginLayoutParams) mList.getLayoutParams();
if (mRotation == ROTATION_LANDSCAPE) {
params.topMargin = edge;
} else if (mRotation == ROTATION_SEASCAPE) {
@@ -108,7 +112,19 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
} else {
params.rightMargin = edge;
}
- mChild.setLayoutParams(params);
+ mList.setLayoutParams(params);
+ }
+
+ if (mSeparatedView != null) {
+ MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams();
+ if (mRotation == ROTATION_LANDSCAPE) {
+ params.topMargin = edge;
+ } else if (mRotation == ROTATION_SEASCAPE) {
+ params.bottomMargin = edge;
+ } else {
+ params.rightMargin = edge;
+ }
+ mSeparatedView.setLayoutParams(params);
}
}
@@ -119,13 +135,15 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- if (mChild == null) {
+ if (mList == null) {
if (getChildCount() != 0) {
- mChild = getChildAt(0);
- mChild.setBackground(mBackground);
+ mList = getChildAt(0);
+ mList.setBackground(mListBackground);
+ mSeparatedView = getChildAt(1);
+ mSeparatedView.setBackground(mSeparatedViewBackground);
updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
- mOldHeight = mChild.getMeasuredHeight();
- mChild.addOnLayoutChangeListener(
+ mOldHeight = mList.getMeasuredHeight();
+ mList.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
updatePosition());
updateRotation();
@@ -133,7 +151,7 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
return;
}
}
- int newHeight = mChild.getMeasuredHeight();
+ int newHeight = mList.getMeasuredHeight();
if (newHeight != mOldHeight) {
animateChild(mOldHeight, newHeight);
}
@@ -170,37 +188,60 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
} else {
rotateLeft();
}
+ if (mHasSeparatedButton) {
+ if (from == ROTATION_SEASCAPE || to == ROTATION_SEASCAPE) {
+ // Separated view has top margin, so seascape separated view need special rotation,
+ // not a full left or right rotation.
+ swapLeftAndTop(mSeparatedView);
+ } else if (from == ROTATION_LANDSCAPE) {
+ rotateRight(mSeparatedView);
+ } else {
+ rotateLeft(mSeparatedView);
+ }
+ }
if (to != ROTATION_NONE) {
- if (mChild instanceof LinearLayout) {
+ if (mList instanceof LinearLayout) {
mRotatedBackground = true;
- mBackground.setRotatedBackground(true);
- LinearLayout linearLayout = (LinearLayout) mChild;
+ mListBackground.setRotatedBackground(true);
+ mSeparatedViewBackground.setRotatedBackground(true);
+ LinearLayout linearLayout = (LinearLayout) mList;
if (mSwapOrientation) {
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
+ setOrientation(LinearLayout.HORIZONTAL);
}
- swapDimens(this.mChild);
+ swapDimens(mList);
+ swapDimens(mSeparatedView);
}
} else {
- if (mChild instanceof LinearLayout) {
+ if (mList instanceof LinearLayout) {
mRotatedBackground = false;
- mBackground.setRotatedBackground(false);
- LinearLayout linearLayout = (LinearLayout) mChild;
+ mListBackground.setRotatedBackground(false);
+ mSeparatedViewBackground.setRotatedBackground(false);
+ LinearLayout linearLayout = (LinearLayout) mList;
if (mSwapOrientation) {
linearLayout.setOrientation(LinearLayout.VERTICAL);
+ setOrientation(LinearLayout.VERTICAL);
}
- swapDimens(mChild);
+ swapDimens(mList);
+ swapDimens(mSeparatedView);
}
}
}
private void rotateRight() {
rotateRight(this);
- rotateRight(mChild);
+ rotateRight(mList);
swapDimens(this);
- LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+ LayoutParams p = (LayoutParams) mList.getLayoutParams();
p.gravity = rotateGravityRight(p.gravity);
- mChild.setLayoutParams(p);
+ mList.setLayoutParams(p);
+
+ LayoutParams separatedViewLayoutParams = (LayoutParams) mSeparatedView.getLayoutParams();
+ separatedViewLayoutParams.gravity = rotateGravityRight(separatedViewLayoutParams.gravity);
+ mSeparatedView.setLayoutParams(separatedViewLayoutParams);
+
+ setGravity(p.gravity);
}
private void swapDimens(View v) {
@@ -247,12 +288,18 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
private void rotateLeft() {
rotateLeft(this);
- rotateLeft(mChild);
+ rotateLeft(mList);
swapDimens(this);
- LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+ LayoutParams p = (LayoutParams) mList.getLayoutParams();
p.gravity = rotateGravityLeft(p.gravity);
- mChild.setLayoutParams(p);
+ mList.setLayoutParams(p);
+
+ LayoutParams separatedViewLayoutParams = (LayoutParams) mSeparatedView.getLayoutParams();
+ separatedViewLayoutParams.gravity = rotateGravityLeft(separatedViewLayoutParams.gravity);
+ mSeparatedView.setLayoutParams(separatedViewLayoutParams);
+
+ setGravity(p.gravity);
}
private int rotateGravityLeft(int gravity) {
@@ -310,6 +357,15 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
v.setLayoutParams(params);
}
+ private void swapLeftAndTop(View v) {
+ v.setPadding(v.getPaddingTop(), v.getPaddingLeft(), v.getPaddingBottom(),
+ v.getPaddingRight());
+ MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+ params.setMargins(params.topMargin, params.leftMargin, params.bottomMargin,
+ params.rightMargin);
+ v.setLayoutParams(params);
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -329,14 +385,14 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
mAnimating = false;
}
});
- int fromTop = mChild.getTop();
- int fromBottom = mChild.getBottom();
+ int fromTop = mList.getTop();
+ int fromBottom = mList.getBottom();
int toTop = fromTop - ((newHeight - oldHeight) / 2);
int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
- ObjectAnimator top = ObjectAnimator.ofInt(mChild, "top", fromTop, toTop);
- top.addUpdateListener(animation -> mBackground.invalidateSelf());
+ ObjectAnimator top = ObjectAnimator.ofInt(mList, "top", fromTop, toTop);
+ top.addUpdateListener(animation -> mListBackground.invalidateSelf());
mAnimation.playTogether(top,
- ObjectAnimator.ofInt(mChild, "bottom", fromBottom, toBottom));
+ ObjectAnimator.ofInt(mList, "bottom", fromBottom, toBottom));
}
public void setDivisionView(View v) {
@@ -350,26 +406,30 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
}
private void updatePosition() {
- if (mChild == null) return;
+ if (mList == null) return;
+ // If got separated button, setRotatedBackground to false,
+ // all items won't get white background.
+ mListBackground.setRotatedBackground(mHasSeparatedButton);
+ mSeparatedViewBackground.setRotatedBackground(mHasSeparatedButton);
if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
int index = mRotatedBackground ? 0 : 1;
mDivision.getLocationOnScreen(mTmp2);
float trans = mRotatedBackground ? mDivision.getTranslationX()
: mDivision.getTranslationY();
int viewTop = (int) (mTmp2[index] + trans);
- mChild.getLocationOnScreen(mTmp2);
+ mList.getLocationOnScreen(mTmp2);
viewTop -= mTmp2[index];
setCutPoint(viewTop);
} else {
- setCutPoint(mChild.getMeasuredHeight());
+ setCutPoint(mList.getMeasuredHeight());
}
}
private void setCutPoint(int point) {
- int curPoint = mBackground.getCutPoint();
+ int curPoint = mListBackground.getCutPoint();
if (curPoint == point) return;
if (getAlpha() == 0 || curPoint == 0) {
- mBackground.setCutPoint(point);
+ mListBackground.setCutPoint(point);
return;
}
if (mAnimator != null) {
@@ -379,7 +439,7 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
mAnimator.cancel();
}
mEndPoint = point;
- mAnimator = ObjectAnimator.ofInt(mBackground, "cutPoint", curPoint, point);
+ mAnimator = ObjectAnimator.ofInt(mListBackground, "cutPoint", curPoint, point);
if (mCollapse) {
mAnimator.setStartDelay(300);
mCollapse = false;
@@ -404,6 +464,10 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
mCollapse = true;
}
+ public void setHasSeparatedButton(boolean hasSeparatedButton) {
+ mHasSeparatedButton = hasSeparatedButton;
+ }
+
public static HardwareUiLayout get(View v) {
if (v instanceof HardwareUiLayout) return (HardwareUiLayout) v;
if (v.getParent() instanceof View) {
@@ -413,14 +477,14 @@ public class HardwareUiLayout extends FrameLayout implements Tunable {
}
private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
- if (mHasOutsideTouch || (mChild == null)) {
+ if (mHasOutsideTouch || (mList == null)) {
inoutInfo.setTouchableInsets(
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
return;
}
inoutInfo.setTouchableInsets(
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
- inoutInfo.contentInsets.set(mChild.getLeft(), mChild.getTop(),
- 0, getBottom() - mChild.getBottom());
+ inoutInfo.contentInsets.set(mList.getLeft(), mList.getTop(),
+ 0, getBottom() - mList.getBottom());
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index d232108ded40..897ab88215ef 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -28,12 +28,10 @@ import android.app.WallpaperManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.ServiceConnection;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.graphics.Point;
@@ -42,9 +40,7 @@ import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
-import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -68,9 +64,9 @@ import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
-import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
@@ -93,6 +89,7 @@ import com.android.systemui.Interpolators;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.util.EmergencyDialerConstants;
import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator;
import java.util.ArrayList;
@@ -104,7 +101,7 @@ import java.util.List;
* is provisioned.
*/
class GlobalActionsDialog implements DialogInterface.OnDismissListener,
- DialogInterface.OnClickListener {
+ DialogInterface.OnClickListener, DialogInterface.OnShowListener {
static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -127,6 +124,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
private static final String GLOBAL_ACTION_KEY_RESTART = "restart";
private static final String GLOBAL_ACTION_KEY_LOGOUT = "logout";
+ private static final String GLOBAL_ACTION_KEY_EMERGENCY = "emergency";
private static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot";
private final Context mContext;
@@ -153,6 +151,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private boolean mHasVibrator;
private boolean mHasLogoutButton;
private boolean mHasLockdownButton;
+ private boolean mSeparatedEmergencyButtonEnabled;
private final boolean mShowSilentToggle;
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
private final ScreenshotHelper mScreenshotHelper;
@@ -319,6 +318,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
ArraySet<String> addedKeys = new ArraySet<String>();
mHasLogoutButton = false;
mHasLockdownButton = false;
+ mSeparatedEmergencyButtonEnabled = true;
for (int i = 0; i < defaultActions.length; i++) {
String actionKey = defaultActions[i];
if (addedKeys.contains(actionKey)) {
@@ -365,6 +365,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mItems.add(new LogoutAction());
mHasLogoutButton = true;
}
+ } else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) {
+ if (mSeparatedEmergencyButtonEnabled
+ && !mEmergencyAffordanceManager.needsEmergencyAffordance()) {
+ mItems.add(new EmergencyDialerAction());
+ }
} else {
Log.e(TAG, "Invalid global action key " + actionKey);
}
@@ -386,11 +391,13 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
return false;
};
- ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener);
+ ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener,
+ mSeparatedEmergencyButtonEnabled);
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
dialog.setKeyguardShowing(mKeyguardShowing);
dialog.setOnDismissListener(this);
+ dialog.setOnShowListener(this);
return dialog;
}
@@ -441,6 +448,33 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
}
+ private class EmergencyDialerAction extends SinglePressAction {
+ private EmergencyDialerAction() {
+ super(R.drawable.ic_faster_emergency,
+ R.string.global_action_emergency);
+ }
+
+ @Override
+ public void onPress() {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_EMERGENCY_DIALER_FROM_POWER_MENU);
+ Intent intent = new Intent(EmergencyDialerConstants.ACTION_DIAL);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
+ EmergencyDialerConstants.ENTRY_TYPE_POWER_MENU);
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ }
+
+ @Override
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ @Override
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ }
+
private final class RestartAction extends SinglePressAction implements LongPressAction {
private RestartAction() {
super(R.drawable.ic_restart, R.string.global_action_restart);
@@ -626,6 +660,12 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
private Action getEmergencyAction() {
+ Drawable emergencyIcon = mContext.getDrawable(R.drawable.emergency_icon);
+ if(!mSeparatedEmergencyButtonEnabled) {
+ // use un-colored legacy treatment
+ emergencyIcon.setTintList(null);
+ }
+
return new SinglePressAction(R.drawable.emergency_icon,
R.string.global_action_emergency) {
@Override
@@ -823,6 +863,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
item.onPress();
}
+ /** {@inheritDoc} */
+ public void onShow(DialogInterface dialog) {
+ MetricsLogger.visible(mContext, MetricsEvent.POWER_MENU);
+ }
+
/**
* The adapter used for the list within the global actions dialog, taking
* into account whether the keyguard is showing via
@@ -1354,15 +1399,17 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private final Context mContext;
private final MyAdapter mAdapter;
private final LinearLayout mListView;
+ private final FrameLayout mSeparatedView;
private final HardwareUiLayout mHardwareLayout;
private final OnClickListener mClickListener;
private final OnItemLongClickListener mLongClickListener;
private final GradientDrawable mGradientDrawable;
private final ColorExtractor mColorExtractor;
private boolean mKeyguardShowing;
+ private boolean mShouldDisplaySeparatedButton;
public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
- OnItemLongClickListener longClickListener) {
+ OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton) {
super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
mContext = context;
mAdapter = adapter;
@@ -1370,6 +1417,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mLongClickListener = longClickListener;
mGradientDrawable = new GradientDrawable(mContext);
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+ mShouldDisplaySeparatedButton = shouldDisplaySeparatedButton;
// Window initialization
Window window = getWindow();
@@ -1393,8 +1441,13 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
setContentView(com.android.systemui.R.layout.global_actions_wrapped);
mListView = findViewById(android.R.id.list);
+ mSeparatedView = findViewById(com.android.systemui.R.id.separated_button);
+ if (!mShouldDisplaySeparatedButton) {
+ mSeparatedView.setVisibility(View.GONE);
+ }
mHardwareLayout = HardwareUiLayout.get(mListView);
mHardwareLayout.setOutsideTouchListener(view -> dismiss());
+ mHardwareLayout.setHasSeparatedButton(mShouldDisplaySeparatedButton);
setTitle(R.string.global_actions);
mListView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
@@ -1409,13 +1462,16 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private void updateList() {
mListView.removeAllViews();
+ mSeparatedView.removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
- View v = mAdapter.getView(i, null, mListView);
+ ViewGroup parentView = mShouldDisplaySeparatedButton && i == mAdapter.getCount() - 1
+ ? mSeparatedView : mListView;
+ View v = mAdapter.getView(i, null, parentView);
final int pos = i;
v.setOnClickListener(view -> mClickListener.onClick(this, pos));
v.setOnLongClickListener(view ->
mLongClickListener.onItemLongClick(null, v, pos, 0));
- mListView.addView(v);
+ parentView.addView(v);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java b/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java
new file mode 100644
index 000000000000..d101ccbe30ea
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util;
+
+/**
+ * Constants defined and used in emergency dialer.
+ * Please keep these constants being consistent with those in com.android.phone.EmergencyDialer.
+ */
+public class EmergencyDialerConstants {
+ // Intent action for emergency dialer activity.
+ public static final String ACTION_DIAL = "com.android.phone.EmergencyDialer.DIAL";
+
+ /**
+ * Extra included in {@link #ACTION_DIAL} to indicate the entry type that user starts
+ * the emergency dialer.
+ */
+ public static final String EXTRA_ENTRY_TYPE =
+ "com.android.phone.EmergencyDialer.extra.ENTRY_TYPE";
+
+ // Indicating the entrance to emergency dialer
+ public static final int ENTRY_TYPE_UNKNOWN = 0;
+ public static final int ENTRY_TYPE_LOCKSCREEN_BUTTON = 1;
+ public static final int ENTRY_TYPE_POWER_MENU = 2;
+}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 0833e34ff8b3..d79d833f2233 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -6429,6 +6429,69 @@ message MetricsEvent {
// OS: Q (will also ship in PQ1A)
FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH = 1553;
+ // OPEN: Emergency dialer opened
+ // CLOSE: Emergency dialer closed
+ // SUBTYPE: The entry type that user opened emergency dialer
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ EMERGENCY_DIALER = 1558;
+
+ // FIELD: The screen is currently locked
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ FIELD_EMERGENCY_DIALER_IS_SCREEN_LOCKED = 1559;
+
+ // FIELD: Bit flag indicating the actions performed by user
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ FIELD_EMERGENCY_DIALER_USER_ACTIONS = 1560;
+
+ // FIELD: The duration user stayed at emergency dialer
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ FIELD_EMERGENCY_DIALER_DURATION_MS = 1561;
+
+ // ACTION: Making call via emergency dialer
+ // SUBTYPE: The UI that user made phone call
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ EMERGENCY_DIALER_MAKE_CALL = 1562;
+
+ // FIELD: The phone number type of a call user made
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ FIELD_EMERGENCY_DIALER_PHONE_NUMBER_TYPE = 1563;
+
+ // FIELD: There is a shortcut for the phone number
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ FIELD_EMERGENCY_DIALER_PHONE_NUMBER_HAS_SHORTCUT = 1564;
+
+ // FIELD: The phone is in pocket while using emergency dialer
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ FIELD_EMERGENCY_DIALER_IN_POCKET = 1565;
+
+ // ACTION: The second tap on emergency shortcut to make a phone call
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ EMERGENCY_DIALER_SHORTCUT_CONFIRM_TAP = 1566;
+
+ // FIELD: The time in milliseconds of second tap on shortcut since first tap
+ // CATEGORY: EMERGENCY_DIALER
+ // OS: Q
+ FIELD_EMERGENCY_DIALER_SHORTCUT_TAPS_INTERVAL = 1567;
+
+ // OPEN: Power menu is opened
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: Q
+ POWER_MENU = 1568;
+
+ // ACTION: User tapped emergency dialer icon in the power menu.
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: Q
+ ACTION_EMERGENCY_DIALER_FROM_POWER_MENU = 1569;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index aa426d3cd31f..78b738500a97 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -53,12 +53,16 @@ import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.UserManagerInternal.UserRestrictionsListener;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
+import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
+import android.util.Log;
import android.util.Slog;
import android.util.StatsLog;
@@ -386,6 +390,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
+ // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
+ boolean isHearingAidEnabled;
+ String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
+ if (!TextUtils.isEmpty(value)) {
+ isHearingAidEnabled = Boolean.parseBoolean(value);
+ Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
+ FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
+ }
+
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index f9dccea0d34c..aad890b8bd74 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -22,6 +22,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA
import android.annotation.Nullable;
import android.os.FileUtils;
+import android.os.SystemProperties;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -38,6 +39,10 @@ import java.util.regex.Pattern;
final class MemoryStatUtil {
private static final String TAG = TAG_WITH_CLASS_NAME ? "MemoryStatUtil" : TAG_AM;
+ /** True if device has per-app memcg */
+ private static final Boolean DEVICE_HAS_PER_APP_MEMCG =
+ SystemProperties.getBoolean("ro.config.per_app_memcg", false);
+
/** Path to check if device has memcg */
private static final String MEMCG_TEST_PATH = "/dev/memcg/apps/memory.stat";
/** Path to memory stat file for logging app start memory state */
@@ -55,15 +60,12 @@ final class MemoryStatUtil {
private static final int PGMAJFAULT_INDEX = 11;
private static final int RSS_IN_BYTES_INDEX = 23;
- /** True if device has memcg */
- private static volatile Boolean sDeviceHasMemCg;
-
private MemoryStatUtil() {}
/**
* Reads memory stat for a process.
*
- * Reads from memcg if available on device, else fallback to procfs.
+ * Reads from per-app memcg if available on device, else fallback to procfs.
* Returns null if no stats can be read.
*/
@Nullable
@@ -156,15 +158,10 @@ final class MemoryStatUtil {
}
/**
- * Checks if memcg is available on device.
- *
- * Touches the filesystem to do the check.
+ * Returns whether per-app memcg is available on device.
*/
static boolean hasMemcg() {
- if (sDeviceHasMemCg == null) {
- sDeviceHasMemCg = (new File(MEMCG_TEST_PATH)).exists();
- }
- return sDeviceHasMemCg;
+ return DEVICE_HAS_PER_APP_MEMCG;
}
static final class MemoryStat {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 415a822e3160..4746e12e2838 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -845,10 +845,16 @@ class UserController implements Handler.Callback {
}
void scheduleStartProfiles() {
- if (!mHandler.hasMessages(START_PROFILES_MSG)) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
- DateUtils.SECOND_IN_MILLIS);
- }
+ // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is
+ // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no
+ // attempt will be made to unlock the profile. If we go via FgThread, this will be executed
+ // after the parent had chance to unlock fully.
+ FgThread.getHandler().post(() -> {
+ if (!mHandler.hasMessages(START_PROFILES_MSG)) {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
+ DateUtils.SECOND_IN_MILLIS);
+ }
+ });
}
void startProfiles() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f2b7bbe636e5..b7247166855d 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2299,8 +2299,9 @@ public class NotificationManagerService extends SystemService {
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(
String pkg) {
checkCallerIsSystemOrSameApp(pkg);
+
return mRankingHelper.getNotificationChannelGroups(
- pkg, Binder.getCallingUid(), false, false);
+ pkg, Binder.getCallingUid(), false, false, true);
}
@Override
@@ -2376,7 +2377,9 @@ public class NotificationManagerService extends SystemService {
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroupsForPackage(
String pkg, int uid, boolean includeDeleted) {
checkCallerIsSystem();
- return mRankingHelper.getNotificationChannelGroups(pkg, uid, includeDeleted, true);
+
+ return mRankingHelper.getNotificationChannelGroups(
+ pkg, uid, includeDeleted, true, false);
}
@Override
@@ -4255,13 +4258,6 @@ public class NotificationManagerService extends SystemService {
final String pkg = r.sbn.getPackageName();
final int callingUid = r.sbn.getUid();
- final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
- if (isPackageSuspended) {
- Slog.e(TAG, "Suppressing notification from package due to package "
- + "suspended by administrator.");
- usageStats.registerSuspendedByAdmin(r);
- return isPackageSuspended;
- }
final boolean isBlocked =
mRankingHelper.isGroupBlocked(pkg, callingUid, r.getChannel().getGroup())
|| mRankingHelper.getImportance(pkg, callingUid)
@@ -4270,8 +4266,9 @@ public class NotificationManagerService extends SystemService {
if (isBlocked) {
Slog.e(TAG, "Suppressing notification from package by user request.");
usageStats.registerBlocked(r);
+ return true;
}
- return isBlocked;
+ return false;
}
protected class SnoozeNotificationRunnable implements Runnable {
@@ -4449,7 +4446,11 @@ public class NotificationManagerService extends SystemService {
return;
}
- r.setHidden(isPackageSuspendedLocked(r));
+ final boolean isPackageSuspended = isPackageSuspendedLocked(r);
+ r.setHidden(isPackageSuspended);
+ if (isPackageSuspended) {
+ mUsageStats.registerSuspendedByAdmin(r);
+ }
NotificationRecord old = mNotificationsByKey.get(key);
final StatusBarNotification n = r.sbn;
final Notification notification = n.getNotification();
@@ -6625,7 +6626,6 @@ public class NotificationManagerService extends SystemService {
if (!oldSbnVisible && !sbnVisible) {
continue;
}
-
// If the notification is hidden, don't notifyPosted listeners targeting < P.
// Instead, those listeners will receive notifyPosted when the notification is
// unhidden.
@@ -7059,7 +7059,7 @@ public class NotificationManagerService extends SystemService {
new String[]{pkg});
final String action = suspend ? Intent.ACTION_PACKAGES_SUSPENDED
- : Intent.ACTION_PACKAGES_UNSUSPENDED;
+ : Intent.ACTION_PACKAGES_UNSUSPENDED;
final Intent intent = new Intent(action);
intent.putExtras(extras);
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index af6468333ba0..605348b4d52d 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -36,7 +36,7 @@ public interface RankingConfig {
void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
boolean fromTargetApp);
ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
- int uid, boolean includeDeleted, boolean includeNonGrouped);
+ int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty);
void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
boolean fromTargetApp, boolean hasDndAccess);
void updateNotificationChannel(String pkg, int uid, NotificationChannel channel, boolean fromUser);
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 61b5415ec7a3..da6e9c02c96a 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -830,7 +830,7 @@ public class RankingHelper implements RankingConfig {
@Override
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
- int uid, boolean includeDeleted, boolean includeNonGrouped) {
+ int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty) {
Preconditions.checkNotNull(pkg);
Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
Record r = getRecord(pkg, uid);
@@ -861,6 +861,13 @@ public class RankingHelper implements RankingConfig {
if (includeNonGrouped && nonGrouped.getChannels().size() > 0) {
groups.put(null, nonGrouped);
}
+ if (includeEmpty) {
+ for (NotificationChannelGroup group : r.groups.values()) {
+ if (!groups.containsKey(group.getId())) {
+ groups.put(group.getId(), group);
+ }
+ }
+ }
return new ParceledListSlice<>(new ArrayList<>(groups.values()));
}
@@ -1244,7 +1251,7 @@ public class RankingHelper implements RankingConfig {
/**
* Dump only the ban information as structured JSON for the stats collector.
*
- * This is intentionally redundant with {#link dumpJson} because the old
+ * This is intentionally redundant with {@link dumpJson} because the old
* scraper will expect this format.
*
* @param filter
@@ -1288,7 +1295,7 @@ public class RankingHelper implements RankingConfig {
/**
* Dump only the channel information as structured JSON for the stats collector.
*
- * This is intentionally redundant with {#link dumpJson} because the old
+ * This is intentionally redundant with {@link dumpJson} because the old
* scraper will expect this format.
*
* @param filter
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index cdbf3c66767b..955e2477fc66 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -500,8 +500,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationChannel channel = new NotificationChannel("id", "name",
IMPORTANCE_HIGH);
NotificationRecord r = generateNotificationRecord(channel);
- assertTrue(mService.isBlocked(r, mUsageStats));
- verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r));
+
+ // isBlocked is only used for user blocking, not app suspension
+ assertFalse(mService.isBlocked(r, mUsageStats));
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 98c6ec42207f..a9e713e5778b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -399,7 +399,7 @@ public class RankingHelperTest extends UiServiceTestCase {
mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
List<NotificationChannelGroup> actualGroups =
- mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, false, true, false).getList();
boolean foundNcg = false;
for (NotificationChannelGroup actual : actualGroups) {
if (ncg.getId().equals(actual.getId())) {
@@ -469,7 +469,7 @@ public class RankingHelperTest extends UiServiceTestCase {
mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
List<NotificationChannelGroup> actualGroups =
- mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, false, true, false).getList();
boolean foundNcg = false;
for (NotificationChannelGroup actual : actualGroups) {
if (ncg.getId().equals(actual.getId())) {
@@ -784,6 +784,31 @@ public class RankingHelperTest extends UiServiceTestCase {
new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false);
}
+ @Test
+ public void testGetChannelGroups_includeEmptyGroups() {
+ NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
+ mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
+ NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
+ mHelper.createNotificationChannelGroup(PKG, UID, ncgEmpty, true);
+
+ NotificationChannel channel1 =
+ new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
+ channel1.setGroup(ncg.getId());
+ mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
+
+ List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
+ PKG, UID, false, false, true).getList();
+
+ assertEquals(2, actual.size());
+ for (NotificationChannelGroup group : actual) {
+ if (Objects.equals(group.getId(), ncg.getId())) {
+ assertEquals(1, group.getChannels().size());
+ }
+ if (Objects.equals(group.getId(), ncgEmpty.getId())) {
+ assertEquals(0, group.getChannels().size());
+ }
+ }
+ }
@Test
public void testUpdate() throws Exception {
@@ -1421,7 +1446,7 @@ public class RankingHelperTest extends UiServiceTestCase {
mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
assertEquals(0,
- mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList().size());
+ mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList().size());
}
@Test
@@ -1510,7 +1535,7 @@ public class RankingHelperTest extends UiServiceTestCase {
mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
List<NotificationChannelGroup> actual =
- mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
assertEquals(3, actual.size());
for (NotificationChannelGroup group : actual) {
if (group.getId() == null) {
@@ -1542,13 +1567,13 @@ public class RankingHelperTest extends UiServiceTestCase {
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup(ncg.getId());
mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
- mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
channel1.setImportance(IMPORTANCE_LOW);
mHelper.updateNotificationChannel(PKG, UID, channel1, true);
List<NotificationChannelGroup> actual =
- mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
assertEquals(2, actual.size());
for (NotificationChannelGroup group : actual) {
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
index 383d10baeb12..bb066ad428c6 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -195,6 +195,8 @@ public class ParcelableCallAnalytics implements Parcelable {
public static final int BLOCK_CHECK_FINISHED_TIMING = 9;
public static final int FILTERING_COMPLETED_TIMING = 10;
public static final int FILTERING_TIMED_OUT_TIMING = 11;
+ /** {@hide} */
+ public static final int START_CONNECTION_TO_REQUEST_DISCONNECT_TIMING = 12;
public static final int INVALID = 999999;
@@ -256,6 +258,27 @@ public class ParcelableCallAnalytics implements Parcelable {
public static final int SIP_PHONE = 0x8;
public static final int THIRD_PARTY_PHONE = 0x10;
+ /**
+ * Indicating the call source is not specified.
+ *
+ * @hide
+ */
+ public static final int CALL_SOURCE_UNSPECIFIED = 0;
+
+ /**
+ * Indicating the call is initiated via emergency dialer's dialpad.
+ *
+ * @hide
+ */
+ public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1;
+
+ /**
+ * Indicating the call is initiated via emergency dialer's shortcut button.
+ *
+ * @hide
+ */
+ public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2;
+
public static final long MILLIS_IN_5_MINUTES = 1000 * 60 * 5;
public static final long MILLIS_IN_1_SECOND = 1000;
@@ -319,6 +342,9 @@ public class ParcelableCallAnalytics implements Parcelable {
// A list of video events that have occurred.
private List<VideoEvent> videoEvents;
+ // The source where user initiated this call. ONE OF the CALL_SOURCE_* constants.
+ private int callSource = CALL_SOURCE_UNSPECIFIED;
+
public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType,
boolean isAdditionalCall, boolean isInterrupted, int callTechnologies,
int callTerminationCode, boolean isEmergencyCall, String connectionService,
@@ -356,6 +382,7 @@ public class ParcelableCallAnalytics implements Parcelable {
isVideoCall = readByteAsBoolean(in);
videoEvents = new LinkedList<>();
in.readTypedList(videoEvents, VideoEvent.CREATOR);
+ callSource = in.readInt();
}
public void writeToParcel(Parcel out, int flags) {
@@ -373,6 +400,7 @@ public class ParcelableCallAnalytics implements Parcelable {
out.writeTypedList(eventTimings);
writeBooleanAsByte(out, isVideoCall);
out.writeTypedList(videoEvents);
+ out.writeInt(callSource);
}
/** {@hide} */
@@ -385,6 +413,11 @@ public class ParcelableCallAnalytics implements Parcelable {
this.videoEvents = videoEvents;
}
+ /** {@hide} */
+ public void setCallSource(int callSource) {
+ this.callSource = callSource;
+ }
+
public long getStartTimeMillis() {
return startTimeMillis;
}
@@ -443,6 +476,11 @@ public class ParcelableCallAnalytics implements Parcelable {
return videoEvents;
}
+ /** {@hide} */
+ public int getCallSource() {
+ return callSource;
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 29898ffbd343..573f7db6b20c 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -619,6 +619,18 @@ public class TelecomManager {
"android.telecom.extra.USE_ASSISTED_DIALING";
/**
+ * Optional extra for {@link #placeCall(Uri, Bundle)} containing an integer that specifies
+ * the source where user initiated this call. This data is used in metrics.
+ * Valid source are:
+ * {@link ParcelableCallAnalytics#CALL_SOURCE_UNSPECIFIED},
+ * {@link ParcelableCallAnalytics#CALL_SOURCE_EMERGENCY_DIALPAD},
+ * {@link ParcelableCallAnalytics#CALL_SOURCE_EMERGENCY_SHORTCUT}.
+ *
+ * @hide
+ */
+ public static final String EXTRA_CALL_SOURCE = "android.telecom.extra.CALL_SOURCE";
+
+ /**
* The following 4 constants define how properties such as phone numbers and names are
* displayed to the user.
*/
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index deb289c8e614..bae18840506b 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -110,6 +110,28 @@ public class CarrierConfigManager {
"call_barring_visibility_bool";
/**
+ * Flag indicating whether or not changing the call barring password via the "Call Barring"
+ * settings menu is supported. If true, the option will be visible in the "Call
+ * Barring" settings menu. If false, the option will not be visible.
+ *
+ * Enabled by default.
+ * @hide
+ */
+ public static final String KEY_CALL_BARRING_SUPPORTS_PASSWORD_CHANGE_BOOL =
+ "call_barring_supports_password_change_bool";
+
+ /**
+ * Flag indicating whether or not deactivating all call barring features via the "Call Barring"
+ * settings menu is supported. If true, the option will be visible in the "Call
+ * Barring" settings menu. If false, the option will not be visible.
+ *
+ * Enabled by default.
+ * @hide
+ */
+ public static final String KEY_CALL_BARRING_SUPPORTS_DEACTIVATE_ALL_BOOL =
+ "call_barring_supports_deactivate_all_bool";
+
+ /**
* Flag indicating whether the Phone app should ignore EVENT_SIM_NETWORK_LOCKED
* events from the Sim.
* If true, this will prevent the IccNetworkDepersonalizationPanel from being shown, and
@@ -2095,6 +2117,8 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
sDefaults.putBoolean(KEY_CALL_BARRING_VISIBILITY_BOOL, false);
+ sDefaults.putBoolean(KEY_CALL_BARRING_SUPPORTS_PASSWORD_CHANGE_BOOL, true);
+ sDefaults.putBoolean(KEY_CALL_BARRING_SUPPORTS_DEACTIVATE_ALL_BOOL, true);
sDefaults.putBoolean(KEY_CALL_FORWARDING_VISIBILITY_BOOL, true);
sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL, true);
sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL, true);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 6bf22a05beec..8015b07fa024 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -33,6 +33,7 @@ import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.SmsConstants;
import java.io.UnsupportedEncodingException;
+import java.util.Locale;
/**
* Parses a GSM or UMTS format SMS-CB message into an {@link SmsCbMessage} object. The class is
@@ -44,16 +45,34 @@ public class GsmSmsCbMessage {
* Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5.
*/
private static final String[] LANGUAGE_CODES_GROUP_0 = {
- "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", "tr", "hu",
- "pl", null
+ Locale.GERMAN.getLanguage(), // German
+ Locale.ENGLISH.getLanguage(), // English
+ Locale.ITALIAN.getLanguage(), // Italian
+ Locale.FRENCH.getLanguage(), // French
+ new Locale("es").getLanguage(), // Spanish
+ new Locale("nl").getLanguage(), // Dutch
+ new Locale("sv").getLanguage(), // Swedish
+ new Locale("da").getLanguage(), // Danish
+ new Locale("pt").getLanguage(), // Portuguese
+ new Locale("fi").getLanguage(), // Finnish
+ new Locale("nb").getLanguage(), // Norwegian
+ new Locale("el").getLanguage(), // Greek
+ new Locale("tr").getLanguage(), // Turkish
+ new Locale("hu").getLanguage(), // Hungarian
+ new Locale("pl").getLanguage(), // Polish
+ null
};
/**
* Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5.
*/
private static final String[] LANGUAGE_CODES_GROUP_2 = {
- "cs", "he", "ar", "ru", "is", null, null, null, null, null, null, null, null, null,
- null, null
+ new Locale("cs").getLanguage(), // Czech
+ new Locale("he").getLanguage(), // Hebrew
+ new Locale("ar").getLanguage(), // Arabic
+ new Locale("ru").getLanguage(), // Russian
+ new Locale("is").getLanguage(), // Icelandic
+ null, null, null, null, null, null, null, null, null, null, null
};
private static final char CARRIAGE_RETURN = 0x0d;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
index 0fabc2ff6b86..541ca8d1e5c0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
@@ -118,71 +118,103 @@ public class SmsCbConstants {
public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE
= 0x111E; // 4382
- /** CMAS Message Identifier for Presidential Level alerts for additional languages
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Presidential Level alerts for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE
= 0x111F; // 4383
- /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE
= 0x1120; // 4384
- /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE
= 0x1121; // 4385
- /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE
= 0x1122; // 4386
- /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY_LANGUAGE
= 0x1123; // 4387
- /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED_LANGUAGE
= 0x1124; // 4388
- /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely
- * for additional languages.*/
+ /**
+ * CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY_LANGUAGE
= 0x1125; // 4389
- /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE
= 0x1126; // 4390
- /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely
- * for additional languages.*/
+ /**
+ * CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE
= 0x1127; // 4391
- /** CMAS Message Identifier for Child Abduction Emergency (Amber Alert)
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Child Abduction Emergency (Amber Alert)
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE
= 0x1128; // 4392
- /** CMAS Message Identifier for the Required Monthly Test
- * for additional languages. */
+ /** CMAS Message Identifier for the Required Monthly Test for additional languages. */
public static final int MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE
= 0x1129; // 4393
- /** CMAS Message Identifier for CMAS Exercise
- * for additional languages. */
+ /** CMAS Message Identifier for CMAS Exercise for additional languages. */
public static final int MESSAGE_ID_CMAS_ALERT_EXERCISE_LANGUAGE
= 0x112A; // 4394
- /** CMAS Message Identifier for operator defined use
- * for additional languages. */
+ /** CMAS Message Identifier for operator defined use for additional languages. */
public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE_LANGUAGE
= 0x112B; // 4395
+ /** CMAS Message Identifier for CMAS Public Safety Alerts. */
+ public static final int MESSAGE_ID_CMAS_ALERT_PUBLIC_SAFETY
+ = 0x112C; // 4396
+
+ /** CMAS Message Identifier for CMAS Public Safety Alerts for additional languages. */
+ public static final int MESSAGE_ID_CMAS_ALERT_PUBLIC_SAFETY_LANGUAGE
+ = 0x112D; // 4397
+
+ /** CMAS Message Identifier for CMAS State/Local Test. */
+ public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST
+ = 0x112E; // 4398
+
+ /** CMAS Message Identifier for CMAS State/Local Test for additional languages. */
+ public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST_LANGUAGE
+ = 0x112F; // 4399
+
/** End of CMAS Message Identifier range (including future extensions). */
public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER
= 0x112F; // 4399
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 4a7d7038457e..55c7fc18f6af 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -504,7 +504,7 @@ public class WifiConfiguration implements Parcelable {
/**
* @hide
* Universal name for app creating the configuration
- * see {#link {@link PackageManager#getNameForUid(int)}
+ * see {@link PackageManager#getNameForUid(int)}
*/
@SystemApi
public String creatorName;
@@ -512,7 +512,7 @@ public class WifiConfiguration implements Parcelable {
/**
* @hide
* Universal name for app updating the configuration
- * see {#link {@link PackageManager#getNameForUid(int)}
+ * see {@link PackageManager#getNameForUid(int)}
*/
@SystemApi
public String lastUpdateName;