summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityThread.java2
-rw-r--r--core/java/android/bluetooth/BluetoothA2dp.java6
-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/EthernetNetworkSpecifier.java97
-rw-r--r--core/java/android/net/NetworkIdentity.java15
-rw-r--r--core/java/android/net/ParseException.java37
-rw-r--r--core/java/android/net/VpnManager.java7
-rw-r--r--core/java/android/net/vcn/VcnControlPlaneIkeConfig.java42
-rw-r--r--core/java/android/net/vcn/persistablebundleutils/CertUtils.java22
-rw-r--r--core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java513
-rw-r--r--core/java/android/os/FileUtils.java20
-rw-r--r--core/java/android/os/OWNERS2
-rw-r--r--core/java/android/view/OWNERS1
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java2
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java6
-rw-r--r--core/java/com/android/internal/widget/OWNERS2
19 files changed, 695 insertions, 448 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b99d5cd13a77..65f2c02faa85 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2770,7 +2770,7 @@ public final class ActivityThread extends ClientTransactionHandler {
memInfo.getTotalPrivateDirty(),
memInfo.getTotalPrivateClean(),
memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
- memInfo.getTotalSwappedOut(), memInfo.getTotalPss(),
+ memInfo.getTotalSwappedOut(), memInfo.getTotalRss(),
nativeMax+dalvikMax,
nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 53aaae0470e2..16413e1a1db6 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -139,7 +139,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
public static final String ACTION_CODEC_CONFIG_CHANGED =
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
@@ -684,7 +684,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @return the current codec status
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
@Nullable
@RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
@@ -713,7 +713,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @param codecConfig the codec configuration preference
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
@RequiresPermission(Manifest.permission.BLUETOOTH)
public void setCodecConfigPreference(@NonNull BluetoothDevice device,
@NonNull BluetoothCodecConfig codecConfig) {
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/EthernetNetworkSpecifier.java b/core/java/android/net/EthernetNetworkSpecifier.java
new file mode 100644
index 000000000000..e1685887e806
--- /dev/null
+++ b/core/java/android/net/EthernetNetworkSpecifier.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * A {@link NetworkSpecifier} used to identify ethernet interfaces.
+ *
+ * @see EthernetManager
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class EthernetNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+
+ /**
+ * Name of the network interface.
+ */
+ @NonNull
+ private final String mInterfaceName;
+
+ public EthernetNetworkSpecifier(@NonNull String interfaceName) {
+ Preconditions.checkStringNotEmpty(interfaceName);
+ mInterfaceName = interfaceName;
+ }
+
+ // This may be null in the future to support specifiers based on data other than the interface
+ // name.
+ @Nullable
+ public String getInterfaceName() {
+ return mInterfaceName;
+ }
+
+ @Override
+ public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
+ return equals(other);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (!(o instanceof EthernetNetworkSpecifier)) return false;
+ return TextUtils.equals(mInterfaceName, ((EthernetNetworkSpecifier) o).mInterfaceName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(mInterfaceName);
+ }
+
+ @Override
+ public String toString() {
+ return "EthernetNetworkSpecifier (" + mInterfaceName + ")";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mInterfaceName);
+ }
+
+ public static final @NonNull Parcelable.Creator<EthernetNetworkSpecifier> CREATOR =
+ new Parcelable.Creator<EthernetNetworkSpecifier>() {
+ public EthernetNetworkSpecifier createFromParcel(Parcel in) {
+ return new EthernetNetworkSpecifier(in.readString());
+ }
+ public EthernetNetworkSpecifier[] newArray(int size) {
+ return new EthernetNetworkSpecifier[size];
+ }
+ };
+}
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index a5ece7b713c7..b037261f0bc2 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -179,21 +179,6 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
}
/**
- * Build a {@link NetworkIdentity} from the given {@link NetworkState} and
- * {@code subType}, assuming that any mobile networks are using the current IMSI.
- * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
- * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
- */
- // TODO: Delete this function after NetworkPolicyManagerService finishes the migration.
- public static NetworkIdentity buildNetworkIdentity(Context context,
- NetworkState state, boolean defaultNetwork, @NetworkType int subType) {
- final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network,
- state.networkCapabilities, state.linkProperties, state.subscriberId,
- state.legacyNetworkType);
- return buildNetworkIdentity(context, snapshot, defaultNetwork, subType);
- }
-
- /**
* Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and
* {@code subType}, assuming that any mobile networks are using the current IMSI.
* The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
diff --git a/core/java/android/net/ParseException.java b/core/java/android/net/ParseException.java
deleted file mode 100644
index bcfdd7ef09cc..000000000000
--- a/core/java/android/net/ParseException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-
-/**
- * Thrown when parsing failed.
- */
-// See non-public class {@link WebAddress}.
-public class ParseException extends RuntimeException {
- public String response;
-
- ParseException(@NonNull String response) {
- super(response);
- this.response = response;
- }
-
- ParseException(@NonNull String response, @NonNull Throwable cause) {
- super(response, cause);
- this.response = response;
- }
-}
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index f472ed4381d1..77754d1256a7 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -16,12 +16,15 @@
package android.net;
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.content.ComponentName;
@@ -56,18 +59,21 @@ import java.util.List;
*/
public class VpnManager {
/** Type representing a lack of VPN @hide */
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_NONE = -1;
/**
* A VPN created by an app using the {@link VpnService} API.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_SERVICE = 1;
/**
* A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_PLATFORM = 2;
/**
@@ -76,6 +82,7 @@ public class VpnManager {
* @hide
*/
@Deprecated
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_LEGACY = 3;
/**
diff --git a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
index de086f63b14d..22d7faf2fe18 100644
--- a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
+++ b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
@@ -19,11 +19,13 @@ package android.net.vcn;
import static android.net.vcn.VcnControlPlaneConfig.CONFIG_TYPE_IKE;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
+import android.net.vcn.persistablebundleutils.IkeSessionParamsUtils;
+import android.net.vcn.persistablebundleutils.TunnelModeChildSessionParamsUtils;
import android.os.PersistableBundle;
import android.util.ArraySet;
+import android.util.Log;
import java.util.Objects;
@@ -38,14 +40,11 @@ import java.util.Objects;
public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName();
- // STOPSHIP: b/163604823 Make mIkeParams and mChildParams @NonNull when it is supported to
- // construct mIkeParams and mChildParams from PersistableBundles.
-
private static final String IKE_PARAMS_KEY = "mIkeParams";
- @Nullable private final IkeSessionParams mIkeParams;
+ @NonNull private final IkeSessionParams mIkeParams;
private static final String CHILD_PARAMS_KEY = "mChildParams";
- @Nullable private final TunnelModeChildSessionParams mChildParams;
+ @NonNull private final TunnelModeChildSessionParams mChildParams;
private static final ArraySet<String> BUNDLE_KEY_SET = new ArraySet<>();
@@ -80,11 +79,19 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
final PersistableBundle ikeParamsBundle = in.getPersistableBundle(IKE_PARAMS_KEY);
final PersistableBundle childParamsBundle = in.getPersistableBundle(CHILD_PARAMS_KEY);
- // STOPSHIP: b/163604823 Support constructing mIkeParams and mChildParams from
- // PersistableBundles.
+ Objects.requireNonNull(ikeParamsBundle, "IKE Session Params was null");
+ Objects.requireNonNull(childParamsBundle, "Child Session Params was null");
+
+ mIkeParams = IkeSessionParamsUtils.fromPersistableBundle(ikeParamsBundle);
+ mChildParams = TunnelModeChildSessionParamsUtils.fromPersistableBundle(childParamsBundle);
+
+ for (String key : in.keySet()) {
+ if (!BUNDLE_KEY_SET.contains(key)) {
+ Log.w(TAG, "Found an unexpected key in the PersistableBundle: " + key);
+ }
+ }
- mIkeParams = null;
- mChildParams = null;
+ validate();
}
private void validate() {
@@ -101,9 +108,11 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
@NonNull
public PersistableBundle toPersistableBundle() {
final PersistableBundle result = super.toPersistableBundle();
-
- // STOPSHIP: b/163604823 Support converting mIkeParams and mChildParams to
- // PersistableBundles.
+ result.putPersistableBundle(
+ IKE_PARAMS_KEY, IkeSessionParamsUtils.toPersistableBundle(mIkeParams));
+ result.putPersistableBundle(
+ CHILD_PARAMS_KEY,
+ TunnelModeChildSessionParamsUtils.toPersistableBundle(mChildParams));
return result;
}
@@ -134,10 +143,9 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
VcnControlPlaneIkeConfig other = (VcnControlPlaneIkeConfig) o;
- // STOPSHIP: b/163604823 Also check mIkeParams and mChildParams when it is supported to
- // construct mIkeParams and mChildParams from PersistableBundles. They are not checked
- // now so that VcnGatewayConnectionConfigTest and VcnConfigTest can pass.
- return super.equals(o);
+ return super.equals(o)
+ && Objects.equals(mIkeParams, other.mIkeParams)
+ && Objects.equals(mChildParams, other.mChildParams);
}
/** @hide */
diff --git a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
index b6036b4a6fd1..35b318687773 100644
--- a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
+++ b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
@@ -18,18 +18,24 @@ package android.net.vcn.persistablebundleutils;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Objects;
/**
- * CertUtils provides utility methods for constructing Certificate.
+ * CertUtils provides utility methods for constructing Certificate and PrivateKey.
*
* @hide
*/
public class CertUtils {
private static final String CERT_TYPE_X509 = "X.509";
+ private static final String PRIVATE_KEY_TYPE_RSA = "RSA";
/** Decodes an ASN.1 DER encoded Certificate */
public static X509Certificate certificateFromByteArray(byte[] derEncoded) {
@@ -43,4 +49,18 @@ public class CertUtils {
throw new IllegalArgumentException("Fail to decode certificate", e);
}
}
+
+ /** Decodes a PKCS#8 encoded RSA private key */
+ public static RSAPrivateKey privateKeyFromByteArray(byte[] pkcs8Encoded) {
+ Objects.requireNonNull(pkcs8Encoded, "pkcs8Encoded was null");
+ PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pkcs8Encoded);
+
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(PRIVATE_KEY_TYPE_RSA);
+
+ return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ throw new IllegalArgumentException("Fail to decode PrivateKey", e);
+ }
+ }
}
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
new file mode 100644
index 000000000000..9d3462cb0b2e
--- /dev/null
+++ b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vcn.persistablebundleutils;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.InetAddresses;
+import android.net.eap.EapSessionConfig;
+import android.net.ipsec.ike.IkeSaProposal;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer;
+import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest;
+import android.os.PersistableBundle;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.vcn.util.PersistableBundleUtils;
+
+import java.net.InetAddress;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Abstract utility class to convert IkeSessionParams to/from PersistableBundle.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = Visibility.PRIVATE)
+public final class IkeSessionParamsUtils {
+ private static final String SERVER_HOST_NAME_KEY = "SERVER_HOST_NAME_KEY";
+ private static final String SA_PROPOSALS_KEY = "SA_PROPOSALS_KEY";
+ private static final String LOCAL_ID_KEY = "LOCAL_ID_KEY";
+ private static final String REMOTE_ID_KEY = "REMOTE_ID_KEY";
+ private static final String LOCAL_AUTH_KEY = "LOCAL_AUTH_KEY";
+ private static final String REMOTE_AUTH_KEY = "REMOTE_AUTH_KEY";
+ private static final String CONFIG_REQUESTS_KEY = "CONFIG_REQUESTS_KEY";
+ private static final String RETRANS_TIMEOUTS_KEY = "RETRANS_TIMEOUTS_KEY";
+ private static final String HARD_LIFETIME_SEC_KEY = "HARD_LIFETIME_SEC_KEY";
+ private static final String SOFT_LIFETIME_SEC_KEY = "SOFT_LIFETIME_SEC_KEY";
+ private static final String DPD_DELAY_SEC_KEY = "DPD_DELAY_SEC_KEY";
+ private static final String NATT_KEEPALIVE_DELAY_SEC_KEY = "NATT_KEEPALIVE_DELAY_SEC_KEY";
+ private static final String IKE_OPTIONS_KEY = "IKE_OPTIONS_KEY";
+
+ private static final Set<Integer> IKE_OPTIONS = new ArraySet<>();
+
+ static {
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID);
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH);
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_MOBIKE);
+ }
+
+ /** Serializes an IkeSessionParams to a PersistableBundle. */
+ @NonNull
+ public static PersistableBundle toPersistableBundle(@NonNull IkeSessionParams params) {
+ if (params.getConfiguredNetwork() != null || params.getIke3gppExtension() != null) {
+ throw new IllegalStateException(
+ "Cannot convert a IkeSessionParams with a caller configured network or with"
+ + " 3GPP extension enabled");
+ }
+
+ final PersistableBundle result = new PersistableBundle();
+
+ result.putString(SERVER_HOST_NAME_KEY, params.getServerHostname());
+
+ final PersistableBundle saProposalBundle =
+ PersistableBundleUtils.fromList(
+ params.getSaProposals(), IkeSaProposalUtils::toPersistableBundle);
+ result.putPersistableBundle(SA_PROPOSALS_KEY, saProposalBundle);
+
+ result.putPersistableBundle(
+ LOCAL_ID_KEY,
+ IkeIdentificationUtils.toPersistableBundle(params.getLocalIdentification()));
+ result.putPersistableBundle(
+ REMOTE_ID_KEY,
+ IkeIdentificationUtils.toPersistableBundle(params.getRemoteIdentification()));
+
+ result.putPersistableBundle(
+ LOCAL_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getLocalAuthConfig()));
+ result.putPersistableBundle(
+ REMOTE_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getRemoteAuthConfig()));
+
+ final List<ConfigRequest> reqList = new ArrayList<>();
+ for (IkeConfigRequest req : params.getConfigurationRequests()) {
+ reqList.add(new ConfigRequest(req));
+ }
+ final PersistableBundle configReqListBundle =
+ PersistableBundleUtils.fromList(reqList, ConfigRequest::toPersistableBundle);
+ result.putPersistableBundle(CONFIG_REQUESTS_KEY, configReqListBundle);
+
+ result.putIntArray(RETRANS_TIMEOUTS_KEY, params.getRetransmissionTimeoutsMillis());
+ result.putInt(HARD_LIFETIME_SEC_KEY, params.getHardLifetimeSeconds());
+ result.putInt(SOFT_LIFETIME_SEC_KEY, params.getSoftLifetimeSeconds());
+ result.putInt(DPD_DELAY_SEC_KEY, params.getDpdDelaySeconds());
+ result.putInt(NATT_KEEPALIVE_DELAY_SEC_KEY, params.getNattKeepAliveDelaySeconds());
+
+ final List<Integer> enabledIkeOptions = new ArrayList<>();
+ for (int option : IKE_OPTIONS) {
+ if (params.hasIkeOption(option)) {
+ enabledIkeOptions.add(option);
+ }
+ }
+
+ final int[] optionArray = enabledIkeOptions.stream().mapToInt(i -> i).toArray();
+ result.putIntArray(IKE_OPTIONS_KEY, optionArray);
+
+ return result;
+ }
+
+ /** Constructs an IkeSessionParams by deserializing a PersistableBundle. */
+ @NonNull
+ public static IkeSessionParams fromPersistableBundle(@NonNull PersistableBundle in) {
+ Objects.requireNonNull(in, "PersistableBundle is null");
+
+ final IkeSessionParams.Builder builder = new IkeSessionParams.Builder();
+
+ builder.setServerHostname(in.getString(SERVER_HOST_NAME_KEY));
+
+ PersistableBundle proposalBundle = in.getPersistableBundle(SA_PROPOSALS_KEY);
+ Objects.requireNonNull(in, "SA Proposals was null");
+ List<IkeSaProposal> saProposals =
+ PersistableBundleUtils.toList(
+ proposalBundle, IkeSaProposalUtils::fromPersistableBundle);
+ for (IkeSaProposal proposal : saProposals) {
+ builder.addSaProposal(proposal);
+ }
+
+ builder.setLocalIdentification(
+ IkeIdentificationUtils.fromPersistableBundle(
+ in.getPersistableBundle(LOCAL_ID_KEY)));
+ builder.setRemoteIdentification(
+ IkeIdentificationUtils.fromPersistableBundle(
+ in.getPersistableBundle(REMOTE_ID_KEY)));
+
+ AuthConfigUtils.setBuilderByReadingPersistableBundle(
+ in.getPersistableBundle(LOCAL_AUTH_KEY),
+ in.getPersistableBundle(REMOTE_AUTH_KEY),
+ builder);
+
+ builder.setRetransmissionTimeoutsMillis(in.getIntArray(RETRANS_TIMEOUTS_KEY));
+ builder.setLifetimeSeconds(
+ in.getInt(HARD_LIFETIME_SEC_KEY), in.getInt(SOFT_LIFETIME_SEC_KEY));
+ builder.setDpdDelaySeconds(in.getInt(DPD_DELAY_SEC_KEY));
+ builder.setNattKeepAliveDelaySeconds(in.getInt(NATT_KEEPALIVE_DELAY_SEC_KEY));
+
+ final PersistableBundle configReqListBundle = in.getPersistableBundle(CONFIG_REQUESTS_KEY);
+ Objects.requireNonNull(configReqListBundle, "Config request list was null");
+ final List<ConfigRequest> reqList =
+ PersistableBundleUtils.toList(configReqListBundle, ConfigRequest::new);
+ for (ConfigRequest req : reqList) {
+ switch (req.type) {
+ case ConfigRequest.IPV4_P_CSCF_ADDRESS:
+ if (req.address == null) {
+ builder.addPcscfServerRequest(AF_INET);
+ } else {
+ builder.addPcscfServerRequest(req.address);
+ }
+ break;
+ case ConfigRequest.IPV6_P_CSCF_ADDRESS:
+ if (req.address == null) {
+ builder.addPcscfServerRequest(AF_INET6);
+ } else {
+ builder.addPcscfServerRequest(req.address);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unrecognized config request type: " + req.type);
+ }
+ }
+
+ // Clear IKE Options that are by default enabled
+ for (int option : IKE_OPTIONS) {
+ builder.removeIkeOption(option);
+ }
+
+ final int[] optionArray = in.getIntArray(IKE_OPTIONS_KEY);
+ for (int option : optionArray) {
+ builder.addIkeOption(option);
+ }
+
+ return builder.build();
+ }
+
+ private static final class AuthConfigUtils {
+ private static final int IKE_AUTH_METHOD_PSK = 1;
+ private static final int IKE_AUTH_METHOD_PUB_KEY_SIGNATURE = 2;
+ private static final int IKE_AUTH_METHOD_EAP = 3;
+
+ private static final String AUTH_METHOD_KEY = "AUTH_METHOD_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(@NonNull IkeAuthConfig authConfig) {
+ if (authConfig instanceof IkeAuthPskConfig) {
+ IkeAuthPskConfig config = (IkeAuthPskConfig) authConfig;
+ return IkeAuthPskConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PSK));
+ } else if (authConfig instanceof IkeAuthDigitalSignLocalConfig) {
+ IkeAuthDigitalSignLocalConfig config = (IkeAuthDigitalSignLocalConfig) authConfig;
+ return IkeAuthDigitalSignConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE));
+ } else if (authConfig instanceof IkeAuthDigitalSignRemoteConfig) {
+ IkeAuthDigitalSignRemoteConfig config = (IkeAuthDigitalSignRemoteConfig) authConfig;
+ return IkeAuthDigitalSignConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE));
+ } else if (authConfig instanceof IkeAuthEapConfig) {
+ IkeAuthEapConfig config = (IkeAuthEapConfig) authConfig;
+ return IkeAuthEapConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_EAP));
+ } else {
+ throw new IllegalStateException("Invalid IkeAuthConfig subclass");
+ }
+ }
+
+ private static PersistableBundle createPersistableBundle(int type) {
+ final PersistableBundle result = new PersistableBundle();
+ result.putInt(AUTH_METHOD_KEY, type);
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ final int localMethodType = localAuthBundle.getInt(AUTH_METHOD_KEY);
+ final int remoteMethodType = remoteAuthBundle.getInt(AUTH_METHOD_KEY);
+ switch (localMethodType) {
+ case IKE_AUTH_METHOD_PSK:
+ if (remoteMethodType != IKE_AUTH_METHOD_PSK) {
+ throw new IllegalArgumentException(
+ "Expect remote auth method to be PSK based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthPskConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ case IKE_AUTH_METHOD_PUB_KEY_SIGNATURE:
+ if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) {
+ throw new IllegalArgumentException(
+ "Expect remote auth method to be digital signature based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthDigitalSignConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ case IKE_AUTH_METHOD_EAP:
+ if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) {
+ throw new IllegalArgumentException(
+ "When using EAP for local authentication, expect remote auth"
+ + " method to be digital signature based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthEapConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ default:
+ throw new IllegalArgumentException(
+ "Invalid EAP method type " + localMethodType);
+ }
+ }
+ }
+
+ private static final class IkeAuthPskConfigUtils {
+ private static final String PSK_KEY = "PSK_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthPskConfig config, @NonNull PersistableBundle result) {
+ result.putPersistableBundle(
+ PSK_KEY, PersistableBundleUtils.fromByteArray(config.getPsk()));
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ final PersistableBundle localPskBundle = localAuthBundle.getPersistableBundle(PSK_KEY);
+ final PersistableBundle remotePskBundle =
+ remoteAuthBundle.getPersistableBundle(PSK_KEY);
+ Objects.requireNonNull(localAuthBundle, "Local PSK was null");
+ Objects.requireNonNull(remoteAuthBundle, "Remote PSK was null");
+
+ final byte[] localPsk = PersistableBundleUtils.toByteArray(localPskBundle);
+ final byte[] remotePsk = PersistableBundleUtils.toByteArray(remotePskBundle);
+ if (!Arrays.equals(localPsk, remotePsk)) {
+ throw new IllegalArgumentException("Local PSK and remote PSK are different");
+ }
+ builder.setAuthPsk(localPsk);
+ }
+ }
+
+ private static class IkeAuthDigitalSignConfigUtils {
+ private static final String END_CERT_KEY = "END_CERT_KEY";
+ private static final String INTERMEDIATE_CERTS_KEY = "INTERMEDIATE_CERTS_KEY";
+ private static final String PRIVATE_KEY_KEY = "PRIVATE_KEY_KEY";
+ private static final String TRUST_CERT_KEY = "TRUST_CERT_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthDigitalSignLocalConfig config, @NonNull PersistableBundle result) {
+ try {
+ result.putPersistableBundle(
+ END_CERT_KEY,
+ PersistableBundleUtils.fromByteArray(
+ config.getClientEndCertificate().getEncoded()));
+
+ final List<X509Certificate> certList = config.getIntermediateCertificates();
+ final List<byte[]> encodedCertList = new ArrayList<>(certList.size());
+ for (X509Certificate cert : certList) {
+ encodedCertList.add(cert.getEncoded());
+ }
+
+ final PersistableBundle certsBundle =
+ PersistableBundleUtils.fromList(
+ encodedCertList, PersistableBundleUtils::fromByteArray);
+ result.putPersistableBundle(INTERMEDIATE_CERTS_KEY, certsBundle);
+ } catch (CertificateEncodingException e) {
+ throw new IllegalArgumentException("Fail to encode certificate");
+ }
+
+ // TODO: b/170670506 Consider putting PrivateKey in Android KeyStore
+ result.putPersistableBundle(
+ PRIVATE_KEY_KEY,
+ PersistableBundleUtils.fromByteArray(config.getPrivateKey().getEncoded()));
+ return result;
+ }
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthDigitalSignRemoteConfig config, @NonNull PersistableBundle result) {
+ try {
+ X509Certificate caCert = config.getRemoteCaCert();
+ if (caCert != null) {
+ result.putPersistableBundle(
+ TRUST_CERT_KEY,
+ PersistableBundleUtils.fromByteArray(caCert.getEncoded()));
+ }
+ } catch (CertificateEncodingException e) {
+ throw new IllegalArgumentException("Fail to encode the certificate");
+ }
+
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ // Deserialize localAuth
+ final PersistableBundle endCertBundle =
+ localAuthBundle.getPersistableBundle(END_CERT_KEY);
+ Objects.requireNonNull(endCertBundle, "End cert was null");
+ final byte[] encodedCert = PersistableBundleUtils.toByteArray(endCertBundle);
+ final X509Certificate endCert = CertUtils.certificateFromByteArray(encodedCert);
+
+ final PersistableBundle certsBundle =
+ localAuthBundle.getPersistableBundle(INTERMEDIATE_CERTS_KEY);
+ Objects.requireNonNull(certsBundle, "Intermediate certs was null");
+ final List<byte[]> encodedCertList =
+ PersistableBundleUtils.toList(certsBundle, PersistableBundleUtils::toByteArray);
+ final List<X509Certificate> certList = new ArrayList<>(encodedCertList.size());
+ for (byte[] encoded : encodedCertList) {
+ certList.add(CertUtils.certificateFromByteArray(encoded));
+ }
+
+ final PersistableBundle privateKeyBundle =
+ localAuthBundle.getPersistableBundle(PRIVATE_KEY_KEY);
+ Objects.requireNonNull(privateKeyBundle, "PrivateKey bundle was null");
+ final PrivateKey privateKey =
+ CertUtils.privateKeyFromByteArray(
+ PersistableBundleUtils.toByteArray(privateKeyBundle));
+
+ // Deserialize remoteAuth
+ final PersistableBundle trustCertBundle =
+ remoteAuthBundle.getPersistableBundle(TRUST_CERT_KEY);
+
+ X509Certificate caCert = null;
+ if (trustCertBundle != null) {
+ final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+ caCert = CertUtils.certificateFromByteArray(encodedCaCert);
+ }
+
+ builder.setAuthDigitalSignature(caCert, endCert, certList, privateKey);
+ }
+ }
+
+ private static final class IkeAuthEapConfigUtils {
+ private static final String EAP_CONFIG_KEY = "EAP_CONFIG_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthEapConfig config, @NonNull PersistableBundle result) {
+ result.putPersistableBundle(
+ EAP_CONFIG_KEY,
+ EapSessionConfigUtils.toPersistableBundle(config.getEapConfig()));
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ // Deserialize localAuth
+ final PersistableBundle eapBundle =
+ localAuthBundle.getPersistableBundle(EAP_CONFIG_KEY);
+ Objects.requireNonNull(eapBundle, "EAP Config was null");
+ final EapSessionConfig eapConfig =
+ EapSessionConfigUtils.fromPersistableBundle(eapBundle);
+
+ // Deserialize remoteAuth
+ final PersistableBundle trustCertBundle =
+ remoteAuthBundle.getPersistableBundle(
+ IkeAuthDigitalSignConfigUtils.TRUST_CERT_KEY);
+
+ X509Certificate serverCaCert = null;
+ if (trustCertBundle != null) {
+ final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+ serverCaCert = CertUtils.certificateFromByteArray(encodedCaCert);
+ }
+ builder.setAuthEap(serverCaCert, eapConfig);
+ }
+ }
+
+ private static final class ConfigRequest {
+ private static final int IPV4_P_CSCF_ADDRESS = 1;
+ private static final int IPV6_P_CSCF_ADDRESS = 2;
+
+ private static final String TYPE_KEY = "type";
+ private static final String ADDRESS_KEY = "address";
+
+ public final int type;
+
+ // Null when it is an empty request
+ @Nullable public final InetAddress address;
+
+ ConfigRequest(IkeConfigRequest config) {
+ if (config instanceof ConfigRequestIpv4PcscfServer) {
+ type = IPV4_P_CSCF_ADDRESS;
+ address = ((ConfigRequestIpv4PcscfServer) config).getAddress();
+ } else if (config instanceof ConfigRequestIpv6PcscfServer) {
+ type = IPV6_P_CSCF_ADDRESS;
+ address = ((ConfigRequestIpv6PcscfServer) config).getAddress();
+ } else {
+ throw new IllegalStateException("Unknown TunnelModeChildConfigRequest");
+ }
+ }
+
+ ConfigRequest(PersistableBundle in) {
+ Objects.requireNonNull(in, "PersistableBundle was null");
+
+ type = in.getInt(TYPE_KEY);
+
+ String addressStr = in.getString(ADDRESS_KEY);
+ if (addressStr == null) {
+ address = null;
+ } else {
+ address = InetAddresses.parseNumericAddress(addressStr);
+ }
+ }
+
+ @NonNull
+ public PersistableBundle toPersistableBundle() {
+ final PersistableBundle result = new PersistableBundle();
+
+ result.putInt(TYPE_KEY, type);
+ if (address != null) {
+ result.putString(ADDRESS_KEY, address.getHostAddress());
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index a4d6c3845fbf..0264d2335c4b 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1235,9 +1235,9 @@ public final class FileUtils {
}
/**
- * Creates a directory with name {@code name} under an existing directory {@code baseDir}.
- * Returns a {@code File} object representing the directory on success, {@code null} on
- * failure.
+ * Creates a directory with name {@code name} under an existing directory {@code baseDir} if it
+ * doesn't exist already. Returns a {@code File} object representing the directory if it exists
+ * and {@code null} if not.
*
* @hide
*/
@@ -1247,13 +1247,23 @@ public final class FileUtils {
return createDir(dir) ? dir : null;
}
- /** @hide */
+ /**
+ * Ensure the given directory exists, creating it if needed. This method is threadsafe.
+ *
+ * @return false if the directory doesn't exist and couldn't be created
+ *
+ * @hide
+ */
public static boolean createDir(File dir) {
+ if (dir.mkdir()) {
+ return true;
+ }
+
if (dir.exists()) {
return dir.isDirectory();
}
- return dir.mkdir();
+ return false;
}
/**
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 6c49b365c4f3..d9665953dceb 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -54,7 +54,7 @@ per-file HwRemoteBinder.java = file:platform/system/libhwbinder:/OWNERS
per-file IHwBinder.java = file:platform/system/libhwbinder:/OWNERS
per-file IHwInterface.java = file:platform/system/libhwbinder:/OWNERS
-per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
+per-file GraphicsEnvironment.java = file:platform/frameworks/native:/opengl/OWNERS
per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
per-file *Power* = file:/services/core/java/com/android/server/power/OWNERS
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index a86984f44a41..31f6f6afdd53 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -80,5 +80,6 @@ per-file Window*.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file Window*.aidl = file:/services/core/java/com/android/server/wm/OWNERS
# Scroll Capture
+per-file *ScrollCapture*.aidl = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 10f6c610d5d3..96818fa26a73 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -67,7 +67,7 @@ import java.util.function.Consumer;
* <p>Content capture provides real-time, continuous capture of application activity, display and
* events to an intelligence service that is provided by the Android system. The intelligence
* service then uses that info to mediate and speed user journey through different apps. For
- * example, when the user receives a restaurant address in a chat app and switchs to a map app
+ * example, when the user receives a restaurant address in a chat app and switches to a map app
* to search for that restaurant, the intelligence service could offer an autofill dialog to
* let the user automatically select its address.
*
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index fe87b64940fb..c220428df58b 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -648,8 +648,6 @@ public class ZygoteInit {
*/
private static void performSystemServerDexOpt(String classPath) {
final String[] classPathElements = classPath.split(":");
- final IInstalld installd = IInstalld.Stub
- .asInterface(ServiceManager.getService("installd"));
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
String classPathForElement = "";
@@ -686,6 +684,10 @@ public class ZygoteInit {
final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
final String seInfo = null;
final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
+ // Wait for installd to be made available
+ IInstalld installd = IInstalld.Stub.asInterface(
+ ServiceManager.waitForService("installd"));
+
try {
installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
instructionSet, dexoptNeeded, outputPath, dexFlags, systemServerFilter,
diff --git a/core/java/com/android/internal/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS
index d284d5167843..8e68be0f742a 100644
--- a/core/java/com/android/internal/widget/OWNERS
+++ b/core/java/com/android/internal/widget/OWNERS
@@ -1,4 +1,6 @@
per-file PointerLocationView.java = michaelwr@google.com, svv@google.com
+per-file RecyclerView.java = mount@google.com
+per-file ViewPager.java = mount@google.com
# LockSettings related
per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS