Merge "Use static utils from f/l/n instead of the networkstack"
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 4e46aa3..9564dde 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -41,6 +41,10 @@
private IActivityManager mAm;
private IPackageManager mPm;
+ Am() {
+ svcInit();
+ }
+
/**
* Command-line entry point.
*
@@ -50,6 +54,20 @@
(new Am()).run(args);
}
+ private void svcInit() {
+ mAm = ActivityManager.getService();
+ if (mAm == null) {
+ System.err.println(NO_SYSTEM_ERROR_CODE);
+ return;
+ }
+
+ mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+ if (mPm == null) {
+ System.err.println(NO_SYSTEM_ERROR_CODE);
+ return;
+ }
+ }
+
@Override
public void onShowUsage(PrintStream out) {
try {
@@ -61,19 +79,6 @@
@Override
public void onRun() throws Exception {
-
- mAm = ActivityManager.getService();
- if (mAm == null) {
- System.err.println(NO_SYSTEM_ERROR_CODE);
- throw new AndroidException("Can't connect to activity manager; is the system running?");
- }
-
- mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
- if (mPm == null) {
- System.err.println(NO_SYSTEM_ERROR_CODE);
- throw new AndroidException("Can't connect to package manager; is the system running?");
- }
-
String op = nextArgRequired();
if (op.equals("instrument")) {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index db3cedd..ea86c0f 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -475,6 +475,8 @@
field public static final String OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = "android:auto_revoke_permissions_if_unused";
field public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = "android:bind_accessibility_service";
field public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
+ field public static final String OPSTR_ESTABLISH_VPN_MANAGER = "android:establish_vpn_manager";
+ field public static final String OPSTR_ESTABLISH_VPN_SERVICE = "android:establish_vpn_service";
field public static final String OPSTR_GET_ACCOUNTS = "android:get_accounts";
field public static final String OPSTR_GPS = "android:gps";
field public static final String OPSTR_INSTANT_APP_START_FOREGROUND = "android:instant_app_start_foreground";
@@ -9149,6 +9151,7 @@
field public static final String NAMESPACE_BIOMETRICS = "biometrics";
field public static final String NAMESPACE_BLOBSTORE = "blobstore";
field public static final String NAMESPACE_BLUETOOTH = "bluetooth";
+ field public static final String NAMESPACE_CAPTIVEPORTALLOGIN = "captive_portal_login";
field public static final String NAMESPACE_CLIPBOARD = "clipboard";
field public static final String NAMESPACE_CONNECTIVITY = "connectivity";
field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 0b336f6..63f700b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1313,9 +1313,23 @@
public static final int OP_RECORD_INCOMING_PHONE_AUDIO =
AppProtoEnums.APP_OP_RECORD_INCOMING_PHONE_AUDIO;
+ /**
+ * VPN app establishes a connection through the VpnService API.
+ *
+ * @hide
+ */
+ public static final int OP_ESTABLISH_VPN_SERVICE = AppProtoEnums.APP_OP_ESTABLISH_VPN_SERVICE;
+
+ /**
+ * VPN app establishes a connection through the VpnManager API.
+ *
+ * @hide
+ */
+ public static final int OP_ESTABLISH_VPN_MANAGER = AppProtoEnums.APP_OP_ESTABLISH_VPN_MANAGER;
+
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int _NUM_OP = 117;
+ public static final int _NUM_OP = 119;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1754,6 +1768,22 @@
public static final String OPSTR_RECORD_INCOMING_PHONE_AUDIO =
"android:record_incoming_phone_audio";
+ /**
+ * VPN app establishes a connection through the VpnService API.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String OPSTR_ESTABLISH_VPN_SERVICE = "android:establish_vpn_service";
+
+ /**
+ * VPN app establishes a connection through the VpnManager API.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String OPSTR_ESTABLISH_VPN_MANAGER = "android:establish_vpn_manager";
+
/** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -1970,6 +2000,8 @@
OP_BLUETOOTH_ADVERTISE, // OP_BLUETOOTH_ADVERTISE
OP_RECORD_INCOMING_PHONE_AUDIO, // OP_RECORD_INCOMING_PHONE_AUDIO
OP_NEARBY_WIFI_DEVICES, // OP_NEARBY_WIFI_DEVICES
+ OP_ESTABLISH_VPN_SERVICE, // OP_ESTABLISH_VPN_SERVICE
+ OP_ESTABLISH_VPN_MANAGER, // OP_ESTABLISH_VPN_MANAGER
};
/**
@@ -2093,6 +2125,8 @@
OPSTR_BLUETOOTH_ADVERTISE,
OPSTR_RECORD_INCOMING_PHONE_AUDIO,
OPSTR_NEARBY_WIFI_DEVICES,
+ OPSTR_ESTABLISH_VPN_SERVICE,
+ OPSTR_ESTABLISH_VPN_MANAGER,
};
/**
@@ -2216,7 +2250,9 @@
"ACTIVITY_RECOGNITION_SOURCE",
"BLUETOOTH_ADVERTISE",
"RECORD_INCOMING_PHONE_AUDIO",
- "NEARBY_WIFI_DEVICES"
+ "NEARBY_WIFI_DEVICES",
+ "ESTABLISH_VPN_SERVICE",
+ "ESTABLISH_VPN_MANAGER",
};
/**
@@ -2342,6 +2378,8 @@
Manifest.permission.BLUETOOTH_ADVERTISE,
null, // no permission for OP_RECORD_INCOMING_PHONE_AUDIO,
Manifest.permission.NEARBY_WIFI_DEVICES,
+ null, // no permission for OP_ESTABLISH_VPN_SERVICE
+ null, // no permission for OP_ESTABLISH_VPN_MANAGER
};
/**
@@ -2467,6 +2505,8 @@
null, // BLUETOOTH_ADVERTISE
null, // RECORD_INCOMING_PHONE_AUDIO
null, // NEARBY_WIFI_DEVICES
+ null, // ESTABLISH_VPN_SERVICE
+ null, // ESTABLISH_VPN_MANAGER
};
/**
@@ -2591,6 +2631,8 @@
null, // BLUETOOTH_ADVERTISE
null, // RECORD_INCOMING_PHONE_AUDIO
null, // NEARBY_WIFI_DEVICES
+ null, // ESTABLISH_VPN_SERVICE
+ null, // ESTABLISH_VPN_MANAGER
};
/**
@@ -2714,6 +2756,8 @@
AppOpsManager.MODE_ALLOWED, // BLUETOOTH_ADVERTISE
AppOpsManager.MODE_ALLOWED, // RECORD_INCOMING_PHONE_AUDIO
AppOpsManager.MODE_ALLOWED, // NEARBY_WIFI_DEVICES
+ AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_SERVICE
+ AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_MANAGER
};
/**
@@ -2841,6 +2885,8 @@
false, // BLUETOOTH_ADVERTISE
false, // RECORD_INCOMING_PHONE_AUDIO
false, // NEARBY_WIFI_DEVICES
+ false, // OP_ESTABLISH_VPN_SERVICE
+ false, // OP_ESTABLISH_VPN_MANAGER
};
/**
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 83108d2..a5a2470 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -817,7 +817,7 @@
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public Bundle getCurrentAgEvents(BluetoothDevice device) {
- if (DBG) log("getCurrentCalls()");
+ if (DBG) log("getCurrentAgEvents()");
final IBluetoothHeadsetClient service =
getService();
if (service != null && isEnabled() && isValidDevice(device)) {
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 1468d9f..61882ff 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -381,6 +381,8 @@
private static native void nativeUnmarshall(
long nativePtr, byte[] data, int offset, int length);
private static native int nativeCompareData(long thisNativePtr, long otherNativePtr);
+ private static native boolean nativeCompareDataInRange(
+ long ptrA, int offsetA, long ptrB, int offsetB, int length);
private static native void nativeAppendFrom(
long thisNativePtr, long otherNativePtr, int offset, int length);
@CriticalNative
@@ -678,11 +680,16 @@
}
/** @hide */
- public final int compareData(Parcel other) {
+ public int compareData(Parcel other) {
return nativeCompareData(mNativePtr, other.mNativePtr);
}
/** @hide */
+ public static boolean compareData(Parcel a, int offsetA, Parcel b, int offsetB, int length) {
+ return nativeCompareDataInRange(a.mNativePtr, offsetA, b.mNativePtr, offsetB, length);
+ }
+
+ /** @hide */
public final void setClassCookie(Class clz, Object cookie) {
if (mClassCookies == null) {
mClassCookies = new ArrayMap<>();
@@ -3609,7 +3616,6 @@
private final int mType;
@Nullable private final ClassLoader mLoader;
@Nullable private Object mObject;
- @Nullable private volatile Parcel mValueParcel;
/**
* This goes from non-null to null once. Always check the nullability of this object before
@@ -3707,7 +3713,7 @@
return false;
}
// Finally we compare the payload.
- return getValueParcel(source).compareData(value.getValueParcel(otherSource)) == 0;
+ return Parcel.compareData(source, mPosition, otherSource, value.mPosition, mLength);
}
@Override
@@ -3715,17 +3721,6 @@
// Accessing mSource first to provide memory barrier for mObject
return Objects.hash(mSource == null, mObject, mLoader, mType, mLength);
}
-
- /** This extracts the parcel section responsible for the object and returns it. */
- private Parcel getValueParcel(Parcel source) {
- Parcel parcel = mValueParcel;
- if (parcel == null) {
- parcel = Parcel.obtain();
- parcel.appendFrom(source, mPosition, mLength);
- mValueParcel = parcel;
- }
- return parcel;
- }
}
/**
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 25e3a4f..4145d27 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -181,6 +181,14 @@
public static final String NAMESPACE_CONNECTIVITY = "connectivity";
/**
+ * Namespace for CaptivePortalLogin module.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_CAPTIVEPORTALLOGIN = "captive_portal_login";
+
+ /**
* Namespace for content capture feature used by on-device machine intelligence
* to provide suggestions in a privacy-safe manner.
*
diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java
index 5ec882c..475caa5 100644
--- a/core/java/com/android/internal/os/SomeArgs.java
+++ b/core/java/com/android/internal/os/SomeArgs.java
@@ -63,6 +63,8 @@
public int argi4;
public int argi5;
public int argi6;
+ public long argl1;
+ public long argl2;
private SomeArgs() {
/* do nothing - reduce visibility */
@@ -129,5 +131,7 @@
argi4 = 0;
argi5 = 0;
argi6 = 0;
+ argl1 = 0;
+ argl2 = 0;
}
}
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index be9aaaf..0d530f6 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -604,6 +604,25 @@
return thisParcel->compareData(*otherParcel);
}
+static jboolean android_os_Parcel_compareDataInRange(JNIEnv* env, jclass clazz, jlong thisNativePtr,
+ jint thisOffset, jlong otherNativePtr,
+ jint otherOffset, jint length) {
+ Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
+ LOG_ALWAYS_FATAL_IF(thisParcel == nullptr, "Should not be null");
+
+ Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
+ LOG_ALWAYS_FATAL_IF(otherParcel == nullptr, "Should not be null");
+
+ int result;
+ status_t err =
+ thisParcel->compareDataInRange(thisOffset, *otherParcel, otherOffset, length, &result);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ return JNI_FALSE;
+ }
+ return (result == 0) ? JNI_TRUE : JNI_FALSE;
+}
+
static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
jlong otherNativePtr, jint offset, jint length)
{
@@ -841,6 +860,7 @@
{"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall},
{"nativeUnmarshall", "(J[BII)V", (void*)android_os_Parcel_unmarshall},
{"nativeCompareData", "(JJ)I", (void*)android_os_Parcel_compareData},
+ {"nativeCompareDataInRange", "(JIJII)Z", (void*)android_os_Parcel_compareDataInRange},
{"nativeAppendFrom", "(JJII)V", (void*)android_os_Parcel_appendFrom},
// @CriticalNative
{"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java
index ddd0070..09f4840 100644
--- a/core/tests/coretests/src/android/os/BundleTest.java
+++ b/core/tests/coretests/src/android/os/BundleTest.java
@@ -273,16 +273,21 @@
Parcelable p1 = new CustomParcelable(13, "Tiramisu");
Parcelable p2 = new CustomParcelable(13, "Tiramisu");
Bundle a = new Bundle();
- a.putParcelable("key", p1);
+ a.putParcelable("key1", p1);
a.readFromParcel(getParcelledBundle(a));
a.setClassLoader(getClass().getClassLoader());
Bundle b = new Bundle();
- b.putParcelable("key", p2);
+ // Adding extra element so that the position of the elements of interest in their respective
+ // source parcels are different so we can cover that case of Parcel.compareData(). We'll
+ // remove the element later so the map is equal.
+ b.putString("key0", "string");
+ b.putParcelable("key1", p2);
b.readFromParcel(getParcelledBundle(b));
b.setClassLoader(getClass().getClassLoader());
- // 2 lazy values with identical parcels inside
a.isEmpty();
b.isEmpty();
+ b.remove("key0");
+ // 2 lazy values with identical parcels inside
assertTrue(Bundle.kindofEquals(a, b));
}
diff --git a/core/tests/coretests/src/android/os/ParcelTest.java b/core/tests/coretests/src/android/os/ParcelTest.java
index dcb3e2f..fdd278b 100644
--- a/core/tests/coretests/src/android/os/ParcelTest.java
+++ b/core/tests/coretests/src/android/os/ParcelTest.java
@@ -17,6 +17,9 @@
package android.os;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import android.platform.test.annotations.Presubmit;
@@ -110,4 +113,130 @@
assertEquals(string, p.readString16());
}
}
+
+ @Test
+ public void testCompareDataInRange_whenSameData() {
+ Parcel pA = Parcel.obtain();
+ int iA = pA.dataPosition();
+ pA.writeInt(13);
+ pA.writeString("Tiramisu");
+ int length = pA.dataPosition() - iA;
+ Parcel pB = Parcel.obtain();
+ pB.writeString("Prefix");
+ int iB = pB.dataPosition();
+ pB.writeInt(13);
+ pB.writeString("Tiramisu");
+
+ assertTrue(Parcel.compareData(pA, iA, pB, iB, length));
+ }
+
+ @Test
+ public void testCompareDataInRange_whenSameDataWithBinder() {
+ Binder binder = new Binder();
+ Parcel pA = Parcel.obtain();
+ int iA = pA.dataPosition();
+ pA.writeInt(13);
+ pA.writeStrongBinder(binder);
+ pA.writeString("Tiramisu");
+ int length = pA.dataPosition() - iA;
+ Parcel pB = Parcel.obtain();
+ pB.writeString("Prefix");
+ int iB = pB.dataPosition();
+ pB.writeInt(13);
+ pB.writeStrongBinder(binder);
+ pB.writeString("Tiramisu");
+
+ assertTrue(Parcel.compareData(pA, iA, pB, iB, length));
+ }
+
+ @Test
+ public void testCompareDataInRange_whenDifferentData() {
+ Parcel pA = Parcel.obtain();
+ int iA = pA.dataPosition();
+ pA.writeInt(13);
+ pA.writeString("Tiramisu");
+ int length = pA.dataPosition() - iA;
+ Parcel pB = Parcel.obtain();
+ int iB = pB.dataPosition();
+ pB.writeString("Prefix");
+ pB.writeInt(13);
+ pB.writeString("Tiramisu");
+
+ assertFalse(Parcel.compareData(pA, iA, pB, iB, length));
+ }
+
+ @Test
+ public void testCompareDataInRange_whenLimitOutOfBounds_throws() {
+ Parcel pA = Parcel.obtain();
+ int iA = pA.dataPosition();
+ pA.writeInt(12);
+ pA.writeString("Tiramisu");
+ int length = pA.dataPosition() - iA;
+ Parcel pB = Parcel.obtain();
+ pB.writeString("Prefix");
+ int iB = pB.dataPosition();
+ pB.writeInt(13);
+ pB.writeString("Tiramisu");
+ pB.writeInt(-1);
+
+ assertThrows(IllegalArgumentException.class,
+ () -> Parcel.compareData(pA, iA + length, pB, iB, 1));
+ assertThrows(IllegalArgumentException.class,
+ () -> Parcel.compareData(pA, iA, pB, pB.dataSize(), 1));
+ assertThrows(IllegalArgumentException.class,
+ () -> Parcel.compareData(pA, iA, pB, iB, length + 1));
+ assertThrows(IllegalArgumentException.class,
+ () -> Parcel.compareData(pA, iA + length + 1, pB, iB, 0));
+ assertThrows(IllegalArgumentException.class,
+ () -> Parcel.compareData(pA, iA, pB, iB + pB.dataSize() + 1, 0));
+ }
+
+ @Test
+ public void testCompareDataInRange_whenLengthZero() {
+ Parcel pA = Parcel.obtain();
+ int iA = pA.dataPosition();
+ pA.writeInt(12);
+ pA.writeString("Tiramisu");
+ int length = pA.dataPosition() - iA;
+ Parcel pB = Parcel.obtain();
+ pB.writeString("Prefix");
+ int iB = pB.dataPosition();
+ pB.writeInt(13);
+ pB.writeString("Tiramisu");
+
+ assertTrue(Parcel.compareData(pA, 0, pB, iB, 0));
+ assertTrue(Parcel.compareData(pA, iA + length, pB, iB, 0));
+ assertTrue(Parcel.compareData(pA, iA, pB, pB.dataSize(), 0));
+ }
+
+ @Test
+ public void testCompareDataInRange_whenNegativeLength_throws() {
+ Parcel pA = Parcel.obtain();
+ int iA = pA.dataPosition();
+ pA.writeInt(12);
+ pA.writeString("Tiramisu");
+ Parcel pB = Parcel.obtain();
+ pB.writeString("Prefix");
+ int iB = pB.dataPosition();
+ pB.writeInt(13);
+ pB.writeString("Tiramisu");
+
+ assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, iA, pB, iB, -1));
+ }
+
+ @Test
+ public void testCompareDataInRange_whenNegativeOffset_throws() {
+ Parcel pA = Parcel.obtain();
+ int iA = pA.dataPosition();
+ pA.writeInt(12);
+ pA.writeString("Tiramisu");
+ Parcel pB = Parcel.obtain();
+ pB.writeString("Prefix");
+ int iB = pB.dataPosition();
+ pB.writeInt(13);
+ pB.writeString("Tiramisu");
+
+ assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, -1, pB, iB, 0));
+ assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, 0, pB, -1, 0));
+ }
}
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index d6ee951..aeb8143 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -58,13 +58,13 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.Range;
-import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
+import com.android.net.module.util.BinderUtils;
import com.android.net.module.util.NetdUtils;
import com.android.net.module.util.PermissionUtils;
@@ -1056,9 +1056,9 @@
public void systemReady() {
if (isNetdAlive()) {
- Slog.d(TAG, "IpSecService is ready");
+ Log.d(TAG, "IpSecService is ready");
} else {
- Slog.wtf(TAG, "IpSecService not ready: failed to connect to NetD Native Service!");
+ Log.wtf(TAG, "IpSecService not ready: failed to connect to NetD Native Service!");
}
}
@@ -1332,7 +1332,7 @@
final INetd netd = mSrvConfig.getNetdInstance();
netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
- Binder.withCleanCallingIdentity(() -> {
+ BinderUtils.withCleanCallingIdentity(() -> {
NetdUtils.setInterfaceUp(netd, intfName);
});
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 243a336b..bf4ef48 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -126,6 +126,7 @@
import libcore.io.IoUtils;
import java.io.File;
+import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -195,6 +196,7 @@
private final Context mContext;
private final ConnectivityManager mConnectivityManager;
+ private final AppOpsManager mAppOpsManager;
// The context is for specific user which is created from mUserId
private final Context mUserIdContext;
@VisibleForTesting final Dependencies mDeps;
@@ -407,6 +409,46 @@
public boolean isInterfacePresent(final Vpn vpn, final String iface) {
return vpn.jniCheck(iface) != 0;
}
+
+ /**
+ * @see ParcelFileDescriptor#adoptFd(int)
+ */
+ public ParcelFileDescriptor adoptFd(Vpn vpn, int mtu) {
+ return ParcelFileDescriptor.adoptFd(jniCreate(vpn, mtu));
+ }
+
+ /**
+ * Call native method to create the VPN interface and return the FileDescriptor of /dev/tun.
+ */
+ public int jniCreate(Vpn vpn, int mtu) {
+ return vpn.jniCreate(mtu);
+ }
+
+ /**
+ * Call native method to get the interface name of VPN.
+ */
+ public String jniGetName(Vpn vpn, int fd) {
+ return vpn.jniGetName(fd);
+ }
+
+ /**
+ * Call native method to set the VPN addresses and return the number of addresses.
+ */
+ public int jniSetAddresses(Vpn vpn, String interfaze, String addresses) {
+ return vpn.jniSetAddresses(interfaze, addresses);
+ }
+
+ /**
+ * @see IoUtils#setBlocking(FileDescriptor, boolean)
+ */
+ public void setBlocking(FileDescriptor fd, boolean blocking) {
+ try {
+ IoUtils.setBlocking(fd, blocking);
+ } catch (IOException e) {
+ throw new IllegalStateException(
+ "Cannot set tunnel's fd as blocking=" + blocking, e);
+ }
+ }
}
public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd,
@@ -431,6 +473,7 @@
mVpnProfileStore = vpnProfileStore;
mContext = context;
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+ mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
mDeps = deps;
mNms = netService;
@@ -826,7 +869,6 @@
VpnProfile profile = getVpnProfilePrivileged(alwaysOnPackage);
if (profile != null) {
startVpnProfilePrivileged(profile, alwaysOnPackage);
-
// If the above startVpnProfilePrivileged() call returns, the Ikev2VpnProfile was
// correctly parsed, and the VPN has started running in a different thread. The only
// other possibility is that the above call threw an exception, which will be
@@ -974,9 +1016,15 @@
} catch (Exception e) {
// ignore
}
+ mAppOpsManager.finishOp(
+ AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage, null);
mContext.unbindService(mConnection);
cleanupVpnStateLocked();
} else if (mVpnRunner != null) {
+ if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
+ mAppOpsManager.finishOp(
+ AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null);
+ }
// cleanupVpnStateLocked() is called from mVpnRunner.exit()
mVpnRunner.exit();
}
@@ -1041,10 +1089,8 @@
return false;
}
- final AppOpsManager appOpMgr =
- (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
for (final String appOpStr : toChange) {
- appOpMgr.setMode(
+ mAppOpsManager.setMode(
appOpStr,
uid,
packageName,
@@ -1366,9 +1412,9 @@
Set<Range<Integer>> oldUsers = mNetworkCapabilities.getUids();
// Configure the interface. Abort if any of these steps fails.
- ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
+ final ParcelFileDescriptor tun = mDeps.adoptFd(this, config.mtu);
try {
- String interfaze = jniGetName(tun.getFd());
+ final String interfaze = mDeps.jniGetName(this, tun.getFd());
// TEMP use the old jni calls until there is support for netd address setting
StringBuilder builder = new StringBuilder();
@@ -1376,7 +1422,7 @@
builder.append(" ");
builder.append(address);
}
- if (jniSetAddresses(interfaze, builder.toString()) < 1) {
+ if (mDeps.jniSetAddresses(this, interfaze, builder.toString()) < 1) {
throw new IllegalArgumentException("At least one address must be specified");
}
Connection connection = new Connection();
@@ -1422,11 +1468,11 @@
jniReset(oldInterface);
}
- try {
- IoUtils.setBlocking(tun.getFileDescriptor(), config.blocking);
- } catch (IOException e) {
- throw new IllegalStateException(
- "Cannot set tunnel's fd as blocking=" + config.blocking, e);
+ mDeps.setBlocking(tun.getFileDescriptor(), config.blocking);
+ // Record that the VPN connection is established by an app which uses VpnService API.
+ if (oldNetworkAgent != mNetworkAgent) {
+ mAppOpsManager.startOp(
+ AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage, null, null);
}
} catch (RuntimeException e) {
IoUtils.closeQuietly(tun);
@@ -1781,9 +1827,17 @@
synchronized (Vpn.this) {
if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
if (mConnection != null) {
+ mAppOpsManager.finishOp(
+ AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage,
+ null);
mContext.unbindService(mConnection);
cleanupVpnStateLocked();
} else if (mVpnRunner != null) {
+ if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
+ mAppOpsManager.finishOp(
+ AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage,
+ null);
+ }
// cleanupVpnStateLocked() is called from mVpnRunner.exit()
mVpnRunner.exit();
}
@@ -3254,8 +3308,7 @@
*
* @param packageName the package name of the app provisioning this profile
*/
- public synchronized void startVpnProfile(
- @NonNull String packageName) {
+ public synchronized void startVpnProfile(@NonNull String packageName) {
requireNonNull(packageName, "No package name provided");
enforceNotRestrictedUser();
@@ -3318,6 +3371,13 @@
Log.d(TAG, "Unknown VPN profile type: " + profile.type);
break;
}
+
+ // Record that the VPN connection is established by an app which uses VpnManager API.
+ if (!VpnConfig.LEGACY_VPN.equals(packageName)) {
+ mAppOpsManager.startOp(
+ AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null,
+ null);
+ }
} catch (GeneralSecurityException e) {
// Reset mConfig
mConfig = null;
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 7f24c36..1579aaf 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -765,6 +765,8 @@
// send a sticky broadcast containing USB accessory handshake information
Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_HANDSHAKE)
+ .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+ | Intent.FLAG_RECEIVER_FOREGROUND)
.putExtra(UsbManager.EXTRA_ACCESSORY_UEVENT_TIME,
mAccessoryConnectionStartTime)
.putExtra(UsbManager.EXTRA_ACCESSORY_STRING_COUNT,