summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/preloaded-classes2
-rw-r--r--core/api/current.txt4
-rw-r--r--core/api/module-lib-current.txt8
-rw-r--r--core/api/system-current.txt26
-rw-r--r--core/java/android/content/Intent.java1
-rw-r--r--core/java/android/ddm/DdmHandleHeap.java183
-rw-r--r--core/java/android/ddm/DdmHandleThread.java181
-rw-r--r--core/java/android/ddm/DdmRegister.java4
-rw-r--r--core/java/android/net/vcn/VcnManager.java65
-rw-r--r--core/java/android/uwb/AngleMeasurement.java107
-rw-r--r--core/java/android/uwb/AngleOfArrivalMeasurement.java21
-rw-r--r--core/java/android/uwb/IUwbAdapter.aidl13
-rw-r--r--core/java/android/uwb/RangingManager.java33
-rw-r--r--core/java/android/uwb/UwbManager.java5
-rw-r--r--core/java/com/android/internal/compat/AndroidBuildClassifier.java10
-rw-r--r--core/java/com/android/internal/compat/OverrideAllowedState.java14
-rw-r--r--core/jni/AndroidRuntime.cpp22
-rw-r--r--core/res/res/values/strings.xml10
-rw-r--r--core/tests/uwbtests/src/android/uwb/RangingManagerTest.java110
-rw-r--r--core/tests/uwbtests/src/android/uwb/UwbTestUtils.java29
-rw-r--r--keystore/java/android/security/AndroidKeyStoreMaintenance.java18
-rw-r--r--keystore/java/android/security/KeyStore.java14
-rw-r--r--media/jni/soundpool/Sound.cpp12
-rw-r--r--media/jni/soundpool/Stream.cpp4
-rw-r--r--media/jni/soundpool/StreamManager.cpp2
-rw-r--r--media/jni/soundpool/android_media_SoundPool.cpp3
-rw-r--r--packages/Connectivity/framework/api/current.txt8
-rw-r--r--packages/Connectivity/framework/api/module-lib-current.txt1
-rw-r--r--packages/Connectivity/framework/api/system-current.txt1
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityManager.java103
-rw-r--r--packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl4
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkCapabilities.java109
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkInfo.java3
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkRequest.java15
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkState.java4
-rw-r--r--packages/Connectivity/framework/src/android/net/ParseException.java (renamed from core/java/android/net/ParseException.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosSocketInfo.java6
-rw-r--r--packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java52
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java144
-rw-r--r--services/core/java/com/android/server/IpSecService.java19
-rw-r--r--services/core/java/com/android/server/NetIdManager.java3
-rw-r--r--services/core/java/com/android/server/VcnManagementService.java4
-rw-r--r--services/core/java/com/android/server/compat/CompatChange.java100
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java43
-rw-r--r--services/core/java/com/android/server/compat/OverrideValidatorImpl.java4
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java11
-rw-r--r--services/core/java/com/android/server/connectivity/PermissionMonitor.java66
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java160
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java25
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java10
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java43
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java18
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java26
-rw-r--r--telephony/java/android/telephony/ims/RcsContactPresenceTuple.java49
-rw-r--r--telephony/java/android/telephony/ims/RcsContactUceCapability.java36
-rw-r--r--telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl1
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java25
-rw-r--r--tests/net/common/java/android/net/NetworkCapabilitiesTest.java105
-rw-r--r--tests/net/java/android/net/ConnectivityManagerTest.java22
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java174
-rw-r--r--tests/net/java/com/android/server/IpSecServiceTest.java10
-rw-r--r--tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java48
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java10
64 files changed, 1393 insertions, 975 deletions
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 5e88d97db91f..56c35bc41d05 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -1838,11 +1838,9 @@ android.database.sqlite.SqliteWrapper
android.ddm.DdmHandleAppName$Names
android.ddm.DdmHandleAppName
android.ddm.DdmHandleExit
-android.ddm.DdmHandleHeap
android.ddm.DdmHandleHello
android.ddm.DdmHandleNativeHeap
android.ddm.DdmHandleProfiling
-android.ddm.DdmHandleThread
android.ddm.DdmHandleViewDebug
android.ddm.DdmRegister
android.debug.AdbManager
diff --git a/core/api/current.txt b/core/api/current.txt
index 0bfcc623e1c0..0e7ecefbdbdc 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -25018,10 +25018,6 @@ package android.net {
ctor public NetworkSpecifier();
}
- public class ParseException extends java.lang.RuntimeException {
- field public String response;
- }
-
public abstract class PlatformVpnProfile {
method public final int getType();
method @NonNull public final String getTypeString();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 2285c3849b4c..7c6ff8ede3cc 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -20,6 +20,14 @@ package android.app.usage {
}
+package android.content {
+
+ public class Intent implements java.lang.Cloneable android.os.Parcelable {
+ field public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE";
+ }
+
+}
+
package android.net {
public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index a9e3fb54c7eb..acce0a8822c2 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6409,12 +6409,12 @@ package android.net.util {
package android.net.vcn {
public class VcnManager {
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener);
+ method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties);
- method public void removeVcnNetworkPolicyListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener);
+ method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
}
- public static interface VcnManager.VcnNetworkPolicyListener {
+ public static interface VcnManager.VcnNetworkPolicyChangeListener {
method public void onPolicyChanged();
}
@@ -9356,6 +9356,10 @@ package android.telephony {
field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
}
+ public static final class CarrierConfigManager.Ims {
+ field public static final String KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY = "ims.publish_service_desc_feature_tag_map_override_string_array";
+ }
+
public static final class CarrierConfigManager.Wifi {
field public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = "wifi.hotspot_maximum_client_count";
field public static final String KEY_PREFIX = "wifi.";
@@ -11542,6 +11546,7 @@ package android.telephony.ims {
method public void onAutoConfigurationErrorReceived(int, @NonNull String);
method public void onConfigurationChanged(@NonNull byte[]);
method public void onConfigurationReset();
+ method public void onPreProvisioningReceived(@NonNull byte[]);
method public void onRemoved();
}
@@ -12011,6 +12016,7 @@ package android.telephony.ims.stub {
method public int getConfigInt(int);
method public String getConfigString(int);
method public final void notifyAutoConfigurationErrorReceived(int, @NonNull String);
+ method public final void notifyPreProvisioningReceived(@NonNull byte[]);
method public final void notifyProvisionedValueChanged(int, int);
method public final void notifyProvisionedValueChanged(int, String);
method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
@@ -12294,6 +12300,7 @@ package android.util {
package android.uwb {
public final class AngleMeasurement implements android.os.Parcelable {
+ ctor public AngleMeasurement(double, double, double);
method public int describeContents();
method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
method @FloatRange(from=0.0, to=3.141592653589793) public double getErrorRadians();
@@ -12302,14 +12309,6 @@ package android.uwb {
field @NonNull public static final android.os.Parcelable.Creator<android.uwb.AngleMeasurement> CREATOR;
}
- public static final class AngleMeasurement.Builder {
- ctor public AngleMeasurement.Builder();
- method @NonNull public android.uwb.AngleMeasurement build();
- method @NonNull public android.uwb.AngleMeasurement.Builder setConfidenceLevel(double);
- method @NonNull public android.uwb.AngleMeasurement.Builder setErrorRadians(double);
- method @NonNull public android.uwb.AngleMeasurement.Builder setRadians(double);
- }
-
public final class AngleOfArrivalMeasurement implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.uwb.AngleMeasurement getAltitude();
@@ -12319,10 +12318,9 @@ package android.uwb {
}
public static final class AngleOfArrivalMeasurement.Builder {
- ctor public AngleOfArrivalMeasurement.Builder();
+ ctor public AngleOfArrivalMeasurement.Builder(@NonNull android.uwb.AngleMeasurement);
method @NonNull public android.uwb.AngleOfArrivalMeasurement build();
method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAltitude(@NonNull android.uwb.AngleMeasurement);
- method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAzimuth(@NonNull android.uwb.AngleMeasurement);
}
public final class DistanceMeasurement implements android.os.Parcelable {
@@ -12422,7 +12420,7 @@ package android.uwb {
public final class UwbManager {
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public long elapsedRealtimeResolutionNanos();
method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.PersistableBundle getSpecificationInfo();
- method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public AutoCloseable openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
+ method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback);
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 6bfc12d8d19e..4d68e90437be 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2329,6 +2329,7 @@ public class Intent implements Parcelable, Cloneable {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE";
/**
* Alarm Changed Action: This is broadcast when the AlarmClock
diff --git a/core/java/android/ddm/DdmHandleHeap.java b/core/java/android/ddm/DdmHandleHeap.java
index e24aeb2af3a1..8fa235294451 100644
--- a/core/java/android/ddm/DdmHandleHeap.java
+++ b/core/java/android/ddm/DdmHandleHeap.java
@@ -30,15 +30,7 @@ import java.nio.ByteBuffer;
*/
public class DdmHandleHeap extends ChunkHandler {
- public static final int CHUNK_HPIF = type("HPIF");
- public static final int CHUNK_HPSG = type("HPSG");
- public static final int CHUNK_HPDU = type("HPDU");
- public static final int CHUNK_HPDS = type("HPDS");
- public static final int CHUNK_NHSG = type("NHSG");
public static final int CHUNK_HPGC = type("HPGC");
- public static final int CHUNK_REAE = type("REAE");
- public static final int CHUNK_REAQ = type("REAQ");
- public static final int CHUNK_REAL = type("REAL");
private static DdmHandleHeap mInstance = new DdmHandleHeap();
@@ -50,15 +42,7 @@ public class DdmHandleHeap extends ChunkHandler {
* Register for the messages we're interested in.
*/
public static void register() {
- DdmServer.registerHandler(CHUNK_HPIF, mInstance);
- DdmServer.registerHandler(CHUNK_HPSG, mInstance);
- DdmServer.registerHandler(CHUNK_HPDU, mInstance);
- DdmServer.registerHandler(CHUNK_HPDS, mInstance);
- DdmServer.registerHandler(CHUNK_NHSG, mInstance);
DdmServer.registerHandler(CHUNK_HPGC, mInstance);
- DdmServer.registerHandler(CHUNK_REAE, mInstance);
- DdmServer.registerHandler(CHUNK_REAQ, mInstance);
- DdmServer.registerHandler(CHUNK_REAL, mInstance);
}
/**
@@ -81,24 +65,8 @@ public class DdmHandleHeap extends ChunkHandler {
Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
int type = request.type;
- if (type == CHUNK_HPIF) {
- return handleHPIF(request);
- } else if (type == CHUNK_HPSG) {
- return handleHPSGNHSG(request, false);
- } else if (type == CHUNK_HPDU) {
- return handleHPDU(request);
- } else if (type == CHUNK_HPDS) {
- return handleHPDS(request);
- } else if (type == CHUNK_NHSG) {
- return handleHPSGNHSG(request, true);
- } else if (type == CHUNK_HPGC) {
+ if (type == CHUNK_HPGC) {
return handleHPGC(request);
- } else if (type == CHUNK_REAE) {
- return handleREAE(request);
- } else if (type == CHUNK_REAQ) {
- return handleREAQ(request);
- } else if (type == CHUNK_REAL) {
- return handleREAL(request);
} else {
throw new RuntimeException("Unknown packet "
+ ChunkHandler.name(type));
@@ -106,112 +74,6 @@ public class DdmHandleHeap extends ChunkHandler {
}
/*
- * Handle a "HeaP InFo" request.
- */
- private Chunk handleHPIF(Chunk request) {
- ByteBuffer in = wrapChunk(request);
-
- int when = in.get();
- if (false)
- Log.v("ddm-heap", "Heap segment enable: when=" + when);
-
- boolean ok = DdmVmInternal.heapInfoNotify(when);
- if (!ok) {
- return createFailChunk(1, "Unsupported HPIF what");
- } else {
- return null; // empty response
- }
- }
-
- /*
- * Handle a "HeaP SeGment" or "Native Heap SeGment" request.
- */
- private Chunk handleHPSGNHSG(Chunk request, boolean isNative) {
- ByteBuffer in = wrapChunk(request);
-
- int when = in.get();
- int what = in.get();
- if (false)
- Log.v("ddm-heap", "Heap segment enable: when=" + when
- + ", what=" + what + ", isNative=" + isNative);
-
- boolean ok = DdmVmInternal.heapSegmentNotify(when, what, isNative);
- if (!ok) {
- return createFailChunk(1, "Unsupported HPSG what/when");
- } else {
- // TODO: if "when" is non-zero and we want to see a dump
- // right away, initiate a GC.
- return null; // empty response
- }
- }
-
- /*
- * Handle a "HeaP DUmp" request.
- *
- * This currently just returns a result code. We could pull up
- * the entire contents of the file and return them, but hprof dump
- * files can be a few megabytes.
- */
- private Chunk handleHPDU(Chunk request) {
- ByteBuffer in = wrapChunk(request);
- byte result;
-
- /* get the filename for the output file */
- int len = in.getInt();
- String fileName = getString(in, len);
- if (false)
- Log.d("ddm-heap", "Heap dump: file='" + fileName + "'");
-
- try {
- Debug.dumpHprofData(fileName);
- result = 0;
- } catch (UnsupportedOperationException uoe) {
- Log.w("ddm-heap", "hprof dumps not supported in this VM");
- result = -1;
- } catch (IOException ioe) {
- result = -1;
- } catch (RuntimeException re) {
- result = -1;
- }
-
- /* create a non-empty reply so the handler fires on completion */
- byte[] reply = { result };
- return new Chunk(CHUNK_HPDU, reply, 0, reply.length);
- }
-
- /*
- * Handle a "HeaP Dump Streaming" request.
- *
- * This tells the VM to create a heap dump and send it directly to
- * DDMS. The dumps are large enough that we don't want to copy the
- * data into a byte[] and send it from here.
- */
- private Chunk handleHPDS(Chunk request) {
- ByteBuffer in = wrapChunk(request);
- byte result;
-
- /* get the filename for the output file */
- if (false)
- Log.d("ddm-heap", "Heap dump: [DDMS]");
-
- String failMsg = null;
- try {
- Debug.dumpHprofDataDdms();
- } catch (UnsupportedOperationException uoe) {
- failMsg = "hprof dumps not supported in this VM";
- } catch (RuntimeException re) {
- failMsg = "Exception: " + re.getMessage();
- }
-
- if (failMsg != null) {
- Log.w("ddm-heap", failMsg);
- return createFailChunk(1, failMsg);
- } else {
- return null;
- }
- }
-
- /*
* Handle a "HeaP Garbage Collection" request.
*/
private Chunk handleHPGC(Chunk request) {
@@ -223,47 +85,4 @@ public class DdmHandleHeap extends ChunkHandler {
return null; // empty response
}
-
- /*
- * Handle a "REcent Allocation Enable" request.
- */
- private Chunk handleREAE(Chunk request) {
- ByteBuffer in = wrapChunk(request);
- boolean enable;
-
- enable = (in.get() != 0);
-
- if (false)
- Log.d("ddm-heap", "Recent allocation enable request: " + enable);
-
- DdmVmInternal.enableRecentAllocations(enable);
-
- return null; // empty response
- }
-
- /*
- * Handle a "REcent Allocation Query" request.
- */
- private Chunk handleREAQ(Chunk request) {
- //ByteBuffer in = wrapChunk(request);
-
- byte[] reply = new byte[1];
- reply[0] = DdmVmInternal.getRecentAllocationStatus() ? (byte)1 :(byte)0;
- return new Chunk(CHUNK_REAQ, reply, 0, reply.length);
- }
-
- /*
- * Handle a "REcent ALlocations" request.
- */
- private Chunk handleREAL(Chunk request) {
- //ByteBuffer in = wrapChunk(request);
-
- if (false)
- Log.d("ddm-heap", "Recent allocations request");
-
- /* generate the reply in a ready-to-go format */
- byte[] reply = DdmVmInternal.getRecentAllocations();
- return new Chunk(CHUNK_REAL, reply, 0, reply.length);
- }
}
-
diff --git a/core/java/android/ddm/DdmHandleThread.java b/core/java/android/ddm/DdmHandleThread.java
deleted file mode 100644
index 613ab75f9c1b..000000000000
--- a/core/java/android/ddm/DdmHandleThread.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2007 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.ddm;
-
-import org.apache.harmony.dalvik.ddmc.Chunk;
-import org.apache.harmony.dalvik.ddmc.ChunkHandler;
-import org.apache.harmony.dalvik.ddmc.DdmServer;
-import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
-import android.util.Log;
-import java.nio.ByteBuffer;
-
-/**
- * Handle thread-related traffic.
- */
-public class DdmHandleThread extends ChunkHandler {
-
- public static final int CHUNK_THEN = type("THEN");
- public static final int CHUNK_THCR = type("THCR");
- public static final int CHUNK_THDE = type("THDE");
- public static final int CHUNK_THST = type("THST");
- public static final int CHUNK_STKL = type("STKL");
-
- private static DdmHandleThread mInstance = new DdmHandleThread();
-
-
- /* singleton, do not instantiate */
- private DdmHandleThread() {}
-
- /**
- * Register for the messages we're interested in.
- */
- public static void register() {
- DdmServer.registerHandler(CHUNK_THEN, mInstance);
- DdmServer.registerHandler(CHUNK_THST, mInstance);
- DdmServer.registerHandler(CHUNK_STKL, mInstance);
- }
-
- /**
- * Called when the DDM server connects. The handler is allowed to
- * send messages to the server.
- */
- public void connected() {}
-
- /**
- * Called when the DDM server disconnects. Can be used to disable
- * periodic transmissions or clean up saved state.
- */
- public void disconnected() {}
-
- /**
- * Handle a chunk of data.
- */
- public Chunk handleChunk(Chunk request) {
- if (false)
- Log.v("ddm-thread", "Handling " + name(request.type) + " chunk");
- int type = request.type;
-
- if (type == CHUNK_THEN) {
- return handleTHEN(request);
- } else if (type == CHUNK_THST) {
- return handleTHST(request);
- } else if (type == CHUNK_STKL) {
- return handleSTKL(request);
- } else {
- throw new RuntimeException("Unknown packet "
- + ChunkHandler.name(type));
- }
- }
-
- /*
- * Handle a "THread notification ENable" request.
- */
- private Chunk handleTHEN(Chunk request) {
- ByteBuffer in = wrapChunk(request);
-
- boolean enable = (in.get() != 0);
- //Log.i("ddm-thread", "Thread notify enable: " + enable);
-
- DdmVmInternal.threadNotify(enable);
- return null; // empty response
- }
-
- /*
- * Handle a "THread STatus" request. This is constructed by the VM.
- */
- private Chunk handleTHST(Chunk request) {
- ByteBuffer in = wrapChunk(request);
- // currently nothing to read from "in"
-
- //Log.d("ddm-thread", "Thread status request");
-
- byte[] status = DdmVmInternal.getThreadStats();
- if (status != null)
- return new Chunk(CHUNK_THST, status, 0, status.length);
- else
- return createFailChunk(1, "Can't build THST chunk");
- }
-
- /*
- * Handle a STacK List request.
- *
- * This is done by threadId, which isn't great since those are
- * recycled. We need a thread serial ID. The Linux tid is an okay
- * answer as it's unlikely to recycle at the exact wrong moment.
- * However, we're using the short threadId in THST messages, so we
- * use them here for consistency. (One thought is to keep the current
- * thread ID in the low 16 bits and somehow serialize the top 16 bits.)
- */
- private Chunk handleSTKL(Chunk request) {
- ByteBuffer in = wrapChunk(request);
- int threadId;
-
- threadId = in.getInt();
-
- //Log.d("ddm-thread", "Stack list request " + threadId);
-
- StackTraceElement[] trace = DdmVmInternal.getStackTraceById(threadId);
- if (trace == null) {
- return createFailChunk(1, "Stack trace unavailable");
- } else {
- return createStackChunk(trace, threadId);
- }
- }
-
- /*
- * Serialize a StackTraceElement[] into an STKL chunk.
- *
- * We include the threadId in the response so the other side doesn't have
- * to match up requests and responses as carefully.
- */
- private Chunk createStackChunk(StackTraceElement[] trace, int threadId) {
- int bufferSize = 0;
-
- bufferSize += 4; // version, flags, whatever
- bufferSize += 4; // thread ID
- bufferSize += 4; // frame count
- for (StackTraceElement elem : trace) {
- bufferSize += 4 + elem.getClassName().length() * 2;
- bufferSize += 4 + elem.getMethodName().length() * 2;
- bufferSize += 4;
- if (elem.getFileName() != null)
- bufferSize += elem.getFileName().length() * 2;
- bufferSize += 4; // line number
- }
-
- ByteBuffer out = ByteBuffer.allocate(bufferSize);
- out.putInt(0);
- out.putInt(threadId);
- out.putInt(trace.length);
- for (StackTraceElement elem : trace) {
- out.putInt(elem.getClassName().length());
- putString(out, elem.getClassName());
- out.putInt(elem.getMethodName().length());
- putString(out, elem.getMethodName());
- if (elem.getFileName() != null) {
- out.putInt(elem.getFileName().length());
- putString(out, elem.getFileName());
- } else {
- out.putInt(0);
- }
- out.putInt(elem.getLineNumber());
- }
-
- return new Chunk(CHUNK_STKL, out);
- }
-}
-
diff --git a/core/java/android/ddm/DdmRegister.java b/core/java/android/ddm/DdmRegister.java
index e0faa51a938e..ca1031287e3e 100644
--- a/core/java/android/ddm/DdmRegister.java
+++ b/core/java/android/ddm/DdmRegister.java
@@ -16,9 +16,10 @@
package android.ddm;
-import org.apache.harmony.dalvik.ddmc.DdmServer;
import android.util.Log;
+import org.apache.harmony.dalvik.ddmc.DdmServer;
+
/**
* Just a place to stick handler registrations, instead of scattering
* them around.
@@ -46,7 +47,6 @@ public class DdmRegister {
if (false)
Log.v("ddm", "Registering DDM message handlers");
DdmHandleHello.register();
- DdmHandleThread.register();
DdmHandleHeap.register();
DdmHandleNativeHeap.register();
DdmHandleProfiling.register();
diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
index 8ebf757760c3..062438c6e5db 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -73,7 +73,8 @@ import java.util.concurrent.Executor;
public class VcnManager {
@NonNull private static final String TAG = VcnManager.class.getSimpleName();
- private static final Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
+ private static final Map<
+ VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>();
@NonNull private final Context mContext;
@@ -93,13 +94,13 @@ public class VcnManager {
}
/**
- * Get all currently registered VcnNetworkPolicyListeners for testing purposes.
+ * Get all currently registered VcnNetworkPolicyChangeListeners for testing purposes.
*
* @hide
*/
@VisibleForTesting(visibility = Visibility.PRIVATE)
@NonNull
- public static Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
+ public static Map<VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
getAllPolicyListeners() {
return Collections.unmodifiableMap(REGISTERED_POLICY_LISTENERS);
}
@@ -162,14 +163,14 @@ public class VcnManager {
}
// TODO(b/180537630): remove all VcnUnderlyingNetworkPolicyListener refs once Telephony is using
- // the new VcnNetworkPolicyListener API
+ // the new VcnNetworkPolicyChangeListener API
/**
* VcnUnderlyingNetworkPolicyListener is the interface through which internal system components
* can register to receive updates for VCN-underlying Network policies from the System Server.
*
* @hide
*/
- public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyListener {}
+ public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyChangeListener {}
/**
* Add a listener for VCN-underlying network policy updates.
@@ -185,7 +186,7 @@ public class VcnManager {
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
public void addVcnUnderlyingNetworkPolicyListener(
@NonNull Executor executor, @NonNull VcnUnderlyingNetworkPolicyListener listener) {
- addVcnNetworkPolicyListener(executor, listener);
+ addVcnNetworkPolicyChangeListener(executor, listener);
}
/**
@@ -198,7 +199,7 @@ public class VcnManager {
*/
public void removeVcnUnderlyingNetworkPolicyListener(
@NonNull VcnUnderlyingNetworkPolicyListener listener) {
- removeVcnNetworkPolicyListener(listener);
+ removeVcnNetworkPolicyChangeListener(listener);
}
/**
@@ -233,20 +234,20 @@ public class VcnManager {
}
/**
- * VcnNetworkPolicyListener is the interface through which internal system components (e.g.
- * Network Factories) can register to receive updates for VCN-underlying Network policies from
- * the System Server.
+ * VcnNetworkPolicyChangeListener is the interface through which internal system components
+ * (e.g. Network Factories) can register to receive updates for VCN-underlying Network policies
+ * from the System Server.
*
* <p>Any Network Factory that brings up Networks capable of being VCN-underlying Networks
- * should register a VcnNetworkPolicyListener. VcnManager will then use this listener to notify
- * the registrant when VCN Network policies change. Upon receiving this signal, the listener
- * must check {@link VcnManager} for the current Network policy result for each of its Networks
- * via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}.
+ * should register a VcnNetworkPolicyChangeListener. VcnManager will then use this listener to
+ * notify the registrant when VCN Network policies change. Upon receiving this signal, the
+ * listener must check {@link VcnManager} for the current Network policy result for each of its
+ * Networks via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}.
*
* @hide
*/
@SystemApi
- public interface VcnNetworkPolicyListener {
+ public interface VcnNetworkPolicyChangeListener {
/**
* Notifies the implementation that the VCN's underlying Network policy has changed.
*
@@ -260,20 +261,21 @@ public class VcnManager {
/**
* Add a listener for VCN-underlying Network policy updates.
*
- * <p>A {@link VcnNetworkPolicyListener} is eligible to begin receiving callbacks once it is
- * registered. No callbacks are guaranteed upon registration.
+ * <p>A {@link VcnNetworkPolicyChangeListener} is eligible to begin receiving callbacks once it
+ * is registered. No callbacks are guaranteed upon registration.
*
* @param executor the Executor that will be used for invoking all calls to the specified
* Listener
- * @param listener the VcnNetworkPolicyListener to be added
+ * @param listener the VcnNetworkPolicyChangeListener to be added
* @throws SecurityException if the caller does not have permission NETWORK_FACTORY
- * @throws IllegalStateException if the specified VcnNetworkPolicyListener is already registered
+ * @throws IllegalStateException if the specified VcnNetworkPolicyChangeListener is already
+ * registered
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public void addVcnNetworkPolicyListener(
- @NonNull Executor executor, @NonNull VcnNetworkPolicyListener listener) {
+ public void addVcnNetworkPolicyChangeListener(
+ @NonNull Executor executor, @NonNull VcnNetworkPolicyChangeListener listener) {
requireNonNull(executor, "executor must not be null");
requireNonNull(listener, "listener must not be null");
@@ -292,15 +294,18 @@ public class VcnManager {
}
/**
- * Remove the specified VcnNetworkPolicyListener from VcnManager.
+ * Remove the specified VcnNetworkPolicyChangeListener from VcnManager.
*
* <p>If the specified listener is not currently registered, this is a no-op.
*
- * @param listener the VcnNetworkPolicyListener that will be removed
+ * @param listener the VcnNetworkPolicyChangeListener that will be removed
+ * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
* @hide
*/
@SystemApi
- public void removeVcnNetworkPolicyListener(@NonNull VcnNetworkPolicyListener listener) {
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ public void removeVcnNetworkPolicyChangeListener(
+ @NonNull VcnNetworkPolicyChangeListener listener) {
requireNonNull(listener, "listener must not be null");
VcnUnderlyingNetworkPolicyListenerBinder binder =
@@ -320,8 +325,9 @@ public class VcnManager {
* Applies the network policy for a {@link android.net.Network} with the given parameters.
*
* <p>Prior to a new NetworkAgent being registered, or upon notification that Carrier VCN policy
- * may have changed via {@link VcnNetworkPolicyListener#onPolicyChanged()}, a Network Provider
- * MUST poll for the updated Network policy based on that Network's capabilities and properties.
+ * may have changed via {@link VcnNetworkPolicyChangeListener#onPolicyChanged()}, a Network
+ * Provider MUST poll for the updated Network policy based on that Network's capabilities and
+ * properties.
*
* @param networkCapabilities the NetworkCapabilities to be used in determining the Network
* policy result for this Network.
@@ -532,17 +538,18 @@ public class VcnManager {
}
/**
- * Binder wrapper for added VcnNetworkPolicyListeners to receive signals from System Server.
+ * Binder wrapper for added VcnNetworkPolicyChangeListeners to receive signals from System
+ * Server.
*
* @hide
*/
private static class VcnUnderlyingNetworkPolicyListenerBinder
extends IVcnUnderlyingNetworkPolicyListener.Stub {
@NonNull private final Executor mExecutor;
- @NonNull private final VcnNetworkPolicyListener mListener;
+ @NonNull private final VcnNetworkPolicyChangeListener mListener;
private VcnUnderlyingNetworkPolicyListenerBinder(
- Executor executor, VcnNetworkPolicyListener listener) {
+ Executor executor, VcnNetworkPolicyChangeListener listener) {
mExecutor = executor;
mListener = listener;
}
diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java
index 9df213b2092f..8c771baaea37 100644
--- a/core/java/android/uwb/AngleMeasurement.java
+++ b/core/java/android/uwb/AngleMeasurement.java
@@ -38,9 +38,30 @@ public final class AngleMeasurement implements Parcelable {
private final double mErrorRadians;
private final double mConfidenceLevel;
- private AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+ /**
+ * Constructs a new {@link AngleMeasurement} object
+ *
+ * @param radians the angle in radians
+ * @param errorRadians the error of the angle measurement in radians
+ * @param confidenceLevel confidence level of the angle measurement
+ *
+ * @throws IllegalArgumentException if the radians, errorRadians, or confidenceLevel is out of
+ * allowed range
+ */
+ public AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+ if (radians < -Math.PI || radians > Math.PI) {
+ throw new IllegalArgumentException("Invalid radians: " + radians);
+ }
mRadians = radians;
+
+ if (errorRadians < 0.0 || errorRadians > Math.PI) {
+ throw new IllegalArgumentException("Invalid error radians: " + errorRadians);
+ }
mErrorRadians = errorRadians;
+
+ if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
+ throw new IllegalArgumentException("Invalid confidence level: " + confidenceLevel);
+ }
mConfidenceLevel = confidenceLevel;
}
@@ -122,11 +143,7 @@ public final class AngleMeasurement implements Parcelable {
new Creator<AngleMeasurement>() {
@Override
public AngleMeasurement createFromParcel(Parcel in) {
- Builder builder = new Builder();
- builder.setRadians(in.readDouble());
- builder.setErrorRadians(in.readDouble());
- builder.setConfidenceLevel(in.readDouble());
- return builder.build();
+ return new AngleMeasurement(in.readDouble(), in.readDouble(), in.readDouble());
}
@Override
@@ -134,82 +151,4 @@ public final class AngleMeasurement implements Parcelable {
return new AngleMeasurement[size];
}
};
-
- /**
- * Builder class for {@link AngleMeasurement}.
- */
- public static final class Builder {
- private double mRadians = Double.NaN;
- private double mErrorRadians = Double.NaN;
- private double mConfidenceLevel = Double.NaN;
-
- /**
- * Set the angle in radians
- *
- * @param radians angle in radians
- * @throws IllegalArgumentException if angle exceeds allowed limits of [-Math.PI, +Math.PI]
- */
- @NonNull
- public Builder setRadians(double radians) {
- if (radians < -Math.PI || radians > Math.PI) {
- throw new IllegalArgumentException("Invalid radians: " + radians);
- }
- mRadians = radians;
- return this;
- }
-
- /**
- * Set the angle error in radians
- *
- * @param errorRadians error of the angle in radians
- * @throws IllegalArgumentException if the error exceeds the allowed limits of [0, +Math.PI]
- */
- @NonNull
- public Builder setErrorRadians(double errorRadians) {
- if (errorRadians < 0.0 || errorRadians > Math.PI) {
- throw new IllegalArgumentException(
- "Invalid error radians: " + errorRadians);
- }
- mErrorRadians = errorRadians;
- return this;
- }
-
- /**
- * Set the angle confidence level
- *
- * @param confidenceLevel level of confidence of the angle measurement
- * @throws IllegalArgumentException if the error exceeds the allowed limits of [0.0, 1.0]
- */
- @NonNull
- public Builder setConfidenceLevel(double confidenceLevel) {
- if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
- throw new IllegalArgumentException(
- "Invalid confidence level: " + confidenceLevel);
- }
- mConfidenceLevel = confidenceLevel;
- return this;
- }
-
- /**
- * Build the {@link AngleMeasurement} object
- *
- * @throws IllegalStateException if angle, error, or confidence values are missing
- */
- @NonNull
- public AngleMeasurement build() {
- if (Double.isNaN(mRadians)) {
- throw new IllegalStateException("Angle is not set");
- }
-
- if (Double.isNaN(mErrorRadians)) {
- throw new IllegalStateException("Angle error is not set");
- }
-
- if (Double.isNaN(mConfidenceLevel)) {
- throw new IllegalStateException("Angle confidence level is not set");
- }
-
- return new AngleMeasurement(mRadians, mErrorRadians, mConfidenceLevel);
- }
- }
}
diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java
index 3d8626b98bed..db04ad16c191 100644
--- a/core/java/android/uwb/AngleOfArrivalMeasurement.java
+++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java
@@ -116,9 +116,8 @@ public final class AngleOfArrivalMeasurement implements Parcelable {
new Creator<AngleOfArrivalMeasurement>() {
@Override
public AngleOfArrivalMeasurement createFromParcel(Parcel in) {
- Builder builder = new Builder();
-
- builder.setAzimuth(in.readParcelable(AngleMeasurement.class.getClassLoader()));
+ Builder builder =
+ new Builder(in.readParcelable(AngleMeasurement.class.getClassLoader()));
builder.setAltitude(in.readParcelable(AngleMeasurement.class.getClassLoader()));
@@ -135,18 +134,16 @@ public final class AngleOfArrivalMeasurement implements Parcelable {
* Builder class for {@link AngleOfArrivalMeasurement}.
*/
public static final class Builder {
- private AngleMeasurement mAzimuthAngleMeasurement = null;
+ private final AngleMeasurement mAzimuthAngleMeasurement;
private AngleMeasurement mAltitudeAngleMeasurement = null;
/**
- * Set the azimuth angle
+ * Constructs an {@link AngleOfArrivalMeasurement} object
*
- * @param azimuthAngle azimuth angle
+ * @param azimuthAngle the azimuth angle of the measurement
*/
- @NonNull
- public Builder setAzimuth(@NonNull AngleMeasurement azimuthAngle) {
+ public Builder(@NonNull AngleMeasurement azimuthAngle) {
mAzimuthAngleMeasurement = azimuthAngle;
- return this;
}
/**
@@ -162,15 +159,9 @@ public final class AngleOfArrivalMeasurement implements Parcelable {
/**
* Build the {@link AngleOfArrivalMeasurement} object
- *
- * @throws IllegalStateException if the required azimuth angle is not provided
*/
@NonNull
public AngleOfArrivalMeasurement build() {
- if (mAzimuthAngleMeasurement == null) {
- throw new IllegalStateException("Azimuth angle measurement is not set");
- }
-
return new AngleOfArrivalMeasurement(mAzimuthAngleMeasurement,
mAltitudeAngleMeasurement);
}
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
index 468a69c7bddb..4036892fb9e7 100644
--- a/core/java/android/uwb/IUwbAdapter.aidl
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -62,9 +62,6 @@ interface IUwbAdapter {
/**
* Request to open a new ranging session
*
- * This function must return before calling any functions in
- * IUwbAdapterCallbacks.
- *
* This function does not start the ranging session, but all necessary
* components must be initialized and ready to start a new ranging
* session prior to calling IUwbAdapterCallback#onRangingOpened.
@@ -77,12 +74,16 @@ interface IUwbAdapter {
* RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being called
* if the ranging session fails to be opened.
*
+ * If the provided sessionHandle is already open for the calling client, then
+ * #onRangingOpenFailed must be called and the new session must not be opened.
+ *
+ * @param sessionHandle the session handle to open ranging for
* @param rangingCallbacks the callbacks used to deliver ranging information
* @param parameters the configuration to use for ranging
- * @return a SessionHandle used to identify this ranging request
*/
- SessionHandle openRanging(in IUwbRangingCallbacks rangingCallbacks,
- in PersistableBundle parameters);
+ void openRanging(in SessionHandle sessionHandle,
+ in IUwbRangingCallbacks rangingCallbacks,
+ in PersistableBundle parameters);
/**
* Request to start ranging
diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java
index c0d818774ba0..85f2c1ccc180 100644
--- a/core/java/android/uwb/RangingManager.java
+++ b/core/java/android/uwb/RangingManager.java
@@ -17,6 +17,7 @@
package android.uwb;
import android.annotation.NonNull;
+import android.os.CancellationSignal;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.util.Log;
@@ -32,6 +33,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
private final IUwbAdapter mAdapter;
private final Hashtable<SessionHandle, RangingSession> mRangingSessionTable = new Hashtable<>();
+ private int mNextSessionId = 1;
public RangingManager(IUwbAdapter adapter) {
mAdapter = adapter;
@@ -44,29 +46,26 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
* @param executor {@link Executor} to run callbacks
* @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession}
* that is being opened.
- * @return a new {@link RangingSession}
+ * @return a {@link CancellationSignal} that may be used to cancel the opening of the
+ * {@link RangingSession}.
*/
- public RangingSession openSession(@NonNull PersistableBundle params, @NonNull Executor executor,
+ public CancellationSignal openSession(@NonNull PersistableBundle params,
+ @NonNull Executor executor,
@NonNull RangingSession.Callback callbacks) {
- SessionHandle sessionHandle;
- try {
- sessionHandle = mAdapter.openRanging(this, params);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
synchronized (this) {
- if (hasSession(sessionHandle)) {
- Log.w(TAG, "Newly created session unexpectedly reuses an active SessionHandle");
- executor.execute(() -> callbacks.onClosed(
- RangingSession.Callback.REASON_GENERIC_ERROR,
- new PersistableBundle()));
- }
-
+ SessionHandle sessionHandle = new SessionHandle(mNextSessionId++);
RangingSession session =
new RangingSession(executor, callbacks, mAdapter, sessionHandle);
mRangingSessionTable.put(sessionHandle, session);
- return session;
+ try {
+ mAdapter.openRanging(sessionHandle, this, params);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ CancellationSignal cancellationSignal = new CancellationSignal();
+ cancellationSignal.setOnCancelListener(() -> session.close());
+ return cancellationSignal;
}
}
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 63a6d058f358..844bbbe7970b 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -25,6 +25,7 @@ import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
+import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -228,14 +229,14 @@ public final class UwbManager {
* @param callbacks {@link RangingSession.Callback} to associate with the
* {@link RangingSession} that is being opened.
*
- * @return an {@link AutoCloseable} that is able to be used to close or cancel the opening of a
+ * @return an {@link CancellationSignal} that is able to be used to cancel the opening of a
* {@link RangingSession} that has been requested through {@link #openRangingSession}
* but has not yet been made available by
* {@link RangingSession.Callback#onOpened(RangingSession)}.
*/
@NonNull
@RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
- public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters,
+ public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
@NonNull @CallbackExecutor Executor executor,
@NonNull RangingSession.Callback callbacks) {
return mRangingManager.openSession(parameters, executor, callbacks);
diff --git a/core/java/com/android/internal/compat/AndroidBuildClassifier.java b/core/java/com/android/internal/compat/AndroidBuildClassifier.java
index 0b937fad7df1..364db06976a0 100644
--- a/core/java/com/android/internal/compat/AndroidBuildClassifier.java
+++ b/core/java/com/android/internal/compat/AndroidBuildClassifier.java
@@ -31,4 +31,14 @@ public class AndroidBuildClassifier {
public boolean isFinalBuild() {
return "REL".equals(Build.VERSION.CODENAME);
}
+
+ /**
+ * The current platform SDK version.
+ */
+ public int platformTargetSdk() {
+ if (isFinalBuild()) {
+ return Build.VERSION.SDK_INT;
+ }
+ return Build.VERSION_CODES.CUR_DEVELOPMENT;
+ }
}
diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.java b/core/java/com/android/internal/compat/OverrideAllowedState.java
index c0bbe5082131..e408be2ab471 100644
--- a/core/java/com/android/internal/compat/OverrideAllowedState.java
+++ b/core/java/com/android/internal/compat/OverrideAllowedState.java
@@ -34,7 +34,8 @@ public final class OverrideAllowedState implements Parcelable {
DISABLED_NON_TARGET_SDK,
DISABLED_TARGET_SDK_TOO_HIGH,
DEFERRED_VERIFICATION,
- LOGGING_ONLY_CHANGE
+ LOGGING_ONLY_CHANGE,
+ PLATFORM_TOO_OLD
})
@Retention(RetentionPolicy.SOURCE)
public @interface State {
@@ -65,6 +66,10 @@ public final class OverrideAllowedState implements Parcelable {
* Change is marked as logging only, and cannot be toggled.
*/
public static final int LOGGING_ONLY_CHANGE = 5;
+ /**
+ * Change is gated by a target sdk version newer than the current platform sdk version.
+ */
+ public static final int PLATFORM_TOO_OLD = 6;
@State
public final int state;
@@ -123,6 +128,11 @@ public final class OverrideAllowedState implements Parcelable {
throw new SecurityException(String.format(
"Cannot override %1$d because it is marked as a logging-only change.",
changeId));
+ case PLATFORM_TOO_OLD:
+ throw new SecurityException(String.format(
+ "Cannot override %1$d for %2$s because the change's targetSdk threshold "
+ + "(%3$d) is above the platform sdk.",
+ changeId, packageName, changeIdTargetSdk));
}
}
@@ -170,6 +180,8 @@ public final class OverrideAllowedState implements Parcelable {
return "DEFERRED_VERIFICATION";
case LOGGING_ONLY_CHANGE:
return "LOGGING_ONLY_CHANGE";
+ case PLATFORM_TOO_OLD:
+ return "PLATFORM_TOO_OLD";
}
return "UNKNOWN";
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c01f741862b1..ed84434adff5 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -630,6 +630,12 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p
char saveResolvedClassesDelayMsOptsBuf[
sizeof("-Xps-save-resolved-classes-delay-ms:")-1 + PROPERTY_VALUE_MAX];
char madviseRandomOptsBuf[sizeof("-XX:MadviseRandomAccess:")-1 + PROPERTY_VALUE_MAX];
+ char madviseWillNeedFileSizeVdex[
+ sizeof("-XMadviseWillNeedVdexFileSize:")-1 + PROPERTY_VALUE_MAX];
+ char madviseWillNeedFileSizeOdex[
+ sizeof("-XMadviseWillNeedOdexFileSize:")-1 + PROPERTY_VALUE_MAX];
+ char madviseWillNeedFileSizeArt[
+ sizeof("-XMadviseWillNeedArtFileSize:")-1 + PROPERTY_VALUE_MAX];
char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];
char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
@@ -838,6 +844,22 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p
parseRuntimeOption("dalvik.vm.madvise-random", madviseRandomOptsBuf, "-XX:MadviseRandomAccess:");
/*
+ * Use default platform configuration as limits for madvising,
+ * when no properties are specified.
+ */
+ parseRuntimeOption("dalvik.vm.madvise.vdexfile.size",
+ madviseWillNeedFileSizeVdex,
+ "-XMadviseWillNeedVdexFileSize:");
+
+ parseRuntimeOption("dalvik.vm.madvise.odexfile.size",
+ madviseWillNeedFileSizeOdex,
+ "-XMadviseWillNeedOdexFileSize:");
+
+ parseRuntimeOption("dalvik.vm.madvise.artfile.size",
+ madviseWillNeedFileSizeArt,
+ "-XMadviseWillNeedArtFileSize:");
+
+ /*
* Profile related options.
*/
parseRuntimeOption("dalvik.vm.hot-startup-method-samples", hotstartupsamplesOptsBuf,
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8ac00dceea9e..4a06671d9f27 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3605,6 +3605,8 @@
<string name="ext_media_checking_notification_title">Checking <xliff:g id="name" example="SD card">%s</xliff:g>\u2026</string>
<!-- Notification body when external media is being checked [CHAR LIMIT=NONE] -->
<string name="ext_media_checking_notification_message">Reviewing current content</string>
+ <!-- TV specific notification body when external media is being checked [CHAR LIMIT=75] -->
+ <string name="ext_media_checking_notification_message" product="tv">Analyzing media storage</string>
<!-- Notification body when new external media is detected [CHAR LIMIT=30] -->
<string name="ext_media_new_notification_title">New <xliff:g id="name" example="SD card">%s</xliff:g></string>
@@ -3612,11 +3614,15 @@
<string name="ext_media_new_notification_title" product="automotive"><xliff:g id="name" example="SD card">%s</xliff:g> isn\u2019t working</string>
<!-- Notification body when new external media is detected [CHAR LIMIT=NONE] -->
<string name="ext_media_new_notification_message">Tap to set up</string>
+ <!-- TV specific notification body when new external media is detected [CHAR LIMIT=75] -->
+ <string name="ext_media_new_notification_message" product="tv">Select to set up</string>
<!-- Automotive specific notification body when new external media is detected. [CHAR LIMIT=NONE] -->
<string name="ext_media_new_notification_message" product="automotive">You may need to reformat the device. Tap to eject.</string>
<!-- Notification body when external media is ready for use [CHAR LIMIT=NONE] -->
<string name="ext_media_ready_notification_message">For transferring photos and media</string>
+ <!-- TV specific notification body when external media is ready for use [CHAR LIMIT=75] -->
+ <string name="ext_media_ready_notification_message" product="tv">Browse media files</string>
<!-- Notification title when external media is unmountable (corrupt) [CHAR LIMIT=30] -->
<string name="ext_media_unmountable_notification_title">Issue with <xliff:g id="name" example="SD card">%s</xliff:g></string>
@@ -3635,8 +3641,8 @@
<string name="ext_media_unsupported_notification_title" product="automotive"><xliff:g id="name" example="SD card">%s</xliff:g> isn\u2019t working</string>
<!-- Notification body when external media is unsupported [CHAR LIMIT=NONE] -->
<string name="ext_media_unsupported_notification_message">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Tap to set up in a supported format.</string>
- <!-- TV-specific notification body when external media is unsupported [CHAR LIMIT=NONE] -->
- <string name="ext_media_unsupported_notification_message" product="tv">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Select to set up in a supported format.</string>
+ <!-- TV-specific notification body when external media is unsupported [CHAR LIMIT=75] -->
+ <string name="ext_media_unsupported_notification_message" product="tv">Select to set up <xliff:g id="name" example="SD card">%s</xliff:g> in a supported format.</string>
<!-- Automotive specific notification body when external media is unsupported [CHAR LIMIT=NONE] -->
<string name="ext_media_unsupported_notification_message" product="automotive">You may need to reformat the device</string>
diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
index c01bb75c32aa..e41805dd3a59 100644
--- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
+++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
@@ -22,7 +22,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -32,6 +31,7 @@ import androidx.test.filters.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import java.util.concurrent.Executor;
@@ -42,51 +42,23 @@ import java.util.concurrent.Executor;
@RunWith(AndroidJUnit4.class)
public class RangingManagerTest {
- private static final IUwbAdapter ADAPTER = mock(IUwbAdapter.class);
private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
private static final PersistableBundle PARAMS = new PersistableBundle();
private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN;
@Test
public void testOpenSession_OpenRangingInvoked() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
rangingManager.openSession(PARAMS, EXECUTOR, callback);
- verify(ADAPTER, times(1)).openRanging(eq(rangingManager), eq(PARAMS));
- }
-
- @Test
- public void testOpenSession_ErrorIfSameSessionHandleReturned() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
-
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
-
- // Calling openSession will cause the same session handle to be returned. The onClosed
- // callback should be invoked
- RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
- rangingManager.openSession(PARAMS, EXECUTOR, callback2);
- verify(callback, times(0)).onClosed(anyInt(), any());
- verify(callback2, times(1)).onClosed(anyInt(), any());
- }
-
- @Test
- public void testOnRangingOpened_ValidSessionHandle() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
-
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
- rangingManager.onRangingOpened(handle);
- verify(callback, times(1)).onOpened(any());
+ verify(adapter, times(1)).openRanging(any(), eq(rangingManager), eq(PARAMS));
}
@Test
public void testOnRangingOpened_InvalidSessionHandle() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
rangingManager.onRangingOpened(new SessionHandle(2));
@@ -95,18 +67,20 @@ public class RangingManagerTest {
@Test
public void testOnRangingOpened_MultipleSessionsRegistered() throws RemoteException {
- SessionHandle sessionHandle1 = new SessionHandle(1);
- SessionHandle sessionHandle2 = new SessionHandle(2);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- when(ADAPTER.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
-
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ RangingManager rangingManager = new RangingManager(adapter);
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingOpened(sessionHandle1);
verify(callback1, times(1)).onOpened(any());
@@ -119,12 +93,17 @@ public class RangingManagerTest {
@Test
public void testCorrectCallbackInvoked() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
+
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle handle = sessionHandleCaptor.getValue();
+
rangingManager.onRangingOpened(handle);
verify(callback, times(1)).onOpened(any());
@@ -156,20 +135,23 @@ public class RangingManagerTest {
@Test
public void testOnRangingClosed_MultipleSessionsRegistered() throws RemoteException {
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
// Verify that if multiple sessions are registered, only the session that is
// requested to close receives the associated callbacks
- SessionHandle sessionHandle1 = new SessionHandle(1);
- SessionHandle sessionHandle2 = new SessionHandle(2);
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
- when(ADAPTER.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
+ RangingManager rangingManager = new RangingManager(adapter);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- RangingManager rangingManager = new RangingManager(ADAPTER);
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingClosed(sessionHandle1, REASON, PARAMS);
verify(callback1, times(1)).onClosed(anyInt(), any());
@@ -182,19 +164,22 @@ public class RangingManagerTest {
@Test
public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException {
- SessionHandle sessionHandle1 = new SessionHandle(1);
- SessionHandle sessionHandle2 = new SessionHandle(2);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
- when(ADAPTER.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ RangingManager rangingManager = new RangingManager(adapter);
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
rangingManager.onRangingStarted(sessionHandle1, PARAMS);
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingStarted(sessionHandle2, PARAMS);
rangingManager.onRangingResult(sessionHandle1, UwbTestUtils.getRangingReports(1));
@@ -232,17 +217,24 @@ public class RangingManagerTest {
private void runReason(@RangingChangeReason int reasonIn,
@RangingSession.Callback.Reason int reasonOut) throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
+
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
+
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle handle = sessionHandleCaptor.getValue();
rangingManager.onRangingOpenFailed(handle, reasonIn, PARAMS);
verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS));
// Open a new session
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ handle = sessionHandleCaptor.getValue();
rangingManager.onRangingOpened(handle);
rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS);
diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
index 8e7f7c562ade..75c6924a1939 100644
--- a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
+++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
@@ -16,34 +16,23 @@
package android.uwb;
-import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.SystemClock;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.Executor;
public class UwbTestUtils {
private UwbTestUtils() {}
- public static boolean isUwbSupported(Context context) {
- PackageManager packageManager = context.getPackageManager();
- return packageManager.hasSystemFeature(PackageManager.FEATURE_UWB);
- }
-
public static AngleMeasurement getAngleMeasurement() {
- return new AngleMeasurement.Builder()
- .setRadians(getDoubleInRange(-Math.PI, Math.PI))
- .setErrorRadians(getDoubleInRange(0, Math.PI))
- .setConfidenceLevel(getDoubleInRange(0, 1))
- .build();
+ return new AngleMeasurement(
+ getDoubleInRange(-Math.PI, Math.PI),
+ getDoubleInRange(0, Math.PI),
+ getDoubleInRange(0, 1));
}
public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() {
- return new AngleOfArrivalMeasurement.Builder()
+ return new AngleOfArrivalMeasurement.Builder(getAngleMeasurement())
.setAltitude(getAngleMeasurement())
- .setAzimuth(getAngleMeasurement())
.build();
}
@@ -69,14 +58,6 @@ public class UwbTestUtils {
.build();
}
- public static List<RangingMeasurement> getRangingMeasurements(int num) {
- List<RangingMeasurement> result = new ArrayList<>();
- for (int i = 0; i < num; i++) {
- result.add(getRangingMeasurement());
- }
- return result;
- }
-
public static RangingReport getRangingReports(int numMeasurements) {
RangingReport.Builder builder = new RangingReport.Builder();
for (int i = 0; i < numMeasurements; i++) {
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index 55015696ff47..35b1c169f283 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -121,4 +121,22 @@ public class AndroidKeyStoreMaintenance {
return SYSTEM_ERROR;
}
}
+
+ /**
+ * Queries user state from Keystore 2.0.
+ *
+ * @param userId - Android user id of the user.
+ * @return UserState enum variant as integer if successful or an error
+ */
+ public static int getState(int userId) {
+ try {
+ return getService().getState(userId);
+ } catch (ServiceSpecificException e) {
+ Log.e(TAG, "getState failed", e);
+ return e.errorCode;
+ } catch (Exception e) {
+ Log.e(TAG, "Can not connect to keystore", e);
+ return SYSTEM_ERROR;
+ }
+ }
}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 93658e69eac8..937f01ce3767 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -43,6 +43,7 @@ import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeystoreResponse;
import android.security.keystore.UserNotAuthenticatedException;
+import android.security.maintenance.UserState;
import android.system.keystore2.Domain;
import android.util.Log;
@@ -196,6 +197,19 @@ public class KeyStore {
public State state(int userId) {
final int ret;
try {
+ if (android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) {
+ int userState = AndroidKeyStoreMaintenance.getState(userId);
+ switch (userState) {
+ case UserState.UNINITIALIZED:
+ return KeyStore.State.UNINITIALIZED;
+ case UserState.LSKF_UNLOCKED:
+ return KeyStore.State.UNLOCKED;
+ case UserState.LSKF_LOCKED:
+ return KeyStore.State.LOCKED;
+ default:
+ throw new AssertionError(KeyStore.VALUE_CORRUPTED);
+ }
+ }
ret = mBinder.getState(userId);
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
diff --git a/media/jni/soundpool/Sound.cpp b/media/jni/soundpool/Sound.cpp
index f8b4bdb1f4d5..50e0d336f981 100644
--- a/media/jni/soundpool/Sound.cpp
+++ b/media/jni/soundpool/Sound.cpp
@@ -99,8 +99,8 @@ static status_t decode(int fd, int64_t offset, int64_t length,
__func__);
break;
}
- int sampleSize = AMediaExtractor_readSampleData(ex.get(), buf, bufsize);
- ALOGV("%s: read %d", __func__, sampleSize);
+ ssize_t sampleSize = AMediaExtractor_readSampleData(ex.get(), buf, bufsize);
+ ALOGV("%s: read %zd", __func__, sampleSize);
if (sampleSize < 0) {
sampleSize = 0;
sawInputEOS = true;
@@ -124,8 +124,8 @@ static status_t decode(int fd, int64_t offset, int64_t length,
}
AMediaCodecBufferInfo info;
- const int status = AMediaCodec_dequeueOutputBuffer(codec.get(), &info, 1);
- ALOGV("%s: dequeueoutput returned: %d", __func__, status);
+ const ssize_t status = AMediaCodec_dequeueOutputBuffer(codec.get(), &info, 1);
+ ALOGV("%s: dequeueoutput returned: %zd", __func__, status);
if (status >= 0) {
if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
ALOGV("%s: output EOS", __func__);
@@ -167,10 +167,10 @@ static status_t decode(int fd, int64_t offset, int64_t length,
} else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
ALOGV("%s: no output buffer right now", __func__);
} else if (status <= AMEDIA_ERROR_BASE) {
- ALOGE("%s: decode error: %d", __func__, status);
+ ALOGE("%s: decode error: %zd", __func__, status);
break;
} else {
- ALOGV("%s: unexpected info code: %d", __func__, status);
+ ALOGV("%s: unexpected info code: %zd", __func__, status);
}
}
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp
index 73e319a5902e..f261bab0a20c 100644
--- a/media/jni/soundpool/Stream.cpp
+++ b/media/jni/soundpool/Stream.cpp
@@ -317,7 +317,8 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID,
// audio track while the new one is being started and avoids processing them with
// wrong audio audio buffer size (mAudioBufferSize)
auto toggle = mToggle ^ 1;
- void* userData = (void*)((uintptr_t)this | toggle);
+ // NOLINTNEXTLINE(performance-no-int-to-ptr)
+ void* userData = reinterpret_cast<void*>((uintptr_t)this | toggle);
audio_channel_mask_t soundChannelMask = sound->getChannelMask();
// When sound contains a valid channel mask, use it as is.
// Otherwise, use stream count to calculate channel mask.
@@ -386,6 +387,7 @@ exit:
void Stream::staticCallback(int event, void* user, void* info)
{
const auto userAsInt = (uintptr_t)user;
+ // NOLINTNEXTLINE(performance-no-int-to-ptr)
auto stream = reinterpret_cast<Stream*>(userAsInt & ~1);
stream->callback(event, info, int(userAsInt & 1), 0 /* tries */);
}
diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp
index 502ee00b583e..8b84bf3eb8d8 100644
--- a/media/jni/soundpool/StreamManager.cpp
+++ b/media/jni/soundpool/StreamManager.cpp
@@ -330,7 +330,7 @@ ssize_t StreamManager::removeFromQueues_l(
// streams on mProcessingStreams are undergoing processing by the StreamManager thread
// and do not participate in normal stream migration.
- return found;
+ return (ssize_t)found;
}
void StreamManager::addToRestartQueue_l(Stream *stream) {
diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp
index 357cc63bd41e..a66d99fbd9f4 100644
--- a/media/jni/soundpool/android_media_SoundPool.cpp
+++ b/media/jni/soundpool/android_media_SoundPool.cpp
@@ -34,7 +34,8 @@ static struct fields_t {
jclass mSoundPoolClass;
} fields;
static inline SoundPool* MusterSoundPool(JNIEnv *env, jobject thiz) {
- return (SoundPool*)env->GetLongField(thiz, fields.mNativeContext);
+ // NOLINTNEXTLINE(performance-no-int-to-ptr)
+ return reinterpret_cast<SoundPool*>(env->GetLongField(thiz, fields.mNativeContext));
}
static const char* const kAudioAttributesClassPathName = "android/media/AudioAttributes";
struct audio_attributes_fields_t {
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index a8f1a4d2a7f8..243e4ca4295a 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -143,6 +143,7 @@ package android.net {
public static class ConnectivityManager.NetworkCallback {
ctor public ConnectivityManager.NetworkCallback();
+ ctor public ConnectivityManager.NetworkCallback(int);
method public void onAvailable(@NonNull android.net.Network);
method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
@@ -150,6 +151,7 @@ package android.net {
method public void onLosing(@NonNull android.net.Network, int);
method public void onLost(@NonNull android.net.Network);
method public void onUnavailable();
+ field public static final int FLAG_INCLUDE_LOCATION_INFO = 1; // 0x1
}
public static interface ConnectivityManager.OnNetworkActiveListener {
@@ -293,6 +295,7 @@ package android.net {
method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
method public int getOwnerUid();
method public int getSignalStrength();
+ method @NonNull public java.util.Set<java.lang.Integer> getSubIds();
method @Nullable public android.net.TransportInfo getTransportInfo();
method public boolean hasCapability(int);
method public boolean hasTransport(int);
@@ -399,6 +402,11 @@ package android.net {
method public android.net.NetworkRequest.Builder removeTransportType(int);
method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
+ method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
+ }
+
+ public class ParseException extends java.lang.RuntimeException {
+ field public String response;
}
public class ProxyInfo implements android.os.Parcelable {
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 5b64d5239cda..4b3336644ef9 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -7,6 +7,7 @@ package android.net {
public class ConnectivityManager {
method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshot();
+ method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index a732430e6a9c..a98f14ea9408 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -296,6 +296,7 @@ package android.net {
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
+ method @NonNull public android.net.NetworkCapabilities.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index adf22da5be94..8c66db9a205a 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -16,7 +16,6 @@
package android.net;
import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.IpSecManager.INVALID_RESOURCE_ID;
import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
import static android.net.NetworkRequest.Type.LISTEN;
import static android.net.NetworkRequest.Type.REQUEST;
@@ -44,6 +43,7 @@ import android.net.SocketKeepalive.Callback;
import android.net.TetheringManager.StartTetheringCallback;
import android.net.TetheringManager.TetheringEventCallback;
import android.net.TetheringManager.TetheringRequest;
+import android.net.wifi.WifiNetworkSuggestion;
import android.os.Binder;
import android.os.Build;
import android.os.Build.VERSION_CODES;
@@ -1315,7 +1315,7 @@ public class ConnectivityManager {
}
/**
- * Returns an array of {@link android.net.NetworkCapabilities} objects, representing
+ * Returns an array of {@link NetworkCapabilities} objects, representing
* the Networks that applications run by the given user will use by default.
* @hide
*/
@@ -1395,11 +1395,19 @@ public class ConnectivityManager {
}
/**
- * Get the {@link android.net.NetworkCapabilities} for the given {@link Network}. This
+ * Get the {@link NetworkCapabilities} for the given {@link Network}. This
* will return {@code null} if the network is unknown.
*
+ * This will remove any location sensitive data in {@link TransportInfo} embedded in
+ * {@link NetworkCapabilities#getTransportInfo()}. Some transport info instances like
+ * {@link android.net.wifi.WifiInfo} contain location sensitive information. Retrieving
+ * this location sensitive information (subject to app's location permissions) will be
+ * noted by system. To include any location sensitive data in {@link TransportInfo},
+ * use a {@link NetworkCallback} with
+ * {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} flag.
+ *
* @param network The {@link Network} object identifying the network in question.
- * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}.
+ * @return The {@link NetworkCapabilities} for the network, or {@code null}.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@Nullable
@@ -1997,7 +2005,7 @@ public class ConnectivityManager {
dup = createInvalidFd();
}
return new NattSocketKeepalive(mService, network, dup,
- INVALID_RESOURCE_ID /* Unused */, source, destination, executor, callback);
+ -1 /* Unused */, source, destination, executor, callback);
}
/**
@@ -3245,6 +3253,54 @@ public class ConnectivityManager {
*/
public static class NetworkCallback {
/**
+ * No flags associated with this callback.
+ * @hide
+ */
+ public static final int FLAG_NONE = 0;
+ /**
+ * Use this flag to include any location sensitive data in {@link NetworkCapabilities} sent
+ * via {@link #onCapabilitiesChanged(Network, NetworkCapabilities)}.
+ * <p>
+ * These include:
+ * <li> Some transport info instances (retrieved via
+ * {@link NetworkCapabilities#getTransportInfo()}) like {@link android.net.wifi.WifiInfo}
+ * contain location sensitive information.
+ * <li> OwnerUid (retrieved via {@link NetworkCapabilities#getOwnerUid()} is location
+ * sensitive for wifi suggestor apps (i.e using {@link WifiNetworkSuggestion}).</li>
+ * </p>
+ * <p>
+ * Note:
+ * <li> Retrieving this location sensitive information (subject to app's location
+ * permissions) will be noted by system. </li>
+ * <li> Without this flag any {@link NetworkCapabilities} provided via the callback does
+ * not include location sensitive info.
+ * </p>
+ */
+ public static final int FLAG_INCLUDE_LOCATION_INFO = 1 << 0;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = "FLAG_", value = {
+ FLAG_NONE,
+ FLAG_INCLUDE_LOCATION_INFO
+ })
+ public @interface Flag { }
+
+ /**
+ * All the valid flags for error checking.
+ */
+ private static final int VALID_FLAGS = FLAG_INCLUDE_LOCATION_INFO;
+
+ public NetworkCallback() {
+ this(FLAG_NONE);
+ }
+
+ public NetworkCallback(@Flag int flags) {
+ Preconditions.checkArgument((flags & VALID_FLAGS) == flags);
+ mFlags = flags;
+ }
+
+ /**
* Called when the framework connects to a new network to evaluate whether it satisfies this
* request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable}
* callback. There is no guarantee that this new network will satisfy any requests, or that
@@ -3381,7 +3437,7 @@ public class ConnectivityManager {
* calling these methods while in a callback may return an outdated or even a null object.
*
* @param network The {@link Network} whose capabilities have changed.
- * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
+ * @param networkCapabilities The new {@link NetworkCapabilities} for this
* network.
*/
public void onCapabilitiesChanged(@NonNull Network network,
@@ -3450,6 +3506,7 @@ public class ConnectivityManager {
public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
private NetworkRequest networkRequest;
+ private final int mFlags;
}
/**
@@ -3639,14 +3696,15 @@ public class ConnectivityManager {
}
Messenger messenger = new Messenger(handler);
Binder binder = new Binder();
+ final int callbackFlags = callback.mFlags;
if (reqType == LISTEN) {
request = mService.listenForNetwork(
- need, messenger, binder, callingPackageName,
+ need, messenger, binder, callbackFlags, callingPackageName,
getAttributionTag());
} else {
request = mService.requestNetwork(
need, reqType.ordinal(), messenger, timeoutMs, binder, legacyType,
- callingPackageName, getAttributionTag());
+ callbackFlags, callingPackageName, getAttributionTag());
}
if (request != null) {
sCallbacks.put(request, callback);
@@ -3693,7 +3751,7 @@ public class ConnectivityManager {
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+ * Request a network to satisfy a set of {@link NetworkCapabilities}.
*
* <p>This method will attempt to find the best network that matches the passed
* {@link NetworkRequest}, and to bring up one that does if none currently satisfies the
@@ -3777,7 +3835,7 @@ public class ConnectivityManager {
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+ * Request a network to satisfy a set of {@link NetworkCapabilities}.
*
* This method behaves identically to {@link #requestNetwork(NetworkRequest, NetworkCallback)}
* but runs all the callbacks on the passed Handler.
@@ -3799,7 +3857,7 @@ public class ConnectivityManager {
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
+ * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
* by a timeout.
*
* This function behaves identically to the non-timed-out version
@@ -3834,7 +3892,7 @@ public class ConnectivityManager {
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
+ * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
* by a timeout.
*
* This method behaves identically to
@@ -3879,7 +3937,7 @@ public class ConnectivityManager {
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+ * Request a network to satisfy a set of {@link NetworkCapabilities}.
*
* This function behaves identically to the version that takes a NetworkCallback, but instead
* of {@link NetworkCallback} a {@link PendingIntent} is used. This means
@@ -4911,7 +4969,7 @@ public class ConnectivityManager {
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, but
+ * Request a network to satisfy a set of {@link NetworkCapabilities}, but
* does not cause any networks to retain the NET_CAPABILITY_FOREGROUND capability. This can
* be used to request that the system provide a network without causing the network to be
* in the foreground.
@@ -5053,4 +5111,21 @@ public class ConnectivityManager {
throw e.rethrowFromSystemServer();
}
}
+
+ // The first network ID of IPSec tunnel interface.
+ private static final int TUN_INTF_NETID_START = 0xFC00;
+ // The network ID range of IPSec tunnel interface.
+ private static final int TUN_INTF_NETID_RANGE = 0x0400;
+
+ /**
+ * Get the network ID range reserved for IPSec tunnel interfaces.
+ *
+ * @return A Range which indicates the network ID range of IPSec tunnel interface.
+ * @hide
+ */
+ @SystemApi(client = MODULE_LIBRARIES)
+ @NonNull
+ public static Range<Integer> getIpSecNetIdRange() {
+ return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1);
+ }
}
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index cd49258d1c47..f9393e315b83 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -143,7 +143,7 @@ interface IConnectivityManager
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType,
in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
- String callingPackageName, String callingAttributionTag);
+ int callbackFlags, String callingPackageName, String callingAttributionTag);
NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
in PendingIntent operation, String callingPackageName, String callingAttributionTag);
@@ -151,7 +151,7 @@ interface IConnectivityManager
void releasePendingNetworkRequest(in PendingIntent operation);
NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities,
- in Messenger messenger, in IBinder binder, String callingPackageName,
+ in Messenger messenger, in IBinder binder, int callbackFlags, String callingPackageName,
String callingAttributionTag);
void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index c82cd3b4f357..058f3c999dd7 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -25,6 +25,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.ConnectivityManager.NetworkCallback;
+import android.net.wifi.WifiNetworkSuggestion;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -131,6 +132,7 @@ public final class NetworkCapabilities implements Parcelable {
mPrivateDnsBroken = false;
mRequestorUid = Process.INVALID_UID;
mRequestorPackageName = null;
+ mSubIds = new ArraySet<>();
}
/**
@@ -159,6 +161,7 @@ public final class NetworkCapabilities implements Parcelable {
mPrivateDnsBroken = nc.mPrivateDnsBroken;
mRequestorUid = nc.mRequestorUid;
mRequestorPackageName = nc.mRequestorPackageName;
+ mSubIds = new ArraySet<>(nc.mSubIds);
}
/**
@@ -1048,6 +1051,16 @@ public final class NetworkCapabilities implements Parcelable {
*
* Instances of NetworkCapabilities sent to apps without the appropriate permissions will have
* this field cleared out.
+ *
+ * <p>
+ * This field will only be populated for VPN and wifi network suggestor apps (i.e using
+ * {@link WifiNetworkSuggestion}), and only for the network they own.
+ * In the case of wifi network suggestors apps, this field is also location sensitive, so the
+ * app needs to hold {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. If the
+ * app targets SDK version greater than or equal to {@link Build.VERSION_CODES#S}, then they
+ * also need to use {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} to get the info in their
+ * callback. The app will be blamed for location access if this field is included.
+ * </p>
*/
public int getOwnerUid() {
return mOwnerUid;
@@ -1655,6 +1668,7 @@ public final class NetworkCapabilities implements Parcelable {
combineSSIDs(nc);
combineRequestor(nc);
combineAdministratorUids(nc);
+ combineSubIds(nc);
}
/**
@@ -1674,8 +1688,9 @@ public final class NetworkCapabilities implements Parcelable {
&& satisfiedBySpecifier(nc)
&& (onlyImmutable || satisfiedBySignalStrength(nc))
&& (onlyImmutable || satisfiedByUids(nc))
- && (onlyImmutable || satisfiedBySSID(nc)))
- && (onlyImmutable || satisfiedByRequestor(nc));
+ && (onlyImmutable || satisfiedBySSID(nc))
+ && (onlyImmutable || satisfiedByRequestor(nc))
+ && (onlyImmutable || satisfiedBySubIds(nc)));
}
/**
@@ -1771,7 +1786,8 @@ public final class NetworkCapabilities implements Parcelable {
&& equalsOwnerUid(that)
&& equalsPrivateDnsBroken(that)
&& equalsRequestor(that)
- && equalsAdministratorUids(that);
+ && equalsAdministratorUids(that)
+ && equalsSubIds(that);
}
@Override
@@ -1793,7 +1809,8 @@ public final class NetworkCapabilities implements Parcelable {
+ Objects.hashCode(mPrivateDnsBroken) * 47
+ Objects.hashCode(mRequestorUid) * 53
+ Objects.hashCode(mRequestorPackageName) * 59
- + Arrays.hashCode(mAdministratorUids) * 61;
+ + Arrays.hashCode(mAdministratorUids) * 61
+ + Objects.hashCode(mSubIds) * 67;
}
@Override
@@ -1827,6 +1844,7 @@ public final class NetworkCapabilities implements Parcelable {
dest.writeInt(mOwnerUid);
dest.writeInt(mRequestorUid);
dest.writeString(mRequestorPackageName);
+ dest.writeIntArray(CollectionUtils.toIntArray(mSubIds));
}
public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
@@ -1850,6 +1868,11 @@ public final class NetworkCapabilities implements Parcelable {
netCap.mOwnerUid = in.readInt();
netCap.mRequestorUid = in.readInt();
netCap.mRequestorPackageName = in.readString();
+ netCap.mSubIds = new ArraySet<>();
+ final int[] subIdInts = Objects.requireNonNull(in.createIntArray());
+ for (int i = 0; i < subIdInts.length; i++) {
+ netCap.mSubIds.add(subIdInts[i]);
+ }
return netCap;
}
@Override
@@ -1933,11 +1956,14 @@ public final class NetworkCapabilities implements Parcelable {
sb.append(" SSID: ").append(mSSID);
}
-
if (mPrivateDnsBroken) {
sb.append(" PrivateDnsBroken");
}
+ if (!mSubIds.isEmpty()) {
+ sb.append(" SubscriptionIds: ").append(mSubIds);
+ }
+
sb.append("]");
return sb.toString();
}
@@ -2251,6 +2277,67 @@ public final class NetworkCapabilities implements Parcelable {
}
/**
+ * Set of the subscription IDs that identifies the network or request, empty if none.
+ */
+ @NonNull
+ private ArraySet<Integer> mSubIds = new ArraySet<>();
+
+ /**
+ * Sets the subscription ID set that associated to this network or request.
+ *
+ * @hide
+ */
+ @NonNull
+ public NetworkCapabilities setSubIds(@NonNull Set<Integer> subIds) {
+ mSubIds = new ArraySet(Objects.requireNonNull(subIds));
+ return this;
+ }
+
+ /**
+ * Gets the subscription ID set that associated to this network or request.
+ * @return
+ */
+ @NonNull
+ public Set<Integer> getSubIds() {
+ return new ArraySet<>(mSubIds);
+ }
+
+ /**
+ * Tests if the subscription ID set of this network is the same as that of the passed one.
+ */
+ private boolean equalsSubIds(@NonNull NetworkCapabilities nc) {
+ return Objects.equals(mSubIds, nc.mSubIds);
+ }
+
+ /**
+ * Check if the subscription ID set requirements of this object are matched by the passed one.
+ * If specified in the request, the passed one need to have at least one subId and at least
+ * one of them needs to be in the request set.
+ */
+ private boolean satisfiedBySubIds(@NonNull NetworkCapabilities nc) {
+ if (mSubIds.isEmpty()) return true;
+ if (nc.mSubIds.isEmpty()) return false;
+ for (final Integer subId : nc.mSubIds) {
+ if (mSubIds.contains(subId)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Combine subscription ID set of the capabilities.
+ *
+ * <p>This is only legal if the subscription Ids are equal.
+ *
+ * <p>If both subscription IDs are not equal, they belong to different subscription
+ * (or no subscription). In this case, it would not make sense to add them together.
+ */
+ private void combineSubIds(@NonNull NetworkCapabilities nc) {
+ if (!Objects.equals(mSubIds, nc.mSubIds)) {
+ throw new IllegalStateException("Can't combine two subscription ID sets");
+ }
+ }
+
+ /**
* Builder class for NetworkCapabilities.
*
* This class is mainly for for {@link NetworkAgent} instances to use. Many fields in
@@ -2556,6 +2643,18 @@ public final class NetworkCapabilities implements Parcelable {
}
/**
+ * Set the subscription ID set.
+ *
+ * @param subIds a set that represent the subscription IDs. Empty if clean up.
+ * @return this builder.
+ */
+ @NonNull
+ public Builder setSubIds(@NonNull final Set<Integer> subIds) {
+ mCaps.setSubIds(subIds);
+ return this;
+ }
+
+ /**
* Builds the instance of the capabilities.
*
* @return the built instance of NetworkCapabilities.
diff --git a/packages/Connectivity/framework/src/android/net/NetworkInfo.java b/packages/Connectivity/framework/src/android/net/NetworkInfo.java
index d752901e2eb0..bb2349459331 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkInfo.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkInfo.java
@@ -21,7 +21,6 @@ import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
-import android.telephony.Annotation.NetworkType;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -164,7 +163,7 @@ public class NetworkInfo implements Parcelable {
* @param typeName a human-readable string for the network type, or an empty string or null.
* @param subtypeName a human-readable string for the subtype, or an empty string or null.
*/
- public NetworkInfo(int type, @NetworkType int subtype,
+ public NetworkInfo(int type, int subtype,
@Nullable String typeName, @Nullable String subtypeName) {
if (!ConnectivityManager.isNetworkTypeValid(type)
&& type != ConnectivityManager.TYPE_NONE) {
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index aa6975678adc..3fd95ee58df2 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -461,6 +461,21 @@ public class NetworkRequest implements Parcelable {
}
nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
}
+
+ /**
+ * Sets the optional subscription ID set.
+ * <p>
+ * This specify the subscription IDs requirement.
+ * A network will satisfy this request only if it matches one of the subIds in this set.
+ * An empty set matches all networks, including those without a subId.
+ *
+ * @param subIds A {@code Set} that represents subscription IDs.
+ */
+ @NonNull
+ public Builder setSubIds(@NonNull Set<Integer> subIds) {
+ mNetworkCapabilities.setSubIds(subIds);
+ return this;
+ }
}
// implement the Parcelable interface
diff --git a/packages/Connectivity/framework/src/android/net/NetworkState.java b/packages/Connectivity/framework/src/android/net/NetworkState.java
index d01026566ca0..9b69674728a8 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkState.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkState.java
@@ -22,7 +22,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Slog;
+import android.util.Log;
/**
* Snapshot of network state.
@@ -83,7 +83,7 @@ public class NetworkState implements Parcelable {
if (VALIDATE_ROAMING_STATE && networkInfo != null && networkCapabilities != null) {
if (networkInfo.isRoaming() == networkCapabilities
.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
- Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
+ Log.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
+ " and " + networkCapabilities);
}
}
diff --git a/core/java/android/net/ParseException.java b/packages/Connectivity/framework/src/android/net/ParseException.java
index bcfdd7ef09cc..bcfdd7ef09cc 100644
--- a/core/java/android/net/ParseException.java
+++ b/packages/Connectivity/framework/src/android/net/ParseException.java
diff --git a/packages/Connectivity/framework/src/android/net/QosSocketInfo.java b/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
index d37c4691ddde..53d966937a70 100644
--- a/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
+++ b/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
@@ -92,7 +92,7 @@ public final class QosSocketInfo implements Parcelable {
Objects.requireNonNull(socket, "socket cannot be null");
mNetwork = Objects.requireNonNull(network, "network cannot be null");
- mParcelFileDescriptor = ParcelFileDescriptor.dup(socket.getFileDescriptor$());
+ mParcelFileDescriptor = ParcelFileDescriptor.fromSocket(socket);
mLocalSocketAddress =
new InetSocketAddress(socket.getLocalAddress(), socket.getLocalPort());
}
@@ -114,10 +114,10 @@ public final class QosSocketInfo implements Parcelable {
try {
return new InetSocketAddress(InetAddress.getByAddress(address), port);
} catch (final UnknownHostException e) {
- /* The catch block was purposely left empty. UnknownHostException will never be thrown
+ /* This can never happen. UnknownHostException will never be thrown
since the address provided is numeric and non-null. */
+ throw new RuntimeException("UnknownHostException on numeric address", e);
}
- return new InetSocketAddress();
}
@Override
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index c1dca5df1b2f..16a946dc7bc6 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -138,9 +138,6 @@ public class DynamicSystemInstallationService extends Service
private long mCurrentPartitionSize;
private long mCurrentPartitionInstalledSize;
- private boolean mJustCancelledByUser;
- private boolean mKeepNotification;
-
// This is for testing only now
private boolean mEnableWhenCompleted;
@@ -174,11 +171,6 @@ public class DynamicSystemInstallationService extends Service
if (cache != null) {
cache.flush();
}
-
- if (!mKeepNotification) {
- // Cancel the persistent notification.
- mNM.cancel(NOTIFICATION_ID);
- }
}
@Override
@@ -231,9 +223,11 @@ public class DynamicSystemInstallationService extends Service
return;
}
+ boolean removeNotification = false;
switch (result) {
case RESULT_CANCELLED:
postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED, null);
+ removeNotification = true;
break;
case RESULT_ERROR_IO:
@@ -251,7 +245,7 @@ public class DynamicSystemInstallationService extends Service
}
// if it's not successful, reset the task and stop self.
- resetTaskAndStop();
+ resetTaskAndStop(removeNotification);
}
private void executeInstallCommand(Intent intent) {
@@ -302,12 +296,12 @@ public class DynamicSystemInstallationService extends Service
return;
}
- stopForeground(true);
- mJustCancelledByUser = true;
-
if (mInstallTask.cancel(false)) {
- // Will stopSelf() in onResult()
+ // onResult() would call resetTaskAndStop() upon task completion.
Log.d(TAG, "Cancel request filed successfully");
+ // Dismiss the notification as soon as possible as DynamicSystemManager.remove() may
+ // block.
+ stopForeground(STOP_FOREGROUND_REMOVE);
} else {
Log.e(TAG, "Trying to cancel installation while it's already completed.");
}
@@ -322,8 +316,7 @@ public class DynamicSystemInstallationService extends Service
if (!isDynamicSystemInstalled() && (getStatus() != STATUS_READY)) {
Log.e(TAG, "Trying to discard AOT while there is no complete installation");
// Stop foreground state and dismiss stale notification.
- stopForeground(STOP_FOREGROUND_REMOVE);
- resetTaskAndStop();
+ resetTaskAndStop(true);
return;
}
@@ -331,8 +324,8 @@ public class DynamicSystemInstallationService extends Service
getString(R.string.toast_dynsystem_discarded),
Toast.LENGTH_LONG).show();
- resetTaskAndStop();
postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED, null);
+ resetTaskAndStop(true);
mDynSystem.remove();
}
@@ -412,12 +405,13 @@ public class DynamicSystemInstallationService extends Service
}
private void resetTaskAndStop() {
- mInstallTask = null;
+ resetTaskAndStop(/* removeNotification= */ false);
+ }
- new Handler().postDelayed(() -> {
- stopForeground(STOP_FOREGROUND_DETACH);
- stopSelf();
- }, 50);
+ private void resetTaskAndStop(boolean removeNotification) {
+ mInstallTask = null;
+ stopForeground(removeNotification ? STOP_FOREGROUND_REMOVE : STOP_FOREGROUND_DETACH);
+ stopSelf();
}
private void prepareNotification() {
@@ -525,7 +519,7 @@ public class DynamicSystemInstallationService extends Service
private void postStatus(int status, int cause, Throwable detail) {
String statusString;
String causeString;
- mKeepNotification = false;
+ boolean notifyOnNotificationBar = true;
switch (status) {
case STATUS_NOT_STARTED:
@@ -551,18 +545,16 @@ public class DynamicSystemInstallationService extends Service
break;
case CAUSE_INSTALL_CANCELLED:
causeString = "INSTALL_CANCELLED";
+ notifyOnNotificationBar = false;
break;
case CAUSE_ERROR_IO:
causeString = "ERROR_IO";
- mKeepNotification = true;
break;
case CAUSE_ERROR_INVALID_URL:
causeString = "ERROR_INVALID_URL";
- mKeepNotification = true;
break;
case CAUSE_ERROR_EXCEPTION:
causeString = "ERROR_EXCEPTION";
- mKeepNotification = true;
break;
default:
causeString = "CAUSE_NOT_SPECIFIED";
@@ -571,16 +563,6 @@ public class DynamicSystemInstallationService extends Service
Log.d(TAG, "status=" + statusString + ", cause=" + causeString + ", detail=" + detail);
- boolean notifyOnNotificationBar = true;
-
- if (status == STATUS_NOT_STARTED
- && cause == CAUSE_INSTALL_CANCELLED
- && mJustCancelledByUser) {
- // if task is cancelled by user, do not notify them
- notifyOnNotificationBar = false;
- mJustCancelledByUser = false;
- }
-
if (notifyOnNotificationBar) {
mNM.notify(NOTIFICATION_ID, buildNotification(status, cause, detail));
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 3d55c16c7007..afa3bd1da6e7 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -85,6 +85,7 @@ import android.net.ConnectionInfo;
import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
import android.net.DataStallReportParcelable;
import android.net.DnsResolverServiceManager;
import android.net.ICaptivePortal;
@@ -190,7 +191,6 @@ import com.android.connectivity.aidl.INetworkAgent;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.AsyncChannel;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.LocationPermissionChecker;
import com.android.internal.util.MessageUtils;
@@ -344,8 +344,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private String mCurrentTcpBufferSizes;
private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
- new Class[] { AsyncChannel.class, ConnectivityService.class, NetworkAgent.class,
- NetworkAgentInfo.class });
+ new Class[] { ConnectivityService.class, NetworkAgent.class, NetworkAgentInfo.class });
private enum ReapUnvalidatedNetworks {
// Tear down networks that have no chance (e.g. even if validated) of becoming
@@ -1100,7 +1099,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNetworkRanker = new NetworkRanker();
final NetworkRequest defaultInternetRequest = createDefaultRequest();
mDefaultRequest = new NetworkRequestInfo(
- defaultInternetRequest, null, new Binder(),
+ defaultInternetRequest, null,
+ new Binder(), NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
null /* attributionTags */);
mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
mDefaultNetworkRequests.add(mDefaultRequest);
@@ -1356,7 +1356,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (enable) {
handleRegisterNetworkRequest(new NetworkRequestInfo(
- networkRequest, null, new Binder(),
+ networkRequest, null,
+ new Binder(),
+ NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
null /* attributionTags */));
} else {
handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
@@ -1717,8 +1719,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
result.put(
nai.network,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc, mDeps.getCallingUid(), callingPackageName,
- callingAttributionTag));
+ nc, false /* includeLocationSensitiveInfo */,
+ mDeps.getCallingUid(), callingPackageName, callingAttributionTag));
}
}
@@ -1731,7 +1733,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
result.put(
network,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc, mDeps.getCallingUid(), callingPackageName,
+ nc,
+ false /* includeLocationSensitiveInfo */,
+ mDeps.getCallingUid(), callingPackageName,
callingAttributionTag));
}
}
@@ -1813,6 +1817,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
enforceAccessPermission();
return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
getNetworkCapabilitiesInternal(network),
+ false /* includeLocationSensitiveInfo */,
mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
}
@@ -1846,8 +1851,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
@VisibleForTesting
@Nullable
NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- @Nullable NetworkCapabilities nc, int callerUid, @NonNull String callerPkgName,
- @Nullable String callingAttributionTag) {
+ @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
+ int callerUid, @NonNull String callerPkgName, @Nullable String callingAttributionTag) {
if (nc == null) {
return null;
}
@@ -1855,7 +1860,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkCapabilities newNc;
// Avoid doing location permission check if the transport info has no location sensitive
// data.
- if (nc.getTransportInfo() != null && nc.getTransportInfo().hasLocationSensitiveFields()) {
+ if (includeLocationSensitiveInfo
+ && nc.getTransportInfo() != null
+ && nc.getTransportInfo().hasLocationSensitiveFields()) {
hasLocationPermission =
hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
newNc = new NetworkCapabilities(nc, hasLocationPermission);
@@ -1872,6 +1879,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Owner UIDs already checked above. No need to re-check.
return newNc;
}
+ // If the caller does not want location sensitive data & target SDK >= S, then mask info.
+ // Else include the owner UID iff the caller has location permission to provide backwards
+ // compatibility for older apps.
+ if (!includeLocationSensitiveInfo
+ && isTargetSdkAtleast(
+ Build.VERSION_CODES.S, callerUid, callerPkgName)) {
+ newNc.setOwnerUid(INVALID_UID);
+ return newNc;
+ }
+
if (hasLocationPermission == null) {
// Location permission not checked yet, check now for masking owner UID.
hasLocationPermission =
@@ -2890,22 +2907,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
super(looper);
}
- private boolean maybeHandleAsyncChannelMessage(Message msg) {
- switch (msg.what) {
- default:
- return false;
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
- handleAsyncChannelHalfConnect(msg);
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- handleAsyncChannelDisconnected(msg);
- break;
- }
- }
- return true;
- }
-
private void maybeHandleNetworkAgentMessage(Message msg) {
final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
final NetworkAgentInfo nai = arg.first;
@@ -3197,8 +3198,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public void handleMessage(Message msg) {
- if (!maybeHandleAsyncChannelMessage(msg)
- && !maybeHandleNetworkMonitorMessage(msg)
+ if (!maybeHandleNetworkMonitorMessage(msg)
&& !maybeHandleNetworkAgentInfoMessage(msg)) {
maybeHandleNetworkAgentMessage(msg);
}
@@ -3462,21 +3462,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
return false;
}
- private void handleAsyncChannelHalfConnect(Message msg) {
- ensureRunningOnConnectivityServiceThread();
- if (mNetworkProviderInfos.containsKey(msg.replyTo)) {
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- if (VDBG) log("NetworkFactory connected");
- // Finish setting up the full connection
- NetworkProviderInfo npi = mNetworkProviderInfos.get(msg.replyTo);
- sendAllRequestsToProvider(npi);
- } else {
- loge("Error connecting NetworkFactory");
- mNetworkProviderInfos.remove(msg.obj);
- }
- }
- }
-
private void handleNetworkAgentRegistered(Message msg) {
final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
if (!mNetworkAgentInfos.contains(nai)) {
@@ -3507,14 +3492,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- // This is a no-op if it's called with a message designating a provider that has
- // already been destroyed, because its reference will not be found in the relevant
- // maps.
- private void handleAsyncChannelDisconnected(Message msg) {
- NetworkProviderInfo npi = mNetworkProviderInfos.remove(msg.replyTo);
- if (DBG && npi != null) log("unregisterNetworkFactory for " + npi.name);
- }
-
// Destroys a network, remove references to it from the internal state managed by
// ConnectivityService, free its interfaces and clean up.
// Must be called on the Handler thread.
@@ -5155,8 +5132,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
private final IBinder.DeathRecipient mDeathRecipient;
public final int providerId;
- NetworkProviderInfo(String name, Messenger messenger, AsyncChannel asyncChannel,
- int providerId, @NonNull IBinder.DeathRecipient deathRecipient) {
+ NetworkProviderInfo(String name, Messenger messenger, int providerId,
+ @NonNull IBinder.DeathRecipient deathRecipient) {
this.name = name;
this.messenger = messenger;
this.providerId = providerId;
@@ -5250,6 +5227,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private final IBinder mBinder;
final int mPid;
final int mUid;
+ final @NetworkCallback.Flag int mCallbackFlags;
@Nullable
final String mCallingAttributionTag;
// In order to preserve the mapping of NetworkRequest-to-callback when apps register
@@ -5297,17 +5275,26 @@ public class ConnectivityService extends IConnectivityManager.Stub
mPid = getCallingPid();
mUid = mDeps.getCallingUid();
mNetworkRequestCounter.incrementCountOrThrow(mUid);
+ /**
+ * Location sensitive data not included in pending intent. Only included in
+ * {@link NetworkCallback}.
+ */
+ mCallbackFlags = NetworkCallback.FLAG_NONE;
mCallingAttributionTag = callingAttributionTag;
}
NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final Messenger m,
- @Nullable final IBinder binder, @Nullable String callingAttributionTag) {
- this(Collections.singletonList(r), r, m, binder, callingAttributionTag);
+ @Nullable final IBinder binder,
+ @NetworkCallback.Flag int callbackFlags,
+ @Nullable String callingAttributionTag) {
+ this(Collections.singletonList(r), r, m, binder, callbackFlags, callingAttributionTag);
}
NetworkRequestInfo(@NonNull final List<NetworkRequest> r,
@NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m,
- @Nullable final IBinder binder, @Nullable String callingAttributionTag) {
+ @Nullable final IBinder binder,
+ @NetworkCallback.Flag int callbackFlags,
+ @Nullable String callingAttributionTag) {
super();
ensureAllNetworkRequestsHaveType(r);
mRequests = initializeRequests(r);
@@ -5318,6 +5305,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mUid = mDeps.getCallingUid();
mPendingIntent = null;
mNetworkRequestCounter.incrementCountOrThrow(mUid);
+ mCallbackFlags = callbackFlags;
mCallingAttributionTag = callingAttributionTag;
try {
@@ -5359,6 +5347,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mUid = nri.mUid;
mPendingIntent = nri.mPendingIntent;
mNetworkRequestCounter.incrementCountOrThrow(mUid);
+ mCallbackFlags = nri.mCallbackFlags;
mCallingAttributionTag = nri.mCallingAttributionTag;
}
@@ -5408,7 +5397,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
+ " callback request Id: "
+ mNetworkRequestForCallback.requestId
+ " " + mRequests
- + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
+ + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
+ + "callback flags: " + mCallbackFlags;
}
}
@@ -5492,13 +5482,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private boolean checkUnsupportedStartingFrom(int version, String callingPackageName) {
- final UserHandle user = UserHandle.getUserHandleForUid(mDeps.getCallingUid());
+ private boolean isTargetSdkAtleast(int version, int callingUid,
+ @NonNull String callingPackageName) {
+ final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
final PackageManager pm =
mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
try {
- final int callingVersion = pm.getApplicationInfo(
- callingPackageName, 0 /* flags */).targetSdkVersion;
+ final int callingVersion = pm.getTargetSdkVersion(callingPackageName);
if (callingVersion < version) return false;
} catch (PackageManager.NameNotFoundException e) { }
return true;
@@ -5507,10 +5497,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder,
- int legacyType, @NonNull String callingPackageName,
+ int legacyType, int callbackFlags, @NonNull String callingPackageName,
@Nullable String callingAttributionTag) {
if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
- if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
+ if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(),
+ callingPackageName)) {
throw new SecurityException("Insufficient permissions to specify legacy type");
}
}
@@ -5572,7 +5563,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
nextNetworkRequestId(), reqType);
final NetworkRequestInfo nri = getNriToRegister(
- networkRequest, messenger, binder, callingAttributionTag);
+ networkRequest, messenger, binder, callbackFlags, callingAttributionTag);
if (DBG) log("requestNetwork for " + nri);
// For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
@@ -5607,6 +5598,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private NetworkRequestInfo getNriToRegister(@NonNull final NetworkRequest nr,
@Nullable final Messenger msgr, @Nullable final IBinder binder,
+ @NetworkCallback.Flag int callbackFlags,
@Nullable String callingAttributionTag) {
final List<NetworkRequest> requests;
if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) {
@@ -5615,7 +5607,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
} else {
requests = Collections.singletonList(nr);
}
- return new NetworkRequestInfo(requests, nr, msgr, binder, callingAttributionTag);
+ return new NetworkRequestInfo(
+ requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
}
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
@@ -5741,8 +5734,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
- Messenger messenger, IBinder binder, @NonNull String callingPackageName,
- @Nullable String callingAttributionTag) {
+ Messenger messenger, IBinder binder,
+ @NetworkCallback.Flag int callbackFlags,
+ @NonNull String callingPackageName, @NonNull String callingAttributionTag) {
final int callingUid = mDeps.getCallingUid();
if (!hasWifiNetworkListenPermission(networkCapabilities)) {
enforceAccessPermission();
@@ -5763,7 +5757,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
NetworkRequest.Type.LISTEN);
NetworkRequestInfo nri =
- new NetworkRequestInfo(networkRequest, messenger, binder, callingAttributionTag);
+ new NetworkRequestInfo(networkRequest, messenger, binder, callbackFlags,
+ callingAttributionTag);
if (VDBG) log("listenForNetwork for " + nri);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -5832,8 +5827,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
public int registerNetworkProvider(Messenger messenger, String name) {
enforceNetworkFactoryOrSettingsPermission();
NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
- null /* asyncChannel */, nextNetworkProviderId(),
- () -> unregisterNetworkProvider(messenger));
+ nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
return npi.providerId;
}
@@ -7092,6 +7086,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
putParcelable(bundle, networkAgent.network);
}
+ final boolean includeLocationSensitiveInfo =
+ (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0;
switch (notificationType) {
case ConnectivityManager.CALLBACK_AVAILABLE: {
final NetworkCapabilities nc =
@@ -7100,7 +7096,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
putParcelable(
bundle,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc, nri.mUid, nrForCallback.getRequestorPackageName(),
+ nc, includeLocationSensitiveInfo, nri.mUid,
+ nrForCallback.getRequestorPackageName(),
nri.mCallingAttributionTag));
putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
networkAgent.linkProperties, nri.mPid, nri.mUid));
@@ -7120,7 +7117,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
putParcelable(
bundle,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- netCap, nri.mUid, nrForCallback.getRequestorPackageName(),
+ netCap, includeLocationSensitiveInfo, nri.mUid,
+ nrForCallback.getRequestorPackageName(),
nri.mCallingAttributionTag));
break;
}
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 81d4b9da63c8..4c3c6ef21fc5 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -56,6 +56,7 @@ import android.system.Os;
import android.system.OsConstants;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Range;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -756,13 +757,9 @@ public class IpSecService extends IIpSecService.Stub {
}
}
- // These values have been reserved in NetIdManager
- @VisibleForTesting static final int TUN_INTF_NETID_START = 0xFC00;
-
- public static final int TUN_INTF_NETID_RANGE = 0x0400;
-
private final SparseBooleanArray mTunnelNetIds = new SparseBooleanArray();
- private int mNextTunnelNetIdIndex = 0;
+ final Range<Integer> mNetIdRange = ConnectivityManager.getIpSecNetIdRange();
+ private int mNextTunnelNetId = mNetIdRange.getLower();
/**
* Reserves a netId within the range of netIds allocated for IPsec tunnel interfaces
@@ -775,11 +772,13 @@ public class IpSecService extends IIpSecService.Stub {
*/
@VisibleForTesting
int reserveNetId() {
+ final int range = mNetIdRange.getUpper() - mNetIdRange.getLower() + 1;
synchronized (mTunnelNetIds) {
- for (int i = 0; i < TUN_INTF_NETID_RANGE; i++) {
- int index = mNextTunnelNetIdIndex;
- int netId = index + TUN_INTF_NETID_START;
- if (++mNextTunnelNetIdIndex >= TUN_INTF_NETID_RANGE) mNextTunnelNetIdIndex = 0;
+ for (int i = 0; i < range; i++) {
+ final int netId = mNextTunnelNetId;
+ if (++mNextTunnelNetId > mNetIdRange.getUpper()) {
+ mNextTunnelNetId = mNetIdRange.getLower();
+ }
if (!mTunnelNetIds.get(netId)) {
mTunnelNetIds.put(netId, true);
return netId;
diff --git a/services/core/java/com/android/server/NetIdManager.java b/services/core/java/com/android/server/NetIdManager.java
index 097fb3ae47e3..61925c80a22b 100644
--- a/services/core/java/com/android/server/NetIdManager.java
+++ b/services/core/java/com/android/server/NetIdManager.java
@@ -17,6 +17,7 @@
package com.android.server;
import android.annotation.NonNull;
+import android.net.ConnectivityManager;
import android.util.SparseBooleanArray;
import com.android.internal.annotations.GuardedBy;
@@ -31,7 +32,7 @@ public class NetIdManager {
// Sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
public static final int MIN_NET_ID = 100; // some reserved marks
// Top IDs reserved by IpSecService
- public static final int MAX_NET_ID = 65535 - IpSecService.TUN_INTF_NETID_RANGE;
+ public static final int MAX_NET_ID = ConnectivityManager.getIpSecNetIdRange().getLower() - 1;
@GuardedBy("mNetIdInUse")
private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray();
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 502e74a4cc6a..1ef93f4da255 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -667,6 +667,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
requireNonNull(listener, "listener was null");
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.NETWORK_FACTORY,
+ "Must have permission NETWORK_FACTORY to unregister a policy listener");
+
Binder.withCleanCallingIdentity(() -> {
synchronized (mLock) {
PolicyListenerBinderDeath listenerBinderDeath =
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index df83df9a73fb..ae9b0015de43 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import com.android.internal.compat.AndroidBuildClassifier;
import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.internal.compat.OverrideAllowedState;
import com.android.server.compat.config.Change;
@@ -55,7 +56,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
* A change ID to be used only in the CTS test for this SystemApi
*/
@ChangeId
- @EnabledSince(targetSdkVersion = 1235) // Needs to be > test APK targetSdkVersion.
+ @EnabledSince(targetSdkVersion = 31) // Needs to be > test APK targetSdkVersion.
static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.
/**
@@ -80,6 +81,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
}
/**
+ * @param change an object generated by services/core/xsd/platform-compat-config.xsd
+ */
+ public CompatChange(Change change) {
+ this(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
+ change.getEnableSinceTargetSdk(), change.getDisabled(), change.getLoggingOnly(),
+ change.getDescription(), change.getOverridable());
+ }
+
+ /**
* @param changeId Unique ID for the change. See {@link android.compat.Compatibility}.
* @param name Short descriptive name.
* @param enableAfterTargetSdk {@code targetSdkVersion} restriction. See {@link EnabledAfter};
@@ -93,15 +103,10 @@ public final class CompatChange extends CompatibilityChangeInfo {
boolean overridable) {
super(changeId, name, enableAfterTargetSdk, enableSinceTargetSdk, disabled, loggingOnly,
description, overridable);
- }
- /**
- * @param change an object generated by services/core/xsd/platform-compat-config.xsd
- */
- public CompatChange(Change change) {
- super(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
- change.getEnableSinceTargetSdk(), change.getDisabled(), change.getLoggingOnly(),
- change.getDescription(), change.getOverridable());
+ // Initialize override maps.
+ mEvaluatedOverrides = new HashMap<>();
+ mRawOverrides = new HashMap<>();
}
void registerListener(ChangeListener listener) {
@@ -127,18 +132,13 @@ public final class CompatChange extends CompatibilityChangeInfo {
throw new IllegalArgumentException(
"Can't add overrides for a logging only change " + toString());
}
- if (mEvaluatedOverrides == null) {
- mEvaluatedOverrides = new HashMap<>();
- }
mEvaluatedOverrides.put(pname, enabled);
notifyListener(pname);
}
private void removePackageOverrideInternal(String pname) {
- if (mEvaluatedOverrides != null) {
- if (mEvaluatedOverrides.remove(pname) != null) {
- notifyListener(pname);
- }
+ if (mEvaluatedOverrides.remove(pname) != null) {
+ notifyListener(pname);
}
}
@@ -157,9 +157,6 @@ public final class CompatChange extends CompatibilityChangeInfo {
throw new IllegalArgumentException(
"Can't add overrides for a logging only change " + toString());
}
- if (mRawOverrides == null) {
- mRawOverrides = new HashMap<>();
- }
mRawOverrides.put(packageName, override);
recheckOverride(packageName, allowedState, context);
}
@@ -212,7 +209,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
}
boolean hasPackageOverride(String pname) {
- return mRawOverrides != null && mRawOverrides.containsKey(pname);
+ return mRawOverrides.containsKey(pname);
}
/**
* Remove any package override for the given package name, restoring the default behaviour.
@@ -223,7 +220,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
*/
boolean removePackageOverride(String pname, OverrideAllowedState allowedState,
Context context) {
- if (mRawOverrides != null && (mRawOverrides.remove(pname) != null)) {
+ if (mRawOverrides.remove(pname) != null) {
recheckOverride(pname, allowedState, context);
return true;
}
@@ -237,18 +234,24 @@ public final class CompatChange extends CompatibilityChangeInfo {
* @param app Info about the app in question
* @return {@code true} if the change should be enabled for the package.
*/
- boolean isEnabled(ApplicationInfo app) {
+ boolean isEnabled(ApplicationInfo app, AndroidBuildClassifier buildClassifier) {
if (app == null) {
return defaultValue();
}
- if (mEvaluatedOverrides != null && mEvaluatedOverrides.containsKey(app.packageName)) {
+ if (mEvaluatedOverrides.containsKey(app.packageName)) {
return mEvaluatedOverrides.get(app.packageName);
}
if (getDisabled()) {
return false;
}
if (getEnableSinceTargetSdk() != -1) {
- return app.targetSdkVersion >= getEnableSinceTargetSdk();
+ // If the change is gated by a platform version newer than the one currently installed
+ // on the device, disregard the app's target sdk version.
+ int compareSdk = Math.min(app.targetSdkVersion, buildClassifier.platformTargetSdk());
+ if (compareSdk != app.targetSdkVersion) {
+ compareSdk = app.targetSdkVersion;
+ }
+ return compareSdk >= getEnableSinceTargetSdk();
}
return true;
}
@@ -289,7 +292,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
* @return true if there is such override
*/
private boolean hasOverride(String packageName) {
- return mEvaluatedOverrides != null && mEvaluatedOverrides.containsKey(packageName);
+ return mEvaluatedOverrides.containsKey(packageName);
}
/**
@@ -298,20 +301,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
* @return true if there is such a deferred override
*/
private boolean hasRawOverride(String packageName) {
- return mRawOverrides != null && mRawOverrides.containsKey(packageName);
+ return mRawOverrides.containsKey(packageName);
}
- void loadOverrides(ChangeOverrides changeOverrides) {
- if (mRawOverrides == null) {
- mRawOverrides = new HashMap<>();
- }
+ void clearOverrides() {
mRawOverrides.clear();
-
- if (mEvaluatedOverrides == null) {
- mEvaluatedOverrides = new HashMap<>();
- }
mEvaluatedOverrides.clear();
+ }
+ void loadOverrides(ChangeOverrides changeOverrides) {
// Load deferred overrides for backwards compatibility
if (changeOverrides.getDeferred() != null) {
for (OverrideValue override : changeOverrides.getDeferred().getOverrideValue()) {
@@ -345,34 +343,30 @@ public final class CompatChange extends CompatibilityChangeInfo {
}
ChangeOverrides saveOverrides() {
- if (mRawOverrides == null || mRawOverrides.isEmpty()) {
+ if (mRawOverrides.isEmpty()) {
return null;
}
ChangeOverrides changeOverrides = new ChangeOverrides();
changeOverrides.setChangeId(getId());
ChangeOverrides.Raw rawOverrides = new ChangeOverrides.Raw();
List<RawOverrideValue> rawList = rawOverrides.getRawOverrideValue();
- if (mRawOverrides != null) {
- for (Map.Entry<String, PackageOverride> entry : mRawOverrides.entrySet()) {
- RawOverrideValue override = new RawOverrideValue();
- override.setPackageName(entry.getKey());
- override.setMinVersionCode(entry.getValue().getMinVersionCode());
- override.setMaxVersionCode(entry.getValue().getMaxVersionCode());
- override.setEnabled(entry.getValue().getEnabled());
- rawList.add(override);
- }
+ for (Map.Entry<String, PackageOverride> entry : mRawOverrides.entrySet()) {
+ RawOverrideValue override = new RawOverrideValue();
+ override.setPackageName(entry.getKey());
+ override.setMinVersionCode(entry.getValue().getMinVersionCode());
+ override.setMaxVersionCode(entry.getValue().getMaxVersionCode());
+ override.setEnabled(entry.getValue().getEnabled());
+ rawList.add(override);
}
changeOverrides.setRaw(rawOverrides);
ChangeOverrides.Validated validatedOverrides = new ChangeOverrides.Validated();
List<OverrideValue> validatedList = validatedOverrides.getOverrideValue();
- if (mEvaluatedOverrides != null) {
- for (Map.Entry<String, Boolean> entry : mEvaluatedOverrides.entrySet()) {
- OverrideValue override = new OverrideValue();
- override.setPackageName(entry.getKey());
- override.setEnabled(entry.getValue());
- validatedList.add(override);
- }
+ for (Map.Entry<String, Boolean> entry : mEvaluatedOverrides.entrySet()) {
+ OverrideValue override = new OverrideValue();
+ override.setPackageName(entry.getKey());
+ override.setEnabled(entry.getValue());
+ validatedList.add(override);
}
changeOverrides.setValidated(validatedOverrides);
return changeOverrides;
@@ -394,10 +388,10 @@ public final class CompatChange extends CompatibilityChangeInfo {
if (getLoggingOnly()) {
sb.append("; loggingOnly");
}
- if (mEvaluatedOverrides != null && mEvaluatedOverrides.size() > 0) {
+ if (!mEvaluatedOverrides.isEmpty()) {
sb.append("; packageOverrides=").append(mEvaluatedOverrides);
}
- if (mRawOverrides != null && mRawOverrides.size() > 0) {
+ if (!mRawOverrides.isEmpty()) {
sb.append("; rawOverrides=").append(mRawOverrides);
}
if (getOverridable()) {
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 66a652053857..ef86f42d6c3c 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -67,18 +67,21 @@ final class CompatConfig {
private static final String TAG = "CompatConfig";
private static final String APP_COMPAT_DATA_DIR = "/data/misc/appcompat";
+ private static final String STATIC_OVERRIDES_PRODUCT_DIR = "/product/etc/appcompat";
private static final String OVERRIDES_FILE = "compat_framework_overrides.xml";
@GuardedBy("mChanges")
private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>();
private final OverrideValidatorImpl mOverrideValidator;
+ private final AndroidBuildClassifier mAndroidBuildClassifier;
private Context mContext;
private File mOverridesFile;
@VisibleForTesting
CompatConfig(AndroidBuildClassifier androidBuildClassifier, Context context) {
mOverrideValidator = new OverrideValidatorImpl(androidBuildClassifier, context, this);
+ mAndroidBuildClassifier = androidBuildClassifier;
mContext = context;
}
@@ -94,8 +97,7 @@ final class CompatConfig {
config.initConfigFromLib(Environment.buildPath(
apex.apexDirectory, "etc", "compatconfig"));
}
- File overridesFile = new File(APP_COMPAT_DATA_DIR, OVERRIDES_FILE);
- config.initOverrides(overridesFile);
+ config.initOverrides();
config.invalidateCache();
return config;
}
@@ -133,7 +135,7 @@ final class CompatConfig {
synchronized (mChanges) {
for (int i = 0; i < mChanges.size(); ++i) {
CompatChange c = mChanges.valueAt(i);
- if (!c.isEnabled(app)) {
+ if (!c.isEnabled(app, mAndroidBuildClassifier)) {
disabled.add(c.getId());
}
}
@@ -175,7 +177,7 @@ final class CompatConfig {
// we know nothing about this change: default behaviour is enabled.
return true;
}
- return c.isEnabled(app);
+ return c.isEnabled(app, mAndroidBuildClassifier);
}
}
@@ -475,7 +477,7 @@ final class CompatConfig {
synchronized (mChanges) {
for (int i = 0; i < mChanges.size(); ++i) {
CompatChange c = mChanges.valueAt(i);
- if (c.isEnabled(applicationInfo)) {
+ if (c.isEnabled(applicationInfo, mAndroidBuildClassifier)) {
enabled.add(c.getId());
} else {
disabled.add(c.getId());
@@ -525,10 +527,34 @@ final class CompatConfig {
}
}
- void initOverrides(File overridesFile) {
+ private void initOverrides() {
+ initOverrides(new File(APP_COMPAT_DATA_DIR, OVERRIDES_FILE),
+ new File(STATIC_OVERRIDES_PRODUCT_DIR, OVERRIDES_FILE));
+ }
+
+ @VisibleForTesting
+ void initOverrides(File dynamicOverridesFile, File staticOverridesFile) {
+ // Clear overrides from all changes before loading.
+ synchronized (mChanges) {
+ for (int i = 0; i < mChanges.size(); ++i) {
+ mChanges.valueAt(i).clearOverrides();
+ }
+ }
+
+ loadOverrides(staticOverridesFile);
+
+ mOverridesFile = dynamicOverridesFile;
+ loadOverrides(dynamicOverridesFile);
+
+ if (staticOverridesFile.exists()) {
+ // Only save overrides if there is a static overrides file.
+ saveOverrides();
+ }
+ }
+
+ private void loadOverrides(File overridesFile) {
if (!overridesFile.exists()) {
- mOverridesFile = overridesFile;
- // There have not been any overrides added yet.
+ // Overrides file doesn't exist.
return;
}
@@ -548,7 +574,6 @@ final class CompatConfig {
Slog.w(TAG, "Error processing " + overridesFile + " " + e.toString());
return;
}
- mOverridesFile = overridesFile;
}
/**
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index fe5b4a98797d..aa66a1a8b01f 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -22,6 +22,7 @@ import static com.android.internal.compat.OverrideAllowedState.DISABLED_NON_TARG
import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE;
import static com.android.internal.compat.OverrideAllowedState.DISABLED_TARGET_SDK_TOO_HIGH;
import static com.android.internal.compat.OverrideAllowedState.LOGGING_ONLY_CHANGE;
+import static com.android.internal.compat.OverrideAllowedState.PLATFORM_TOO_OLD;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -85,6 +86,9 @@ public class OverrideValidatorImpl extends IOverrideValidator.Stub {
if (debuggableBuild) {
return new OverrideAllowedState(ALLOWED, -1, -1);
}
+ if (maxTargetSdk >= mAndroidBuildClassifier.platformTargetSdk()) {
+ return new OverrideAllowedState(PLATFORM_TOO_OLD, -1, maxTargetSdk);
+ }
PackageManager packageManager = mContext.getPackageManager();
if (packageManager == null) {
throw new IllegalStateException("No PackageManager!");
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index edfc8b8f31b0..40e386359a40 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -66,18 +66,22 @@ public class PlatformCompat extends IPlatformCompat.Stub {
private final Context mContext;
private final ChangeReporter mChangeReporter;
private final CompatConfig mCompatConfig;
+ private final AndroidBuildClassifier mBuildClassifier;
public PlatformCompat(Context context) {
mContext = context;
mChangeReporter = new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
- mCompatConfig = CompatConfig.create(new AndroidBuildClassifier(), mContext);
+ mBuildClassifier = new AndroidBuildClassifier();
+ mCompatConfig = CompatConfig.create(mBuildClassifier, mContext);
}
@VisibleForTesting
- PlatformCompat(Context context, CompatConfig compatConfig) {
+ PlatformCompat(Context context, CompatConfig compatConfig,
+ AndroidBuildClassifier buildClassifier) {
mContext = context;
mChangeReporter = new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
mCompatConfig = compatConfig;
+ mBuildClassifier = buildClassifier;
registerPackageReceiver(context);
}
@@ -392,7 +396,8 @@ public class PlatformCompat extends IPlatformCompat.Stub {
return false;
}
if (change.getEnableSinceTargetSdk() > 0) {
- return change.getEnableSinceTargetSdk() >= Build.VERSION_CODES.Q;
+ return change.getEnableSinceTargetSdk() >= Build.VERSION_CODES.Q
+ && change.getEnableSinceTargetSdk() <= mBuildClassifier.platformTargetSdk();
}
return true;
}
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 9411e33434d8..488677ac1b59 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -31,14 +31,17 @@ import static android.os.Process.SYSTEM_UID;
import static com.android.net.module.util.CollectionUtils.toIntArray;
import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManagerInternal;
import android.net.INetd;
import android.net.UidRange;
+import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -54,7 +57,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.net.module.util.CollectionUtils;
-import com.android.server.LocalServices;
import java.util.ArrayList;
import java.util.HashMap;
@@ -71,7 +73,7 @@ import java.util.Set;
*
* @hide
*/
-public class PermissionMonitor implements PackageManagerInternal.PackageListObserver {
+public class PermissionMonitor {
private static final String TAG = "PermissionMonitor";
private static final boolean DBG = true;
protected static final Boolean SYSTEM = Boolean.TRUE;
@@ -83,6 +85,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
private final SystemConfigManager mSystemConfigManager;
private final INetd mNetd;
private final Dependencies mDeps;
+ private final Context mContext;
@GuardedBy("this")
private final Set<UserHandle> mUsers = new HashSet<>();
@@ -102,6 +105,25 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
@GuardedBy("this")
private final Set<Integer> mAllApps = new HashSet<>();
+ private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ final Uri packageData = intent.getData();
+ final String packageName =
+ packageData != null ? packageData.getSchemeSpecificPart() : null;
+
+ if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+ onPackageAdded(packageName, uid);
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ onPackageRemoved(packageName, uid);
+ } else {
+ Log.wtf(TAG, "received unexpected intent: " + action);
+ }
+ }
+ };
+
/**
* Dependencies of PermissionMonitor, for injection in tests.
*/
@@ -127,6 +149,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
mSystemConfigManager = context.getSystemService(SystemConfigManager.class);
mNetd = netd;
mDeps = deps;
+ mContext = context;
}
// Intended to be called only once at startup, after the system is ready. Installs a broadcast
@@ -134,12 +157,14 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
public synchronized void startMonitoring() {
log("Monitoring");
- PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
- if (pmi != null) {
- pmi.getPackageList(this);
- } else {
- loge("failed to get the PackageManagerInternal service");
- }
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ intentFilter.addDataScheme("package");
+ mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */).registerReceiver(
+ mIntentReceiver, intentFilter, null /* broadcastPermission */,
+ null /* scheduler */);
+
List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS
| MATCH_ANY_USER);
if (apps == null) {
@@ -347,9 +372,10 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
*
* @hide
*/
- @Override
public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
- sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+ // TODO: Netd is using appId for checking traffic permission. Correct the methods that are
+ // using appId instead of uid actually
+ sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
// If multiple packages share a UID (cf: android:sharedUserId) and ask for different
// permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
@@ -384,9 +410,10 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
*
* @hide
*/
- @Override
public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
- sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+ // TODO: Netd is using appId for checking traffic permission. Correct the methods that are
+ // using appId instead of uid actually
+ sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
// If the newly-removed package falls within some VPN's uid range, update Netd with it.
// This needs to happen before the mApps update below, since removeBypassingUids() depends
@@ -432,19 +459,6 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
}
}
- /**
- * Called when a package is changed.
- *
- * @param packageName The name of the changed package.
- * @param uid The uid of the changed package.
- *
- * @hide
- */
- @Override
- public synchronized void onPackageChanged(@NonNull final String packageName, final int uid) {
- sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
- }
-
private static int getNetdPermissionMask(String[] requestedPermissions,
int[] requestedPermissionsFlags) {
int permissions = 0;
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
index f00edcc85404..fcd6b842426a 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
@@ -120,6 +120,11 @@ class CompatConfigBuilder {
return this;
}
+ CompatConfigBuilder addEnabledSinceApexChangeWithId(int sdk, long id) {
+ mChanges.add(new CompatChange(id, "", -1, sdk, false, false, "", false));
+ return this;
+ }
+
CompatConfig build() {
CompatConfig config = new CompatConfig(mBuildClassifier, mContext);
config.forceNonDebuggableFinalForTest(false);
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index 8b0e948579fb..bd774056aef8 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -86,6 +86,7 @@ public class CompatConfigTest {
// Assume userdebug/eng non-final build
when(mBuildClassifier.isDebuggableBuild()).thenReturn(true);
when(mBuildClassifier.isFinalBuild()).thenReturn(false);
+ when(mBuildClassifier.platformTargetSdk()).thenReturn(30);
ChangeIdStateCache.disable();
when(mPackageManager.getApplicationInfo(anyString(), anyInt()))
.thenThrow(new NameNotFoundException());
@@ -567,6 +568,34 @@ public class CompatConfigTest {
}
@Test
+ public void testReadApexConfig() throws IOException {
+ String configXml = "<config>"
+ + "<compat-change id=\"1234\" name=\"MY_CHANGE1\" enableAfterTargetSdk=\"2\" />"
+ + "<compat-change id=\"1235\" name=\"MY_CHANGE2\" disabled=\"true\" />"
+ + "<compat-change id=\"1236\" name=\"MY_CHANGE3\" />"
+ + "<compat-change id=\"1237\" name=\"MY_CHANGE4\" enableSinceTargetSdk=\"31\" />"
+ + "</config>";
+
+ File dir = createTempDir();
+ writeToFile(dir, "platform_compat_config.xml", configXml);
+ CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext);
+ compatConfig.forceNonDebuggableFinalForTest(false);
+
+ compatConfig.initConfigFromLib(dir);
+
+ assertThat(compatConfig.isChangeEnabled(1234L,
+ ApplicationInfoBuilder.create().withTargetSdk(1).build())).isFalse();
+ assertThat(compatConfig.isChangeEnabled(1234L,
+ ApplicationInfoBuilder.create().withTargetSdk(3).build())).isTrue();
+ assertThat(compatConfig.isChangeEnabled(1235L,
+ ApplicationInfoBuilder.create().withTargetSdk(5).build())).isFalse();
+ assertThat(compatConfig.isChangeEnabled(1236L,
+ ApplicationInfoBuilder.create().withTargetSdk(1).build())).isTrue();
+ assertThat(compatConfig.isChangeEnabled(1237L,
+ ApplicationInfoBuilder.create().withTargetSdk(31).build())).isTrue();
+ }
+
+ @Test
public void testReadConfigMultipleFiles() throws IOException {
String configXml1 = "<config>"
+ "<compat-change id=\"1234\" name=\"MY_CHANGE1\" enableAfterTargetSdk=\"2\" />"
@@ -602,12 +631,12 @@ public class CompatConfigTest {
.addEnableSinceSdkChangeWithId(2, 2L)
.build();
compatConfig.forceNonDebuggableFinalForTest(true);
- compatConfig.initOverrides(overridesFile);
+ compatConfig.initOverrides(overridesFile, new File(""));
when(mPackageManager.getApplicationInfo(eq("foo.bar"), anyInt()))
.thenReturn(ApplicationInfoBuilder.create()
- .withPackageName("foo.bar")
- .debuggable()
- .build());
+ .withPackageName("foo.bar")
+ .debuggable()
+ .build());
when(mPackageManager.getApplicationInfo(eq("bar.baz"), anyInt()))
.thenThrow(new NameNotFoundException());
@@ -649,7 +678,7 @@ public class CompatConfigTest {
.addEnableSinceSdkChangeWithId(2, 2L)
.build();
compatConfig.forceNonDebuggableFinalForTest(true);
- compatConfig.initOverrides(overridesFile);
+ compatConfig.initOverrides(overridesFile, new File(""));
compatConfig.addOverrides(new CompatibilityOverrideConfig(Collections.singletonMap(1L,
new PackageOverride.Builder()
@@ -673,11 +702,11 @@ public class CompatConfigTest {
}
@Test
- public void testLoadOverridesRaw() throws Exception {
+ public void testInitOverridesRaw() throws Exception {
File tempDir = createTempDir();
File overridesFile = new File(tempDir, "overrides.xml");
// Change 1 is enabled for foo.bar (validated)
- // Change 2 is disabled for bar.baz (deferred)
+ // Change 2 is disabled for bar.baz (raw)
String xmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<overrides>\n"
+ " <change-overrides changeId=\"1\">\n"
@@ -709,7 +738,7 @@ public class CompatConfigTest {
.addEnableSinceSdkChangeWithId(2, 2L)
.build();
compatConfig.forceNonDebuggableFinalForTest(true);
- compatConfig.initOverrides(overridesFile);
+ compatConfig.initOverrides(overridesFile, new File(""));
ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
.withPackageName("foo.bar")
.withVersionCode(100L)
@@ -728,7 +757,7 @@ public class CompatConfigTest {
}
@Test
- public void testLoadOverridesDeferred() throws Exception {
+ public void testInitOverridesDeferred() throws Exception {
File tempDir = createTempDir();
File overridesFile = new File(tempDir, "overrides.xml");
// Change 1 is enabled for foo.bar (validated)
@@ -754,7 +783,7 @@ public class CompatConfigTest {
.addEnableSinceSdkChangeWithId(2, 2L)
.build();
compatConfig.forceNonDebuggableFinalForTest(true);
- compatConfig.initOverrides(overridesFile);
+ compatConfig.initOverrides(overridesFile, new File(""));
ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
.withPackageName("foo.bar")
.debuggable()
@@ -767,4 +796,115 @@ public class CompatConfigTest {
assertThat(compatConfig.isChangeEnabled(1L, applicationInfo)).isTrue();
assertThat(compatConfig.willChangeBeEnabled(2L, "bar.baz")).isFalse();
}
+
+ @Test
+ public void testInitOverridesWithStaticFile() throws Exception {
+ File tempDir = createTempDir();
+ File dynamicOverridesFile = new File(tempDir, "dynamic_overrides.xml");
+ File staticOverridesFile = new File(tempDir, "static_overrides.xml");
+ // Change 1 is enabled for foo.bar (raw)
+ // Change 2 is disabled for bar.baz (raw)
+ String dynamicXmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<overrides>"
+ + "<change-overrides changeId=\"1\">"
+ + "<raw>"
+ + " <raw-override-value packageName=\"foo.bar\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + "</raw>"
+ + "</change-overrides>"
+ + "<change-overrides changeId=\"2\">"
+ + "<raw>"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"false\">\n"
+ + " </raw-override-value>\n"
+ + "</raw>"
+ + "</change-overrides>"
+ + "</overrides>";
+ writeToFile(tempDir, "dynamic_overrides.xml", dynamicXmlData);
+ // Change 2 is enabled for foo.bar and bar.baz (raw)
+ // Change 3 is enabled for bar.baz (raw)
+ String staticXmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<overrides>"
+ + "<change-overrides changeId=\"2\">"
+ + "<raw>"
+ + " <raw-override-value packageName=\"foo.bar\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + "</raw>"
+ + "</change-overrides>"
+ + "<change-overrides changeId=\"3\">"
+ + "<raw>"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + "</raw>"
+ + "</change-overrides>"
+ + "</overrides>";
+ writeToFile(tempDir, "static_overrides.xml", staticXmlData);
+ CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+ .addDisabledChangeWithId(1L)
+ .addDisabledChangeWithId(2L)
+ .addDisabledChangeWithId(3L)
+ .build();
+ compatConfig.forceNonDebuggableFinalForTest(true);
+ // Adding an override that will be cleared after initOverrides is called.
+ compatConfig.addOverride(1L, "bar.baz", true);
+ compatConfig.initOverrides(dynamicOverridesFile, staticOverridesFile);
+ when(mPackageManager.getApplicationInfo(eq("foo.bar"), anyInt()))
+ .thenThrow(new NameNotFoundException());
+ when(mPackageManager.getApplicationInfo(eq("bar.baz"), anyInt()))
+ .thenThrow(new NameNotFoundException());
+
+ assertThat(compatConfig.willChangeBeEnabled(1L, "foo.bar")).isTrue();
+ assertThat(compatConfig.willChangeBeEnabled(2L, "foo.bar")).isTrue();
+ assertThat(compatConfig.willChangeBeEnabled(2L, "bar.baz")).isFalse();
+ assertThat(compatConfig.willChangeBeEnabled(3L, "bar.baz")).isTrue();
+ assertThat(readFile(dynamicOverridesFile))
+ .isEqualTo("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ + "<overrides>\n"
+ + " <change-overrides changeId=\"1\">\n"
+ + " <validated>\n"
+ + " </validated>\n"
+ + " <raw>\n"
+ + " <raw-override-value packageName=\"foo.bar\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + " </raw>\n"
+ + " </change-overrides>\n"
+ + " <change-overrides changeId=\"2\">\n"
+ + " <validated>\n"
+ + " </validated>\n"
+ + " <raw>\n"
+ + " <raw-override-value packageName=\"foo.bar\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"false\">\n"
+ + " </raw-override-value>\n"
+ + " </raw>\n"
+ + " </change-overrides>\n"
+ + " <change-overrides changeId=\"3\">\n"
+ + " <validated>\n"
+ + " </validated>\n"
+ + " <raw>\n"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + " </raw>\n"
+ + " </change-overrides>\n"
+ + "</overrides>\n");
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
index 0fd6445fbeeb..57fdcd340a02 100644
--- a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
@@ -22,6 +22,7 @@ import static com.android.internal.compat.OverrideAllowedState.DISABLED_NON_TARG
import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE;
import static com.android.internal.compat.OverrideAllowedState.DISABLED_TARGET_SDK_TOO_HIGH;
import static com.android.internal.compat.OverrideAllowedState.LOGGING_ONLY_CHANGE;
+import static com.android.internal.compat.OverrideAllowedState.PLATFORM_TOO_OLD;
import static com.google.common.truth.Truth.assertThat;
@@ -52,6 +53,7 @@ public class OverrideValidatorImplTest {
private static final int TARGET_SDK = 10;
private static final int TARGET_SDK_BEFORE = 9;
private static final int TARGET_SDK_AFTER = 11;
+ private static final int PLATFORM_SDK_VERSION = 30;
@Mock
private PackageManager mPackageManager;
@@ -61,6 +63,7 @@ public class OverrideValidatorImplTest {
private AndroidBuildClassifier debuggableBuild() {
AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class);
when(buildClassifier.isDebuggableBuild()).thenReturn(true);
+ when(buildClassifier.platformTargetSdk()).thenReturn(PLATFORM_SDK_VERSION);
return buildClassifier;
}
@@ -68,6 +71,7 @@ public class OverrideValidatorImplTest {
AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class);
when(buildClassifier.isDebuggableBuild()).thenReturn(false);
when(buildClassifier.isFinalBuild()).thenReturn(false);
+ when(buildClassifier.platformTargetSdk()).thenReturn(PLATFORM_SDK_VERSION);
return buildClassifier;
}
@@ -75,6 +79,7 @@ public class OverrideValidatorImplTest {
AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class);
when(buildClassifier.isDebuggableBuild()).thenReturn(false);
when(buildClassifier.isFinalBuild()).thenReturn(true);
+ when(buildClassifier.platformTargetSdk()).thenReturn(PLATFORM_SDK_VERSION);
return buildClassifier;
}
@@ -333,6 +338,26 @@ public class OverrideValidatorImplTest {
}
@Test
+ public void getOverrideAllowedState_targetSdkChangeGreaterThanOsVersion_rejectOverride()
+ throws Exception {
+ final AndroidBuildClassifier buildClassifier = finalBuild();
+ CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext)
+ .addEnabledSinceApexChangeWithId(PLATFORM_SDK_VERSION + 1, 1).build();
+ IOverrideValidator overrideValidator = config.getOverrideValidator();
+ when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
+ .thenReturn(ApplicationInfoBuilder.create()
+ .withPackageName(PACKAGE_NAME)
+ .debuggable()
+ .build());
+
+ OverrideAllowedState stateTargetSdkLessChange =
+ overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME);
+ assertThat(stateTargetSdkLessChange).isEqualTo(
+ new OverrideAllowedState(PLATFORM_TOO_OLD, -1,
+ PLATFORM_SDK_VERSION));
+ }
+
+ @Test
public void getOverrideAllowedState_finalBuildEnabledChangeDebugApp_rejectOverride()
throws Exception {
CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext)
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index 799b06734b54..3fc6e9918382 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -78,11 +78,12 @@ public class PlatformCompatTest {
when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
.thenThrow(new PackageManager.NameNotFoundException());
mCompatConfig = new CompatConfig(mBuildClassifier, mContext);
- mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+ mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
// Assume userdebug/eng non-final build
mCompatConfig.forceNonDebuggableFinalForTest(false);
when(mBuildClassifier.isDebuggableBuild()).thenReturn(true);
when(mBuildClassifier.isFinalBuild()).thenReturn(false);
+ when(mBuildClassifier.platformTargetSdk()).thenReturn(30);
LocalServices.removeServiceForTest(PackageManagerInternal.class);
LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
}
@@ -99,7 +100,7 @@ public class PlatformCompatTest {
.addLoggingOnlyChangeWithId(7L)
.addOverridableChangeWithId(8L)
.build();
- mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+ mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
assertThat(mPlatformCompat.listAllChanges()).asList().containsExactly(
new CompatibilityChangeInfo(1L, "", -1, -1, false, false, "", false),
new CompatibilityChangeInfo(2L, "change2", -1, -1, true, false, "", false),
@@ -125,8 +126,9 @@ public class PlatformCompatTest {
.addEnableSinceSdkChangeWithId(Build.VERSION_CODES.Q, 5L)
.addEnableSinceSdkChangeWithId(Build.VERSION_CODES.R, 6L)
.addLoggingOnlyChangeWithId(7L)
+ .addEnableSinceSdkChangeWithId(31, 8L)
.build();
- mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+ mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
assertThat(mPlatformCompat.listUIChanges()).asList().containsExactly(
new CompatibilityChangeInfo(1L, "", -1, -1, false, false, "", false),
new CompatibilityChangeInfo(2L, "change2", -1, -1, true, false, "", false),
@@ -144,7 +146,7 @@ public class PlatformCompatTest {
.addEnableAfterSdkChangeWithId(Build.VERSION_CODES.O, 3L)
.build();
mCompatConfig.forceNonDebuggableFinalForTest(true);
- mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+ mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
// Before adding overrides.
assertThat(mPlatformCompat.isChangeEnabledByPackageName(1, PACKAGE_NAME, 0)).isTrue();
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 9c9670c99c2d..dc05488618cf 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -33,7 +33,11 @@ import android.os.RemoteException;
import android.service.carrier.CarrierService;
import android.telecom.TelecomManager;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.ImsSsData;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.feature.RcsFeature;
import com.android.internal.telephony.ICarrierConfigLoader;
import com.android.telephony.Rlog;
@@ -3941,6 +3945,43 @@ public class CarrierConfigManager {
KEY_PREFIX + "enable_presence_publish_bool";
/**
+ * Each string in this array contains a mapping between the service-id and version portion
+ * of the service-description element and the associated IMS feature tag(s) that are
+ * associated with each element (see RCC.07 Table 7).
+ * <p>
+ * Each string contains 3 parts, which define the mapping between service-description and
+ * feature tag(s) that must be present in the IMS REGISTER for the RCS service to be
+ * published as part of the RCS PUBLISH procedure:
+ * [service-id]|[version]|[desc]|[feature_tag];[feature_tag];...
+ * <ul>
+ * <li>[service-id]: the service-id element associated with the RCS capability.</li>
+ * <li>[version]: The version element associated with that service-id</li>
+ * <li>[desc]: The optional desecription element associated with that service-id</li>
+ * <li>[feature_tag];[feature_tag]: The list of all feature tags associated with this
+ * capability that MUST ALL be present in the IMS registration for this this
+ * capability to be published to the network.</li>
+ * </ul>
+ * <p>
+ * Features managed by the framework will be considered capable when the ImsService reports
+ * that those services are capable via the
+ * {@link MmTelFeature#notifyCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities)} or
+ * {@link RcsFeature#notifyCapabilitiesStatusChanged(RcsFeature.RcsImsCapabilities)} APIs.
+ * For RCS services not managed by the framework, the capability of these services are
+ * determined by looking at the feature tags associated with the IMS registration using the
+ * {@link ImsRegistrationAttributes} API and mapping them to the service-description map.
+ * <p>
+ * The framework contains a default value of this key, which is based off of RCC.07
+ * specification. Capabilities based of carrier extensions may be added to this list on a
+ * carrier-by-carrier basis as required in order to support additional services in the
+ * PUBLISH. If this list contains a service-id and version that overlaps with the default,
+ * it will override the framework default.
+ * @hide
+ */
+ @SystemApi
+ public static final String KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY =
+ KEY_PREFIX + "publish_service_desc_feature_tag_map_override_string_array";
+
+ /**
* Flag indicating whether or not this carrier supports the exchange of phone numbers with
* the carrier's RCS presence server in order to retrieve the RCS capabilities of requested
* contacts used in the RCS User Capability Exchange (UCE) procedure. See RCC.71, section 3
@@ -3999,6 +4040,8 @@ public class CarrierConfigManager {
defaults.putInt(KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT, 4000);
defaults.putBoolean(KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
defaults.putBoolean(KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
+ defaults.putStringArray(KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY,
+ new String[] {});
defaults.putBoolean(KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL, false);
defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false);
defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, true);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 23dcee6387b8..8244342eee19 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -14720,13 +14720,17 @@ public class TelephonyManager {
* </ul>
* @param appType icc application type, like {@link #APPTYPE_USIM} or {@link
* #APPTYPE_ISIM} or {@link#APPTYPE_UNKNOWN}
- * @param nafId Network Application Function(NAF) fully qualified domain name and
- * the selected GBA mode. It shall contain two parts delimited by "@" sign. The first
- * part is the constant string "3GPP-bootstrapping" (GBA_ME),
- * "3GPP-bootstrapping-uicc" (GBA_ U), or "3GPP-bootstrapping-digest" (GBA_Digest),
- * and the latter part shall be the FQDN of the NAF (e.g.
- * "3GPP-bootstrapping@naf1.operator.com" or "3GPP-bootstrapping-uicc@naf1.operator.com",
- * or "3GPP-bootstrapping-digest@naf1.operator.com").
+ * @param nafId A URI to specify Network Application Function(NAF) fully qualified domain
+ * name (FQDN) and the selected GBA mode. The authority of the URI must contain two parts
+ * delimited by "@" sign. The first part is the constant string "3GPP-bootstrapping" (GBA_ME),
+ * "3GPP-bootstrapping-uicc" (GBA_ U), or "3GPP-bootstrapping-digest" (GBA_Digest).
+ * The second part shall be the FQDN of the NAF. The scheme of the URI is not actually used
+ * for the authentication, which may be set the same as the resource that the application is
+ * going to access. For example, the nafId can be
+ * "https://3GPP-bootstrapping@naf1.operator.com",
+ * "https://3GPP-bootstrapping-uicc@naf1.operator.com",
+ * "https://3GPP-bootstrapping-digest@naf1.operator.com",
+ * "ftps://3GPP-bootstrapping-digest@naf1.operator.com".
* @param securityProtocol Security protocol identifier between UE and NAF.  See
* 3GPP TS 33.220 Annex H. Application can use
   * {@link UaSecurityProtocolIdentifier#createDefaultUaSpId},
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index aa9145b01be9..1e80ab7a405c 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -993,6 +993,16 @@ public class ProvisioningManager {
}
}
+ @Override
+ public void onPreProvisioningReceived(byte[] configXml) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mExecutor.execute(() -> mLocalCallback.onPreProvisioningReceived(configXml));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
private void setExecutor(Executor executor) {
mExecutor = executor;
}
@@ -1005,7 +1015,7 @@ public class ProvisioningManager {
* due to various triggers defined in GSMA RCC.14 for ACS(auto configuration
* server) or other operator defined triggers. If RCS provisioning is already
* completed at the time of callback registration, then this method shall be
- * invoked with the current configuration
+ * invoked with the current configuration.
* @param configXml The RCS configuration XML received by OTA. It is defined
* by GSMA RCC.07.
*/
@@ -1038,6 +1048,20 @@ public class ProvisioningManager {
*/
public void onRemoved() {}
+ /**
+ * Some carriers using ACS (auto configuration server) may send a carrier-specific
+ * pre-provisioning configuration XML if the user has not been provisioned for RCS
+ * services yet. When this provisioning XML is received, the framework will move
+ * into a "not provisioned" state for RCS. In order for provisioning to proceed,
+ * the application must parse this configuration XML and perform the carrier specific
+ * opt-in flow for RCS services. If the user accepts, {@link #triggerRcsReconfiguration}
+ * must be called in order for the device to move out of this state and try to fetch
+ * the RCS provisioning information.
+ *
+ * @param configXml the pre-provisioning config in carrier specified format.
+ */
+ public void onPreProvisioningReceived(@NonNull byte[] configXml) {}
+
/**@hide*/
public final IRcsConfigCallback getBinder() {
return mBinder;
diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
index fa3024f89cde..9c28c36521f5 100644
--- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
+++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.net.Uri;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -45,6 +46,15 @@ public final class RcsContactPresenceTuple implements Parcelable {
private static final String LOG_TAG = "RcsContactPresenceTuple";
/**
+ * The service ID used to indicate that service discovery via presence is available.
+ * <p>
+ * See RCC.07 v5.0 specification for more information.
+ * @hide
+ */
+ public static final String SERVICE_ID_PRESENCE =
+ "org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcse.dp";
+
+ /**
* The service ID used to indicate that MMTEL service is available.
* <p>
* See the GSMA RCC.07 specification for more information.
@@ -335,6 +345,13 @@ public final class RcsContactPresenceTuple implements Parcelable {
public @NonNull @DuplexMode List<String> getUnsupportedDuplexModes() {
return Collections.unmodifiableList(mUnsupportedDuplexModeList);
}
+
+ @Override
+ public String toString() {
+ return "servCaps{" + "a=" + mIsAudioCapable + ", v=" + mIsVideoCapable
+ + ", supported=" + mSupportedDuplexModeList + ", unsupported="
+ + mUnsupportedDuplexModeList + '}';
+ }
}
/**
@@ -514,4 +531,36 @@ public final class RcsContactPresenceTuple implements Parcelable {
public @Nullable ServiceCapabilities getServiceCapabilities() {
return mServiceCapabilities;
}
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder("{");
+ if (Build.IS_ENG) {
+ builder.append("u=");
+ builder.append(mContactUri);
+ } else {
+ builder.append("u=");
+ builder.append(mContactUri != null ? "XXX" : "null");
+ }
+ builder.append(", id=");
+ builder.append(mServiceId);
+ builder.append(", v=");
+ builder.append(mServiceVersion);
+ builder.append(", s=");
+ builder.append(mStatus);
+ if (mTimestamp != null) {
+ builder.append(", timestamp=");
+ builder.append(mTimestamp);
+ }
+ if (mServiceDescription != null) {
+ builder.append(", servDesc=");
+ builder.append(mServiceDescription);
+ }
+ if (mServiceCapabilities != null) {
+ builder.append(", servCaps=");
+ builder.append(mServiceCapabilities);
+ }
+ builder.append("}");
+ return builder.toString();
+ }
}
diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
index b28dc27e06e0..52d0f036788c 100644
--- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java
+++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.Uri;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -345,4 +346,39 @@ public final class RcsContactUceCapability implements Parcelable {
public @NonNull Uri getContactUri() {
return mContactUri;
}
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder("RcsContactUceCapability");
+ if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) {
+ builder.append("(presence) {");
+ } else if (mCapabilityMechanism == CAPABILITY_MECHANISM_OPTIONS) {
+ builder.append("(options) {");
+ } else {
+ builder.append("(?) {");
+ }
+ if (Build.IS_ENG) {
+ builder.append("uri=");
+ builder.append(mContactUri);
+ } else {
+ builder.append("uri (isNull)=");
+ builder.append(mContactUri != null ? "XXX" : "null");
+ }
+ builder.append(", sourceType=");
+ builder.append(mSourceType);
+ builder.append(", requestResult=");
+ builder.append(mRequestResult);
+
+ if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) {
+ builder.append(", presenceTuples={");
+ builder.append(mPresenceTuples);
+ builder.append("}");
+ } else if (mCapabilityMechanism == CAPABILITY_MECHANISM_OPTIONS) {
+ builder.append(", featureTags={");
+ builder.append(mFeatureTags);
+ builder.append("}");
+ }
+
+ return builder.toString();
+ }
}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl
index 5a8973e37bce..d0853d1846ac 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl
@@ -25,5 +25,6 @@ oneway interface IRcsConfigCallback {
void onAutoConfigurationErrorReceived(int errorCode, String errorString);
void onConfigurationReset();
void onRemoved();
+ void onPreProvisioningReceived(in byte[] config);
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index 34984e05e181..4dcb7f59f4a7 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -542,11 +542,34 @@ public class ImsConfigImplBase {
}
mRcsCallbacks.broadcastAction(c -> {
try {
- //TODO compressed by default?
c.onAutoConfigurationErrorReceived(errorCode, errorString);
} catch (RemoteException e) {
Log.w(TAG, "dead binder in notifyAutoConfigurationErrorReceived, skipping.");
}
});
}
+
+ /**
+ * Notifies application that pre-provisioning config is received.
+ *
+ * <p>Some carriers using ACS (auto configuration server) may send a carrier-specific
+ * pre-provisioning configuration XML if the user has not been provisioned for RCS
+ * services yet. When such provisioning XML is received, ACS client must call this
+ * method to notify the application with the XML.
+ *
+ * @param configXml the pre-provisioning config in carrier specified format.
+ */
+ public final void notifyPreProvisioningReceived(@NonNull byte[] configXml) {
+ // can be null in testing
+ if (mRcsCallbacks == null) {
+ return;
+ }
+ mRcsCallbacks.broadcastAction(c -> {
+ try {
+ c.onPreProvisioningReceived(configXml);
+ } catch (RemoteException e) {
+ Log.w(TAG, "dead binder in notifyPreProvisioningReceived, skipping.");
+ }
+ });
+ }
}
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index e84b992a1379..0dfec7592274 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -28,6 +28,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
@@ -44,6 +45,10 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
import static android.os.Process.INVALID_UID;
+import static com.android.modules.utils.build.SdkLevel.isAtLeastR;
+import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
+import static com.android.testutils.MiscAsserts.assertEmpty;
+import static com.android.testutils.MiscAsserts.assertThrows;
import static com.android.testutils.ParcelUtils.assertParcelSane;
import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
@@ -67,7 +72,6 @@ import android.util.ArraySet;
import androidx.test.runner.AndroidJUnit4;
-import com.android.modules.utils.build.SdkLevel;
import com.android.testutils.CompatUtil;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -85,6 +89,9 @@ import java.util.Set;
public class NetworkCapabilitiesTest {
private static final String TEST_SSID = "TEST_SSID";
private static final String DIFFERENT_TEST_SSID = "DIFFERENT_TEST_SSID";
+ private static final int TEST_SUBID1 = 1;
+ private static final int TEST_SUBID2 = 2;
+ private static final int TEST_SUBID3 = 3;
@Rule
public DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule();
@@ -92,14 +99,6 @@ public class NetworkCapabilitiesTest {
private DiscoverySession mDiscoverySession = Mockito.mock(DiscoverySession.class);
private PeerHandle mPeerHandle = Mockito.mock(PeerHandle.class);
- private boolean isAtLeastR() {
- return SdkLevel.isAtLeastR();
- }
-
- private boolean isAtLeastS() {
- return SdkLevel.isAtLeastS();
- }
-
@Test
public void testMaybeMarkCapabilitiesRestricted() {
// verify EIMS is restricted
@@ -305,7 +304,9 @@ public class NetworkCapabilitiesTest {
.setUids(uids)
.addCapability(NET_CAPABILITY_EIMS)
.addCapability(NET_CAPABILITY_NOT_METERED);
- if (isAtLeastR()) {
+ if (isAtLeastS()) {
+ netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
+ } else if (isAtLeastR()) {
netCap.setOwnerUid(123);
netCap.setAdministratorUids(new int[] {5, 11});
}
@@ -380,7 +381,7 @@ public class NetworkCapabilitiesTest {
private void testParcelSane(NetworkCapabilities cap) {
if (isAtLeastS()) {
- assertParcelSane(cap, 16);
+ assertParcelSane(cap, 17);
} else if (isAtLeastR()) {
assertParcelSane(cap, 15);
} else {
@@ -614,6 +615,20 @@ public class NetworkCapabilitiesTest {
assertFalse(nc2.appliesToUid(12));
assertTrue(nc1.appliesToUid(22));
assertTrue(nc2.appliesToUid(22));
+
+ // Verify the subscription id list can be combined only when they are equal.
+ if (isAtLeastS()) {
+ nc1.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
+ nc2.setSubIds(Set.of(TEST_SUBID2));
+ assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
+
+ nc2.setSubIds(Set.of());
+ assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
+
+ nc2.setSubIds(Set.of(TEST_SUBID2, TEST_SUBID1));
+ nc2.combineCapabilities(nc1);
+ assertEquals(Set.of(TEST_SUBID2, TEST_SUBID1), nc2.getSubIds());
+ }
}
@Test @IgnoreUpTo(Build.VERSION_CODES.Q)
@@ -762,6 +777,24 @@ public class NetworkCapabilitiesTest {
nc1.setUids(uidRange(10, 13));
nc2.set(nc1); // Overwrites, as opposed to combineCapabilities
assertEquals(nc1, nc2);
+
+ if (isAtLeastS()) {
+ assertThrows(NullPointerException.class, () -> nc1.setSubIds(null));
+ nc1.setSubIds(Set.of());
+ nc2.set(nc1);
+ assertEquals(nc1, nc2);
+
+ nc1.setSubIds(Set.of(TEST_SUBID1));
+ nc2.set(nc1);
+ assertEquals(nc1, nc2);
+
+ nc2.setSubIds(Set.of(TEST_SUBID2, TEST_SUBID1));
+ nc2.set(nc1);
+ assertEquals(nc1, nc2);
+
+ nc2.setSubIds(Set.of(TEST_SUBID3, TEST_SUBID2));
+ assertNotEquals(nc1, nc2);
+ }
}
@Test
@@ -842,6 +875,50 @@ public class NetworkCapabilitiesTest {
} catch (NullPointerException expected) { }
}
+ private static NetworkCapabilities capsWithSubIds(Integer ... subIds) {
+ // Since the NetworkRequest would put NOT_VCN_MANAGED capabilities in general, for
+ // every NetworkCapabilities that simulates networks needs to add it too in order to
+ // satisfy these requests.
+ final NetworkCapabilities nc = new NetworkCapabilities.Builder()
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ .setSubIds(new ArraySet<>(subIds)).build();
+ assertEquals(new ArraySet<>(subIds), nc.getSubIds());
+ return nc;
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testSubIds() throws Exception {
+ final NetworkCapabilities ncWithoutId = capsWithSubIds();
+ final NetworkCapabilities ncWithId = capsWithSubIds(TEST_SUBID1);
+ final NetworkCapabilities ncWithOtherIds = capsWithSubIds(TEST_SUBID1, TEST_SUBID3);
+ final NetworkCapabilities ncWithoutRequestedIds = capsWithSubIds(TEST_SUBID3);
+
+ final NetworkRequest requestWithoutId = new NetworkRequest.Builder().build();
+ assertEmpty(requestWithoutId.networkCapabilities.getSubIds());
+ final NetworkRequest requestWithIds = new NetworkRequest.Builder()
+ .setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2)).build();
+ assertEquals(Set.of(TEST_SUBID1, TEST_SUBID2),
+ requestWithIds.networkCapabilities.getSubIds());
+
+ assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutId));
+ assertTrue(requestWithIds.canBeSatisfiedBy(ncWithOtherIds));
+ assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutRequestedIds));
+ assertTrue(requestWithIds.canBeSatisfiedBy(ncWithId));
+ assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithoutId));
+ assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithId));
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testEqualsSubIds() throws Exception {
+ assertEquals(capsWithSubIds(), capsWithSubIds());
+ assertNotEquals(capsWithSubIds(), capsWithSubIds(TEST_SUBID1));
+ assertEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID1));
+ assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2));
+ assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2, TEST_SUBID1));
+ assertEquals(capsWithSubIds(TEST_SUBID1, TEST_SUBID2),
+ capsWithSubIds(TEST_SUBID2, TEST_SUBID1));
+ }
+
@Test
public void testLinkBandwidthKbps() {
final NetworkCapabilities nc = new NetworkCapabilities();
@@ -1022,5 +1099,11 @@ public class NetworkCapabilitiesTest {
fail("Should not set null into NetworkCapabilities.Builder");
} catch (NullPointerException expected) { }
assertEquals(nc, new NetworkCapabilities.Builder(nc).build());
+
+ if (isAtLeastS()) {
+ final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
+ .setSubIds(Set.of(TEST_SUBID1)).build();
+ assertEquals(Set.of(TEST_SUBID1), nc2.getSubIds());
+ }
}
}
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 098b029b75e6..6fc605e269fe 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -220,7 +220,7 @@ public class ConnectivityManagerTest {
// register callback
when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
- any(), nullable(String.class))).thenReturn(request);
+ anyInt(), any(), nullable(String.class))).thenReturn(request);
manager.requestNetwork(request, callback, handler);
// callback triggers
@@ -248,7 +248,7 @@ public class ConnectivityManagerTest {
// register callback
when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
- any(), nullable(String.class))).thenReturn(req1);
+ anyInt(), any(), nullable(String.class))).thenReturn(req1);
manager.requestNetwork(req1, callback, handler);
// callback triggers
@@ -266,7 +266,7 @@ public class ConnectivityManagerTest {
// callback can be registered again
when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
- any(), nullable(String.class))).thenReturn(req2);
+ anyInt(), any(), nullable(String.class))).thenReturn(req2);
manager.requestNetwork(req2, callback, handler);
// callback triggers
@@ -289,8 +289,8 @@ public class ConnectivityManagerTest {
info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
when(mCtx.getApplicationInfo()).thenReturn(info);
- when(mService.requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(), any(),
- nullable(String.class))).thenReturn(request);
+ when(mService.requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(), anyInt(),
+ any(), nullable(String.class))).thenReturn(request);
Handler handler = new Handler(Looper.getMainLooper());
manager.requestNetwork(request, callback, handler);
@@ -358,34 +358,34 @@ public class ConnectivityManagerTest {
manager.requestNetwork(request, callback);
verify(mService).requestNetwork(eq(request.networkCapabilities),
- eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
// Verify that register network callback does not calls requestNetwork at all.
manager.registerNetworkCallback(request, callback);
- verify(mService, never()).requestNetwork(any(), anyInt(), any(), anyInt(), any(),
+ verify(mService, never()).requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(),
anyInt(), any(), any());
- verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(),
+ verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
manager.registerDefaultNetworkCallback(callback);
verify(mService).requestNetwork(eq(null),
- eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
manager.requestBackgroundNetwork(request, handler, callback);
verify(mService).requestNetwork(eq(request.networkCapabilities),
- eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
manager.registerSystemDefaultNetworkCallback(callback, handler);
verify(mService).requestNetwork(eq(null),
- eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index a6b20fb73e25..2c8c8a6409ea 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1454,6 +1454,8 @@ public class ConnectivityServiceTest {
applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
.thenReturn(applicationInfo);
+ when(mPackageManager.getTargetSdkVersion(anyString()))
+ .thenReturn(applicationInfo.targetSdkVersion);
when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
// InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
@@ -3749,8 +3751,8 @@ public class ConnectivityServiceTest {
networkCapabilities.addTransportType(TRANSPORT_WIFI)
.setNetworkSpecifier(new MatchAllNetworkSpecifier());
mService.requestNetwork(networkCapabilities, NetworkRequest.Type.REQUEST.ordinal(),
- null, 0, null, ConnectivityManager.TYPE_WIFI, mContext.getPackageName(),
- getAttributionTag());
+ null, 0, null, ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE,
+ mContext.getPackageName(), getAttributionTag());
});
class NonParcelableSpecifier extends NetworkSpecifier {
@@ -8756,6 +8758,7 @@ public class ConnectivityServiceTest {
applicationInfo.targetSdkVersion = targetSdk;
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
.thenReturn(applicationInfo);
+ when(mPackageManager.getTargetSdkVersion(any())).thenReturn(targetSdk);
when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(locationToggle);
@@ -8770,102 +8773,183 @@ public class ConnectivityServiceTest {
}
}
- private int getOwnerUidNetCapsForCallerPermission(int ownerUid, int callerUid) {
+ private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid,
+ boolean includeLocationSensitiveInfo) {
final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid);
return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- netCap, callerUid, mContext.getPackageName(), getAttributionTag()).getOwnerUid();
+ netCap, includeLocationSensitiveInfo, callerUid,
+ mContext.getPackageName(), getAttributionTag())
+ .getOwnerUid();
}
- private void verifyWifiInfoCopyNetCapsForCallerPermission(
- int callerUid, boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
+ private void verifyWifiInfoCopyNetCapsPermission(
+ int callerUid, boolean includeLocationSensitiveInfo,
+ boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
final WifiInfo wifiInfo = mock(WifiInfo.class);
when(wifiInfo.hasLocationSensitiveFields()).thenReturn(true);
final NetworkCapabilities netCap = new NetworkCapabilities().setTransportInfo(wifiInfo);
mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- netCap, callerUid, mContext.getPackageName(), getAttributionTag());
+ netCap, includeLocationSensitiveInfo, callerUid,
+ mContext.getPackageName(), getAttributionTag());
verify(wifiInfo).makeCopy(eq(shouldMakeCopyWithLocationSensitiveFieldsParcelable));
}
+ private void verifyOwnerUidAndWifiInfoNetCapsPermission(
+ boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag,
+ boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag,
+ boolean shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag,
+ boolean shouldInclLocationSensitiveWifiInfoWithIncludeFlag) {
+ final int myUid = Process.myUid();
+
+ final int expectedOwnerUidWithoutIncludeFlag =
+ shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag
+ ? Process.myUid() : INVALID_UID;
+ assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission(
+ myUid, myUid, false /* includeLocationSensitiveInfo */));
+
+ final int expectedOwnerUidWithIncludeFlag =
+ shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID;
+ assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission(
+ myUid, myUid, true /* includeLocationSensitiveInfo */));
+
+ verifyWifiInfoCopyNetCapsPermission(myUid,
+ false, /* includeLocationSensitiveInfo */
+ shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag);
+
+ verifyWifiInfoCopyNetCapsPermission(myUid,
+ true, /* includeLocationSensitiveInfo */
+ shouldInclLocationSensitiveWifiInfoWithIncludeFlag);
+
+ }
+
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWithFineLocationAfterQ()
+ public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQ()
throws Exception {
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
- final int myUid = Process.myUid();
- assertEquals(myUid, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ // Ensure that we include owner uid even if the request asks to remove it since the
+ // app has necessary permissions and targetSdk < S.
+ true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ // Ensure that we remove location info if the request asks to remove it even if the
+ // app has necessary permissions.
+ true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
+ }
+
+ @Test
+ public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag()
+ throws Exception {
+ setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION);
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ // Ensure that we include owner uid even if the request asks to remove it since the
+ // app has necessary permissions and targetSdk < S.
+ true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ // Ensure that we remove location info if the request asks to remove it even if the
+ // app has necessary permissions.
+ true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWithCoarseLocationPreQ()
+ public void
+ testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag()
+ throws Exception {
+ setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ // Ensure that we owner UID if the request asks us to remove it even if the app
+ // has necessary permissions since targetSdk >= S.
+ false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ // Ensure that we remove location info if the request asks to remove it even if the
+ // app has necessary permissions.
+ true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
+ }
+
+ @Test
+ public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ()
throws Exception {
setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION);
- final int myUid = Process.myUid();
- assertEquals(myUid, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ // Ensure that we owner UID if the request asks us to remove it even if the app
+ // has necessary permissions since targetSdk >= S.
+ true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ // Ensure that we remove location info if the request asks to remove it even if the
+ // app has necessary permissions.
+ true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedLocationOff() throws Exception {
+ public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception {
// Test that even with fine location permission, and UIDs matching, the UID is sanitized.
setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
- final int myUid = Process.myUid();
- assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWrongUid() throws Exception {
+ public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception {
// Test that even with fine location permission, not being the owner leads to sanitization.
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
final int myUid = Process.myUid();
- assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid + 1, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ assertEquals(Process.INVALID_UID,
+ getOwnerUidNetCapsPermission(myUid + 1, myUid,
+ true /* includeLocationSensitiveInfo */));
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWithCoarseLocationAfterQ()
+ public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ()
throws Exception {
// Test that not having fine location permission leads to sanitization.
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION);
- // Test that without the location permission, the owner field is sanitized.
- final int myUid = Process.myUid();
- assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWithoutLocationPermission()
+ public void testCreateWithLocationInfoSanitizedWithoutLocationPermission()
throws Exception {
+ // Test that not having fine location permission leads to sanitization.
setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */);
- // Test that without the location permission, the owner field is sanitized.
- final int myUid = Process.myUid();
- assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
@@ -9456,8 +9540,8 @@ public class ConnectivityServiceTest {
assertThrows("Expect throws for invalid request type " + reqTypeInt,
IllegalArgumentException.class,
() -> mService.requestNetwork(nc, reqTypeInt, null, 0, null,
- ConnectivityManager.TYPE_NONE, mContext.getPackageName(),
- getAttributionTag())
+ ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE,
+ mContext.getPackageName(), getAttributionTag())
);
}
}
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index f97eabf6366d..6232423b4f9e 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -35,6 +35,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.IpSecAlgorithm;
import android.net.IpSecConfig;
@@ -47,6 +48,7 @@ import android.os.Process;
import android.system.ErrnoException;
import android.system.Os;
import android.system.StructStat;
+import android.util.Range;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -647,9 +649,9 @@ public class IpSecServiceTest {
@Test
public void testReserveNetId() {
- int start = mIpSecService.TUN_INTF_NETID_START;
- for (int i = 0; i < mIpSecService.TUN_INTF_NETID_RANGE; i++) {
- assertEquals(start + i, mIpSecService.reserveNetId());
+ final Range<Integer> netIdRange = ConnectivityManager.getIpSecNetIdRange();
+ for (int netId = netIdRange.getLower(); netId <= netIdRange.getUpper(); netId++) {
+ assertEquals(netId, mIpSecService.reserveNetId());
}
// Check that resource exhaustion triggers an exception
@@ -661,7 +663,7 @@ public class IpSecServiceTest {
// Now release one and try again
int releasedNetId =
- mIpSecService.TUN_INTF_NETID_START + mIpSecService.TUN_INTF_NETID_RANGE / 2;
+ netIdRange.getLower() + (netIdRange.getUpper() - netIdRange.getLower()) / 2;
mIpSecService.releaseNetId(releasedNetId);
assertEquals(releasedNetId, mIpSecService.reserveNetId());
}
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index e4e24b464838..fec5ef39374a 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -48,18 +48,22 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.net.INetd;
import android.net.UidRange;
+import android.net.Uri;
import android.os.Build;
import android.os.SystemConfigManager;
import android.os.UserHandle;
@@ -70,12 +74,11 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.server.LocalServices;
-import com.android.server.pm.PackageList;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.AdditionalAnswers;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
@@ -112,7 +115,6 @@ public class PermissionMonitorTest {
@Mock private Context mContext;
@Mock private PackageManager mPackageManager;
@Mock private INetd mNetdService;
- @Mock private PackageManagerInternal mMockPmi;
@Mock private UserManager mUserManager;
@Mock private PermissionMonitor.Dependencies mDeps;
@Mock private SystemConfigManager mSystemConfigManager;
@@ -131,16 +133,14 @@ public class PermissionMonitorTest {
when(mContext.getSystemService(Context.SYSTEM_CONFIG_SERVICE))
.thenReturn(mSystemConfigManager);
when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
+ final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext));
+ doReturn(UserHandle.ALL).when(asUserCtx).getUser();
+ when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx);
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
- LocalServices.removeServiceForTest(PackageManagerInternal.class);
- LocalServices.addService(PackageManagerInternal.class, mMockPmi);
- when(mMockPmi.getPackageList(any())).thenReturn(new PackageList(new ArrayList<String>(),
- /* observer */ null));
when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null);
mPermissionMonitor.startMonitoring();
- verify(mMockPmi).getPackageList(mPermissionMonitor);
}
private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
@@ -770,4 +770,32 @@ public class PermissionMonitorTest {
INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
new int[]{ MOCK_UID2 });
}
+
+ @Test
+ public void testIntentReceiver() throws Exception {
+ final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(), any(), any(), any());
+ final BroadcastReceiver receiver = receiverCaptor.getValue();
+
+ // Verify receiving PACKAGE_ADDED intent.
+ final Intent addedIntent = new Intent(Intent.ACTION_PACKAGE_ADDED,
+ Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
+ addedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1);
+ setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1,
+ new String[] { INTERNET, UPDATE_DEVICE_STATS });
+ receiver.onReceive(mContext, addedIntent);
+ mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[] { MOCK_UID1 });
+
+ // Verify receiving PACKAGE_REMOVED intent.
+ when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(null);
+ final Intent removedIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED,
+ Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
+ removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1);
+ receiver.onReceive(mContext, removedIntent);
+ mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[] { MOCK_UID1 });
+ }
+
}
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 11498dec8165..a02002752c38 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -593,6 +593,16 @@ public class VcnManagementServiceTest {
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
}
+ @Test(expected = SecurityException.class)
+ public void testRemoveVcnUnderlyingNetworkPolicyListenerInvalidPermission() {
+ doThrow(new SecurityException())
+ .when(mMockContext)
+ .enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.NETWORK_FACTORY), any());
+
+ mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+ }
+
@Test
public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() {
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);