Merge "Create a OnTunerEventListener"
diff --git a/api/current.txt b/api/current.txt
index 92a89e6..a307fa4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -36228,6 +36228,7 @@
method public boolean isUserUnlocked();
method public boolean isUserUnlocked(android.os.UserHandle);
method public boolean requestQuietModeEnabled(boolean, @NonNull android.os.UserHandle);
+ method public boolean requestQuietModeEnabled(boolean, @NonNull android.os.UserHandle, int);
method @Deprecated public boolean setRestrictionsChallenge(String);
method @Deprecated public void setUserRestriction(String, boolean);
method @Deprecated public void setUserRestrictions(android.os.Bundle);
@@ -36289,6 +36290,7 @@
field public static final String DISALLOW_USER_SWITCH = "no_user_switch";
field public static final String ENSURE_VERIFY_APPS = "ensure_verify_apps";
field public static final String KEY_RESTRICTIONS_PENDING = "restrictions_pending";
+ field public static final int QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED = 1; // 0x1
field public static final int USER_CREATION_FAILED_NOT_PERMITTED = 1; // 0x1
field public static final int USER_CREATION_FAILED_NO_MORE_USERS = 2; // 0x2
field public static final int USER_OPERATION_ERROR_CURRENT_USER = 4; // 0x4
diff --git a/api/system-current.txt b/api/system-current.txt
index 3ff6116..451d2ab 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -661,6 +661,7 @@
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] getRegisteredExperimentIds() throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
+ method public void registerPullAtomCallback(int, @Nullable android.app.StatsManager.PullAtomMetadata, @NonNull java.util.concurrent.Executor, @NonNull android.app.StatsManager.StatsPullAtomCallback);
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
@@ -668,6 +669,7 @@
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setFetchReportsOperation(android.app.PendingIntent, long) throws android.app.StatsManager.StatsUnavailableException;
+ method public void unregisterPullAtomCallback(int);
field public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
field public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS = "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
field public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES = "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
@@ -676,6 +678,23 @@
field public static final String EXTRA_STATS_DIMENSIONS_VALUE = "android.app.extra.STATS_DIMENSIONS_VALUE";
field public static final String EXTRA_STATS_SUBSCRIPTION_ID = "android.app.extra.STATS_SUBSCRIPTION_ID";
field public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID = "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
+ field public static final int PULL_SKIP = 1; // 0x1
+ field public static final int PULL_SUCCESS = 0; // 0x0
+ }
+
+ public static class StatsManager.PullAtomMetadata {
+ }
+
+ public static class StatsManager.PullAtomMetadata.Builder {
+ ctor public StatsManager.PullAtomMetadata.Builder();
+ method @NonNull public android.app.StatsManager.PullAtomMetadata build();
+ method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setAdditiveFields(@NonNull int[]);
+ method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setCoolDownNs(long);
+ method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setTimeoutNs(long);
+ }
+
+ public static interface StatsManager.StatsPullAtomCallback {
+ method public int onPullAtom(int, @NonNull java.util.List<android.util.StatsEvent>);
}
public static class StatsManager.StatsUnavailableException extends android.util.AndroidException {
@@ -6219,6 +6238,7 @@
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinPasspoint(@NonNull String, boolean);
+ method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void clearWifiConnectedNetworkScorer();
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
@@ -6263,6 +6283,7 @@
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean setSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
+ method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public boolean setWifiConnectedNetworkScorer(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiConnectedNetworkScorer);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
@@ -6352,6 +6373,11 @@
method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
}
+ public static interface WifiManager.ScoreChangeCallback {
+ method public void onStatusChange(int, boolean);
+ method public void onTriggerUpdateOfWifiUsabilityStats(int);
+ }
+
public static interface WifiManager.SoftApCallback {
method public default void onBlockedClientConnecting(@NonNull android.net.wifi.WifiClient, int);
method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability);
@@ -6368,6 +6394,12 @@
field public static final int DATA_ACTIVITY_OUT = 2; // 0x2
}
+ public static interface WifiManager.WifiConnectedNetworkScorer {
+ method public void setScoreChangeCallback(@NonNull android.net.wifi.WifiManager.ScoreChangeCallback);
+ method public void start(int);
+ method public void stop(int);
+ }
+
public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
ctor public WifiNetworkConnectionStatistics(int, int);
ctor public WifiNetworkConnectionStatistics();
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 7af7a4a..f6014e5 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -95,7 +95,7 @@
void updateNotificationChannelForPackage(String pkg, int uid, in NotificationChannel channel);
NotificationChannel getNotificationChannel(String callingPkg, int userId, String pkg, String channelId);
NotificationChannel getConversationNotificationChannel(String callingPkg, int userId, String pkg, String channelId, boolean returnParentIfNoConversationChannel, String conversationId);
- void createConversationNotificationChannelForPackage(String pkg, int uid, in NotificationChannel parentChannel, String conversationId);
+ void createConversationNotificationChannelForPackage(String pkg, int uid, String triggeringKey, in NotificationChannel parentChannel, String conversationId);
NotificationChannel getNotificationChannelForPackage(String pkg, int uid, String channelId, boolean includeDeleted);
void deleteNotificationChannel(String pkg, String channelId);
void deleteConversationNotificationChannels(String pkg, int uid, String conversationId);
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index dde6dda..0beceb0 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -18,11 +18,13 @@
import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.PACKAGE_USAGE_STATS;
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
+import android.os.Binder;
import android.os.IBinder;
import android.os.IPullAtomCallback;
import android.os.IPullAtomResultReceiver;
@@ -108,13 +110,11 @@
/**
* Value indicating that this pull was successful and that the result should be used.
*
- * @hide
**/
public static final int PULL_SUCCESS = 0;
/**
* Value indicating that this pull was unsuccessful and that the result should not be used.
- * @hide
**/
public static final int PULL_SKIP = 1;
@@ -512,6 +512,17 @@
/**
+ * Temp registration for while the migration is in progress.
+ *
+ * @hide
+ */
+ public void registerPullAtomCallback(int atomTag, @Nullable PullAtomMetadata metadata,
+ @NonNull StatsPullAtomCallback callback,
+ @NonNull @CallbackExecutor Executor executor) {
+ registerPullAtomCallback(atomTag, metadata, executor, callback);
+ }
+
+ /**
* Registers a callback for an atom when that atom is to be pulled. The stats service will
* invoke pullData in the callback when the stats service determines that this atom needs to be
* pulled.
@@ -520,18 +531,19 @@
* @param metadata Optional metadata specifying the timeout, cool down time, and
* additive fields for mapping isolated to host uids.
* @param callback The callback to be invoked when the stats service pulls the atom.
- * @param executor The executor in which to run the callback
+ * @param executor The executor in which to run the callback.
*
- * @hide
*/
public void registerPullAtomCallback(int atomTag, @Nullable PullAtomMetadata metadata,
- @NonNull StatsPullAtomCallback callback, @NonNull Executor executor) {
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull StatsPullAtomCallback callback) {
long coolDownNs = metadata == null ? DEFAULT_COOL_DOWN_NS : metadata.mCoolDownNs;
long timeoutNs = metadata == null ? DEFAULT_TIMEOUT_NS : metadata.mTimeoutNs;
int[] additiveFields = metadata == null ? new int[0] : metadata.mAdditiveFields;
if (additiveFields == null) {
additiveFields = new int[0];
}
+
synchronized (sLock) {
try {
IStatsManagerService service = getIStatsManagerServiceLocked();
@@ -551,7 +563,6 @@
*
* @param atomTag The tag of the atom of which to unregister
*
- * @hide
*/
public void unregisterPullAtomCallback(int atomTag) {
synchronized (sLock) {
@@ -577,21 +588,26 @@
@Override
public void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver) {
- mExecutor.execute(() -> {
- List<StatsEvent> data = new ArrayList<>();
- int successInt = mCallback.onPullAtom(atomTag, data);
- boolean success = successInt == PULL_SUCCESS;
- StatsEventParcel[] parcels = new StatsEventParcel[data.size()];
- for (int i = 0; i < data.size(); i++) {
- parcels[i] = new StatsEventParcel();
- parcels[i].buffer = data.get(i).getBytes();
- }
- try {
- resultReceiver.pullFinished(atomTag, success, parcels);
- } catch (RemoteException e) {
- Slog.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId);
- }
- });
+ long token = Binder.clearCallingIdentity();
+ try {
+ mExecutor.execute(() -> {
+ List<StatsEvent> data = new ArrayList<>();
+ int successInt = mCallback.onPullAtom(atomTag, data);
+ boolean success = successInt == PULL_SUCCESS;
+ StatsEventParcel[] parcels = new StatsEventParcel[data.size()];
+ for (int i = 0; i < data.size(); i++) {
+ parcels[i] = new StatsEventParcel();
+ parcels[i].buffer = data.get(i).getBytes();
+ }
+ try {
+ resultReceiver.pullFinished(atomTag, success, parcels);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId);
+ }
+ });
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
}
@@ -599,7 +615,6 @@
* Metadata required for registering a StatsPullAtomCallback.
* All fields are optional, and defaults will be used for fields that are unspecified.
*
- * @hide
*/
public static class PullAtomMetadata {
private final long mCoolDownNs;
@@ -614,22 +629,27 @@
}
/**
- * Returns a new PullAtomMetadata.Builder object for constructing PullAtomMetadata for
- * StatsManager#registerPullAtomCallback
+ * Temp for while migrations are in progress.
+ *
+ * @hide
*/
public static PullAtomMetadata.Builder newBuilder() {
return new PullAtomMetadata.Builder();
}
/**
- * Builder for PullAtomMetadata.
+ * Builder for PullAtomMetadata.
*/
public static class Builder {
private long mCoolDownNs;
private long mTimeoutNs;
private int[] mAdditiveFields;
- private Builder() {
+ /**
+ * Returns a new PullAtomMetadata.Builder object for constructing PullAtomMetadata for
+ * StatsManager#registerPullAtomCallback
+ */
+ public Builder() {
mCoolDownNs = DEFAULT_COOL_DOWN_NS;
mTimeoutNs = DEFAULT_TIMEOUT_NS;
mAdditiveFields = null;
@@ -662,7 +682,7 @@
* will be combined when the non-additive fields are the same.
*/
@NonNull
- public Builder setAdditiveFields(int[] additiveFields) {
+ public Builder setAdditiveFields(@NonNull int[] additiveFields) {
mAdditiveFields = additiveFields;
return this;
}
@@ -705,14 +725,13 @@
/**
* Callback interface for pulling atoms requested by the stats service.
*
- * @hide
*/
public interface StatsPullAtomCallback {
/**
* Pull data for the specified atom tag, filling in the provided list of StatsEvent data.
* @return {@link #PULL_SUCCESS} if the pull was successful, or {@link #PULL_SKIP} if not.
*/
- int onPullAtom(int atomTag, List<StatsEvent> data);
+ int onPullAtom(int atomTag, @NonNull List<StatsEvent> data);
}
private class StatsdDeathRecipient implements IBinder.DeathRecipient {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 68acfc7..3df94a7 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4051,6 +4051,7 @@
* @hide
*/
@SystemApi
+ @SuppressLint("ServiceName")
public static final String WIFI_COND_SERVICE = "wificond";
/**
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index edaaf81..33d6131 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -113,7 +113,7 @@
boolean isUserRunning(int userId);
boolean isUserNameSet(int userId);
boolean hasRestrictedProfiles();
- boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target);
+ boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target, int flags);
String getUserName();
long getUserStartRealtime();
long getUserUnlockRealtime();
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 2eaefca..12e843c 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -133,6 +133,22 @@
public static final String USER_TYPE_SYSTEM_HEADLESS = "android.os.usertype.system.HEADLESS";
/**
+ * Flag passed to {@link #requestQuietModeEnabled} to request disabling quiet mode only if
+ * there is no need to confirm the user credentials. If credentials are required to disable
+ * quiet mode, {@link #requestQuietModeEnabled} will do nothing and return {@code false}.
+ */
+ public static final int QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED = 0x1;
+
+ /**
+ * List of flags available for the {@link #requestQuietModeEnabled} method.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = { "QUIET_MODE_" }, value = {
+ QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED })
+ public @interface QuietModeFlag {}
+
+ /**
* @hide
* No user restriction.
*/
@@ -3216,6 +3232,25 @@
}
/**
+ * Perform the same operation as {@link #requestQuietModeEnabled(boolean, UserHandle)}, but
+ * with a flag to tweak the behavior of the request.
+ *
+ * @param enableQuietMode whether quiet mode should be enabled or disabled
+ * @param userHandle user handle of the profile
+ * @param flags Can be 0 or {@link #QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED}.
+ * @return {@code false} if user's credential is needed in order to turn off quiet mode,
+ * {@code true} otherwise
+ * @throws SecurityException if the caller is invalid
+ * @throws IllegalArgumentException if {@code userHandle} is not a managed profile
+ *
+ * @see #isQuietModeEnabled(UserHandle)
+ */
+ public boolean requestQuietModeEnabled(boolean enableQuietMode, @NonNull UserHandle userHandle,
+ @QuietModeFlag int flags) {
+ return requestQuietModeEnabled(enableQuietMode, userHandle, null, flags);
+ }
+
+ /**
* Similar to {@link #requestQuietModeEnabled(boolean, UserHandle)}, except you can specify
* a target to start when user is unlocked. If {@code target} is specified, caller must have
* the {@link android.Manifest.permission#MANAGE_USERS} permission.
@@ -3225,9 +3260,23 @@
*/
public boolean requestQuietModeEnabled(
boolean enableQuietMode, @NonNull UserHandle userHandle, IntentSender target) {
+ return requestQuietModeEnabled(enableQuietMode, userHandle, target, 0);
+ }
+ /**
+ * Similar to {@link #requestQuietModeEnabled(boolean, UserHandle)}, except you can specify
+ * a target to start when user is unlocked. If {@code target} is specified, caller must have
+ * the {@link android.Manifest.permission#MANAGE_USERS} permission.
+ *
+ * @see {@link #requestQuietModeEnabled(boolean, UserHandle)}
+ * @hide
+ */
+ public boolean requestQuietModeEnabled(
+ boolean enableQuietMode, @NonNull UserHandle userHandle, IntentSender target,
+ int flags) {
try {
return mService.requestQuietModeEnabled(
- mContext.getPackageName(), enableQuietMode, userHandle.getIdentifier(), target);
+ mContext.getPackageName(), enableQuietMode, userHandle.getIdentifier(), target,
+ flags);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 389040c..4f400a8 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -16,6 +16,9 @@
package android.service.notification;
+import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
+import static android.util.FeatureFlagUtils.*;
+
import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationManager;
@@ -29,6 +32,8 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -436,6 +441,19 @@
return logMaker;
}
+ /**
+ * @hide
+ */
+ public String getShortcutId(Context context) {
+ String conversationId = getNotification().getShortcutId();
+ if (isEnabled(context, NOTIF_CONVO_BYPASS_SHORTCUT_REQ)
+ && getNotification().getNotificationStyle() == Notification.MessagingStyle.class
+ && TextUtils.isEmpty(conversationId)) {
+ conversationId = getId() + getTag() + PLACEHOLDER_CONVERSATION_ID;
+ }
+ return conversationId;
+ }
+
private String getGroupLogTag() {
return shortenTag(getGroup());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index 6d3f3f4..64bdd97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.notification.row;
import static android.app.Notification.EXTRA_IS_GROUP_CONVERSATION;
-import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
@@ -103,7 +102,6 @@
private NotificationEntry mEntry;
private StatusBarNotification mSbn;
private boolean mIsDeviceProvisioned;
-
private int mStartingChannelImportance;
private boolean mStartedAsBubble;
private boolean mIsBubbleable;
@@ -212,11 +210,10 @@
mLauncherApps = launcherApps;
mConversationId = mNotificationChannel.getConversationId();
if (TextUtils.isEmpty(mNotificationChannel.getConversationId())) {
- mConversationId = mSbn.getNotification().getShortcutId();
+ mConversationId = mSbn.getShortcutId(mContext);
}
- // TODO: flag this when flag exists
if (TextUtils.isEmpty(mConversationId)) {
- mConversationId = mSbn.getId() + mSbn.getTag() + PLACEHOLDER_CONVERSATION_ID;
+ throw new IllegalArgumentException("Does not have required information");
}
// TODO: consider querying this earlier in the notification pipeline and passing it in
LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery()
@@ -243,10 +240,9 @@
// a custom channel
if (TextUtils.isEmpty(mNotificationChannel.getConversationId())) {
try {
- // TODO: associate this key with this channel service side so the customization
- // isn't forgotten on the next update
mINotificationManager.createConversationNotificationChannelForPackage(
- mPackageName, mAppUid, mNotificationChannel, mConversationId);
+ mPackageName, mAppUid, mSbn.getKey(), mNotificationChannel,
+ mConversationId);
mNotificationChannel = mINotificationManager.getConversationNotificationChannel(
mContext.getOpPackageName(), UserHandle.getUserId(mAppUid), mPackageName,
mNotificationChannel.getId(), false, mConversationId);
@@ -363,7 +359,6 @@
image.setImageDrawable(mLauncherApps.getShortcutBadgedIconDrawable(mShortcutInfo,
mContext.getResources().getDisplayMetrics().densityDpi));
} else {
- // TODO: flag this behavior
if (mSbn.getNotification().extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION, false)) {
// TODO: maybe use a generic group icon, or a composite of recent senders
image.setImageDrawable(mPm.getDefaultActivityIcon());
@@ -391,7 +386,6 @@
if (mShortcutInfo != null) {
name.setText(mShortcutInfo.getShortLabel());
} else {
- // TODO: flag this behavior
Bundle extras = mSbn.getNotification().extras;
String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE);
if (TextUtils.isEmpty(nameString)) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 61f0b26..9ae477e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -797,7 +797,7 @@
null,
true);
verify(mMockINotificationManager, times(1)).createConversationNotificationChannelForPackage(
- anyString(), anyInt(), any(), eq(CONVERSATION_ID));
+ anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
}
@Test
@@ -817,7 +817,7 @@
null,
true);
verify(mMockINotificationManager, never()).createConversationNotificationChannelForPackage(
- anyString(), anyInt(), any(), eq(CONVERSATION_ID));
+ anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
}
@Test
diff --git a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
index eaf120e..0e14364 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
@@ -15,7 +15,10 @@
*/
package com.android.server.notification;
+import android.app.Notification;
+import android.app.NotificationChannel;
import android.content.Context;
+import android.util.FeatureFlagUtils;
import android.util.Slog;
/**
@@ -26,8 +29,10 @@
private static final boolean DBG = false;
private RankingConfig mConfig;
+ private Context mContext;
public void initialize(Context ctx, NotificationUsageStats usageStats) {
+ mContext = ctx;
if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + ".");
}
@@ -41,11 +46,11 @@
if (DBG) Slog.d(TAG, "missing config");
return null;
}
-
- record.updateNotificationChannel(mConfig.getConversationNotificationChannel(
+ NotificationChannel updatedChannel = mConfig.getConversationNotificationChannel(
record.sbn.getPackageName(),
record.sbn.getUid(), record.getChannel().getId(),
- record.getNotification().getShortcutId(), true, false));
+ record.sbn.getShortcutId(mContext), true, false);
+ record.updateNotificationChannel(updatedChannel);
return null;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1d49364..385d84a 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -208,6 +208,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
+import android.util.FeatureFlagUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
@@ -3038,7 +3039,7 @@
@Override
public void createConversationNotificationChannelForPackage(String pkg, int uid,
- NotificationChannel parentChannel, String conversationId) {
+ String triggeringKey, NotificationChannel parentChannel, String conversationId) {
enforceSystemOrSystemUI("only system can call this");
Preconditions.checkNotNull(parentChannel);
Preconditions.checkNotNull(conversationId);
@@ -3049,6 +3050,8 @@
conversationChannel.setConversationId(parentId, conversationId);
createNotificationChannelsImpl(
pkg, uid, new ParceledListSlice(Arrays.asList(conversationChannel)));
+ mRankingHandler.requestSort();
+ handleSavePolicyFile();
}
@Override
@@ -5257,9 +5260,10 @@
if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) {
channelId = (new Notification.TvExtender(notification)).getChannelId();
}
- // TODO: flag this behavior
String shortcutId = notification.getShortcutId();
- if (shortcutId == null
+ if (FeatureFlagUtils.isEnabled(getContext(),
+ FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ)
+ && shortcutId == null
&& notification.getNotificationStyle() == Notification.MessagingStyle.class) {
shortcutId = id + tag + NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 185d75c..b0c1863 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -16,6 +16,7 @@
package com.android.server.notification;
+import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
@@ -40,6 +41,7 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.FeatureFlagUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -139,6 +141,8 @@
private boolean mAreChannelsBypassingDnd;
private boolean mHideSilentStatusBarIcons = DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS;
+ private boolean mAllowInvalidShortcuts = false;
+
private static final String BADGING_FORCED_TRUE = "force_badging_true_for_bug";
// STOPSHIP (b/142218092) this should be removed before ship
@@ -164,6 +168,8 @@
updateBadgingEnabled();
updateBubblesEnabled();
syncChannelsBypassingDnd(mContext.getUserId());
+ mAllowInvalidShortcuts = FeatureFlagUtils.isEnabled(mContext,
+ FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ);
}
public void readXml(XmlPullParser parser, boolean forRestore, int userId)
@@ -266,7 +272,14 @@
}
channel.setImportanceLockedByCriticalDeviceFunction(
r.defaultAppLockedImportance);
- r.channels.put(id, channel);
+ boolean isInvalidShortcutChannel =
+ channel.getConversationId() != null &&
+ channel.getConversationId().contains(
+ PLACEHOLDER_CONVERSATION_ID);
+ if (mAllowInvalidShortcuts || (!mAllowInvalidShortcuts
+ && !isInvalidShortcutChannel)) {
+ r.channels.put(id, channel);
+ }
}
}
// Delegate
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 66a2b01..2a249d2 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -74,6 +74,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager.EnforcingUser;
+import android.os.UserManager.QuietModeFlag;
import android.os.UserManagerInternal;
import android.os.UserManagerInternal.UserRestrictionsListener;
import android.os.storage.StorageManager;
@@ -914,7 +915,7 @@
@Override
public boolean requestQuietModeEnabled(@NonNull String callingPackage, boolean enableQuietMode,
- @UserIdInt int userId, @Nullable IntentSender target) {
+ @UserIdInt int userId, @Nullable IntentSender target, @QuietModeFlag int flags) {
Objects.requireNonNull(callingPackage);
if (enableQuietMode && target != null) {
@@ -925,24 +926,24 @@
ensureCanModifyQuietMode(callingPackage, Binder.getCallingUid(), userId, target != null);
final long identity = Binder.clearCallingIdentity();
try {
- boolean result = false;
if (enableQuietMode) {
setQuietModeEnabled(
userId, true /* enableQuietMode */, target, callingPackage);
- result = true;
- } else {
- boolean needToShowConfirmCredential =
- mLockPatternUtils.isSecure(userId)
- && !StorageManager.isUserKeyUnlocked(userId);
- if (needToShowConfirmCredential) {
- showConfirmCredentialToDisableQuietMode(userId, target);
- } else {
- setQuietModeEnabled(
- userId, false /* enableQuietMode */, target, callingPackage);
- result = true;
- }
+ return true;
}
- return result;
+ boolean needToShowConfirmCredential =
+ mLockPatternUtils.isSecure(userId)
+ && !StorageManager.isUserKeyUnlocked(userId);
+ if (needToShowConfirmCredential) {
+ if ((flags & UserManager.QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED) != 0) {
+ return false;
+ }
+ showConfirmCredentialToDisableQuietMode(userId, target);
+ return false;
+ }
+ setQuietModeEnabled(
+ userId, false /* enableQuietMode */, target, callingPackage);
+ return true;
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 3bc860a..1e85688 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -173,7 +173,6 @@
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -349,14 +348,14 @@
}
private void registerWifiBytesTransfer() {
int tagId = StatsLog.WIFI_BYTES_TRANSFER;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3, 4, 5})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullWifiBytesTransfer(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullWifiBytesTransfer(atomTag, data)
);
}
@@ -441,14 +440,14 @@
private void registerWifiBytesTransferBackground() {
int tagId = StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {3, 4, 5, 6})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullWifiBytesTransferBackground(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullWifiBytesTransferBackground(atomTag, data)
);
}
@@ -479,14 +478,14 @@
private void registerMobileBytesTransfer() {
int tagId = StatsLog.MOBILE_BYTES_TRANSFER;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3, 4, 5})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullMobileBytesTransfer(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullMobileBytesTransfer(atomTag, data)
);
}
@@ -517,14 +516,14 @@
private void registerMobileBytesTransferBackground() {
int tagId = StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {3, 4, 5, 6})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullMobileBytesTransferBackground(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullMobileBytesTransferBackground(atomTag, data)
);
}
@@ -555,14 +554,14 @@
private void registerBluetoothBytesTransfer() {
int tagId = StatsLog.BLUETOOTH_BYTES_TRANSFER;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullBluetoothBytesTransfer(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullBluetoothBytesTransfer(atomTag, data)
);
}
@@ -634,8 +633,8 @@
mStatsManager.registerPullAtomCallback(
tagId,
/* PullAtomMetadata */ null,
- (atomTag, data) -> pullKernelWakelock(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullKernelWakelock(atomTag, data)
);
}
@@ -670,14 +669,14 @@
private void registerCpuTimePerFreq() {
int tagId = StatsLog.CPU_TIME_PER_FREQ;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {3})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullCpuTimePerFreq(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullCpuTimePerFreq(atomTag, data)
);
}
@@ -701,14 +700,14 @@
private void registerCpuTimePerUid() {
int tagId = StatsLog.CPU_TIME_PER_UID;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullCpuTimePerUid(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullCpuTimePerUid(atomTag, data)
);
}
@@ -730,14 +729,14 @@
// the throttling is 3sec, handled in
// frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
int tagId = StatsLog.CPU_TIME_PER_UID_FREQ;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {4})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullCpuTimeperUidFreq(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullCpuTimeperUidFreq(atomTag, data)
);
}
@@ -762,14 +761,14 @@
// the throttling is 3sec, handled in
// frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
int tagId = StatsLog.CPU_ACTIVE_TIME;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullCpuActiveTime(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullCpuActiveTime(atomTag, data)
);
}
@@ -789,14 +788,14 @@
// the throttling is 3sec, handled in
// frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
int tagId = StatsLog.CPU_CLUSTER_TIME;
- PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {3})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
- (atomTag, data) -> pullCpuClusterTime(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullCpuClusterTime(atomTag, data)
);
}
@@ -913,8 +912,8 @@
mStatsManager.registerPullAtomCallback(
tagId,
/* metadata */ null,
- (atomTag, data) -> pullBluetoothActivityInfo(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullBluetoothActivityInfo(atomTag, data)
);
}
@@ -949,8 +948,8 @@
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
- (atomTag, data) -> pullSystemUptime(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullSystemUptime(atomTag, data)
);
}
@@ -1232,8 +1231,8 @@
mStatsManager.registerPullAtomCallback(
tagId,
/* PullAtomMetadata */ null,
- (atomTag, data) -> pullIonHeapSize(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullIonHeapSize(atomTag, data)
);
}
@@ -1511,8 +1510,8 @@
mStatsManager.registerPullAtomCallback(
tagId,
/* PullAtomMetadata */ null,
- (atomTag, data) -> pullPowerProfile(atomTag, data),
- Executors.newSingleThreadExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullPowerProfile(atomTag, data)
);
}
@@ -1681,8 +1680,8 @@
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
- (atomTag, data) -> pullBuildInformation(atomTag, data),
- BackgroundThread.getExecutor()
+ BackgroundThread.getExecutor(),
+ (atomTag, data) -> pullBuildInformation(atomTag, data)
);
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 109a6fd..92bdba0 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -223,8 +223,14 @@
"com.android.server.usb.UsbService$Lifecycle";
private static final String MIDI_SERVICE_CLASS =
"com.android.server.midi.MidiService$Lifecycle";
+ private static final String WIFI_APEX_SERVICE_JAR_PATH =
+ "/apex/com.android.wifi/javalib/wifi-service.jar";
private static final String WIFI_SERVICE_CLASS =
"com.android.server.wifi.WifiService";
+ private static final String WIFI_SCANNING_SERVICE_CLASS =
+ "com.android.server.wifi.scanner.WifiScanningService";
+ private static final String WIFI_RTT_SERVICE_CLASS =
+ "com.android.server.wifi.rtt.RttService";
private static final String WIFI_AWARE_SERVICE_CLASS =
"com.android.server.wifi.aware.WifiAwareService";
private static final String WIFI_P2P_SERVICE_CLASS =
@@ -1426,33 +1432,36 @@
PackageManager.FEATURE_WIFI)) {
// Wifi Service must be started first for wifi-related services.
t.traceBegin("StartWifi");
- mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
+ mSystemServiceManager.startServiceFromJar(
+ WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
t.traceBegin("StartWifiScanning");
- mSystemServiceManager.startService(
- "com.android.server.wifi.scanner.WifiScanningService");
+ mSystemServiceManager.startServiceFromJar(
+ WIFI_SCANNING_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_RTT)) {
t.traceBegin("StartRttService");
- mSystemServiceManager.startService(
- "com.android.server.wifi.rtt.RttService");
+ mSystemServiceManager.startServiceFromJar(
+ WIFI_RTT_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_AWARE)) {
t.traceBegin("StartWifiAware");
- mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
+ mSystemServiceManager.startServiceFromJar(
+ WIFI_AWARE_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_DIRECT)) {
t.traceBegin("StartWifiP2P");
- mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
+ mSystemServiceManager.startServiceFromJar(
+ WIFI_P2P_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
index f5af3ec..d16c232a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
@@ -18,6 +18,7 @@
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.util.FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
@@ -30,6 +31,7 @@
import android.app.Notification;
import android.app.NotificationChannel;
import android.os.UserHandle;
+import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import com.android.server.UiServiceTestCase;
@@ -52,6 +54,7 @@
public void testExtractsUpdatedChannel() {
NotificationChannelExtractor extractor = new NotificationChannelExtractor();
extractor.setConfig(mConfig);
+ extractor.initialize(mContext, null);
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
final Notification.Builder builder = new Notification.Builder(getContext())
@@ -71,4 +74,62 @@
assertNull(extractor.process(r));
assertEquals(updatedChannel, r.getChannel());
}
+
+ @Test
+ public void testInvalidShortcutFlagEnabled_looksUpCorrectChannel() {
+ Settings.Global.putString(
+ mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
+
+ NotificationChannelExtractor extractor = new NotificationChannelExtractor();
+ extractor.setConfig(mConfig);
+ extractor.initialize(mContext, null);
+
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+ final Notification.Builder builder = new Notification.Builder(getContext())
+ .setContentTitle("foo")
+ .setStyle(new Notification.MessagingStyle("name"))
+ .setSmallIcon(android.R.drawable.sym_def_app_icon);
+ Notification n = builder.build();
+ StatusBarNotification sbn = new StatusBarNotification("", "", 0, "tag", 0,
+ 0, n, UserHandle.ALL, null, System.currentTimeMillis());
+ NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+
+ NotificationChannel updatedChannel =
+ new NotificationChannel("a", "", IMPORTANCE_HIGH);
+ when(mConfig.getConversationNotificationChannel(
+ any(), anyInt(), eq("a"), eq(r.sbn.getShortcutId(mContext)), eq(true), eq(false)))
+ .thenReturn(updatedChannel);
+
+ assertNull(extractor.process(r));
+ assertEquals(updatedChannel, r.getChannel());
+ }
+
+ @Test
+ public void testInvalidShortcutFlagDisabled_looksUpCorrectChannel() {
+ Settings.Global.putString(
+ mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
+
+ NotificationChannelExtractor extractor = new NotificationChannelExtractor();
+ extractor.setConfig(mConfig);
+ extractor.initialize(mContext, null);
+
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+ final Notification.Builder builder = new Notification.Builder(getContext())
+ .setContentTitle("foo")
+ .setStyle(new Notification.MessagingStyle("name"))
+ .setSmallIcon(android.R.drawable.sym_def_app_icon);
+ Notification n = builder.build();
+ StatusBarNotification sbn = new StatusBarNotification("", "", 0, "tag", 0,
+ 0, n, UserHandle.ALL, null, System.currentTimeMillis());
+ NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+
+ NotificationChannel updatedChannel =
+ new NotificationChannel("a", "", IMPORTANCE_HIGH);
+ when(mConfig.getConversationNotificationChannel(
+ any(), anyInt(), eq("a"), eq(null), eq(true), eq(false)))
+ .thenReturn(updatedChannel);
+
+ assertNull(extractor.process(r));
+ assertEquals(updatedChannel, r.getChannel());
+ }
}
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 2ac4642..c6c64c9 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -5834,7 +5834,8 @@
mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(
orig)));
- mBinderService.createConversationNotificationChannelForPackage(PKG, mUid, orig, "friend");
+ mBinderService.createConversationNotificationChannelForPackage(
+ PKG, mUid, "key", orig, "friend");
NotificationChannel friendChannel = mBinderService.getConversationNotificationChannel(
PKG, 0, PKG, original.getId(), false, "friend");
@@ -5869,9 +5870,10 @@
String conversationId = "friend";
mBinderService.createConversationNotificationChannelForPackage(
- PKG, mUid, NotificationChannel.CREATOR.createFromParcel(msgParcel), conversationId);
+ PKG, mUid, "key", NotificationChannel.CREATOR.createFromParcel(msgParcel),
+ conversationId);
mBinderService.createConversationNotificationChannelForPackage(
- PKG, mUid, NotificationChannel.CREATOR.createFromParcel(callParcel),
+ PKG, mUid, "key", NotificationChannel.CREATOR.createFromParcel(callParcel),
conversationId);
NotificationChannel messagesChild = mBinderService.getConversationNotificationChannel(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 6f16574..c1c74da 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -22,6 +22,7 @@
import static android.app.NotificationManager.IMPORTANCE_MAX;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.util.FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ;
import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
@@ -2858,4 +2859,84 @@
// good
}
}
+
+ @Test
+ public void testPlaceholderConversationId_flagOn() throws Exception {
+ Settings.Global.putString(
+ mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+
+ final String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+ + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
+ + "</package>"
+ + "</ranking>";
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+ null);
+ parser.nextTag();
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+ assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
+ }
+
+ @Test
+ public void testPlaceholderConversationId_flagOff() throws Exception {
+ Settings.Global.putString(
+ mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+
+ final String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+ + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
+ + "</package>"
+ + "</ranking>";
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+ null);
+ parser.nextTag();
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+ assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
+ }
+
+ @Test
+ public void testNormalConversationId_flagOff() throws Exception {
+ Settings.Global.putString(
+ mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+
+ final String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+ + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"other\"/>"
+ + "</package>"
+ + "</ranking>";
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+ null);
+ parser.nextTag();
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+ assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
+ }
+
+ @Test
+ public void testNoConversationId_flagOff() throws Exception {
+ Settings.Global.putString(
+ mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+
+ final String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+ + "<channel id=\"id\" name=\"hi\" importance=\"3\"/>"
+ + "</package>"
+ + "</ranking>";
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+ null);
+ parser.nextTag();
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+ assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
+ }
}
diff --git a/wifi/java/android/net/wifi/IScoreChangeCallback.aidl b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl
new file mode 100644
index 0000000..fd23610
--- /dev/null
+++ b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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 android.net.wifi;
+
+/**
+ * Interface for Wi-Fi network score callback.
+ *
+ * @hide
+ */
+oneway interface IScoreChangeCallback
+{
+ void onStatusChange(int sessionId, boolean exiting);
+
+ void onTriggerUpdateOfWifiUsabilityStats(int sessionId);
+}
diff --git a/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl b/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
new file mode 100644
index 0000000..d9a3b01
--- /dev/null
+++ b/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 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 android.net.wifi;
+
+import android.net.wifi.IScoreChangeCallback;
+
+/**
+ * Interface for Wi-Fi connected network scorer.
+ *
+ * @hide
+ */
+oneway interface IWifiConnectedNetworkScorer
+{
+ void start(int sessionId);
+
+ void stop(int sessionId);
+
+ void setScoreChangeCallback(IScoreChangeCallback cbImpl);
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 67f1663..5a98ac8 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -35,6 +35,7 @@
import android.net.wifi.ISuggestionConnectionStatusListener;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.ITxPacketCountListener;
+import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiConfiguration;
@@ -254,4 +255,8 @@
int calculateSignalLevel(int rssi);
List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List<ScanResult> scanResults);
+
+ boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer);
+
+ void clearWifiConnectedNetworkScorer();
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ec3de43..64d4eaf 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -5806,4 +5806,186 @@
return new SparseArray<>();
}
}
+
+ /**
+ * Callback interface for framework to receive network status changes and trigger of updating
+ * {@link WifiUsabilityStatsEntry}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface ScoreChangeCallback {
+ /**
+ * Called by applications to indicate network status.
+ *
+ * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
+ * {@link WifiConnectedNetworkScorer#start(int)}.
+ * @param isUsable The bit to indicate whether current Wi-Fi network is usable or not.
+ * Populated by connected network scorer in applications.
+ */
+ void onStatusChange(int sessionId, boolean isUsable);
+
+ /**
+ * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}.
+ * To receive update applications need to add WifiUsabilityStatsEntry listener. See
+ * {@link addOnWifiUsabilityStatsListener(Executor, OnWifiUsabilityStatsListener)}.
+ *
+ * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
+ * {@link WifiConnectedNetworkScorer#start(int)}.
+ */
+ void onTriggerUpdateOfWifiUsabilityStats(int sessionId);
+ }
+
+ /**
+ * Callback proxy for {@link ScoreChangeCallback} objects.
+ *
+ * @hide
+ */
+ private class ScoreChangeCallbackProxy implements ScoreChangeCallback {
+ private final IScoreChangeCallback mScoreChangeCallback;
+
+ private ScoreChangeCallbackProxy(IScoreChangeCallback callback) {
+ mScoreChangeCallback = callback;
+ }
+
+ @Override
+ public void onStatusChange(int sessionId, boolean isUsable) {
+ try {
+ mScoreChangeCallback.onStatusChange(sessionId, isUsable);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @Override
+ public void onTriggerUpdateOfWifiUsabilityStats(int sessionId) {
+ try {
+ mScoreChangeCallback.onTriggerUpdateOfWifiUsabilityStats(sessionId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Interface for Wi-Fi connected network scorer. Should be implemented by applications and set
+ * when calling
+ * {@link WifiManager#setWifiConnectedNetworkScorer(Executor, WifiConnectedNetworkScorer)}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface WifiConnectedNetworkScorer {
+ /**
+ * Called by framework to indicate the start of a network connection.
+ * @param sessionId The ID to indicate current Wi-Fi network connection.
+ */
+ void start(int sessionId);
+
+ /**
+ * Called by framework to indicate the end of a network connection.
+ * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
+ * {@link WifiConnectedNetworkScorer#start(int)}.
+ */
+ void stop(int sessionId);
+
+ /**
+ * Framework sets callback for score change events after application sets its scorer.
+ * @param cbImpl The instance for {@link WifiManager#ScoreChangeCallback}. Should be
+ * implemented and instantiated by framework.
+ */
+ void setScoreChangeCallback(@NonNull ScoreChangeCallback cbImpl);
+ }
+
+ /**
+ * Callback proxy for {@link WifiConnectedNetworkScorer} objects.
+ *
+ * @hide
+ */
+ private class WifiConnectedNetworkScorerProxy extends IWifiConnectedNetworkScorer.Stub {
+ private Executor mExecutor;
+ private WifiConnectedNetworkScorer mScorer;
+
+ WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer) {
+ mExecutor = executor;
+ mScorer = scorer;
+ }
+
+ @Override
+ public void start(int sessionId) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "WifiConnectedNetworkScorer: " + "start: sessionId=" + sessionId);
+ }
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mScorer.start(sessionId));
+ }
+
+ @Override
+ public void stop(int sessionId) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "WifiConnectedNetworkScorer: " + "stop: sessionId=" + sessionId);
+ }
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mScorer.stop(sessionId));
+ }
+
+ @Override
+ public void setScoreChangeCallback(IScoreChangeCallback cbImpl) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "WifiConnectedNetworkScorer: "
+ + "setScoreChangeCallback: cbImpl=" + cbImpl);
+ }
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mScorer.setScoreChangeCallback(
+ new ScoreChangeCallbackProxy(cbImpl)));
+ }
+ }
+
+ /**
+ * Set a callback for Wi-Fi connected network scorer. See {@link WifiConnectedNetworkScorer}.
+ * Only a single scorer can be set. Caller will be invoked periodically by framework to inform
+ * client about start and stop of Wi-Fi connection. Caller can clear a previously set scorer
+ * using {@link clearWifiConnectedNetworkScorer()}.
+ *
+ * @param executor The executor on which callback will be invoked.
+ * @param scorer Scorer for Wi-Fi network implemented by application.
+ * @return true Scorer is set successfully.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
+ public boolean setWifiConnectedNetworkScorer(@NonNull @CallbackExecutor Executor executor,
+ @NonNull WifiConnectedNetworkScorer scorer) {
+ if (executor == null) throw new IllegalArgumentException("executor cannot be null");
+ if (scorer == null) throw new IllegalArgumentException("scorer cannot be null");
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "setWifiConnectedNetworkScorer: scorer=" + scorer);
+ }
+ try {
+ return mService.setWifiConnectedNetworkScorer(new Binder(),
+ new WifiConnectedNetworkScorerProxy(executor, scorer));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Allow caller to clear a previously set scorer. After calling this method,
+ * client will no longer receive information about start and stop of Wi-Fi connection.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
+ public void clearWifiConnectedNetworkScorer() {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "clearWifiConnectedNetworkScorer");
+ }
+ try {
+ mService.clearWifiConnectedNetworkScorer();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index 1cf3825..08822e2 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -32,6 +32,7 @@
import android.net.wifi.ISuggestionConnectionStatusListener;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.ITxPacketCountListener;
+import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.IWifiManager;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
@@ -600,4 +601,15 @@
List<ScanResult> scanResults) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public boolean setWifiConnectedNetworkScorer(IBinder binder,
+ IWifiConnectedNetworkScorer scorer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearWifiConnectedNetworkScorer() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 983ac82..1ee5374 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -82,6 +82,7 @@
import android.net.wifi.WifiManager.SoftApCallback;
import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
import android.net.wifi.WifiManager.TrafficStateCallback;
+import android.net.wifi.WifiManager.WifiConnectedNetworkScorer;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
@@ -138,6 +139,7 @@
@Mock Executor mExecutor;
@Mock Executor mAnotherExecutor;
@Mock ActivityManager mActivityManager;
+ @Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer;
private Handler mHandler;
private TestLooper mLooper;
@@ -2230,4 +2232,63 @@
assertEquals(testResults, mWifiManager
.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>()));
}
+
+ /**
+ * Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl.
+ */
+ @Test
+ public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
+ mExecutor = new SynchronousExecutor();
+ mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
+ verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
+ any(IWifiConnectedNetworkScorer.Stub.class));
+ }
+
+ /**
+ * Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl.
+ */
+ @Test
+ public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
+ mExecutor = new SynchronousExecutor();
+ mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
+ verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
+ any(IWifiConnectedNetworkScorer.Stub.class));
+
+ mWifiManager.clearWifiConnectedNetworkScorer();
+ verify(mWifiService).clearWifiConnectedNetworkScorer();
+ }
+
+ /**
+ * Verify that Wi-Fi connected scorer receives score change callback after registeration.
+ */
+ @Test
+ public void verifyScorerReceiveScoreChangeCallbackAfterRegistration() throws Exception {
+ mExecutor = new SynchronousExecutor();
+ mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
+ ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> scorerCaptor =
+ ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
+ verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
+ scorerCaptor.capture());
+ scorerCaptor.getValue().setScoreChangeCallback(any());
+ mLooper.dispatchAll();
+ verify(mWifiConnectedNetworkScorer).setScoreChangeCallback(any());
+ }
+
+ /**
+ * Verify that Wi-Fi connected scorer receives session ID when start/stop methods are called.
+ */
+ @Test
+ public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception {
+ mExecutor = new SynchronousExecutor();
+ mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
+ ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
+ verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
+ callbackCaptor.capture());
+ callbackCaptor.getValue().start(0);
+ callbackCaptor.getValue().stop(10);
+ mLooper.dispatchAll();
+ verify(mWifiConnectedNetworkScorer).start(0);
+ verify(mWifiConnectedNetworkScorer).stop(10);
+ }
}