Merge "Added UserManager#getUserSwitchability."
diff --git a/api/current.txt b/api/current.txt
index 3489335..e717271 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5262,7 +5262,7 @@
method public int describeContents();
method public boolean getAllowSystemGeneratedContextualActions();
method public int getBadgeIconType();
- method public android.app.Notification.BubbleMetadata getBubbleMetadata();
+ method @Nullable public android.app.Notification.BubbleMetadata getBubbleMetadata();
method public String getChannelId();
method public String getGroup();
method public int getGroupAlertBehavior();
@@ -5479,25 +5479,25 @@
public static final class Notification.BubbleMetadata implements android.os.Parcelable {
method public int describeContents();
method public boolean getAutoExpandBubble();
- method public android.app.PendingIntent getDeleteIntent();
+ method @Nullable public android.app.PendingIntent getDeleteIntent();
method public int getDesiredHeight();
- method public android.graphics.drawable.Icon getIcon();
- method public android.app.PendingIntent getIntent();
+ method @NonNull public android.graphics.drawable.Icon getIcon();
+ method @NonNull public android.app.PendingIntent getIntent();
method public boolean getSuppressInitialNotification();
method @Deprecated public CharSequence getTitle();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.Notification.BubbleMetadata> CREATOR;
}
- public static class Notification.BubbleMetadata.Builder {
+ public static final class Notification.BubbleMetadata.Builder {
ctor public Notification.BubbleMetadata.Builder();
- method public android.app.Notification.BubbleMetadata build();
- method public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean);
- method public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(android.app.PendingIntent);
- method public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int);
- method public android.app.Notification.BubbleMetadata.Builder setIcon(android.graphics.drawable.Icon);
- method public android.app.Notification.BubbleMetadata.Builder setIntent(android.app.PendingIntent);
- method public android.app.Notification.BubbleMetadata.Builder setSuppressInitialNotification(boolean);
+ method @NonNull public android.app.Notification.BubbleMetadata build();
+ method @NonNull public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean);
+ method @NonNull public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(@Nullable android.app.PendingIntent);
+ method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int);
+ method @NonNull public android.app.Notification.BubbleMetadata.Builder setIcon(@NonNull android.graphics.drawable.Icon);
+ method @NonNull public android.app.Notification.BubbleMetadata.Builder setIntent(@NonNull android.app.PendingIntent);
+ method @NonNull public android.app.Notification.BubbleMetadata.Builder setSuppressInitialNotification(boolean);
method @Deprecated public android.app.Notification.BubbleMetadata.Builder setTitle(CharSequence);
}
@@ -5522,7 +5522,7 @@
method @NonNull public android.app.Notification.Builder setAllowSystemGeneratedContextualActions(boolean);
method @NonNull public android.app.Notification.Builder setAutoCancel(boolean);
method @NonNull public android.app.Notification.Builder setBadgeIconType(int);
- method @NonNull public android.app.Notification.Builder setBubbleMetadata(android.app.Notification.BubbleMetadata);
+ method @NonNull public android.app.Notification.Builder setBubbleMetadata(@Nullable android.app.Notification.BubbleMetadata);
method @NonNull public android.app.Notification.Builder setCategory(String);
method @NonNull public android.app.Notification.Builder setChannelId(String);
method @NonNull public android.app.Notification.Builder setChronometerCountDown(boolean);
@@ -6752,7 +6752,8 @@
method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.lang.String>);
method public void setDeviceOwnerLockScreenInfo(@NonNull android.content.ComponentName, CharSequence);
method public void setEndUserSessionMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
- method public int setGlobalPrivateDns(@NonNull android.content.ComponentName, int, @Nullable String);
+ method public int setGlobalPrivateDnsModeOpportunistic(@NonNull android.content.ComponentName);
+ method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String);
method public void setGlobalSetting(@NonNull android.content.ComponentName, String, String);
method public void setKeepUninstalledPackages(@Nullable android.content.ComponentName, @NonNull java.util.List<java.lang.String>);
method public boolean setKeyPairCertificate(@Nullable android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.security.cert.Certificate>, boolean);
@@ -14249,7 +14250,7 @@
method @NonNull public static android.graphics.Insets subtract(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.graphics.Insets> CREATOR;
- field public static final android.graphics.Insets NONE;
+ field @NonNull public static final android.graphics.Insets NONE;
field public final int bottom;
field public final int left;
field public final int right;
@@ -30256,16 +30257,6 @@
field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
}
- public static final class WifiAwareManager.NetworkSpecifierBuilder {
- ctor public WifiAwareManager.NetworkSpecifierBuilder();
- method @NonNull public android.net.NetworkSpecifier build();
- method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setDiscoverySession(@NonNull android.net.wifi.aware.DiscoverySession);
- method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPeerHandle(@NonNull android.net.wifi.aware.PeerHandle);
- method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPort(int);
- method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPskPassphrase(@NonNull String);
- method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setTransportProtocol(int);
- }
-
public final class WifiAwareNetworkInfo implements android.os.Parcelable android.net.TransportInfo {
method public int describeContents();
method @Nullable public java.net.Inet6Address getPeerIpv6Addr();
@@ -30275,6 +30266,22 @@
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkInfo> CREATOR;
}
+ public final class WifiAwareNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkSpecifier> CREATOR;
+ }
+
+ public static final class WifiAwareNetworkSpecifier.Builder {
+ ctor public WifiAwareNetworkSpecifier.Builder();
+ method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier build();
+ method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setDiscoverySession(@NonNull android.net.wifi.aware.DiscoverySession);
+ method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPeerHandle(@NonNull android.net.wifi.aware.PeerHandle);
+ method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(int);
+ method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPskPassphrase(@NonNull String);
+ method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(int);
+ }
+
public class WifiAwareSession implements java.lang.AutoCloseable {
method public void close();
method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, @NonNull byte[]);
@@ -35486,6 +35493,7 @@
field public static final String DISALLOW_CONFIG_VPN = "no_config_vpn";
field public static final String DISALLOW_CONFIG_WIFI = "no_config_wifi";
field public static final String DISALLOW_CONTENT_CAPTURE = "no_content_capture";
+ field public static final String DISALLOW_CONTENT_SUGGESTIONS = "no_content_suggestions";
field public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows";
field public static final String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";
field public static final String DISALLOW_DATA_ROAMING = "no_data_roaming";
@@ -50836,8 +50844,8 @@
method public final boolean startDragAndDrop(android.content.ClipData, android.view.View.DragShadowBuilder, Object, int);
method public boolean startNestedScroll(int);
method public void stopNestedScroll();
- method public void transformMatrixToGlobal(android.graphics.Matrix);
- method public void transformMatrixToLocal(android.graphics.Matrix);
+ method public void transformMatrixToGlobal(@NonNull android.graphics.Matrix);
+ method public void transformMatrixToLocal(@NonNull android.graphics.Matrix);
method public void unscheduleDrawable(@NonNull android.graphics.drawable.Drawable, @NonNull Runnable);
method public void unscheduleDrawable(android.graphics.drawable.Drawable);
method public final void updateDragShadow(android.view.View.DragShadowBuilder);
@@ -53457,11 +53465,6 @@
package android.view.inspector {
- public class GeneratedInspectionCompanionProvider implements android.view.inspector.InspectionCompanionProvider {
- ctor public GeneratedInspectionCompanionProvider();
- method @Nullable public <T> android.view.inspector.InspectionCompanion<T> provide(@NonNull Class<T>);
- }
-
public interface InspectionCompanion<T> {
method @Nullable public default String getNodeName();
method public void mapProperties(@NonNull android.view.inspector.PropertyMapper);
@@ -53542,6 +53545,11 @@
ctor public PropertyReader.PropertyTypeMismatchException(int, @NonNull String, @NonNull String);
}
+ public class StaticInspectionCompanionProvider implements android.view.inspector.InspectionCompanionProvider {
+ ctor public StaticInspectionCompanionProvider();
+ method @Nullable public <T> android.view.inspector.InspectionCompanion<T> provide(@NonNull Class<T>);
+ }
+
public final class WindowInspector {
method @NonNull public static java.util.List<android.view.View> getGlobalWindowViews();
}
@@ -56261,7 +56269,7 @@
method public String[] getDisplayedValues();
method public int getMaxValue();
method public int getMinValue();
- method public int getSelectionDividerHeight();
+ method @Px public int getSelectionDividerHeight();
method @ColorInt public int getTextColor();
method @FloatRange(from=0.0, fromInclusive=false) public float getTextSize();
method public int getValue();
diff --git a/api/system-current.txt b/api/system-current.txt
index 316f7b8..f2a81c7 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4976,8 +4976,8 @@
method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
}
- public static final class WifiAwareManager.NetworkSpecifierBuilder {
- method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPmk(@NonNull byte[]);
+ public static final class WifiAwareNetworkSpecifier.Builder {
+ method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]);
}
public class WifiAwareSession implements java.lang.AutoCloseable {
@@ -5619,7 +5619,7 @@
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isManagedProfile(int);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isPrimaryUser();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isRestrictedProfile();
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean removeUser(android.os.UserHandle);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean removeUser(@NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(@Nullable String);
field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
@@ -5849,6 +5849,7 @@
}
public final class DeviceConfig {
+ method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static boolean getBoolean(String, String, boolean);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static float getFloat(String, String, float);
@@ -5856,7 +5857,8 @@
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static long getLong(String, String, long);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getProperty(String, String);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(String, String, String);
- method public static void removeOnPropertyChangedListener(android.provider.DeviceConfig.OnPropertyChangedListener);
+ method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
+ method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String);
method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(String, String, String, boolean);
field public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager";
@@ -5891,8 +5893,11 @@
field public static final String NAMESPACE = "intelligence_attention";
}
+ public static interface DeviceConfig.OnPropertiesChangedListener {
+ method public void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
+ }
+
public static interface DeviceConfig.OnPropertyChangedListener {
- method public default void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
method public void onPropertyChanged(String, String, String);
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 1856b45..97f5ffe 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2002,6 +2002,7 @@
}
public final class DeviceConfig {
+ method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static boolean getBoolean(String, String, boolean);
method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static float getFloat(String, String, float);
@@ -2009,15 +2010,19 @@
method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static long getLong(String, String, long);
method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(String, String);
method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getString(String, String, String);
- method public static void removeOnPropertyChangedListener(android.provider.DeviceConfig.OnPropertyChangedListener);
+ method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
+ method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
method @RequiresPermission("android.permission.WRITE_DEVICE_CONFIG") public static void resetToDefaults(int, @Nullable String);
method @RequiresPermission("android.permission.WRITE_DEVICE_CONFIG") public static boolean setProperty(String, String, String, boolean);
field public static final String NAMESPACE_AUTOFILL = "autofill";
field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
}
+ public static interface DeviceConfig.OnPropertiesChangedListener {
+ method public void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
+ }
+
public static interface DeviceConfig.OnPropertyChangedListener {
- method public default void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
method public void onPropertyChanged(String, String, String);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 03806fa..a8a34d2 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3177,6 +3177,7 @@
* Returns the bubble metadata that will be used to display app content in a floating window
* over the existing foreground activity.
*/
+ @Nullable
public BubbleMetadata getBubbleMetadata() {
return mBubbleMetadata;
}
@@ -3568,7 +3569,7 @@
* collapsed state, the bubble intent will be invoked and displayed.</b>
*/
@NonNull
- public Builder setBubbleMetadata(BubbleMetadata data) {
+ public Builder setBubbleMetadata(@Nullable BubbleMetadata data) {
mN.mBubbleMetadata = data;
return this;
}
@@ -8562,6 +8563,7 @@
/**
* @return the pending intent used to populate the floating window for this bubble.
*/
+ @NonNull
public PendingIntent getIntent() {
return mPendingIntent;
}
@@ -8569,6 +8571,7 @@
/**
* @return the pending intent to send when the bubble is dismissed by a user, if one exists.
*/
+ @Nullable
public PendingIntent getDeleteIntent() {
return mDeleteIntent;
}
@@ -8583,9 +8586,11 @@
public CharSequence getTitle() {
return "";
}
+
/**
* @return the icon that will be displayed for this bubble when it is collapsed.
*/
+ @NonNull
public Icon getIcon() {
return mIcon;
}
@@ -8654,7 +8659,7 @@
/**
* Builder to construct a {@link BubbleMetadata} object.
*/
- public static class Builder {
+ public static final class Builder {
private PendingIntent mPendingIntent;
private Icon mIcon;
@@ -8672,7 +8677,8 @@
* Sets the intent that will be used when the bubble is expanded. This will display the
* app content in a floating window over the existing foreground activity.
*/
- public BubbleMetadata.Builder setIntent(PendingIntent intent) {
+ @NonNull
+ public BubbleMetadata.Builder setIntent(@NonNull PendingIntent intent) {
if (intent == null) {
throw new IllegalArgumentException("Bubble requires non-null pending intent");
}
@@ -8700,7 +8706,8 @@
* If your app produces multiple bubbles, the image should be unique for each of them.
* </p>
*/
- public BubbleMetadata.Builder setIcon(Icon icon) {
+ @NonNull
+ public BubbleMetadata.Builder setIcon(@NonNull Icon icon) {
if (icon == null) {
throw new IllegalArgumentException("Bubbles require non-null icon");
}
@@ -8713,6 +8720,7 @@
* {@link #setIntent(PendingIntent)}, this height may not be respected if there is not
* enough space on the screen or if the provided height is too small to be useful.
*/
+ @NonNull
public BubbleMetadata.Builder setDesiredHeight(int height) {
mDesiredHeight = Math.max(height, 0);
return this;
@@ -8729,6 +8737,7 @@
* <p>Generally this flag should only be set if the user has performed an action to
* request or create a bubble.</p>
*/
+ @NonNull
public BubbleMetadata.Builder setAutoExpandBubble(boolean shouldExpand) {
setFlag(FLAG_AUTO_EXPAND_BUBBLE, shouldExpand);
return this;
@@ -8745,6 +8754,7 @@
* <p>Generally this flag should only be set if the user has performed an action to
* request or create a bubble.</p>
*/
+ @NonNull
public BubbleMetadata.Builder setSuppressInitialNotification(
boolean shouldSupressNotif) {
setFlag(FLAG_SUPPRESS_INITIAL_NOTIFICATION, shouldSupressNotif);
@@ -8754,7 +8764,8 @@
/**
* Sets an optional intent to send when this bubble is explicitly removed by the user.
*/
- public BubbleMetadata.Builder setDeleteIntent(PendingIntent deleteIntent) {
+ @NonNull
+ public BubbleMetadata.Builder setDeleteIntent(@Nullable PendingIntent deleteIntent) {
mDeleteIntent = deleteIntent;
return this;
}
@@ -8764,6 +8775,7 @@
* <p>Will throw {@link IllegalStateException} if required fields have not been set
* on this builder.</p>
*/
+ @NonNull
public BubbleMetadata build() {
if (mPendingIntent == null) {
throw new IllegalStateException("Must supply pending intent to bubble");
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 095d014..7cdd227 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -84,7 +84,6 @@
import android.service.restrictions.RestrictionsReceiver;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
@@ -2210,7 +2209,7 @@
PRIVATE_DNS_SET_ERROR_FAILURE_SETTING
})
@Retention(RetentionPolicy.SOURCE)
- public @interface SetPrivateDnsModeResultConstants {}
+ public @interface PrivateDnsModeErrorCodes {}
/**
* Activity action: Starts the administrator to get the mode for the provisioning.
@@ -10450,13 +10449,41 @@
}
/**
- * Sets the global Private DNS mode and host to be used.
+ * Sets the global Private DNS mode to opportunistic.
* May only be called by the device owner.
*
- * <p>Note that in case a Private DNS resolver is specified, the method is blocking as it
- * will perform a connectivity check to the resolver, to ensure it is valid. Because of that,
- * the method should not be called on any thread that relates to user interaction, such as the
- * UI thread.
+ * <p>In this mode, the DNS subsystem will attempt a TLS handshake to the network-supplied
+ * resolver prior to attempting name resolution in cleartext.
+ *
+ * @param admin which {@link DeviceAdminReceiver} this request is associated with.
+ *
+ * @return {@code PRIVATE_DNS_SET_SUCCESS} if the mode was set successfully, or
+ * {@code PRIVATE_DNS_SET_ERROR_FAILURE_SETTING} if it could not be set.
+ *
+ * @throws SecurityException if the caller is not the device owner.
+ */
+ public @PrivateDnsModeErrorCodes int setGlobalPrivateDnsModeOpportunistic(
+ @NonNull ComponentName admin) {
+ throwIfParentInstance("setGlobalPrivateDnsModeOpportunistic");
+
+ if (mService == null) {
+ return PRIVATE_DNS_SET_ERROR_FAILURE_SETTING;
+ }
+
+ try {
+ return mService.setGlobalPrivateDns(admin, PRIVATE_DNS_MODE_OPPORTUNISTIC, null);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Sets the global Private DNS host to be used.
+ * May only be called by the device owner.
+ *
+ * <p>Note that the method is blocking as it will perform a connectivity check to the resolver,
+ * to ensure it is valid. Because of that, the method should not be called on any thread that
+ * relates to user interaction, such as the UI thread.
*
* <p>In case a VPN is used in conjunction with Private DNS resolver, the Private DNS resolver
* must be reachable both from within and outside the VPN. Otherwise, the device may lose
@@ -10464,41 +10491,35 @@
* VPN.
*
* @param admin which {@link DeviceAdminReceiver} this request is associated with.
- * @param mode Which mode to set - either {@code PRIVATE_DNS_MODE_OPPORTUNISTIC} or
- * {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME}.
- * Since the opportunistic mode defaults to ordinary DNS lookups, the
- * option to turn it completely off is not available, so this method
- * may not be called with {@code PRIVATE_DNS_MODE_OFF}.
- * @param privateDnsHost The hostname of a server that implements DNS over TLS (RFC7858), if
- * {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME} was specified as the mode,
- * null otherwise.
+ * @param privateDnsHost The hostname of a server that implements DNS over TLS (RFC7858).
*
- * @return One of the values in {@link SetPrivateDnsModeResultConstants}.
+ * @return {@code PRIVATE_DNS_SET_SUCCESS} if the mode was set successfully,
+ * {@code PRIVATE_DNS_SET_ERROR_FAILURE_SETTING} if it could not be set or
+ * {@code PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING} if the specified host does not
+ * implement RFC7858.
*
- * @throws IllegalArgumentException in the following cases: if a {@code privateDnsHost} was
- * provided but the mode was not {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME}, if the mode
- * specified was {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME} but {@code privateDnsHost} does
- * not look like a valid hostname, or if the mode specified is not one of the two valid modes.
+ * @throws IllegalArgumentException if the {@code privateDnsHost} is not a valid hostname.
*
* @throws SecurityException if the caller is not the device owner.
*/
- public int setGlobalPrivateDns(@NonNull ComponentName admin,
- @PrivateDnsMode int mode, @Nullable String privateDnsHost) {
- throwIfParentInstance("setGlobalPrivateDns");
+ @WorkerThread public @PrivateDnsModeErrorCodes int setGlobalPrivateDnsModeSpecifiedHost(
+ @NonNull ComponentName admin, @NonNull String privateDnsHost) {
+ throwIfParentInstance("setGlobalPrivateDnsModeSpecifiedHost");
+ Preconditions.checkNotNull(privateDnsHost, "dns resolver is null");
if (mService == null) {
return PRIVATE_DNS_SET_ERROR_FAILURE_SETTING;
}
- if (mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME && !TextUtils.isEmpty(privateDnsHost)
- && NetworkUtils.isWeaklyValidatedHostname(privateDnsHost)) {
+ if (NetworkUtils.isWeaklyValidatedHostname(privateDnsHost)) {
if (!PrivateDnsConnectivityChecker.canConnectToPrivateDnsServer(privateDnsHost)) {
return PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING;
}
}
try {
- return mService.setGlobalPrivateDns(admin, mode, privateDnsHost);
+ return mService.setGlobalPrivateDns(
+ admin, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, privateDnsHost);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c4a574a..89c0690 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1843,7 +1843,8 @@
}
}
- final boolean extractNativeLibsDefault = targetSdkVersion < Build.VERSION_CODES.Q;
+ // TODO: flip the default based on targetSdkVersion when possible. See b/128335904.
+ final boolean extractNativeLibsDefault = true;
final boolean extractNativeLibs = (extractNativeLibsProvided != null)
? extractNativeLibsProvided : extractNativeLibsDefault;
@@ -3718,11 +3719,10 @@
ai.flags |= ApplicationInfo.FLAG_MULTIARCH;
}
- final boolean extractNativeLibsDefault =
- owner.applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q;
+ // TODO: flip the default based on targetSdkVersion when possible. See b/128335904.
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
- extractNativeLibsDefault)) {
+ true)) {
ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
}
diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java
index af7d11d..bda4e27 100644
--- a/core/java/android/os/BatterySaverPolicyConfig.java
+++ b/core/java/android/os/BatterySaverPolicyConfig.java
@@ -476,10 +476,6 @@
*/
@NonNull
public BatterySaverPolicyConfig build() {
- if (!mEnableAdjustBrightness && Float.compare(1f, mAdjustBrightnessFactor) != 0) {
- throw new IllegalArgumentException("Brightness adjustment factor changed without "
- + "enabling brightness adjustment");
- }
return new BatterySaverPolicyConfig(this);
}
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b7e65b9..e4277e4 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -4761,6 +4761,9 @@
sb.append(")");
pw.println(sb.toString());
+ printControllerActivity(pw, sb, prefix, CELLULAR_CONTROLLER_NAME,
+ getModemControllerActivity(), which);
+
pw.print(" Cellular data received: "); pw.println(formatBytesLocked(mobileRxTotalBytes));
pw.print(" Cellular data sent: "); pw.println(formatBytesLocked(mobileTxTotalBytes));
pw.print(" Cellular packets received: "); pw.println(mobileRxTotalPackets);
@@ -4818,9 +4821,6 @@
if (!didOne) sb.append(" (no activity)");
pw.println(sb.toString());
- printControllerActivity(pw, sb, prefix, CELLULAR_CONTROLLER_NAME,
- getModemControllerActivity(), which);
-
pw.print(prefix);
sb.setLength(0);
sb.append(prefix);
@@ -4837,6 +4837,9 @@
sb.append(")");
pw.println(sb.toString());
+ printControllerActivity(pw, sb, prefix, WIFI_CONTROLLER_NAME,
+ getWifiControllerActivity(), which);
+
pw.print(" Wifi data received: "); pw.println(formatBytesLocked(wifiRxTotalBytes));
pw.print(" Wifi data sent: "); pw.println(formatBytesLocked(wifiTxTotalBytes));
pw.print(" Wifi packets received: "); pw.println(wifiRxTotalPackets);
@@ -4914,9 +4917,6 @@
if (!didOne) sb.append(" (no activity)");
pw.println(sb.toString());
- printControllerActivity(pw, sb, prefix, WIFI_CONTROLLER_NAME,
- getWifiControllerActivity(), which);
-
pw.print(prefix);
sb.setLength(0);
sb.append(prefix);
@@ -4949,8 +4949,10 @@
pw.print(prefix);
sb.setLength(0);
sb.append(prefix);
- sb.append(" Battery Drain (mAh): ");
- sb.append(Double.toString(((double) gpsBatteryDrainMaMs)/(3600 * 1000)));
+ sb.append(" GPS Battery Drain: ");
+ sb.append(new DecimalFormat("#.##").format(
+ ((double) gpsBatteryDrainMaMs) / (3600 * 1000)));
+ sb.append("mAh");
pw.println(sb.toString());
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 3725879..185df5e 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -955,6 +955,21 @@
public static final String DISALLOW_CONTENT_CAPTURE = "no_content_capture";
/**
+ * Specifies if the current user is able to receive content suggestions for selections based on
+ * the contents of their screen.
+ *
+ * <p>Device owner and profile owner can set this restriction. When it is set by device owner,
+ * only the target user will be affected.
+ *
+ * <p>The default value is <code>false</code>.
+ *
+ * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+ * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_CONTENT_SUGGESTIONS = "no_content_suggestions";
+
+ /**
* Specifies if user switching is blocked on the current user.
*
* <p> This restriction can only be set by the device owner, it will be applied to all users.
@@ -2732,11 +2747,16 @@
* Removes a user and all associated data.
*
* @param user the user that needs to be removed.
+ * @return {@code true} if the user was successfully removed, {@code false} otherwise.
+ * @throws IllegalArgumentException if {@code user} is {@code null}
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public boolean removeUser(UserHandle user) {
+ public boolean removeUser(@NonNull UserHandle user) {
+ if (user == null) {
+ throw new IllegalArgumentException("user cannot be null");
+ }
return removeUser(user.getIdentifier());
}
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 0ac7c37..e4593e5 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -30,6 +30,7 @@
import android.database.ContentObserver;
import android.net.Uri;
import android.provider.Settings.ResetMode;
+import android.util.ArrayMap;
import android.util.Pair;
import com.android.internal.annotations.GuardedBy;
@@ -398,8 +399,11 @@
private static final Object sLock = new Object();
@GuardedBy("sLock")
- private static Map<OnPropertyChangedListener, Pair<String, Executor>> sListeners =
- new HashMap<>();
+ private static ArrayMap<OnPropertyChangedListener, Pair<String, Executor>> sSingleListeners =
+ new ArrayMap<>();
+ @GuardedBy("sLock")
+ private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =
+ new ArrayMap<>();
@GuardedBy("sLock")
private static Map<String, Pair<ContentObserver, Integer>> sNamespaces = new HashMap<>();
@@ -597,20 +601,58 @@
@NonNull String namespace,
@NonNull @CallbackExecutor Executor executor,
@NonNull OnPropertyChangedListener onPropertyChangedListener) {
- // TODO enforce READ_DEVICE_CONFIG permission
synchronized (sLock) {
- Pair<String, Executor> oldNamespace = sListeners.get(onPropertyChangedListener);
+ Pair<String, Executor> oldNamespace = sSingleListeners.get(onPropertyChangedListener);
if (oldNamespace == null) {
// Brand new listener, add it to the list.
- sListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
+ sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
incrementNamespace(namespace);
} else if (namespace.equals(oldNamespace.first)) {
// Listener is already registered for this namespace, update executor just in case.
- sListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
+ sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
} else {
// Update this listener from an old namespace to the new one.
- decrementNamespace(sListeners.get(onPropertyChangedListener).first);
- sListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
+ decrementNamespace(sSingleListeners.get(onPropertyChangedListener).first);
+ sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
+ incrementNamespace(namespace);
+ }
+ }
+ }
+
+ /**
+ * Add a listener for property changes.
+ * <p>
+ * This listener will be called whenever properties in the specified namespace change. Callbacks
+ * will be made on the specified executor. Future calls to this method with the same listener
+ * will replace the old namespace and executor. Remove the listener entirely by calling
+ * {@link #removeOnPropertiesChangedListener(OnPropertiesChangedListener)}.
+ *
+ * @param namespace The namespace containing properties to monitor.
+ * @param executor The executor which will be used to run callbacks.
+ * @param onPropertiesChangedListener The listener to add.
+ * @hide
+ * @see #removeOnPropertiesChangedListener(OnPropertiesChangedListener)
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(READ_DEVICE_CONFIG)
+ public static void addOnPropertiesChangedListener(
+ @NonNull String namespace,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnPropertiesChangedListener onPropertiesChangedListener) {
+ synchronized (sLock) {
+ Pair<String, Executor> oldNamespace = sListeners.get(onPropertiesChangedListener);
+ if (oldNamespace == null) {
+ // Brand new listener, add it to the list.
+ sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
+ incrementNamespace(namespace);
+ } else if (namespace.equals(oldNamespace.first)) {
+ // Listener is already registered for this namespace, update executor just in case.
+ sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
+ } else {
+ // Update this listener from an old namespace to the new one.
+ decrementNamespace(sListeners.get(onPropertiesChangedListener).first);
+ sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
incrementNamespace(namespace);
}
}
@@ -627,11 +669,33 @@
@SystemApi
@TestApi
public static void removeOnPropertyChangedListener(
- OnPropertyChangedListener onPropertyChangedListener) {
+ @NonNull OnPropertyChangedListener onPropertyChangedListener) {
+ Preconditions.checkNotNull(onPropertyChangedListener);
synchronized (sLock) {
- if (sListeners.containsKey(onPropertyChangedListener)) {
- decrementNamespace(sListeners.get(onPropertyChangedListener).first);
- sListeners.remove(onPropertyChangedListener);
+ if (sSingleListeners.containsKey(onPropertyChangedListener)) {
+ decrementNamespace(sSingleListeners.get(onPropertyChangedListener).first);
+ sSingleListeners.remove(onPropertyChangedListener);
+ }
+ }
+ }
+
+ /**
+ * Remove a listener for property changes. The listener will receive no further notification of
+ * property changes.
+ *
+ * @param onPropertiesChangedListener The listener to remove.
+ * @hide
+ * @see #addOnPropertiesChangedListener(String, Executor, OnPropertiesChangedListener)
+ */
+ @SystemApi
+ @TestApi
+ public static void removeOnPropertiesChangedListener(
+ @NonNull OnPropertiesChangedListener onPropertiesChangedListener) {
+ Preconditions.checkNotNull(onPropertiesChangedListener);
+ synchronized (sLock) {
+ if (sListeners.containsKey(onPropertiesChangedListener)) {
+ decrementNamespace(sListeners.get(onPropertiesChangedListener).first);
+ sListeners.remove(onPropertiesChangedListener);
}
}
}
@@ -700,14 +764,30 @@
final String name = pathSegments.get(2);
final String value = getProperty(namespace, name);
synchronized (sLock) {
- for (final OnPropertyChangedListener listener : sListeners.keySet()) {
- if (namespace.equals(sListeners.get(listener).first)) {
- sListeners.get(listener).second.execute(new Runnable() {
+ // OnPropertiesChangedListeners
+ for (int i = 0; i < sListeners.size(); i++) {
+ if (namespace.equals(sListeners.valueAt(i).first)) {
+ final int j = i;
+ sListeners.valueAt(i).second.execute(new Runnable() {
@Override
public void run() {
Map<String, String> propertyMap = new HashMap(1);
propertyMap.put(name, value);
- listener.onPropertiesChanged(new Properties(namespace, propertyMap));
+ sListeners.keyAt(j)
+ .onPropertiesChanged(new Properties(namespace, propertyMap));
+ }
+
+ });
+ }
+ }
+ // OnPropertyChangedListeners
+ for (int i = 0; i < sSingleListeners.size(); i++) {
+ if (namespace.equals(sSingleListeners.valueAt(i).first)) {
+ final int j = i;
+ sSingleListeners.valueAt(i).second.execute(new Runnable() {
+ @Override
+ public void run() {
+ sSingleListeners.keyAt(j).onPropertyChanged(namespace, name, value);
}
});
@@ -717,7 +797,7 @@
}
/**
- * Interface for monitoring to properties.
+ * Interface for monitoring single property changes.
* <p>
* Override {@link #onPropertyChanged(String, String, String)} to handle callbacks for changes.
*
@@ -734,22 +814,25 @@
* @param value The new value of the property which has changed.
*/
void onPropertyChanged(String namespace, String name, String value);
+ }
+ /**
+ * Interface for monitoring changes to properties.
+ * <p>
+ * Override {@link #onPropertiesChanged(Properties)} to handle callbacks for changes.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public interface OnPropertiesChangedListener {
/**
* Called when one or more properties have changed.
*
* @param properties Contains the complete collection of properties which have changed for a
- * single namespace.
+ * single namespace.
*/
- default void onPropertiesChanged(@NonNull Properties properties) {
- // During the transitional period, this method calls the old one to ensure legacy
- // callers continue to function as expected. Ignore this if you are implementing it for
- // yourself.
- String namespace = properties.getNamespace();
- for (String name : properties.getKeyset()) {
- onPropertyChanged(namespace, name, properties.getString(name, null));
- }
- }
+ void onPropertiesChanged(@NonNull Properties properties);
}
/**
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 87bdfe0..780b576 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -373,7 +373,10 @@
args.recycle();
Adjustment adjustment = onNotificationEnqueued(sbn, channel);
if (adjustment != null) {
- if (!isBound()) return;
+ if (!isBound()) {
+ Log.w(TAG, "MSG_ON_NOTIFICATION_ENQUEUED: service not bound, skip.");
+ return;
+ }
try {
getNotificationInterface().applyEnqueuedAdjustmentFromAssistant(
mWrapper, adjustment);
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 4315100..cc74e1a 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -63,9 +63,6 @@
private Context mContext; // used for inflation & icon expansion
- // Contains the basic logging data of the notification.
- private LogMaker mLogMaker;
-
/** @hide */
public StatusBarNotification(String pkg, String opPkg, int id,
String tag, int uid, int initialPid, Notification notification, UserHandle user,
@@ -404,24 +401,15 @@
* @hide
*/
public LogMaker getLogMaker() {
- if (mLogMaker == null) {
- // Initialize fields that only change on update (so a new record).
- mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
- .setPackageName(getPackageName())
+ return new LogMaker(MetricsEvent.VIEW_UNKNOWN).setPackageName(getPackageName())
.addTaggedData(MetricsEvent.NOTIFICATION_ID, getId())
.addTaggedData(MetricsEvent.NOTIFICATION_TAG, getTag())
- .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag());
- }
- // Reset fields that can change between updates, or are used by multiple logs.
- return mLogMaker
- .clearCategory()
- .clearType()
- .clearSubtype()
- .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
- .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
- getNotification().isGroupSummary() ? 1 : 0)
- .addTaggedData(MetricsProto.MetricsEvent.FIELD_NOTIFICATION_CATEGORY,
- getNotification().category);
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag())
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
+ getNotification().isGroupSummary() ? 1 : 0)
+ .addTaggedData(MetricsProto.MetricsEvent.FIELD_NOTIFICATION_CATEGORY,
+ getNotification().category);
}
private String getGroupLogTag() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2479497..7fcce6d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24116,7 +24116,7 @@
*
* @param matrix input matrix to modify
*/
- public void transformMatrixToGlobal(Matrix matrix) {
+ public void transformMatrixToGlobal(@NonNull Matrix matrix) {
final ViewParent parent = mParent;
if (parent instanceof View) {
final View vp = (View) parent;
@@ -24141,7 +24141,7 @@
*
* @param matrix input matrix to modify
*/
- public void transformMatrixToLocal(Matrix matrix) {
+ public void transformMatrixToLocal(@NonNull Matrix matrix) {
final ViewParent parent = mParent;
if (parent instanceof View) {
final View vp = (View) parent;
diff --git a/core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java b/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
similarity index 76%
rename from core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java
rename to core/java/android/view/inspector/StaticInspectionCompanionProvider.java
index d4b7e85..42a892d 100644
--- a/core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java
+++ b/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
@@ -20,15 +20,15 @@
import android.annotation.Nullable;
/**
- * An inspection companion provider that loads pre-generated inspection companions
+ * An inspection companion provider that finds companions as inner classes or generated code.
*
* @see android.processor.view.inspector.PlatformInspectableProcessor
*/
-public class GeneratedInspectionCompanionProvider implements InspectionCompanionProvider {
+public class StaticInspectionCompanionProvider implements InspectionCompanionProvider {
/**
- * The suffix used for the generated class
+ * The suffix used for the generated classes and inner classes
*/
- private static final String COMPANION_SUFFIX = "$$InspectionCompanion";
+ private static final String COMPANION_SUFFIX = "$InspectionCompanion";
@Override
@Nullable
@@ -39,7 +39,12 @@
try {
final Class<InspectionCompanion<T>> companionClass =
(Class<InspectionCompanion<T>>) cls.getClassLoader().loadClass(companionName);
- return companionClass.newInstance();
+
+ if (InspectionCompanion.class.isAssignableFrom(companionClass)) {
+ return companionClass.newInstance();
+ } else {
+ return null;
+ }
} catch (ClassNotFoundException e) {
return null;
} catch (IllegalAccessException e) {
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 090640e..150fa88 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -102,9 +102,11 @@
/**
* Notify the host application that a page has finished loading. This method
- * is called only for main frame. When onPageFinished() is called, the
- * rendering picture may not be updated yet. To get the notification for the
- * new Picture, use {@link WebView.PictureListener#onNewPicture}.
+ * is called only for main frame. Receiving an {@code onPageFinished()} callback does not
+ * guarantee that the next frame drawn by WebView will reflect the state of the DOM at this
+ * point. In order to be notified that the current DOM state is ready to be rendered, request a
+ * visual state callback with {@link WebView#postVisualStateCallback} and wait for the supplied
+ * callback to be triggered.
*
* @param view The WebView that is initiating the callback.
* @param url The url of the page.
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index dad2669..685e8de 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1587,6 +1587,7 @@
* others.
* @return The height of the divider
*/
+ @Px
public int getSelectionDividerHeight() {
return mSelectionDividerHeight;
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 17ed2a0..c095376 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1687,8 +1687,21 @@
*
* @return a unique 64-bit token handle which is needed to refer to this token later.
*/
- public long addEscrowToken(byte[] token, int userId) {
- return getLockSettingsInternal().addEscrowToken(token, userId);
+ public long addEscrowToken(byte[] token, int userId,
+ @Nullable EscrowTokenStateChangeCallback callback) {
+ return getLockSettingsInternal().addEscrowToken(token, userId, callback);
+ }
+
+ /**
+ * Callback interface to notify when an added escrow token has been activated.
+ */
+ public interface EscrowTokenStateChangeCallback {
+ /**
+ * The method to be called when the token is activated.
+ * @param handle 64 bit handle corresponding to the escrow token
+ * @param userid user for whom the escrow token has been added
+ */
+ void onEscrowTokenActivated(long handle, int userid);
}
/**
diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java
index 90397df..d459bfb 100644
--- a/core/java/com/android/internal/widget/LockSettingsInternal.java
+++ b/core/java/com/android/internal/widget/LockSettingsInternal.java
@@ -29,15 +29,18 @@
* or change user password.
*
* After adding, if the user currently has lockscreen password, he will need to perform a
- * confirm credential operation in order to activate the token for future use. If the user
+ * confirm credential operation in order to activate the token for future use.
+ * Once the token is activated, the callback that is passed here is called. If the user
* has no secure lockscreen, then the token is activated immediately.
*
* @return a unique 64-bit token handle which is needed to refer to this token later.
*/
- public abstract long addEscrowToken(byte[] token, int userId);
+ public abstract long addEscrowToken(byte[] token, int userId,
+ LockPatternUtils.EscrowTokenStateChangeCallback callback);
/**
* Remove an escrow token.
+ *
* @return true if the given handle refers to a valid token previously returned from
* {@link #addEscrowToken}, whether it's active or not. return false otherwise.
*/
@@ -51,6 +54,7 @@
/**
* Set the lock credential.
+ *
* @return true if password is set.
*/
public abstract boolean setLockCredentialWithToken(byte[] credential, int type,
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index d100f40..04fa524 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -16,6 +16,7 @@
package android.provider;
+import static android.provider.DeviceConfig.OnPropertiesChangedListener;
import static android.provider.DeviceConfig.OnPropertyChangedListener;
import static com.google.common.truth.Truth.assertThat;
@@ -224,29 +225,31 @@
}
@Test
- public void testListener_propertiesCallback() throws InterruptedException {
+ public void testOnPropertiesChangedListener() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
- OnPropertyChangedListener changeListener = new OnPropertyChangedListener() {
- public void onPropertyChanged(String namespace, String name, String value) {
- // ignore legacy callback
- }
-
- @Override
- public void onPropertiesChanged(DeviceConfig.Properties properties) {
- assertThat(properties.getNamespace()).isEqualTo(sNamespace);
- assertThat(properties.getKeyset().size()).isEqualTo(1);
- assertThat(properties.getKeyset()).contains(sKey);
- assertThat(properties.getString(sKey, "default_value")).isEqualTo(sValue);
- countDownLatch.countDown();
- }
+ OnPropertiesChangedListener changeListener = (properties) -> {
+ assertThat(properties.getNamespace()).isEqualTo(sNamespace);
+ assertThat(properties.getKeyset()).contains(sKey);
+ assertThat(properties.getString(sKey, "default_value")).isEqualTo(sValue);
+ countDownLatch.countDown();
};
- testListener(countDownLatch, changeListener);
+ try {
+ DeviceConfig.addOnPropertiesChangedListener(sNamespace,
+ ActivityThread.currentApplication().getMainExecutor(), changeListener);
+ DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
+ assertThat(countDownLatch.await(
+ WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
+ } catch (InterruptedException e) {
+ Assert.fail(e.getMessage());
+ } finally {
+ DeviceConfig.removeOnPropertiesChangedListener(changeListener);
+ }
}
@Test
- public void testListener_legacyCallback() throws InterruptedException {
+ public void testOnPropertyChangedListener() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
OnPropertyChangedListener changeListener = (namespace, name, value) -> {
@@ -256,12 +259,6 @@
countDownLatch.countDown();
};
- testListener(countDownLatch, changeListener);
-
- }
-
- private void testListener(CountDownLatch countDownLatch,
- OnPropertyChangedListener changeListener) {
try {
DeviceConfig.addOnPropertyChangedListener(sNamespace,
ActivityThread.currentApplication().getMainExecutor(), changeListener);
@@ -273,6 +270,7 @@
} finally {
DeviceConfig.removeOnPropertyChangedListener(changeListener);
}
+
}
private static boolean deleteViaContentProvider(String namespace, String key) {
diff --git a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
index c99777b..0f32a82 100644
--- a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
+++ b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
@@ -89,6 +89,17 @@
assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CATEGORY));
}
+ /** Verify that modifying the returned logMaker won't leave stale data behind for
+ * the next caller.*/
+ @Test
+ public void testLogMakerNoStaleData() {
+ StatusBarNotification sbn = getNotification(PKG, GROUP_ID_1, CHANNEL_ID);
+ final LogMaker logMaker = sbn.getLogMaker();
+ int extraTag = MetricsEvent.FIELD_NOTIFICATION_CHANNEL_GROUP_ID; // An arbitrary new tag
+ logMaker.addTaggedData(extraTag, 1);
+ assertNull(sbn.getLogMaker().getTaggedData(extraTag));
+ }
+
@Test
public void testLogMakerWithCategory() {
Notification.Builder builder = getNotificationBuilder(GROUP_ID_1, CHANNEL_ID)
diff --git a/graphics/java/android/graphics/Insets.java b/graphics/java/android/graphics/Insets.java
index c6dc239..1e03c53 100644
--- a/graphics/java/android/graphics/Insets.java
+++ b/graphics/java/android/graphics/Insets.java
@@ -30,7 +30,7 @@
*
*/
public final class Insets implements Parcelable {
- public static final Insets NONE = new Insets(0, 0, 0, 0);
+ public static final @NonNull Insets NONE = new Insets(0, 0, 0, 0);
public final int left;
public final int top;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index a15ff22..c174c24 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -19,8 +19,6 @@
#include "renderstate/RenderState.h"
#include "utils/Color.h"
-#include <SkToSRGBColorFilter.h>
-
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 2ffda83..fe633e9 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -20,7 +20,6 @@
#include "renderthread/EglManager.h"
#include "renderthread/VulkanManager.h"
-#include <SkToSRGBColorFilter.h>
#include <gui/Surface.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
index 58dbea4..69b4672 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
@@ -32,6 +32,7 @@
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.UserHandle;
+import android.os.UserManager;
import android.util.Slog;
import com.android.server.LocalServices;
@@ -63,7 +64,8 @@
public ContentSuggestionsManagerService(Context context) {
super(context, new FrameworkResourcesServiceNameResolver(context,
- com.android.internal.R.string.config_defaultContentSuggestionsService), null);
+ com.android.internal.R.string.config_defaultContentSuggestionsService),
+ UserManager.DISALLOW_CONTENT_SUGGESTIONS);
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
diff --git a/services/core/java/com/android/server/am/BroadcastDispatcher.java b/services/core/java/com/android/server/am/BroadcastDispatcher.java
index b0b1840..d029482 100644
--- a/services/core/java/com/android/server/am/BroadcastDispatcher.java
+++ b/services/core/java/com/android/server/am/BroadcastDispatcher.java
@@ -450,6 +450,8 @@
return mCurrentBroadcast;
}
+ final boolean someQueued = !mOrderedBroadcasts.isEmpty();
+
BroadcastRecord next = null;
if (!mAlarmBroadcasts.isEmpty()) {
next = popLocked(mAlarmBroadcasts);
@@ -459,10 +461,18 @@
}
if (next == null && !mDeferredBroadcasts.isEmpty()) {
+ // We're going to deliver either:
+ // 1. the next "overdue" deferral; or
+ // 2. the next ordinary ordered broadcast; *or*
+ // 3. the next not-yet-overdue deferral.
+
for (int i = 0; i < mDeferredBroadcasts.size(); i++) {
Deferrals d = mDeferredBroadcasts.get(i);
- if (now < d.deferUntil) {
- // No more deferrals due
+ if (now < d.deferUntil && someQueued) {
+ // stop looking when we haven't hit the next time-out boundary
+ // but only if we have un-deferred broadcasts waiting,
+ // otherwise we can deliver whatever deferred broadcast
+ // is next available.
break;
}
@@ -483,7 +493,7 @@
}
}
- if (next == null && !mOrderedBroadcasts.isEmpty()) {
+ if (next == null && someQueued) {
next = mOrderedBroadcasts.remove(0);
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG, "Next broadcast from main queue: " + next);
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index af4db07..b0d8813 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -664,6 +664,12 @@
private void updateDisplayModes(int displayId) {
Display d = mContext.getSystemService(DisplayManager.class).getDisplay(displayId);
+ if (d == null) {
+ // We can occasionally get a display added or changed event for a display that was
+ // subsequently removed, which means this returns null. Check this case and bail
+ // out early; if it gets re-attached we'll eventually get another call back for it.
+ return;
+ }
DisplayInfo info = new DisplayInfo();
d.getDisplayInfo(info);
boolean changed = false;
diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java
index 91b5234..0e9ee40 100644
--- a/services/core/java/com/android/server/location/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/GnssConfiguration.java
@@ -52,7 +52,6 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- //TODO(b/33112647): Create gps_debug.conf with commented career parameters.
private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf";
// config.xml properties
@@ -191,8 +190,6 @@
return Collections.EMPTY_LIST;
}
- // TODO(b/122856486): Validate proxy app names so that a system app or some popular app
- // with location permission is not specified as a proxy app.
ArrayList proxyApps = new ArrayList(proxyAppsArray.length);
for (String proxyApp : proxyAppsArray) {
proxyApps.add(proxyApp);
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 29030fa..c173d66 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -67,6 +67,7 @@
import android.util.Log;
import android.util.StatsLog;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
import com.android.internal.location.GpsNetInitiatedHandler;
import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
@@ -890,12 +891,14 @@
return GPS_POSITION_MODE_STANDALONE;
}
- private boolean handleEnable() {
- if (DEBUG) Log.d(TAG, "handleEnable");
+ @GuardedBy("mLock")
+ private void handleEnableLocked() {
+ if (DEBUG) Log.d(TAG, "handleEnableLocked");
boolean inited = native_init();
if (inited) {
+ mEnabled = true;
mSupportsXtra = native_supports_xtra();
// TODO: remove the following native calls if we can make sure they are redundant.
@@ -912,15 +915,16 @@
mGnssNavigationMessageProvider.onGpsEnabledChanged();
mGnssBatchingProvider.enable();
} else {
+ mEnabled = false;
Log.w(TAG, "Failed to enable location provider");
}
-
- return inited;
}
- private void handleDisable() {
- if (DEBUG) Log.d(TAG, "handleDisable");
+ @GuardedBy("mLock")
+ private void handleDisableLocked() {
+ if (DEBUG) Log.d(TAG, "handleDisableLocked");
+ mEnabled = false;
updateClientUids(new WorkSource());
stopNavigating();
mAlarmManager.cancel(mWakeupIntent);
@@ -946,10 +950,9 @@
}
if (enabled) {
- mEnabled = handleEnable();
+ handleEnableLocked();
} else {
- mEnabled = false;
- handleDisable();
+ handleDisableLocked();
}
}
}
diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
index 90d16cb..c06b03b 100644
--- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
@@ -373,8 +373,8 @@
networkAttributes = new NetworkAttributes();
networkAttributes.mCapabilities = capabilities;
- // TODO(b/119278134): The synchronous method ConnectivityManager.getNetworkInfo() must
- // not be called inside the asynchronous ConnectivityManager.NetworkCallback methods.
+ // TODO: The synchronous method ConnectivityManager.getNetworkInfo() should not be called
+ // inside the asynchronous ConnectivityManager.NetworkCallback methods.
NetworkInfo info = mConnMgr.getNetworkInfo(network);
if (info != null) {
networkAttributes.mApn = info.getExtraInfo();
@@ -387,8 +387,8 @@
}
private void handleSuplConnectionAvailable(Network network) {
- // TODO(b/119278134): The synchronous method ConnectivityManager.getNetworkInfo() must
- // not be called inside the asynchronous ConnectivityManager.NetworkCallback methods.
+ // TODO: The synchronous method ConnectivityManager.getNetworkInfo() should not be called
+ // inside the asynchronous ConnectivityManager.NetworkCallback methods.
NetworkInfo info = mConnMgr.getNetworkInfo(network);
String apn = null;
if (info != null) {
@@ -509,8 +509,8 @@
}
}
- // TODO(25876485): Delete this method when all devices upgrade to HAL @2.0::IAGnssCallback
- // interface which does not require setting route to host.
+ // TODO: Delete this method when all devices upgrade to HAL @2.0::IAGnssCallback
+ // interface which does not require setting route to host.
private void setRouting() {
boolean result = mConnMgr.requestRouteToHostAddress(
ConnectivityManager.TYPE_MOBILE_SUPL,
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index 20f872a..24ee389 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -18,7 +18,6 @@
import android.annotation.SuppressLint;
import android.app.AppOpsManager;
-import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -32,11 +31,11 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.StatsLog;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -76,9 +75,9 @@
private boolean mIsDeviceLocationSettingsEnabled;
// Number of non-framework location access proxy apps is expected to be small (< 5).
- private static final int HASH_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS = 7;
- private HashMap<String, Boolean> mProxyAppToLocationPermissions = new HashMap<>(
- HASH_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS);
+ private static final int ARRAY_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS = 7;
+ private ArrayMap<String, Boolean> mProxyAppToLocationPermissions = new ArrayMap<>(
+ ARRAY_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS);
private PackageManager.OnPermissionsChangedListener mOnPermissionsChangedListener =
uid -> runOnHandler(() -> handlePermissionsChanged(uid));
@@ -97,10 +96,6 @@
}
void updateProxyApps(List<String> nfwLocationAccessProxyApps) {
- // NOTE: This class doesn't explicitly register and listen for SIM_STATE_CHANGED event
- // but rather piggy backs on the GnssLocationProvider SIM_STATE_CHANGED handling
- // so that the order of processing is preserved. GnssLocationProvider should
- // first load the new config parameters for the new SIM and then call this method.
runOnHandler(() -> handleUpdateProxyApps(nfwLocationAccessProxyApps));
}
@@ -246,15 +241,7 @@
// Represents NfwNotification structure in IGnssVisibilityControlCallback.hal
private static class NfwNotification {
- private static final String KEY_PROTOCOL_STACK = "ProtocolStack";
- private static final String KEY_OTHER_PROTOCOL_STACK_NAME = "OtherProtocolStackName";
- private static final String KEY_REQUESTOR = "Requestor";
- private static final String KEY_REQUESTOR_ID = "RequestorId";
- private static final String KEY_RESPONSE_TYPE = "ResponseType";
- private static final String KEY_IN_EMERGENCY_MODE = "InEmergencyMode";
- private static final String KEY_IS_CACHED_LOCATION = "IsCachedLocation";
-
- // This must match with NfwResponseType enum in IGnssVisibilityControlCallback.hal.
+ // These must match with NfwResponseType enum in IGnssVisibilityControlCallback.hal.
private static final byte NFW_RESPONSE_TYPE_REJECTED = 0;
private static final byte NFW_RESPONSE_TYPE_ACCEPTED_NO_LOCATION_PROVIDED = 1;
private static final byte NFW_RESPONSE_TYPE_ACCEPTED_LOCATION_PROVIDED = 2;
@@ -281,30 +268,14 @@
mIsCachedLocation = isCachedLocation;
}
- private void copyFieldsToIntent(Intent intent) {
- intent.putExtra(KEY_PROTOCOL_STACK, mProtocolStack);
- if (!TextUtils.isEmpty(mOtherProtocolStackName)) {
- intent.putExtra(KEY_OTHER_PROTOCOL_STACK_NAME, mOtherProtocolStackName);
- }
- intent.putExtra(KEY_REQUESTOR, mRequestor);
- if (!TextUtils.isEmpty(mRequestorId)) {
- intent.putExtra(KEY_REQUESTOR_ID, mRequestorId);
- }
- intent.putExtra(KEY_RESPONSE_TYPE, mResponseType);
- intent.putExtra(KEY_IN_EMERGENCY_MODE, mInEmergencyMode);
- if (mResponseType == NFW_RESPONSE_TYPE_ACCEPTED_LOCATION_PROVIDED) {
- intent.putExtra(KEY_IS_CACHED_LOCATION, mIsCachedLocation);
- }
- }
-
@SuppressLint("DefaultLocale")
public String toString() {
return String.format(
- "[Notification] proxyAppPackageName: %s, protocolStack: %d"
- + ", otherProtocolStackName: %s, requestor: %d, requestorId: %s"
- + ", responseType: %d, inEmergencyMode: %b, isCachedLocation: %b",
- mProxyAppPackageName, mProtocolStack, mOtherProtocolStackName,
- mRequestor, mRequestorId, mResponseType, mInEmergencyMode, mIsCachedLocation);
+ "{proxyAppPackageName: %s, protocolStack: %d, otherProtocolStackName: %s, "
+ + "requestor: %d, requestorId: %s, responseType: %s, inEmergencyMode:"
+ + " %b, isCachedLocation: %b}",
+ mProxyAppPackageName, mProtocolStack, mOtherProtocolStackName, mRequestor,
+ mRequestorId, getResponseTypeAsString(), mInEmergencyMode, mIsCachedLocation);
}
private String getResponseTypeAsString() {
@@ -405,7 +376,7 @@
}
private void handleNfwNotification(NfwNotification nfwNotification) {
- if (DEBUG) Log.d(TAG, nfwNotification.toString());
+ if (DEBUG) Log.d(TAG, "Non-framework location access notification: " + nfwNotification);
final String proxyAppPackageName = nfwNotification.mProxyAppPackageName;
Boolean isLocationPermissionEnabled = mProxyAppToLocationPermissions.get(
@@ -421,39 +392,27 @@
logEvent(nfwNotification, isPermissionMismatched);
if (TextUtils.isEmpty(proxyAppPackageName)) {
- Log.e(TAG, "ProxyAppPackageName field is not set. Not sending intent to proxy app for "
- + nfwNotification);
+ Log.e(TAG, "ProxyAppPackageName field is not set. AppOps service not notified "
+ + "for non-framework location access notification: " + nfwNotification);
return;
}
if (isLocationPermissionEnabled == null) {
- // App is not in the configured list.
- Log.e(TAG, "Could not find proxy app with name: " + proxyAppPackageName + " in the "
+ Log.w(TAG, "Could not find proxy app with name: " + proxyAppPackageName + " in the "
+ "value specified for config parameter: "
- + GnssConfiguration.CONFIG_NFW_PROXY_APPS + ". Not sending intent to proxy app"
- + " for " + nfwNotification);
- return;
- }
-
- // Send intent to non-framework location proxy app with notification information.
- final Intent intent = new Intent(
- proxyAppPackageName + NFW_INTENT_ACTION_NFW_LOCATION_ACCESS_SUFFIX);
- final String proxAppActivityName =
- proxyAppPackageName + NFW_PROXY_APP_PKG_ACTIVITY_NAME_SUFFIX;
- intent.setClassName(proxyAppPackageName, proxAppActivityName);
- intent.setType(NFW_INTENT_TYPE);
- nfwNotification.copyFieldsToIntent(intent);
-
- // Check if the proxy app is still installed.
- final Integer clsAppUid = getApplicationUid(proxyAppPackageName);
- if (clsAppUid == null || intent.resolveActivity(mPackageManager) == null) {
- Log.i(TAG, "Proxy application " + proxyAppPackageName + " and/or activity "
- + proxAppActivityName + " is not found. Not sending"
- + " intent to proxy app for " + nfwNotification);
+ + GnssConfiguration.CONFIG_NFW_PROXY_APPS + ". AppOps service not notified "
+ + "for non-framework location access notification: " + nfwNotification);
return;
}
// Display location icon attributed to this proxy app.
+ final Integer clsAppUid = getApplicationUid(proxyAppPackageName);
+ if (clsAppUid == null) {
+ Log.e(TAG, "Proxy app " + proxyAppPackageName + " is not found. AppOps service not "
+ + "notified for non-framework location access notification: "
+ + nfwNotification);
+ return;
+ }
mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, clsAppUid, proxyAppPackageName);
// Log proxy app permission mismatch between framework and GNSS HAL.
@@ -461,18 +420,8 @@
Log.w(TAG, "Permission mismatch. Framework proxy app " + proxyAppPackageName
+ " location permission is set to " + isLocationPermissionEnabled
+ " but GNSS non-framework location access response type is "
- + nfwNotification.getResponseTypeAsString() + " for " + nfwNotification);
- }
-
- // Notify proxy app.
- try {
- if (DEBUG) {
- Log.d(TAG, "Sending non-framework location access notification intent: " + intent);
- }
- mContext.startActivityAsUser(intent, UserHandle.getUserHandleForUid(clsAppUid));
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "Activity not found. Failed to send non-framework location access"
- + " notification intent to proxy app activity: " + proxAppActivityName);
+ + nfwNotification.getResponseTypeAsString() + " for notification: "
+ + nfwNotification);
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index b6995db..a53ab84 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -21,6 +21,7 @@
import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
@@ -2648,7 +2649,8 @@
}
}
- private long addEscrowToken(byte[] token, int userId) throws RemoteException {
+ private long addEscrowToken(byte[] token, int userId, EscrowTokenStateChangeCallback callback)
+ throws RemoteException {
if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
synchronized (mSpManager) {
enableSyntheticPasswordLocked();
@@ -2672,7 +2674,7 @@
throw new SecurityException("Escrow token is disabled on the current user");
}
}
- long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
+ long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId, callback);
if (auth != null) {
mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
}
@@ -2943,9 +2945,10 @@
private final class LocalService extends LockSettingsInternal {
@Override
- public long addEscrowToken(byte[] token, int userId) {
+ public long addEscrowToken(byte[] token, int userId,
+ EscrowTokenStateChangeCallback callback) {
try {
- return LockSettingsService.this.addEscrowToken(token, userId);
+ return LockSettingsService.this.addEscrowToken(token, userId, callback);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index dbcfbcd..142ad53 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -16,6 +16,8 @@
package com.android.server.locksettings;
+import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
@@ -281,6 +283,7 @@
byte[] secdiscardableOnDisk;
byte[] weaverSecret;
byte[] aggregatedSecret;
+ EscrowTokenStateChangeCallback mCallback;
}
private final Context mContext;
@@ -746,7 +749,12 @@
private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>();
- public long createTokenBasedSyntheticPassword(byte[] token, int userId) {
+ /**
+ * Create a token based Synthetic password for the given user.
+ * @return
+ */
+ public long createTokenBasedSyntheticPassword(byte[] token, int userId,
+ @Nullable EscrowTokenStateChangeCallback changeCallback) {
long handle = generateHandle();
if (!tokenMap.containsKey(userId)) {
tokenMap.put(userId, new ArrayMap<>());
@@ -762,6 +770,7 @@
tokenData.weaverSecret = null;
}
tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable);
+ tokenData.mCallback = changeCallback;
tokenMap.get(userId).put(handle, tokenData);
return handle;
@@ -810,6 +819,9 @@
createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, authToken,
tokenData.aggregatedSecret, 0L, userId);
tokenMap.get(userId).remove(handle);
+ if (tokenData.mCallback != null) {
+ tokenData.mCallback.onEscrowTokenActivated(handle, userId);
+ }
return true;
}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 7a87a57..0c0c23a 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -1112,7 +1112,7 @@
binder.linkToDeath(info, 0);
added = mServices.add(info);
} catch (RemoteException e) {
- // already dead
+ Slog.e(TAG, "Failed to linkToDeath, already dead", e);
}
}
if (added) {
@@ -1144,6 +1144,11 @@
}
}
}
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ Slog.v(TAG, "onNullBinding() called with: name = [" + name + "]");
+ }
};
if (!mContext.bindServiceAsUser(intent,
serviceConnection,
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d25360a..88e697c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -251,7 +251,6 @@
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
-import java.util.function.Predicate;
/** {@hide} */
public class NotificationManagerService extends SystemService {
@@ -759,7 +758,7 @@
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r == null) {
- Log.w(TAG, "No notification with key: " + key);
+ Slog.w(TAG, "No notification with key: " + key);
return;
}
final long now = System.currentTimeMillis();
@@ -789,7 +788,7 @@
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r == null) {
- Log.w(TAG, "No notification with key: " + key);
+ Slog.w(TAG, "No notification with key: " + key);
return;
}
final long now = System.currentTimeMillis();
@@ -3133,7 +3132,7 @@
synchronized (mNotificationLock) {
final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
if (info.supportsProfiles()) {
- Log.e(TAG, "Ignoring deprecated cancelNotification(pkg, tag, id) "
+ Slog.e(TAG, "Ignoring deprecated cancelNotification(pkg, tag, id) "
+ "from " + info.component
+ " use cancelNotification(key) instead.");
} else {
@@ -4553,7 +4552,7 @@
+ ", incomingUserId=" + incomingUserId
+ ", notificationUid=" + notificationUid
+ ", notification=" + notification;
- Log.e(TAG, noChannelStr);
+ Slog.e(TAG, noChannelStr);
boolean appNotificationsOff = mPreferencesHelper.getImportance(pkg, notificationUid)
== NotificationManager.IMPORTANCE_NONE;
@@ -4650,7 +4649,7 @@
android.Manifest.permission.USE_FULL_SCREEN_INTENT, pkg);
if (fullscreenIntentPermission != PERMISSION_GRANTED) {
notification.fullScreenIntent = null;
- Log.w(TAG, "Package " + pkg +
+ Slog.w(TAG, "Package " + pkg +
": Use of fullScreenIntent requires the USE_FULL_SCREEN_INTENT permission");
}
}
@@ -5179,7 +5178,7 @@
// Ignore summary updates because we don't display most of the information.
if (r.sbn.isGroup() && r.sbn.getNotification().isGroupSummary()) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is not interruptive: summary");
}
return false;
@@ -5187,7 +5186,7 @@
if (old == null) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is interruptive: new notification");
}
return true;
@@ -5195,7 +5194,7 @@
if (r == null) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is not interruptive: null");
}
return false;
@@ -5206,7 +5205,7 @@
if (oldN.extras == null || newN.extras == null) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is not interruptive: no extras");
}
return false;
@@ -5216,7 +5215,7 @@
// consider them one 'session'. Count them for everything else.
if ((r.sbn.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is not interruptive: foreground service");
}
return false;
@@ -5226,11 +5225,11 @@
final String newTitle = String.valueOf(newN.extras.get(Notification.EXTRA_TITLE));
if (!Objects.equals(oldTitle, newTitle)) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is interruptive: changed title");
- Log.v(TAG, "INTERRUPTIVENESS: " + String.format(" old title: %s (%s@0x%08x)",
+ Slog.v(TAG, "INTERRUPTIVENESS: " + String.format(" old title: %s (%s@0x%08x)",
oldTitle, oldTitle.getClass(), oldTitle.hashCode()));
- Log.v(TAG, "INTERRUPTIVENESS: " + String.format(" new title: %s (%s@0x%08x)",
+ Slog.v(TAG, "INTERRUPTIVENESS: " + String.format(" new title: %s (%s@0x%08x)",
newTitle, newTitle.getClass(), newTitle.hashCode()));
}
return true;
@@ -5240,18 +5239,18 @@
final String newText = String.valueOf(newN.extras.get(Notification.EXTRA_TEXT));
if (!Objects.equals(oldText, newText)) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is interruptive: changed text");
- Log.v(TAG, "INTERRUPTIVENESS: " + String.format(" old text: %s (%s@0x%08x)",
+ Slog.v(TAG, "INTERRUPTIVENESS: " + String.format(" old text: %s (%s@0x%08x)",
oldText, oldText.getClass(), oldText.hashCode()));
- Log.v(TAG, "INTERRUPTIVENESS: " + String.format(" new text: %s (%s@0x%08x)",
+ Slog.v(TAG, "INTERRUPTIVENESS: " + String.format(" new text: %s (%s@0x%08x)",
newText, newText.getClass(), newText.hashCode()));
}
return true;
}
if (oldN.hasCompletedProgress() != newN.hasCompletedProgress()) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is interruptive: completed progress");
}
return true;
@@ -5259,7 +5258,7 @@
// Actions
if (Notification.areActionsVisiblyDifferent(oldN, newN)) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is interruptive: changed actions");
}
return true;
@@ -5272,7 +5271,7 @@
// Style based comparisons
if (Notification.areStyledNotificationsVisiblyDifferent(oldB, newB)) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is interruptive: styles differ");
}
return true;
@@ -5281,7 +5280,7 @@
// Remote views
if (Notification.areRemoteViewsChanged(oldB, newB)) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ r.getKey() + " is interruptive: remoteviews differ");
}
return true;
@@ -5510,12 +5509,12 @@
// Ignore summary updates because we don't display most of the information.
if (record.sbn.isGroup() && record.sbn.getNotification().isGroupSummary()) {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ record.getKey() + " is not interruptive: summary");
}
} else {
if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ record.getKey() + " is interruptive: alerted");
}
record.setInterruptive(true);
@@ -6603,7 +6602,7 @@
String pkg = r.sbn.getPackageName();
if (pkg == null) {
- if (DBG) Log.e(TAG, "No package for group summary: " + r.getKey());
+ if (DBG) Slog.e(TAG, "No package for group summary: " + r.getKey());
return;
}
@@ -6862,7 +6861,7 @@
return;
}
} catch (RemoteException re) {
- if (DBG) Log.e(TAG, "Unable to confirm if it's safe to skip category "
+ if (DBG) Slog.e(TAG, "Unable to confirm if it's safe to skip category "
+ "restrictions check thus the check will be done anyway");
}
if (Notification.CATEGORY_CAR_EMERGENCY.equals(notification.category)
@@ -7104,7 +7103,7 @@
canUseManagedServices = false;
}
} catch (RemoteException e) {
- Log.e(TAG, "can't talk to pm", e);
+ Slog.e(TAG, "can't talk to pm", e);
}
}
@@ -7247,21 +7246,29 @@
try {
assistant.onNotificationsSeen(keys);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify assistant (seen): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (seen): " + assistant, ex);
}
}
@GuardedBy("mNotificationLock")
private void onNotificationEnqueuedLocked(final NotificationRecord r) {
+ final boolean debug = isVerboseLogEnabled();
+ if (debug) {
+ Slog.v(TAG, "onNotificationEnqueuedLocked() called with: r = [" + r + "]");
+ }
final StatusBarNotification sbn = r.sbn;
notifyAssistantLocked(
sbn,
true /* sameUserOnly */,
(assistant, sbnHolder) -> {
try {
+ if (debug) {
+ Slog.v(TAG,
+ "calling onNotificationEnqueuedWithChannel " + sbnHolder);
+ }
assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel());
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
}
});
}
@@ -7279,7 +7286,7 @@
try {
assistant.onNotificationExpansionChanged(key, isUserAction, isExpanded);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify assistant (expanded): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (expanded): " + assistant, ex);
}
});
}
@@ -7295,7 +7302,7 @@
try {
assistant.onNotificationDirectReply(key);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify assistant (expanded): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (expanded): " + assistant, ex);
}
});
}
@@ -7316,7 +7323,7 @@
? NotificationAssistantService.SOURCE_FROM_ASSISTANT
: NotificationAssistantService.SOURCE_FROM_APP);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
}
});
}
@@ -7338,7 +7345,7 @@
? NotificationAssistantService.SOURCE_FROM_ASSISTANT
: NotificationAssistantService.SOURCE_FROM_APP);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
}
});
}
@@ -7358,7 +7365,7 @@
assistant.onNotificationSnoozedUntilContext(
sbnHolder, snoozeCriterionId);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
}
});
}
@@ -7380,9 +7387,19 @@
TrimCache trimCache = new TrimCache(sbn);
// There should be only one, but it's a list, so while we enforce
// singularity elsewhere, we keep it general here, to avoid surprises.
+
+ final boolean debug = isVerboseLogEnabled();
+ if (debug) {
+ Slog.v(TAG,
+ "notifyAssistantLocked() called with: sbn = [" + sbn + "], sameUserOnly = ["
+ + sameUserOnly + "], callback = [" + callback + "]");
+ }
for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
boolean sbnVisible = isVisibleToListener(sbn, info)
&& (!sameUserOnly || info.isSameUser(sbn.getUserId()));
+ if (debug) {
+ Slog.v(TAG, "notifyAssistantLocked info=" + info + " snbVisible=" + sbnVisible);
+ }
if (!sbnVisible) {
continue;
}
@@ -7436,6 +7453,10 @@
}
}
}
+
+ private boolean isVerboseLogEnabled() {
+ return Log.isLoggable("notification_assistant", Log.VERBOSE);
+ }
}
public class NotificationListeners extends ManagedServices {
@@ -7530,7 +7551,7 @@
try {
listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener "
+ Slog.e(TAG, "unable to notify listener "
+ "(hideSilentStatusIcons): " + listener, ex);
}
});
@@ -7824,7 +7845,7 @@
try {
listener.onNotificationPosted(sbnHolder, rankingUpdate);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
+ Slog.e(TAG, "unable to notify listener (posted): " + listener, ex);
}
}
@@ -7838,7 +7859,7 @@
try {
listener.onNotificationRemoved(sbnHolder, rankingUpdate, stats, reason);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener (removed): " + listener, ex);
+ Slog.e(TAG, "unable to notify listener (removed): " + listener, ex);
}
}
@@ -7848,7 +7869,7 @@
try {
listener.onNotificationRankingUpdate(rankingUpdate);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener (ranking update): " + listener, ex);
+ Slog.e(TAG, "unable to notify listener (ranking update): " + listener, ex);
}
}
@@ -7857,7 +7878,7 @@
try {
listener.onListenerHintsChanged(hints);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener (listener hints): " + listener, ex);
+ Slog.e(TAG, "unable to notify listener (listener hints): " + listener, ex);
}
}
@@ -7867,7 +7888,7 @@
try {
listener.onInterruptionFilterChanged(interruptionFilter);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener (interruption filter): " + listener, ex);
+ Slog.e(TAG, "unable to notify listener (interruption filter): " + listener, ex);
}
}
@@ -7878,7 +7899,7 @@
try {
listener.onNotificationChannelModification(pkg, user, channel, modificationType);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener (channel changed): " + listener, ex);
+ Slog.e(TAG, "unable to notify listener (channel changed): " + listener, ex);
}
}
@@ -7889,7 +7910,7 @@
try {
listener.onNotificationChannelGroupModification(pkg, user, group, modificationType);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener (channel group changed): " + listener, ex);
+ Slog.e(TAG, "unable to notify listener (channel group changed): " + listener, ex);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 48818f5..46ce4bf 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -637,25 +637,17 @@
final ArrayList<String> people =
adjustment.getSignals().getStringArrayList(Adjustment.KEY_PEOPLE);
setPeopleOverride(people);
- MetricsLogger.action(getAdjustmentLogMaker()
- .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_PEOPLE, people.size()));
}
if (signals.containsKey(Adjustment.KEY_SNOOZE_CRITERIA)) {
final ArrayList<SnoozeCriterion> snoozeCriterionList =
adjustment.getSignals().getParcelableArrayList(
Adjustment.KEY_SNOOZE_CRITERIA);
setSnoozeCriteria(snoozeCriterionList);
- MetricsLogger.action(getAdjustmentLogMaker()
- .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SNOOZE_CRITERIA,
- snoozeCriterionList.size()));
}
if (signals.containsKey(Adjustment.KEY_GROUP_KEY)) {
final String groupOverrideKey =
adjustment.getSignals().getString(Adjustment.KEY_GROUP_KEY);
setOverrideGroupKey(groupOverrideKey);
- MetricsLogger.action(getAdjustmentLogMaker()
- .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_GROUP_KEY,
- groupOverrideKey));
}
if (signals.containsKey(Adjustment.KEY_USER_SENTIMENT)) {
// Only allow user sentiment update from assistant if user hasn't already
@@ -664,32 +656,20 @@
&& (getChannel().getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0) {
setUserSentiment(adjustment.getSignals().getInt(
Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEUTRAL));
- MetricsLogger.action(getAdjustmentLogMaker()
- .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_USER_SENTIMENT,
- getUserSentiment()));
}
}
if (signals.containsKey(Adjustment.KEY_CONTEXTUAL_ACTIONS)) {
setSystemGeneratedSmartActions(
signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS));
- MetricsLogger.action(getAdjustmentLogMaker()
- .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_ACTIONS,
- getSystemGeneratedSmartActions().size()));
}
if (signals.containsKey(Adjustment.KEY_TEXT_REPLIES)) {
setSmartReplies(signals.getCharSequenceArrayList(Adjustment.KEY_TEXT_REPLIES));
- MetricsLogger.action(getAdjustmentLogMaker()
- .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_REPLIES,
- getSmartReplies().size()));
}
if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) {
int importance = signals.getInt(Adjustment.KEY_IMPORTANCE);
importance = Math.max(IMPORTANCE_UNSPECIFIED, importance);
importance = Math.min(IMPORTANCE_HIGH, importance);
setAssistantImportance(importance);
- MetricsLogger.action(getAdjustmentLogMaker()
- .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_IMPORTANCE,
- importance));
}
}
// We have now gotten all the information out of the adjustments and can forget them.
@@ -1280,12 +1260,6 @@
return getLogMaker().setCategory(MetricsEvent.NOTIFICATION_ITEM);
}
- public LogMaker getAdjustmentLogMaker() {
- return getLogMaker()
- .setCategory(MetricsEvent.NOTIFICATION_ITEM)
- .setType(MetricsEvent.TYPE_NOTIFICATION_ASSISTANT_ADJUSTMENT);
- }
-
@VisibleForTesting
static final class Light {
public final int color;
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 22a85eb..4ee6eaf 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -35,6 +35,7 @@
import android.content.pm.ParceledListSlice;
import android.content.pm.Signature;
import android.content.rollback.IRollbackManager;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -117,9 +118,11 @@
final PackageInfo packageInfo = mApexManager.getActivePackage(packageName);
if (packageInfo == null) {
- // TODO: What is the right thing to do here ? This implies there's no active package
- // with the given name. This should never be the case in production (where we only
- // accept updates to existing APEXes) but may be required for testing.
+ // Only allow installing new apexes if on a debuggable build.
+ if (!Build.IS_DEBUGGABLE) {
+ Slog.w(TAG, "Attempted to install new apex " + packageName + " on user build");
+ return false;
+ }
return true;
}
@@ -498,19 +501,21 @@
Slog.w(TAG, "Cannot abort applied session!");
return;
}
- if (isStagedSessionFinalized(session.sessionId)) {
- Slog.w(TAG, "Cannot abort session because it is not active or APEXD is not reachable");
- return;
- }
-
- mApexManager.abortActiveSession();
-
abortSession(session);
+
+ boolean hasApex = sessionContainsApex(session);
+ if (hasApex) {
+ ApexSessionInfo apexSession = mApexManager.getStagedSessionInfo(session.sessionId);
+ if (apexSession == null || isApexSessionFinalized(apexSession)) {
+ Slog.w(TAG,
+ "Cannot abort session because it is not active or APEXD is not reachable");
+ return;
+ }
+ mApexManager.abortActiveSession();
+ }
}
- private boolean isStagedSessionFinalized(int sessionId) {
- ApexSessionInfo session = mApexManager.getStagedSessionInfo(sessionId);
-
+ private boolean isApexSessionFinalized(ApexSessionInfo session) {
/* checking if the session is in a final state, i.e., not active anymore */
return session.isUnknown || session.isActivationFailed || session.isSuccess
|| session.isRolledBack;
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 7e4365d..ae4ff03 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -120,6 +120,7 @@
UserManager.DISALLOW_UNMUTE_DEVICE,
UserManager.DISALLOW_AUTOFILL,
UserManager.DISALLOW_CONTENT_CAPTURE,
+ UserManager.DISALLOW_CONTENT_SUGGESTIONS,
UserManager.DISALLOW_USER_SWITCH,
UserManager.DISALLOW_UNIFIED_PASSWORD,
UserManager.DISALLOW_CONFIG_LOCATION,
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 7d03d82..16d11ef 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -89,9 +89,6 @@
@GuardedBy("mLock")
private ArrayMap<String, Temperature> mTemperatureMap = new ArrayMap<>();
- /** Local PMS handle. */
- private final PowerManager mPowerManager;
-
/** HAL wrapper. */
private ThermalHalWrapper mHalWrapper;
@@ -109,7 +106,6 @@
@VisibleForTesting
ThermalManagerService(Context context, @Nullable ThermalHalWrapper halWrapper) {
super(context);
- mPowerManager = context.getSystemService(PowerManager.class);
mHalWrapper = halWrapper;
// Initialize to invalid to send status onActivityManagerReady
mStatus = INVALID_THROTTLING;
@@ -254,10 +250,11 @@
}
}
- private void shutdownIfNeededLocked(Temperature temperature) {
+ private void shutdownIfNeeded(Temperature temperature) {
if (temperature.getStatus() != Temperature.THROTTLING_SHUTDOWN) {
return;
}
+ final PowerManager powerManager = getContext().getSystemService(PowerManager.class);
switch (temperature.getType()) {
case Temperature.TYPE_CPU:
// Fall through
@@ -266,17 +263,17 @@
case Temperature.TYPE_NPU:
// Fall through
case Temperature.TYPE_SKIN:
- mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
+ powerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
break;
case Temperature.TYPE_BATTERY:
- mPowerManager.shutdown(false, PowerManager.SHUTDOWN_BATTERY_THERMAL_STATE, false);
+ powerManager.shutdown(false, PowerManager.SHUTDOWN_BATTERY_THERMAL_STATE, false);
break;
}
}
private void onTemperatureChanged(Temperature temperature, boolean sendStatus) {
+ shutdownIfNeeded(temperature);
synchronized (mLock) {
- shutdownIfNeededLocked(temperature);
Temperature old = mTemperatureMap.put(temperature.getName(), temperature);
if (old != null) {
if (old.getStatus() != temperature.getStatus()) {
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 28fee4e..4614355 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -43,8 +43,6 @@
import android.util.Log;
import android.util.Slog;
-import com.android.internal.policy.IKeyguardDismissCallback;
-
import java.util.Collections;
import java.util.List;
@@ -495,6 +493,21 @@
}
}
+ /**
+ * @see android.service.trust.TrustAgentService#onTokenStateReceived()
+ *
+ */
+ public void onEscrowTokenActivated(long handle, int userId) {
+ if (DEBUG) Slog.d(TAG, "onEscrowTokenActivated: " + handle + " user: " + userId);
+ if (mTrustAgentService != null) {
+ try {
+ mTrustAgentService.onTokenStateReceived(handle,
+ TrustAgentService.TOKEN_STATE_ACTIVE);
+ } catch (RemoteException e) {
+ onError(e);
+ }
+ }
+ }
private void setCallback(ITrustAgentServiceCallback callback) {
try {
if (mTrustAgentService != null) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index c7044a1..3a39053 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -409,7 +409,10 @@
}
public long addEscrowToken(byte[] token, int userId) {
- return mLockPatternUtils.addEscrowToken(token, userId);
+ return mLockPatternUtils.addEscrowToken(token, userId,
+ (long handle, int userid) -> {
+ dispatchEscrowTokenActivatedLocked(handle, userid);
+ });
}
public boolean removeEscrowToken(long handle, int userId) {
@@ -662,6 +665,15 @@
}
}
+ private void dispatchEscrowTokenActivatedLocked(long handle, int userId) {
+ for (int i = 0; i < mActiveAgents.size(); i++) {
+ AgentInfo agent = mActiveAgents.valueAt(i);
+ if (agent.userId == userId) {
+ agent.agent.onEscrowTokenActivated(handle, userId);
+ }
+ }
+ }
+
void updateDevicePolicyFeatures() {
boolean changed = false;
for (int i = 0; i < mActiveAgents.size(); i++) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 36251f5..d7922b15 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -13352,8 +13352,8 @@
if (policy.mPasswordTokenHandle != 0) {
mLockPatternUtils.removeEscrowToken(policy.mPasswordTokenHandle, userHandle);
}
-
- policy.mPasswordTokenHandle = mLockPatternUtils.addEscrowToken(token, userHandle);
+ policy.mPasswordTokenHandle = mLockPatternUtils.addEscrowToken(token,
+ userHandle, /*EscrowTokenStateChangeCallback*/ null);
saveSettingsLocked(userHandle);
return policy.mPasswordTokenHandle != 0;
} finally {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 4293247..039a4b7 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -29,6 +29,7 @@
import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
+import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
import static com.android.server.testutils.TestUtils.assertExpectException;
import static org.mockito.Matchers.any;
@@ -4157,8 +4158,9 @@
final byte[] token = new byte[32];
final long handle = 123456;
final String password = "password";
- when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM)))
- .thenReturn(handle);
+ when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM),
+ nullable(EscrowTokenStateChangeCallback.class)))
+ .thenReturn(handle);
assertTrue(dpm.setResetPasswordToken(admin1, token));
// test password activation
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index d343ac1..77515258 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -338,7 +338,7 @@
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
- long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+ long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
@@ -367,7 +367,7 @@
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
- long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+ long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
@@ -393,7 +393,7 @@
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
- long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+ long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
@@ -417,7 +417,7 @@
throws RemoteException {
final String token = "some-high-entropy-secure-token";
enableSyntheticPassword();
- long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID);
+ long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID, null);
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
@@ -427,7 +427,7 @@
throws RemoteException {
final String token = "some-high-entropy-secure-token";
initializeCredentialUnderSP(null, PRIMARY_USER_ID);
- long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID);
+ long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID, null);
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
@@ -443,7 +443,7 @@
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
enableSyntheticPassword();
- long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+ long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
// Token not activated immediately since user password exists
assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
// Activate token (password gets migrated to SP at the same time)
@@ -461,7 +461,7 @@
mHasSecureLockScreen = false;
enableSyntheticPassword();
- long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+ long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
try {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 0de807d..e9edba5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -185,6 +185,18 @@
}
@MediumTest
+ public void testRemoveUserByHandle_ThrowsException() {
+ synchronized (mUserRemoveLock) {
+ try {
+ mUserManager.removeUser(null);
+ fail("Expected IllegalArgumentException on passing in a null UserHandle.");
+ } catch (IllegalArgumentException expected) {
+ // Do nothing - exception is expected.
+ }
+ }
+ }
+
+ @MediumTest
public void testAddGuest() throws Exception {
UserInfo userInfo1 = createUser("Guest 1", UserInfo.FLAG_GUEST);
UserInfo userInfo2 = createUser("Guest 2", UserInfo.FLAG_GUEST);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
old mode 100644
new mode 100755
index 5262cf8..d79a168
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2653,6 +2653,18 @@
*/
public static final String KEY_USE_USIM_BOOL = "use_usim_bool";
+ /**
+ * Determines whether the carrier wants to cancel the cs reject notification automatically
+ * when the voice registration state changes.
+ * If true, the notification will be automatically removed
+ * when the voice registration state changes.
+ * If false, the notification will persist until the user dismisses it,
+ * the SIM is removed, or the device is rebooted.
+ * @hide
+ */
+ public static final String KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION =
+ "carrier_auto_cancel_cs_notification";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -3039,6 +3051,7 @@
});
sDefaults.putStringArray(KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY, new String[0]);
sDefaults.putBoolean(KEY_USE_USIM_BOOL, false);
+ sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
}
/**
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 251ca0c..5336141 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -183,11 +183,11 @@
EXPECT_THAT(str->untranslatable_sections, IsEmpty());
// Preserve non-ASCII whitespace including extended ASCII characters
- EXPECT_TRUE(TestParse(R"(<string name="foo3"> Hello </string>)"));
+ EXPECT_TRUE(TestParse(R"(<string name="foo3"> Hello World </string>)"));
str = test::GetValue<String>(&table_, "string/foo3");
ASSERT_THAT(str, NotNull());
- EXPECT_THAT(*str->value, StrEq("\xC2\xA0Hello\xC2\xA0"));
+ EXPECT_THAT(*str->value, StrEq("\xC2\xA0Hello\xE2\x80\xAFWorld\xC2\xA0"));
EXPECT_THAT(str->untranslatable_sections, IsEmpty());
EXPECT_TRUE(TestParse(R"(<string name="foo4">2005年6月1日</string>)"));
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index f0e4d9e..a571aee 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -40,8 +40,6 @@
namespace aapt {
namespace ResourceUtils {
-constexpr int32_t kNonBreakingSpace = 0xa0;
-
Maybe<ResourceName> ToResourceName(
const android::ResTable::resource_name& name_in) {
// TODO: Remove this when ResTable and AssetManager(1) are removed from AAPT2
@@ -854,7 +852,8 @@
Utf8Iterator iter(text);
while (iter.HasNext()) {
char32_t codepoint = iter.Next();
- if (!preserve_spaces_ && !quote_ && codepoint != kNonBreakingSpace && iswspace(codepoint)) {
+ if (!preserve_spaces_ && !quote_ && (codepoint <= std::numeric_limits<char>::max())
+ && isspace(static_cast<char>(codepoint))) {
if (!last_codepoint_was_space_) {
// Emit a space if it's the first.
xml_string_.text += ' ';
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
index 44d88bb..6f6c1aa 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
@@ -97,7 +97,7 @@
/**
* The suffix of the generated class name after the class's binary name.
*/
- private static final String GENERATED_CLASS_SUFFIX = "$$InspectionCompanion";
+ private static final String GENERATED_CLASS_SUFFIX = "$InspectionCompanion";
/**
* The null resource ID, copied to avoid a host dependency on platform code.
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/PlatformInspectableProcessor.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/PlatformInspectableProcessor.java
index 01d9430..fd142c6 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/PlatformInspectableProcessor.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/PlatformInspectableProcessor.java
@@ -34,6 +34,7 @@
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
/**
@@ -127,13 +128,38 @@
final InspectableClassModel model = modelMap.computeIfAbsent(
classElement.get().getQualifiedName().toString(),
- k -> new InspectableClassModel(ClassName.get(classElement.get())));
+ k -> {
+ if (hasNestedInspectionCompanion(classElement.get())) {
+ fail(
+ String.format(
+ "Class %s already has an inspection companion.",
+ classElement.get().getQualifiedName().toString()),
+ element);
+ }
+ return new InspectableClassModel(ClassName.get(classElement.get()));
+ });
processor.process(element, model);
}
}
/**
+ * Determine if a class has a nested class named {@code InspectionCompanion}.
+ *
+ * @param typeElement A type element representing the class to check
+ * @return f the class contains a class named {@code InspectionCompanion}
+ */
+ private static boolean hasNestedInspectionCompanion(TypeElement typeElement) {
+ for (TypeElement nestedClass : ElementFilter.typesIn(typeElement.getEnclosedElements())) {
+ if (nestedClass.getSimpleName().toString().equals("InspectionCompanion")) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Get the nearest enclosing class if there is one.
*
* If {@param element} represents a class, it will be returned wrapped in an optional.
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt
index a44c43e..9a0fe5b 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt
@@ -12,7 +12,7 @@
* Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
* on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
*/
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
/**
* Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
*/
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntEnum.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntEnum.java.txt
index 764aa8b..b491de1 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntEnum.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntEnum.java.txt
@@ -13,7 +13,7 @@
* Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
* on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
*/
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
/**
* Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
*/
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntFlag.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntFlag.java.txt
index 75f2813..7d18058 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntFlag.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntFlag.java.txt
@@ -12,7 +12,7 @@
* Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
* on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
*/
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
/**
* Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
*/
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
index 0cac462..dc27abb 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
@@ -11,7 +11,7 @@
* Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
* on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
*/
-public final class Outer$Inner$$InspectionCompanion implements InspectionCompanion<Outer.Inner> {
+public final class Outer$Inner$InspectionCompanion implements InspectionCompanion<Outer.Inner> {
/**
* Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
*/
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt
index ce0f867..738bcd3 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt
@@ -11,7 +11,7 @@
* Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
* on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
*/
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
/**
* Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
*/
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
index f7357fe..82dd66e 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
@@ -12,7 +12,7 @@
* Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
* on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
*/
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
/**
* Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
*/
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
index 556d8dd..08ea696 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
@@ -12,7 +12,7 @@
* Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
* on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
*/
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
/**
* Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
*/
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt
index d72cdd5..3bfa78a 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt
@@ -11,7 +11,7 @@
* Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
* on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
*/
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
/**
* Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
*/
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index a47e70b..d97f6fb 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -36,7 +36,7 @@
* <ul>
* <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} method.
* <li>Creating a network-specifier when requesting a Aware connection using
- * {@link WifiAwareManager.NetworkSpecifierBuilder}.
+ * {@link WifiAwareNetworkSpecifier.Builder}.
* </ul>
* <p>
* The {@link #close()} method must be called to destroy discovery sessions once they are
@@ -270,7 +270,7 @@
* <p>
* To set up an encrypted link use the
* {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} API.
- * @deprecated Use the replacement {@link WifiAwareManager.NetworkSpecifierBuilder}.
+ * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
*
* @param peerHandle The peer's handle obtained through
* {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
@@ -320,7 +320,7 @@
* <p>
* Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
* and a Publisher is a RESPONDER.
- * @deprecated Use the replacement {@link WifiAwareManager.NetworkSpecifierBuilder}.
+ * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
*
* @param peerHandle The peer's handle obtained through
* {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
@@ -380,7 +380,7 @@
* <p>
* Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
* and a Publisher is a RESPONDER.
- * @deprecated Use the replacement {@link WifiAwareManager.NetworkSpecifierBuilder}.
+ * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
*
* @param peerHandle The peer's handle obtained through
* {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 1a5cd5a..c9b0b12 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -21,7 +21,6 @@
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -35,7 +34,6 @@
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
-import android.text.TextUtils;
import android.util.Log;
import libcore.util.HexEncoding;
@@ -59,7 +57,7 @@
* {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback, Handler)}.
* <li>Create a Aware network specifier to be used with
* {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
- * to set-up a Aware connection with a peer. Refer to {@link NetworkSpecifierBuilder}.
+ * to set-up a Aware connection with a peer. Refer to {@link WifiAwareNetworkSpecifier.Builder}.
* </ul>
* <p>
* Aware may not be usable when Wi-Fi is disabled (and other conditions). To validate that
@@ -108,7 +106,7 @@
* <li>{@link NetworkRequest.Builder#addTransportType(int)} of
* {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
* <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using
- * {@link NetworkSpecifierBuilder}.
+ * {@link WifiAwareNetworkSpecifier.Builder}.
* </ul>
*/
@SystemService(Context.WIFI_AWARE_SERVICE)
@@ -408,7 +406,7 @@
if (!WifiAwareUtils.isLegacyVersion(mContext, Build.VERSION_CODES.Q)) {
throw new UnsupportedOperationException(
- "API not deprecated - use WifiAwareManager.NetworkSpecifierBuilder");
+ "API not deprecated - use WifiAwareNetworkSpecifier.Builder");
}
if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
@@ -813,198 +811,4 @@
mOriginalCallback.onSessionTerminated();
}
}
-
- /**
- * A builder class for a Wi-Fi Aware network specifier to set up an Aware connection with a
- * peer.
- * <p>
- * Note that all Wi-Fi Aware connection specifier objects must call the
- * {@link NetworkSpecifierBuilder#setDiscoverySession(DiscoverySession)} to specify the context
- * within which the connection is created, and
- * {@link NetworkSpecifierBuilder#setPeerHandle(PeerHandle)} to specify the peer to which the
- * connection is created.
- */
- public static final class NetworkSpecifierBuilder {
- private DiscoverySession mDiscoverySession;
- private PeerHandle mPeerHandle;
- private String mPskPassphrase;
- private byte[] mPmk;
- private int mPort = 0; // invalid value
- private int mTransportProtocol = -1; // invalid value
-
- /**
- * Configure the {@link PublishDiscoverySession} or {@link SubscribeDiscoverySession}
- * discovery session in whose context the connection is created.
- * <p>
- * Note: this method must be called for any connection request!
- *
- * @param discoverySession A Wi-Fi Aware discovery session.
- * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull NetworkSpecifierBuilder setDiscoverySession(
- @NonNull DiscoverySession discoverySession) {
- if (discoverySession == null) {
- throw new IllegalArgumentException("Non-null discoverySession required");
- }
- mDiscoverySession = discoverySession;
- return this;
- }
-
- /**
- * Configure the {@link PeerHandle} of the peer to which the Wi-Fi Aware connection is
- * requested. The peer is discovered through Wi-Fi Aware discovery,
- * <p>
- * Note: this method must be called for any connection request!
- *
- * @param peerHandle The peer's handle obtained through
- * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
- * or
- * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
- * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull NetworkSpecifierBuilder setPeerHandle(@NonNull PeerHandle peerHandle) {
- if (peerHandle == null) {
- throw new IllegalArgumentException("Non-null peerHandle required");
- }
- mPeerHandle = peerHandle;
- return this;
- }
-
- /**
- * Configure the PSK Passphrase for the Wi-Fi Aware connection being requested. This method
- * is optional - if not called, then an Open (unencrypted) connection will be created.
- *
- * @param pskPassphrase The (optional) passphrase to be used to encrypt the link.
- * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull NetworkSpecifierBuilder setPskPassphrase(@NonNull String pskPassphrase) {
- if (!WifiAwareUtils.validatePassphrase(pskPassphrase)) {
- throw new IllegalArgumentException("Passphrase must meet length requirements");
- }
- mPskPassphrase = pskPassphrase;
- return this;
- }
-
- /**
- * Configure the PMK for the Wi-Fi Aware connection being requested. This method
- * is optional - if not called, then an Open (unencrypted) connection will be created.
- *
- * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
- * encrypting the data-path. Use the {@link #setPskPassphrase(String)} to
- * specify a Passphrase.
- * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
- * methods.
- * @hide
- */
- @SystemApi
- public @NonNull NetworkSpecifierBuilder setPmk(@NonNull byte[] pmk) {
- if (!WifiAwareUtils.validatePmk(pmk)) {
- throw new IllegalArgumentException("PMK must 32 bytes");
- }
- mPmk = pmk;
- return this;
- }
-
- /**
- * Configure the port number which will be used to create a connection over this link. This
- * configuration should only be done on the server device, e.g. the device creating the
- * {@link java.net.ServerSocket}.
- * <p>Notes:
- * <ul>
- * <li>The server device must be the Publisher device!
- * <li>The port information can only be specified on secure links, specified using
- * {@link #setPskPassphrase(String)}.
- * </ul>
- *
- * @param port A positive integer indicating the port to be used for communication.
- * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull NetworkSpecifierBuilder setPort(int port) {
- if (port <= 0 || port > 65535) {
- throw new IllegalArgumentException("The port must be a positive value (0, 65535]");
- }
- mPort = port;
- return this;
- }
-
- /**
- * Configure the transport protocol which will be used to create a connection over this
- * link. This configuration should only be done on the server device, e.g. the device
- * creating the {@link java.net.ServerSocket} for TCP.
- * <p>Notes:
- * <ul>
- * <li>The server device must be the Publisher device!
- * <li>The transport protocol information can only be specified on secure links,
- * specified using {@link #setPskPassphrase(String)}.
- * </ul>
- * The transport protocol number is assigned by the Internet Assigned Numbers Authority
- * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
- *
- * @param transportProtocol The transport protocol to be used for communication.
- * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
- * methods.
- */
- public @NonNull NetworkSpecifierBuilder setTransportProtocol(int transportProtocol) {
- if (transportProtocol < 0 || transportProtocol > 255) {
- throw new IllegalArgumentException(
- "The transport protocol must be in range [0, 255]");
- }
- mTransportProtocol = transportProtocol;
- return this;
- }
-
- /**
- * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)}
- * for a WiFi Aware connection (link) to the specified peer. The
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
- * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
- * <p> The default builder constructor will initialize a NetworkSpecifier which requests an
- * open (non-encrypted) link. To request an encrypted link use the
- * {@link #setPskPassphrase(String)} builder method.
- *
- * @return A {@link NetworkSpecifier} to be used to construct
- * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass
- * to {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
- * android.net.ConnectivityManager.NetworkCallback)}
- * [or other varieties of that API].
- */
- public @NonNull NetworkSpecifier build() {
- if (mDiscoverySession == null) {
- throw new IllegalStateException("Null discovery session!?");
- }
- if (mPskPassphrase != null & mPmk != null) {
- throw new IllegalStateException(
- "Can only specify a Passphrase or a PMK - not both!");
- }
-
- int role = mDiscoverySession instanceof SubscribeDiscoverySession
- ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
- : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
- if (mPort != 0 || mTransportProtocol != -1) {
- if (role != WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
- throw new IllegalStateException(
- "Port and transport protocol information can only "
- + "be specified on the Publisher device (which is the server");
- }
- if (TextUtils.isEmpty(mPskPassphrase) && mPmk == null) {
- throw new IllegalStateException("Port and transport protocol information can "
- + "only be specified on a secure link");
- }
- }
-
- if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR && mPeerHandle == null) {
- throw new IllegalStateException("Null peerHandle!?");
- }
-
- return new WifiAwareNetworkSpecifier(
- WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, role,
- mDiscoverySession.mClientId, mDiscoverySession.mSessionId, mPeerHandle.peerId,
- null, mPmk, mPskPassphrase, mPort, mTransportProtocol, Process.myUid());
- }
- }
}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
index 020cb56..fd26817b 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
@@ -75,7 +75,7 @@
/**
* Get the port number to be used to create a network connection to the Wi-Fi Aware peer.
* The port information is provided by the app running on the peer which requested the
- * connection, using the {@link WifiAwareManager.NetworkSpecifierBuilder#setPort(int)}.
+ * connection, using the {@link WifiAwareNetworkSpecifier.Builder#setPort(int)}.
*
* @return A port number on the peer. A value of 0 indicates that no port was specified by the
* peer.
@@ -88,7 +88,7 @@
* Get the transport protocol to be used to communicate over a network connection to the Wi-Fi
* Aware peer. The transport protocol is provided by the app running on the peer which requested
* the connection, using the
- * {@link WifiAwareManager.NetworkSpecifierBuilder#setTransportProtocol(int)}.
+ * {@link WifiAwareNetworkSpecifier.Builder#setTransportProtocol(int)}.
* <p>
* The transport protocol number is assigned by the Internet Assigned Numbers Authority
* (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index 59f534a..b225116 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -16,9 +16,15 @@
package android.net.wifi.aware;
+import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.net.NetworkSpecifier;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.Process;
+import android.text.TextUtils;
import java.util.Arrays;
import java.util.Objects;
@@ -29,8 +35,6 @@
* {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} or
* {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)} or their secure (Passphrase)
* versions.
- *
- * @hide
*/
public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
/**
@@ -138,6 +142,8 @@
* device they all get the same link. However, the link is only set up on the first request -
* hence only the first can transmit the port information. But we don't want to expose that
* information to other apps. Limiting to secure links would (usually) imply single app usage.
+ *
+ * @hide
*/
public final int transportProtocol;
@@ -292,4 +298,197 @@
throw new SecurityException("mismatched UIDs");
}
}
+
+ /**
+ * A builder class for a Wi-Fi Aware network specifier to set up an Aware connection with a
+ * peer.
+ * <p>
+ * Note that all Wi-Fi Aware connection specifier objects must call the
+ * {@link Builder#setDiscoverySession(DiscoverySession)} to specify the context
+ * within which the connection is created, and
+ * {@link Builder#setPeerHandle(PeerHandle)} to specify the peer to which the
+ * connection is created.
+ */
+ public static final class Builder {
+ private DiscoverySession mDiscoverySession;
+ private PeerHandle mPeerHandle;
+ private String mPskPassphrase;
+ private byte[] mPmk;
+ private int mPort = 0; // invalid value
+ private int mTransportProtocol = -1; // invalid value
+
+ /**
+ * Configure the {@link PublishDiscoverySession} or {@link SubscribeDiscoverySession}
+ * discovery session in whose context the connection is created.
+ * <p>
+ * Note: this method must be called for any connection request!
+ *
+ * @param discoverySession A Wi-Fi Aware discovery session.
+ * @return the current {@link Builder} builder, enabling chaining of builder
+ * methods.
+ */
+ public @NonNull Builder setDiscoverySession(@NonNull DiscoverySession discoverySession) {
+ if (discoverySession == null) {
+ throw new IllegalArgumentException("Non-null discoverySession required");
+ }
+ mDiscoverySession = discoverySession;
+ return this;
+ }
+
+ /**
+ * Configure the {@link PeerHandle} of the peer to which the Wi-Fi Aware connection is
+ * requested. The peer is discovered through Wi-Fi Aware discovery,
+ * <p>
+ * Note: this method must be called for any connection request!
+ *
+ * @param peerHandle The peer's handle obtained through
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
+ * or
+ * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
+ * @return the current {@link Builder} builder, enabling chaining of builder
+ * methods.
+ */
+ public @NonNull Builder setPeerHandle(@NonNull PeerHandle peerHandle) {
+ if (peerHandle == null) {
+ throw new IllegalArgumentException("Non-null peerHandle required");
+ }
+ mPeerHandle = peerHandle;
+ return this;
+ }
+
+ /**
+ * Configure the PSK Passphrase for the Wi-Fi Aware connection being requested. This method
+ * is optional - if not called, then an Open (unencrypted) connection will be created.
+ *
+ * @param pskPassphrase The (optional) passphrase to be used to encrypt the link.
+ * @return the current {@link Builder} builder, enabling chaining of builder
+ * methods.
+ */
+ public @NonNull Builder setPskPassphrase(@NonNull String pskPassphrase) {
+ if (!WifiAwareUtils.validatePassphrase(pskPassphrase)) {
+ throw new IllegalArgumentException("Passphrase must meet length requirements");
+ }
+ mPskPassphrase = pskPassphrase;
+ return this;
+ }
+
+ /**
+ * Configure the PMK for the Wi-Fi Aware connection being requested. This method
+ * is optional - if not called, then an Open (unencrypted) connection will be created.
+ *
+ * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
+ * encrypting the data-path. Use the {@link #setPskPassphrase(String)} to
+ * specify a Passphrase.
+ * @return the current {@link Builder} builder, enabling chaining of builder
+ * methods.
+ * @hide
+ */
+ @SystemApi
+ public @NonNull Builder setPmk(@NonNull byte[] pmk) {
+ if (!WifiAwareUtils.validatePmk(pmk)) {
+ throw new IllegalArgumentException("PMK must 32 bytes");
+ }
+ mPmk = pmk;
+ return this;
+ }
+
+ /**
+ * Configure the port number which will be used to create a connection over this link. This
+ * configuration should only be done on the server device, e.g. the device creating the
+ * {@link java.net.ServerSocket}.
+ * <p>Notes:
+ * <ul>
+ * <li>The server device must be the Publisher device!
+ * <li>The port information can only be specified on secure links, specified using
+ * {@link #setPskPassphrase(String)}.
+ * </ul>
+ *
+ * @param port A positive integer indicating the port to be used for communication.
+ * @return the current {@link Builder} builder, enabling chaining of builder
+ * methods.
+ */
+ public @NonNull Builder setPort(int port) {
+ if (port <= 0 || port > 65535) {
+ throw new IllegalArgumentException("The port must be a positive value (0, 65535]");
+ }
+ mPort = port;
+ return this;
+ }
+
+ /**
+ * Configure the transport protocol which will be used to create a connection over this
+ * link. This configuration should only be done on the server device, e.g. the device
+ * creating the {@link java.net.ServerSocket} for TCP.
+ * <p>Notes:
+ * <ul>
+ * <li>The server device must be the Publisher device!
+ * <li>The transport protocol information can only be specified on secure links,
+ * specified using {@link #setPskPassphrase(String)}.
+ * </ul>
+ * The transport protocol number is assigned by the Internet Assigned Numbers Authority
+ * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
+ *
+ * @param transportProtocol The transport protocol to be used for communication.
+ * @return the current {@link Builder} builder, enabling chaining of builder
+ * methods.
+ */
+ public @NonNull Builder setTransportProtocol(int transportProtocol) {
+ if (transportProtocol < 0 || transportProtocol > 255) {
+ throw new IllegalArgumentException(
+ "The transport protocol must be in range [0, 255]");
+ }
+ mTransportProtocol = transportProtocol;
+ return this;
+ }
+
+ /**
+ * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)}
+ * for a WiFi Aware connection (link) to the specified peer. The
+ * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
+ * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
+ * <p> The default builder constructor will initialize a NetworkSpecifier which requests an
+ * open (non-encrypted) link. To request an encrypted link use the
+ * {@link #setPskPassphrase(String)} builder method.
+ *
+ * @return A {@link NetworkSpecifier} to be used to construct
+ * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass
+ * to {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
+ * android.net.ConnectivityManager.NetworkCallback)}
+ * [or other varieties of that API].
+ */
+ public @NonNull WifiAwareNetworkSpecifier build() {
+ if (mDiscoverySession == null) {
+ throw new IllegalStateException("Null discovery session!?");
+ }
+ if (mPskPassphrase != null & mPmk != null) {
+ throw new IllegalStateException(
+ "Can only specify a Passphrase or a PMK - not both!");
+ }
+
+ int role = mDiscoverySession instanceof SubscribeDiscoverySession
+ ? WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
+ : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
+
+ if (mPort != 0 || mTransportProtocol != -1) {
+ if (role != WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
+ throw new IllegalStateException(
+ "Port and transport protocol information can only "
+ + "be specified on the Publisher device (which is the server");
+ }
+ if (TextUtils.isEmpty(mPskPassphrase) && mPmk == null) {
+ throw new IllegalStateException("Port and transport protocol information can "
+ + "only be specified on a secure link");
+ }
+ }
+
+ if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR && mPeerHandle == null) {
+ throw new IllegalStateException("Null peerHandle!?");
+ }
+
+ return new WifiAwareNetworkSpecifier(
+ WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, role,
+ mDiscoverySession.mClientId, mDiscoverySession.mSessionId, mPeerHandle.peerId,
+ null, mPmk, mPskPassphrase, mPort, mTransportProtocol, Process.myUid());
+ }
+ }
}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 245b304..3c97813 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -213,7 +213,7 @@
* This API is targeted for applications which can obtain the peer MAC address using OOB
* (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
* when using Aware discovery use the alternative network specifier method -
- * {@link android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder}.
+ * {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
* <p>
* To set up an encrypted link use the
* {@link #createNetworkSpecifierPassphrase(int, byte[], String)} API.
@@ -254,7 +254,7 @@
* This API is targeted for applications which can obtain the peer MAC address using OOB
* (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
* when using Aware discovery use the alternative network specifier method -
- * {@link android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder}.
+ * {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
*
* @param role The role of this device:
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
@@ -300,7 +300,7 @@
* This API is targeted for applications which can obtain the peer MAC address using OOB
* (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
* when using Aware discovery use the alternative network specifier method -
- * {@link android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder}.
+ * {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
*
* @param role The role of this device:
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 3cc96bf..657a338 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -958,9 +958,8 @@
WifiAwareNetworkSpecifier ns =
(WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierOpen(
peerHandle);
- WifiAwareNetworkSpecifier nsb = (WifiAwareNetworkSpecifier) new WifiAwareManager
- .NetworkSpecifierBuilder().setDiscoverySession(publishSession.getValue())
- .setPeerHandle(peerHandle).build();
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+ publishSession.getValue()).setPeerHandle(peerHandle).build();
// validate format
collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
@@ -980,9 +979,9 @@
// (4) request an encrypted (PMK) network specifier from the session
ns = (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierPmk(
peerHandle, pmk);
- nsb = (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
- .setDiscoverySession(publishSession.getValue()).setPeerHandle(peerHandle)
- .setPmk(pmk).setPort(port).setTransportProtocol(transportProtocol).build();
+ nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+ publishSession.getValue()).setPeerHandle(peerHandle).setPmk(pmk).setPort(
+ port).setTransportProtocol(transportProtocol).build();
// validate format
collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
@@ -1006,10 +1005,9 @@
(WifiAwareNetworkSpecifier) publishSession.getValue()
.createNetworkSpecifierPassphrase(
peerHandle, passphrase);
- nsb = (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
- .setDiscoverySession(publishSession.getValue()).setPeerHandle(peerHandle)
- .setPskPassphrase(passphrase).setPort(port).setTransportProtocol(transportProtocol)
- .build();
+ nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+ publishSession.getValue()).setPeerHandle(peerHandle).setPskPassphrase(
+ passphrase).setPort(port).setTransportProtocol(transportProtocol).build();
// validate format
collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
@@ -1257,14 +1255,14 @@
// (3) create network specifier
if (doPmk) {
if (useBuilder) {
- new WifiAwareManager.NetworkSpecifierBuilder().setDiscoverySession(
+ new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
publishSession.getValue()).setPeerHandle(peerHandle).setPmk(pmk).build();
} else {
publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
}
} else {
if (useBuilder) {
- new WifiAwareManager.NetworkSpecifierBuilder().setDiscoverySession(
+ new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
publishSession.getValue()).setPeerHandle(peerHandle).setPskPassphrase(
passphrase).build();
} else {
@@ -1355,10 +1353,8 @@
DiscoverySession publishSession = executeSessionStartup(true);
- WifiAwareNetworkSpecifier nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
- .setDiscoverySession(publishSession).setPeerHandle(peerHandle)
- .setPmk(pmk).setPort(port).build();
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+ publishSession).setPeerHandle(peerHandle).setPmk(pmk).setPort(port).build();
}
/**
@@ -1372,10 +1368,8 @@
DiscoverySession publishSession = executeSessionStartup(true);
- WifiAwareNetworkSpecifier nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
- .setDiscoverySession(publishSession).setPeerHandle(peerHandle)
- .setPort(port).build();
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+ publishSession).setPeerHandle(peerHandle).setPort(port).build();
}
/**
@@ -1389,10 +1383,8 @@
DiscoverySession subscribeSession = executeSessionStartup(false);
- WifiAwareNetworkSpecifier nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
- .setDiscoverySession(subscribeSession).setPeerHandle(peerHandle)
- .setPort(port).build();
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+ subscribeSession).setPeerHandle(peerHandle).setPort(port).build();
}
/**
@@ -1411,8 +1403,7 @@
DiscoverySession publishSession = executeSessionStartup(true);
try {
- WifiAwareNetworkSpecifier nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
.setDiscoverySession(publishSession).setPeerHandle(peerHandle)
.setPmk(pmk).setTransportProtocol(tpNegative).build();
assertTrue("No exception on negative transport protocol!", false);
@@ -1420,23 +1411,19 @@
// nop - exception is correct!
}
try {
- WifiAwareNetworkSpecifier nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
.setDiscoverySession(publishSession).setPeerHandle(peerHandle)
.setPmk(pmk).setTransportProtocol(tpTooLarge).build();
assertTrue("No exception on >255 transport protocol!", false);
} catch (IllegalArgumentException e) {
// nop - exception is correct!
}
- WifiAwareNetworkSpecifier nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
.setDiscoverySession(publishSession).setPeerHandle(peerHandle)
.setPmk(pmk).setTransportProtocol(tpSmallest).build();
- nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
- .setDiscoverySession(
- publishSession).setPeerHandle(peerHandle).setPmk(
- pmk).setTransportProtocol(tpLargest).build();
+ nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+ publishSession).setPeerHandle(peerHandle).setPmk(pmk).setTransportProtocol(
+ tpLargest).build();
}
/**
@@ -1450,8 +1437,7 @@
DiscoverySession publishSession = executeSessionStartup(true);
- WifiAwareNetworkSpecifier nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
.setDiscoverySession(publishSession).setPeerHandle(peerHandle)
.setTransportProtocol(transportProtocol).build();
}
@@ -1467,8 +1453,7 @@
DiscoverySession subscribeSession = executeSessionStartup(false);
- WifiAwareNetworkSpecifier nsb =
- (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+ WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
.setDiscoverySession(subscribeSession).setPeerHandle(peerHandle)
.setTransportProtocol(transportProtocol).build();
}