Merge changes from topics "remove_feature_flag_emergency", "faster_emergency_feature_flag" into pi-dev
* changes:
RESTRICT AUTOMERGE: Removes feature flag for faster emergency call.
Add new metrics in power menu
Add feature flag in Settings.
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index c7618fe..d438554 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1749,7 +1749,7 @@
/**
* 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 ea0fd75..6cee2da5 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -20,13 +20,13 @@
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 @@
* 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 @@
* 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 1b6b5a0..4405108 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2797,7 +2797,7 @@
* 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 @@
* <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 7a6b72e..f4b7d7c 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1567,7 +1567,7 @@
* 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 @@
* 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 @@
* 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 @@
* 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 ebb7f18..ca29ef3 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -201,7 +201,7 @@
/**
* 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/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index b4c8a5e..d26c5162 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2110,7 +2110,7 @@
* 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 @@
}
/**
- * @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 795117e..bf579a7 100644
--- a/core/java/android/inputmethodservice/SoftInputWindow.java
+++ b/core/java/android/inputmethodservice/SoftInputWindow.java
@@ -103,9 +103,9 @@
/**
* 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 69f50a2..a2da6ea 100644
--- a/core/java/android/net/NetworkMisc.java
+++ b/core/java/android/net/NetworkMisc.java
@@ -46,7 +46,7 @@
/**
* 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 d2073b4..5b67406 100644
--- a/core/java/android/net/UrlQuerySanitizer.java
+++ b/core/java/android/net/UrlQuerySanitizer.java
@@ -287,7 +287,7 @@
/**
* 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 @@
}
/**
- * 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 @@
}
/**
- * 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 @@
/**
* 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 @@
* 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 @@
/**
* 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/JsonReader.java b/core/java/android/util/JsonReader.java
index 7d1c6c4..50f63f8 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 @@
/**
* 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 02202db..503eb97 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -123,7 +123,7 @@
/**
* 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 @@
* 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 a597405..86554fe 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -883,8 +883,8 @@
/**
* {@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/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index da5a1cd..0e1e379 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -418,20 +418,28 @@
*
* @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 4a99623..42bbe20 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
-->
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
index 4de8155..993378d 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 @@
}
@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/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 0c38c38..8686253 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4552,7 +4552,7 @@
/**
* 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/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 97d0a6e..3151c28 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -226,7 +226,7 @@
* 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 56423fd..828c673 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -4781,7 +4781,7 @@
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 6595baa..7919723 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 @@
* <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/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index f9dccea0..aad890b 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 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 @@
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 @@
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 @@
}
/**
- * 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/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ae0f7ed..b724716 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 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 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
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index af64683..605348b 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 @@
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 61b5415..da6e9c0 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 @@
@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 @@
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 @@
/**
* 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 @@
/**
* 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/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 98c6ec4..a9e713e 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 4a7d703..55c7fc1 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -504,7 +504,7 @@
/**
* @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 @@
/**
* @hide
* Universal name for app updating the configuration
- * see {#link {@link PackageManager#getNameForUid(int)}
+ * see {@link PackageManager#getNameForUid(int)}
*/
@SystemApi
public String lastUpdateName;