summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nfc/api/system-current.txt22
-rw-r--r--nfc/java/android/nfc/INfcOemExtensionCallback.aidl2
-rw-r--r--nfc/java/android/nfc/NfcOemExtension.java12
-rw-r--r--nfc/java/android/nfc/OemLogItems.aidl19
-rw-r--r--nfc/java/android/nfc/OemLogItems.java325
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java74
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java207
-rw-r--r--services/core/java/com/android/server/net/flags.aconfig7
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java13
9 files changed, 521 insertions, 160 deletions
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 675c8f80add2..a23845fa17e9 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -100,6 +100,7 @@ package android.nfc {
method public void onHceEventReceived(int);
method public void onLaunchHceAppChooserActivity(@NonNull String, @NonNull java.util.List<android.nfc.cardemulation.ApduServiceInfo>, @NonNull android.content.ComponentName, @NonNull String);
method public void onLaunchHceTapAgainDialog(@NonNull android.nfc.cardemulation.ApduServiceInfo, @NonNull String);
+ method public void onLogEventNotified(@NonNull android.nfc.OemLogItems);
method public void onNdefMessage(@NonNull android.nfc.Tag, @NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onNdefRead(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onReaderOptionChanged(boolean);
@@ -115,6 +116,27 @@ package android.nfc {
method public int getNfceeId();
}
+ @FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getAction();
+ method public int getCallingPid();
+ method @Nullable public byte[] getCommandApdu();
+ method public int getEvent();
+ method @Nullable public byte[] getResponseApdu();
+ method @Nullable public java.time.Instant getRfFieldEventTimeMillis();
+ method @Nullable public android.nfc.Tag getTag();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nfc.OemLogItems> CREATOR;
+ field public static final int EVENT_DISABLE = 2; // 0x2
+ field public static final int EVENT_ENABLE = 1; // 0x1
+ field public static final int EVENT_UNSET = 0; // 0x0
+ field public static final int LOG_ACTION_HCE_DATA = 516; // 0x204
+ field public static final int LOG_ACTION_NFC_TOGGLE = 513; // 0x201
+ field public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 1; // 0x1
+ field public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 518; // 0x206
+ field public static final int LOG_ACTION_TAG_DETECTED = 3; // 0x3
+ }
+
@FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingStatus {
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultIsoDepRoute();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultOffHostRoute();
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index 7f1fd15fe68a..b102e873d737 100644
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -18,6 +18,7 @@ package android.nfc;
import android.content.ComponentName;
import android.nfc.cardemulation.ApduServiceInfo;
import android.nfc.NdefMessage;
+import android.nfc.OemLogItems;
import android.nfc.Tag;
import android.os.ResultReceiver;
@@ -51,4 +52,5 @@ interface INfcOemExtensionCallback {
void onNdefMessage(in Tag tag, in NdefMessage message, in ResultReceiver hasOemExecutableContent);
void onLaunchHceAppChooserActivity(in String selectedAid, in List<ApduServiceInfo> services, in ComponentName failedComponent, in String category);
void onLaunchHceTapAgainActivity(in ApduServiceInfo service, in String category);
+ void onLogEventNotified(in OemLogItems item);
}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 1bfe71461ac3..abd99bc02f55 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -392,6 +392,12 @@ public final class NfcOemExtension {
* @param category the category of the service
*/
void onLaunchHceTapAgainDialog(@NonNull ApduServiceInfo service, @NonNull String category);
+
+ /**
+ * Callback when OEM specified log event are notified.
+ * @param item the log items that contains log information of NFC event.
+ */
+ void onLogEventNotified(@NonNull OemLogItems item);
}
@@ -900,6 +906,12 @@ public final class NfcOemExtension {
handleVoid2ArgCallback(service, category, cb::onLaunchHceTapAgainDialog, ex));
}
+ @Override
+ public void onLogEventNotified(OemLogItems item) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(item, cb::onLogEventNotified, ex));
+ }
+
private <T> void handleVoidCallback(
T input, Consumer<T> callbackMethod, Executor executor) {
synchronized (mLock) {
diff --git a/nfc/java/android/nfc/OemLogItems.aidl b/nfc/java/android/nfc/OemLogItems.aidl
new file mode 100644
index 000000000000..3bcb445fc7d2
--- /dev/null
+++ b/nfc/java/android/nfc/OemLogItems.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+parcelable OemLogItems; \ No newline at end of file
diff --git a/nfc/java/android/nfc/OemLogItems.java b/nfc/java/android/nfc/OemLogItems.java
new file mode 100644
index 000000000000..6671941c1cc9
--- /dev/null
+++ b/nfc/java/android/nfc/OemLogItems.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.time.Instant;
+
+/**
+ * A log class for OEMs to get log information of NFC events.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class OemLogItems implements Parcelable {
+ /**
+ * Used when RF field state is changed.
+ */
+ public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 0X01;
+ /**
+ * Used when NFC is toggled. Event should be set to {@link LogEvent#EVENT_ENABLE} or
+ * {@link LogEvent#EVENT_DISABLE} if this action is used.
+ */
+ public static final int LOG_ACTION_NFC_TOGGLE = 0x0201;
+ /**
+ * Used when sending host routing status.
+ */
+ public static final int LOG_ACTION_HCE_DATA = 0x0204;
+ /**
+ * Used when screen state is changed.
+ */
+ public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 0x0206;
+ /**
+ * Used when tag is detected.
+ */
+ public static final int LOG_ACTION_TAG_DETECTED = 0x03;
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = { "LOG_ACTION_" }, value = {
+ LOG_ACTION_RF_FIELD_STATE_CHANGED,
+ LOG_ACTION_NFC_TOGGLE,
+ LOG_ACTION_HCE_DATA,
+ LOG_ACTION_SCREEN_STATE_CHANGED,
+ LOG_ACTION_TAG_DETECTED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LogAction {}
+
+ /**
+ * Represents the event is not set.
+ */
+ public static final int EVENT_UNSET = 0;
+ /**
+ * Represents nfc enable is called.
+ */
+ public static final int EVENT_ENABLE = 1;
+ /**
+ * Represents nfc disable is called.
+ */
+ public static final int EVENT_DISABLE = 2;
+ /** @hide */
+ @IntDef(prefix = { "EVENT_" }, value = {
+ EVENT_UNSET,
+ EVENT_ENABLE,
+ EVENT_DISABLE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LogEvent {}
+ private int mAction;
+ private int mEvent;
+ private int mCallingPid;
+ private byte[] mCommandApdus;
+ private byte[] mResponseApdus;
+ private Instant mRfFieldOnTime;
+ private Tag mTag;
+
+ /** @hide */
+ public OemLogItems(@LogAction int action, @LogEvent int event, int callingPid,
+ byte[] commandApdus, byte[] responseApdus, Instant rfFieldOnTime,
+ Tag tag) {
+ mAction = action;
+ mEvent = event;
+ mTag = tag;
+ mCallingPid = callingPid;
+ mCommandApdus = commandApdus;
+ mResponseApdus = responseApdus;
+ mRfFieldOnTime = rfFieldOnTime;
+ }
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable
+ * instance's marshaled representation. For example, if the object will
+ * include a file descriptor in the output of {@link #writeToParcel(Parcel, int)},
+ * the return value of this method must include the
+ * {@link #CONTENTS_FILE_DESCRIPTOR} bit.
+ *
+ * @return a bitmask indicating the set of special object types marshaled
+ * by this Parcelable object instance.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mAction);
+ dest.writeInt(mEvent);
+ dest.writeInt(mCallingPid);
+ dest.writeInt(mCommandApdus.length);
+ dest.writeByteArray(mCommandApdus);
+ dest.writeInt(mResponseApdus.length);
+ dest.writeByteArray(mResponseApdus);
+ dest.writeLong(mRfFieldOnTime.getEpochSecond());
+ dest.writeInt(mRfFieldOnTime.getNano());
+ dest.writeParcelable(mTag, 0);
+ }
+
+ /** @hide */
+ public static class Builder {
+ private final OemLogItems mItem;
+
+ public Builder(@LogAction int type) {
+ mItem = new OemLogItems(type, EVENT_UNSET, 0, new byte[0], new byte[0], null, null);
+ }
+
+ /** Setter of the log action. */
+ public OemLogItems.Builder setAction(@LogAction int action) {
+ mItem.mAction = action;
+ return this;
+ }
+
+ /** Setter of the log calling event. */
+ public OemLogItems.Builder setCallingEvent(@LogEvent int event) {
+ mItem.mEvent = event;
+ return this;
+ }
+
+ /** Setter of the log calling Pid. */
+ public OemLogItems.Builder setCallingPid(int pid) {
+ mItem.mCallingPid = pid;
+ return this;
+ }
+
+ /** Setter of APDU command. */
+ public OemLogItems.Builder setApduCommand(byte[] apdus) {
+ mItem.mCommandApdus = apdus;
+ return this;
+ }
+
+ /** Setter of RF field on time. */
+ public OemLogItems.Builder setRfFieldOnTime(Instant time) {
+ mItem.mRfFieldOnTime = time;
+ return this;
+ }
+
+ /** Setter of APDU response. */
+ public OemLogItems.Builder setApduResponse(byte[] apdus) {
+ mItem.mResponseApdus = apdus;
+ return this;
+ }
+
+ /** Setter of dispatched tag. */
+ public OemLogItems.Builder setTag(Tag tag) {
+ mItem.mTag = tag;
+ return this;
+ }
+
+ /** Builds an {@link OemLogItems} instance. */
+ public OemLogItems build() {
+ return mItem;
+ }
+ }
+
+ /**
+ * Gets the action of this log.
+ * @return one of {@link LogAction}
+ */
+ @LogAction
+ public int getAction() {
+ return mAction;
+ }
+
+ /**
+ * Gets the event of this log. This will be set to {@link LogEvent#EVENT_ENABLE} or
+ * {@link LogEvent#EVENT_DISABLE} only when action is set to
+ * {@link LogAction#LOG_ACTION_NFC_TOGGLE}
+ * @return one of {@link LogEvent}
+ */
+ @LogEvent
+ public int getEvent() {
+ return mEvent;
+ }
+
+ /**
+ * Gets the calling Pid of this log. This field will be set only when action is set to
+ * {@link LogAction#LOG_ACTION_NFC_TOGGLE}
+ * @return calling Pid
+ */
+ public int getCallingPid() {
+ return mCallingPid;
+ }
+
+ /**
+ * Gets the command APDUs of this log. This field will be set only when action is set to
+ * {@link LogAction#LOG_ACTION_HCE_DATA}
+ * @return a byte array of command APDUs with the same format as
+ * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}
+ */
+ @Nullable
+ public byte[] getCommandApdu() {
+ return mCommandApdus;
+ }
+
+ /**
+ * Gets the response APDUs of this log. This field will be set only when action is set to
+ * {@link LogAction#LOG_ACTION_HCE_DATA}
+ * @return a byte array of response APDUs with the same format as
+ * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}
+ */
+ @Nullable
+ public byte[] getResponseApdu() {
+ return mResponseApdus;
+ }
+
+ /**
+ * Gets the RF field event time in this log in millisecond. This field will be set only when
+ * action is set to {@link LogAction#LOG_ACTION_RF_FIELD_STATE_CHANGED}
+ * @return an {@link Instant} of RF field event time.
+ */
+ @Nullable
+ public Instant getRfFieldEventTimeMillis() {
+ return mRfFieldOnTime;
+ }
+
+ /**
+ * Gets the tag of this log. This field will be set only when action is set to
+ * {@link LogAction#LOG_ACTION_TAG_DETECTED}
+ * @return a detected {@link Tag} in {@link #LOG_ACTION_TAG_DETECTED} case. Return
+ * null otherwise.
+ */
+ @Nullable
+ public Tag getTag() {
+ return mTag;
+ }
+
+ private String byteToHex(byte[] bytes) {
+ char[] HexArray = "0123456789ABCDEF".toCharArray();
+ char[] hexChars = new char[bytes.length * 2];
+ for (int j = 0; j < bytes.length; j++) {
+ int v = bytes[j] & 0xFF;
+ hexChars[j * 2] = HexArray[v >>> 4];
+ hexChars[j * 2 + 1] = HexArray[v & 0x0F];
+ }
+ return new String(hexChars);
+ }
+
+ @Override
+ public String toString() {
+ return "[mCommandApdus: "
+ + ((mCommandApdus != null) ? byteToHex(mCommandApdus) : "null")
+ + "[mResponseApdus: "
+ + ((mResponseApdus != null) ? byteToHex(mResponseApdus) : "null")
+ + ", mCallingApi= " + mEvent
+ + ", mAction= " + mAction
+ + ", mCallingPId = " + mCallingPid
+ + ", mRfFieldOnTime= " + mRfFieldOnTime;
+ }
+ private OemLogItems(Parcel in) {
+ this.mAction = in.readInt();
+ this.mEvent = in.readInt();
+ this.mCallingPid = in.readInt();
+ this.mCommandApdus = new byte[in.readInt()];
+ in.readByteArray(this.mCommandApdus);
+ this.mResponseApdus = new byte[in.readInt()];
+ in.readByteArray(this.mResponseApdus);
+ this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());
+ this.mTag = in.readParcelable(Tag.class.getClassLoader(), Tag.class);
+ }
+
+ public static final @NonNull Parcelable.Creator<OemLogItems> CREATOR =
+ new Parcelable.Creator<OemLogItems>() {
+ @Override
+ public OemLogItems createFromParcel(Parcel in) {
+ return new OemLogItems(in);
+ }
+
+ @Override
+ public OemLogItems[] newArray(int size) {
+ return new OemLogItems[size];
+ }
+ };
+
+}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 6fb5598ee568..a916237364b4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -39,6 +39,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.content.Intent;
+import android.media.AudioDescriptor;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioDevicePort;
@@ -46,6 +47,7 @@ import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioManager.AudioDeviceCategory;
import android.media.AudioPort;
+import android.media.AudioProfile;
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
@@ -611,6 +613,8 @@ public class AudioDeviceInventory {
final int mGroupId;
@NonNull String mPeerDeviceAddress;
@NonNull String mPeerIdentityDeviceAddress;
+ @NonNull List<AudioProfile> mAudioProfiles;
+ @NonNull List<AudioDescriptor> mAudioDescriptors;
/** Disabled operating modes for this device. Use a negative logic so that by default
* an empty list means all modes are allowed.
@@ -619,7 +623,8 @@ public class AudioDeviceInventory {
DeviceInfo(int deviceType, String deviceName, String address,
String identityAddress, int codecFormat,
- int groupId, String peerAddress, String peerIdentityAddress) {
+ int groupId, String peerAddress, String peerIdentityAddress,
+ List<AudioProfile> profiles, List<AudioDescriptor> descriptors) {
mDeviceType = deviceType;
mDeviceName = TextUtils.emptyIfNull(deviceName);
mDeviceAddress = TextUtils.emptyIfNull(address);
@@ -631,6 +636,16 @@ public class AudioDeviceInventory {
mGroupId = groupId;
mPeerDeviceAddress = TextUtils.emptyIfNull(peerAddress);
mPeerIdentityDeviceAddress = TextUtils.emptyIfNull(peerIdentityAddress);
+ mAudioProfiles = profiles;
+ mAudioDescriptors = descriptors;
+ }
+
+ DeviceInfo(int deviceType, String deviceName, String address,
+ String identityAddress, int codecFormat,
+ int groupId, String peerAddress, String peerIdentityAddress) {
+ this(deviceType, deviceName, address, identityAddress, codecFormat,
+ groupId, peerAddress, peerIdentityAddress,
+ new ArrayList<>(), new ArrayList<>());
}
/** Constructor for all devices except A2DP sink and LE Audio */
@@ -638,6 +653,13 @@ public class AudioDeviceInventory {
this(deviceType, deviceName, address, null, AudioSystem.AUDIO_FORMAT_DEFAULT);
}
+ /** Constructor for HDMI OUT, HDMI ARC/EARC sink devices */
+ DeviceInfo(int deviceType, String deviceName, String address,
+ List<AudioProfile> profiles, List<AudioDescriptor> descriptors) {
+ this(deviceType, deviceName, address, null, AudioSystem.AUDIO_FORMAT_DEFAULT,
+ BluetoothLeAudio.GROUP_ID_INVALID, null, null, profiles, descriptors);
+ }
+
/** Constructor for A2DP sink devices */
DeviceInfo(int deviceType, String deviceName, String address,
String identityAddress, int codecFormat) {
@@ -1172,27 +1194,31 @@ public class AudioDeviceInventory {
}
/*package*/ void onToggleHdmi() {
- MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onToggleHdmi")
- .set(MediaMetrics.Property.DEVICE,
- AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HDMI));
+ final int[] hdmiDevices = { AudioSystem.DEVICE_OUT_HDMI,
+ AudioSystem.DEVICE_OUT_HDMI_ARC, AudioSystem.DEVICE_OUT_HDMI_EARC };
+
synchronized (mDevicesLock) {
- // Is HDMI connected?
- final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HDMI, "");
- final DeviceInfo di = mConnectedDevices.get(key);
- if (di == null) {
- Log.e(TAG, "invalid null DeviceInfo in onToggleHdmi");
- mmi.set(MediaMetrics.Property.EARLY_RETURN, "invalid null DeviceInfo").record();
- return;
+ for (DeviceInfo di : mConnectedDevices.values()) {
+ boolean isHdmiDevice = Arrays.stream(hdmiDevices).anyMatch(device ->
+ device == di.mDeviceType);
+ if (isHdmiDevice) {
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onToggleHdmi")
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getDeviceName(di.mDeviceType));
+ AudioDeviceAttributes ada = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT,
+ AudioDeviceInfo.convertInternalDeviceToDeviceType(di.mDeviceType),
+ di.mDeviceAddress, di.mDeviceName, di.mAudioProfiles,
+ di.mAudioDescriptors);
+ // Toggle HDMI to retrigger broadcast with proper formats.
+ setWiredDeviceConnectionState(ada,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, "onToggleHdmi"); // disconnect
+ setWiredDeviceConnectionState(ada,
+ AudioSystem.DEVICE_STATE_AVAILABLE, "onToggleHdmi"); // reconnect
+ mmi.record();
+ }
}
- // Toggle HDMI to retrigger broadcast with proper formats.
- setWiredDeviceConnectionState(
- new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
- AudioSystem.DEVICE_STATE_UNAVAILABLE, "android"); // disconnect
- setWiredDeviceConnectionState(
- new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
- AudioSystem.DEVICE_STATE_AVAILABLE, "android"); // reconnect
}
- mmi.record();
}
@GuardedBy("mDevicesLock")
@@ -1787,7 +1813,15 @@ public class AudioDeviceInventory {
.printSlog(EventLogger.Event.ALOGE, TAG));
return false;
}
- mConnectedDevices.put(deviceKey, new DeviceInfo(device, deviceName, address));
+
+ if (device == AudioSystem.DEVICE_OUT_HDMI ||
+ device == AudioSystem.DEVICE_OUT_HDMI_ARC ||
+ device == AudioSystem.DEVICE_OUT_HDMI_EARC) {
+ mConnectedDevices.put(deviceKey, new DeviceInfo(device, deviceName,
+ address, attributes.getAudioProfiles(), attributes.getAudioDescriptors()));
+ } else {
+ mConnectedDevices.put(deviceKey, new DeviceInfo(device, deviceName, address));
+ }
mDeviceBroker.postAccessoryPlugMediaUnmute(device);
status = true;
} else if (!connect && isConnected) {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 2a3be1e119bf..7de2815eba6b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -513,12 +513,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private boolean mLoadedRestrictBackground;
/**
- * Whether or not network for apps in proc-states greater than
- * {@link NetworkPolicyManager#BACKGROUND_THRESHOLD_STATE} is always blocked.
- */
- private boolean mBackgroundNetworkRestricted;
-
- /**
* Whether or not metered firewall chains should be used for uid policy controlling access to
* metered networks.
*/
@@ -1117,14 +1111,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
writePolicyAL();
}
- // The flag is boot-stable.
- mBackgroundNetworkRestricted = Flags.networkBlockedForTopSleepingAndAbove();
- if (mBackgroundNetworkRestricted) {
- // Firewall rules and UidBlockedState will get updated in
- // updateRulesForGlobalChangeAL below.
- enableFirewallChainUL(FIREWALL_CHAIN_BACKGROUND, true);
- }
-
+ enableFirewallChainUL(FIREWALL_CHAIN_BACKGROUND, true);
setRestrictBackgroundUL(mLoadedRestrictBackground, "init_service");
updateRulesForGlobalChangeAL(false);
updateNotificationsNL();
@@ -1135,11 +1122,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int changes = ActivityManager.UID_OBSERVER_PROCSTATE
| ActivityManager.UID_OBSERVER_GONE
| ActivityManager.UID_OBSERVER_CAPABILITY;
-
- final int cutpoint = mBackgroundNetworkRestricted ? PROCESS_STATE_UNKNOWN
- : NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE;
mActivityManagerInternal.registerNetworkPolicyUidObserver(mUidObserver, changes,
- cutpoint, "android");
+ PROCESS_STATE_UNKNOWN, "android");
mNetworkManager.registerObserver(mAlertObserver);
} catch (RemoteException e) {
// ignored; both services live in system_server
@@ -1280,21 +1264,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// different chains may change.
return true;
}
- if (mBackgroundNetworkRestricted) {
- if ((previousProcState >= BACKGROUND_THRESHOLD_STATE)
+ if ((previousProcState >= BACKGROUND_THRESHOLD_STATE)
!= (newProcState >= BACKGROUND_THRESHOLD_STATE)) {
- // Proc-state change crossed BACKGROUND_THRESHOLD_STATE: The network rules will
- // need to be re-evaluated for the background chain.
- return true;
- }
- if (mUseDifferentDelaysForBackgroundChain
- && newProcState >= BACKGROUND_THRESHOLD_STATE
- && getBackgroundTransitioningDelay(newProcState)
- < getBackgroundTransitioningDelay(previousProcState)) {
- // The old and new proc-state both are in the blocked state but the background
- // transition delay is reduced, so we may have to update the rules sooner.
- return true;
- }
+ // Proc-state change crossed BACKGROUND_THRESHOLD_STATE: The network rules will
+ // need to be re-evaluated for the background chain.
+ return true;
+ }
+ if (mUseDifferentDelaysForBackgroundChain
+ && newProcState >= BACKGROUND_THRESHOLD_STATE
+ && getBackgroundTransitioningDelay(newProcState)
+ < getBackgroundTransitioningDelay(previousProcState)) {
+ // The old and new proc-state both are in the blocked state but the background
+ // transition delay is reduced, so we may have to update the rules sooner.
+ return true;
}
final int networkCapabilities = PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
| PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
@@ -1367,9 +1349,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
synchronized (mUidRulesFirstLock) {
updatePowerSaveAllowlistUL();
- if (mBackgroundNetworkRestricted) {
- updateRulesForBackgroundChainUL();
- }
+ updateRulesForBackgroundChainUL();
updateRulesForRestrictPowerUL();
updateRulesForAppIdleUL();
}
@@ -4100,8 +4080,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
fout.println();
fout.println("Flags:");
- fout.println(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE + ": "
- + mBackgroundNetworkRestricted);
fout.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": "
+ mUseMeteredFirewallChains);
fout.println(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN + ": "
@@ -4251,35 +4229,33 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
fout.decreaseIndent();
}
- if (mBackgroundNetworkRestricted) {
+ fout.println();
+ if (mUseDifferentDelaysForBackgroundChain) {
+ fout.print("Background restrictions short delay: ");
+ TimeUtils.formatDuration(mBackgroundRestrictionShortDelayMs, fout);
fout.println();
- if (mUseDifferentDelaysForBackgroundChain) {
- fout.print("Background restrictions short delay: ");
- TimeUtils.formatDuration(mBackgroundRestrictionShortDelayMs, fout);
- fout.println();
- fout.print("Background restrictions long delay: ");
- TimeUtils.formatDuration(mBackgroundRestrictionLongDelayMs, fout);
- fout.println();
- }
+ fout.print("Background restrictions long delay: ");
+ TimeUtils.formatDuration(mBackgroundRestrictionLongDelayMs, fout);
+ fout.println();
+ }
- size = mBackgroundTransitioningUids.size();
- if (size > 0) {
- final long nowUptime = SystemClock.uptimeMillis();
- fout.println("Uids transitioning to background:");
- fout.increaseIndent();
- for (int i = 0; i < size; i++) {
- fout.print("UID=");
- fout.print(mBackgroundTransitioningUids.keyAt(i));
- fout.print(", ");
- TimeUtils.formatDuration(mBackgroundTransitioningUids.valueAt(i),
- nowUptime, fout);
- fout.println();
- }
- fout.decreaseIndent();
+ size = mBackgroundTransitioningUids.size();
+ if (size > 0) {
+ final long nowUptime = SystemClock.uptimeMillis();
+ fout.println("Uids transitioning to background:");
+ fout.increaseIndent();
+ for (int i = 0; i < size; i++) {
+ fout.print("UID=");
+ fout.print(mBackgroundTransitioningUids.keyAt(i));
+ fout.print(", ");
+ TimeUtils.formatDuration(mBackgroundTransitioningUids.valueAt(i),
+ nowUptime, fout);
+ fout.println();
}
- fout.println();
+ fout.decreaseIndent();
}
+ fout.println();
final SparseBooleanArray knownUids = new SparseBooleanArray();
collectKeys(mUidState, knownUids);
@@ -4465,51 +4441,49 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
updatePowerRestrictionRules = true;
}
- if (mBackgroundNetworkRestricted) {
- final boolean wasAllowed = isProcStateAllowedNetworkWhileBackground(
- oldUidState);
- final boolean isAllowed = isProcStateAllowedNetworkWhileBackground(newUidState);
- if (!wasAllowed && isAllowed) {
- mBackgroundTransitioningUids.delete(uid);
- updateRuleForBackgroundUL(uid);
- updatePowerRestrictionRules = true;
- } else if (!isAllowed) {
- final int transitionIdx = mBackgroundTransitioningUids.indexOfKey(uid);
- final long completionTimeMs = SystemClock.uptimeMillis()
- + getBackgroundTransitioningDelay(procState);
- boolean completionTimeUpdated = false;
- if (wasAllowed) {
- // Rules need to transition from allowed to blocked after the respective
- // delay.
- if (transitionIdx < 0) {
- // This is just a defensive check in case the upstream code ever
- // makes multiple calls for the same process state change.
- mBackgroundTransitioningUids.put(uid, completionTimeMs);
- completionTimeUpdated = true;
- }
- } else if (mUseDifferentDelaysForBackgroundChain) {
- // wasAllowed was false, but the transition delay may have reduced.
- // Currently, this can happen when the uid transitions from
- // LAST_ACTIVITY to CACHED_ACTIVITY, for example.
- if (transitionIdx >= 0
- && completionTimeMs < mBackgroundTransitioningUids.valueAt(
- transitionIdx)) {
- mBackgroundTransitioningUids.setValueAt(transitionIdx,
- completionTimeMs);
- completionTimeUpdated = true;
- }
+ final boolean wasAllowed = isProcStateAllowedNetworkWhileBackground(
+ oldUidState);
+ final boolean isAllowed = isProcStateAllowedNetworkWhileBackground(newUidState);
+ if (!wasAllowed && isAllowed) {
+ mBackgroundTransitioningUids.delete(uid);
+ updateRuleForBackgroundUL(uid);
+ updatePowerRestrictionRules = true;
+ } else if (!isAllowed) {
+ final int transitionIdx = mBackgroundTransitioningUids.indexOfKey(uid);
+ final long completionTimeMs = SystemClock.uptimeMillis()
+ + getBackgroundTransitioningDelay(procState);
+ boolean completionTimeUpdated = false;
+ if (wasAllowed) {
+ // Rules need to transition from allowed to blocked after the respective
+ // delay.
+ if (transitionIdx < 0) {
+ // This is just a defensive check in case the upstream code ever
+ // makes multiple calls for the same process state change.
+ mBackgroundTransitioningUids.put(uid, completionTimeMs);
+ completionTimeUpdated = true;
}
- if (completionTimeUpdated
- && completionTimeMs < mNextProcessBackgroundUidsTime) {
- // Many uids may be in this "transitioning" state at the same time,
- // so we always keep one message to process transition completion at
- // the earliest time.
- mHandler.removeMessages(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS);
- mHandler.sendEmptyMessageAtTime(
- MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, completionTimeMs);
- mNextProcessBackgroundUidsTime = completionTimeMs;
+ } else if (mUseDifferentDelaysForBackgroundChain) {
+ // wasAllowed was false, but the transition delay may have reduced.
+ // Currently, this can happen when the uid transitions from
+ // LAST_ACTIVITY to CACHED_ACTIVITY, for example.
+ if (transitionIdx >= 0
+ && completionTimeMs < mBackgroundTransitioningUids.valueAt(
+ transitionIdx)) {
+ mBackgroundTransitioningUids.setValueAt(transitionIdx,
+ completionTimeMs);
+ completionTimeUpdated = true;
}
}
+ if (completionTimeUpdated
+ && completionTimeMs < mNextProcessBackgroundUidsTime) {
+ // Many uids may be in this "transitioning" state at the same time,
+ // so we always keep one message to process transition completion at
+ // the earliest time.
+ mHandler.removeMessages(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS);
+ mHandler.sendEmptyMessageAtTime(
+ MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, completionTimeMs);
+ mNextProcessBackgroundUidsTime = completionTimeMs;
+ }
}
if (mLowPowerStandbyActive) {
boolean allowedInLpsChanged =
@@ -4545,12 +4519,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (mRestrictPower) {
updateRuleForRestrictPowerUL(uid);
}
- if (mBackgroundNetworkRestricted) {
- // Uid is no longer running, there is no point in any grace period of network
- // access during transitions to lower importance proc-states.
- mBackgroundTransitioningUids.delete(uid);
- updateRuleForBackgroundUL(uid);
- }
+ // Uid is no longer running, there is no point in any grace period of network
+ // access during transitions to lower importance proc-states.
+ mBackgroundTransitioningUids.delete(uid);
+ updateRuleForBackgroundUL(uid);
updateRulesForPowerRestrictionsUL(uid);
if (mLowPowerStandbyActive) {
updateRuleForLowPowerStandbyUL(uid);
@@ -5021,9 +4993,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
"updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-"));
}
try {
- if (mBackgroundNetworkRestricted) {
- updateRulesForBackgroundChainUL();
- }
+ updateRulesForBackgroundChainUL();
updateRulesForAppIdleUL();
updateRulesForRestrictPowerUL();
updateRulesForRestrictBackgroundUL();
@@ -5183,9 +5153,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
updateRuleForDeviceIdleUL(uid);
updateRuleForRestrictPowerUL(uid);
- if (mBackgroundNetworkRestricted) {
- updateRuleForBackgroundUL(uid);
- }
+ updateRuleForBackgroundUL(uid);
// Update internal rules.
updateRulesForPowerRestrictionsUL(uid);
}
@@ -5358,9 +5326,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
updateRuleForDeviceIdleUL(uid);
updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
updateRuleForRestrictPowerUL(uid);
- if (mBackgroundNetworkRestricted) {
- updateRuleForBackgroundUL(uid);
- }
+ updateRuleForBackgroundUL(uid);
// If the uid has the necessary permissions, then it should be added to the restricted mode
// firewall allowlist.
@@ -5611,7 +5577,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
newBlockedReasons |= (mLowPowerStandbyActive ? BLOCKED_REASON_LOW_POWER_STANDBY : 0);
newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0);
newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE);
- newBlockedReasons |= mBackgroundNetworkRestricted ? BLOCKED_REASON_APP_BACKGROUND : 0;
+ newBlockedReasons |= BLOCKED_REASON_APP_BACKGROUND;
newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
@@ -5624,8 +5590,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
& ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS);
newAllowedReasons |= (isAllowlistedFromLowPowerStandbyUL(uid))
? ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST : 0;
- newAllowedReasons |= (mBackgroundNetworkRestricted
- && isUidExemptFromBackgroundRestrictions(uid))
+ newAllowedReasons |= isUidExemptFromBackgroundRestrictions(uid)
? ALLOWED_REASON_NOT_IN_BACKGROUND : 0;
uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
diff --git a/services/core/java/com/android/server/net/flags.aconfig b/services/core/java/com/android/server/net/flags.aconfig
index 7f04e665567e..3c0ff6115fcd 100644
--- a/services/core/java/com/android/server/net/flags.aconfig
+++ b/services/core/java/com/android/server/net/flags.aconfig
@@ -2,13 +2,6 @@ package: "com.android.server.net"
container: "system"
flag {
- name: "network_blocked_for_top_sleeping_and_above"
- namespace: "backstage_power"
- description: "Block network access for apps in a low importance background state"
- bug: "304347838"
-}
-
-flag {
name: "use_metered_firewall_chains"
namespace: "backstage_power"
description: "Use metered firewall chains to control access to metered networks"
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index dddab657be14..5a7027edc20d 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -2158,13 +2158,11 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainEnabled() throws Exception {
verify(mNetworkManager).setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, true);
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
@RequiresFlagsDisabled(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN)
public void testBackgroundChainOnProcStateChangeSameDelay() throws Exception {
// initialization calls setFirewallChainEnabled, so we want to reset the invocations.
@@ -2194,10 +2192,7 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
- @RequiresFlagsEnabled({
- Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE,
- Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN
- })
+ @RequiresFlagsEnabled(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN)
public void testBackgroundChainOnProcStateChangeDifferentDelays() throws Exception {
// The app will be blocked when there is no prior proc-state.
assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
@@ -2247,7 +2242,6 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainOnAllowlistChange() throws Exception {
// initialization calls setFirewallChainEnabled, so we want to reset the invocations.
clearInvocations(mNetworkManager);
@@ -2285,7 +2279,6 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainOnTempAllowlistChange() throws Exception {
// initialization calls setFirewallChainEnabled, so we want to reset the invocations.
clearInvocations(mNetworkManager);
@@ -2387,7 +2380,6 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersProcStateChanges() throws Exception {
int testProcStateSeq = 0;
try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
@@ -2450,7 +2442,6 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersStaleChanges() throws Exception {
final int testProcStateSeq = 51;
try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
@@ -2470,7 +2461,6 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersCapabilityChanges() throws Exception {
int testProcStateSeq = 0;
try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
@@ -2559,7 +2549,6 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testObsoleteHandleUidChanged() throws Exception {
callAndWaitOnUidGone(UID_A);
assertTrue(mService.isUidNetworkingBlocked(UID_A, false));