Merge "BluetoothManagerService: catch NoSuchElementException for unlinkToDeath"
diff --git a/api/current.txt b/api/current.txt
index 56674d5..57fe55a 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -27333,6 +27333,11 @@
field public int serverAddress;
}
+ public class InetAddresses {
+ method public static boolean isNumericAddress(java.lang.String);
+ method public static java.net.InetAddress parseNumericAddress(java.lang.String);
+ }
+
public final class IpPrefix implements android.os.Parcelable {
method public boolean contains(java.net.InetAddress);
method public int describeContents();
diff --git a/core/java/android/net/INetdEventCallback.aidl b/core/java/android/net/INetdEventCallback.aidl
index 4b1a08d..0877a1a4 100644
--- a/core/java/android/net/INetdEventCallback.aidl
+++ b/core/java/android/net/INetdEventCallback.aidl
@@ -45,6 +45,20 @@
in String[] ipAddresses, int ipAddressesCount, long timestamp, int uid);
/**
+ * Represents adding or removing a NAT64 prefix.
+ * This method must not block or perform long-running operations.
+ *
+ * @param netId the ID of the network the prefix was performed on.
+ * @param added true if the NAT64 prefix was added, or false if the NAT64 prefix was removed.
+ * There is only one prefix at a time for each netId. If a prefix is added, it replaces
+ * the previous-added prefix.
+ * @param prefixString the detected NAT64 prefix as a string literal.
+ * @param prefixLength the prefix length associated with this NAT64 prefix.
+ */
+ void onNat64PrefixEvent(int netId, boolean added, @utf8InCpp String prefixString,
+ int prefixLength);
+
+ /**
* Represents a private DNS validation success or failure.
* This method must not block or perform long-running operations.
*
diff --git a/core/java/android/net/InetAddresses.java b/core/java/android/net/InetAddresses.java
new file mode 100644
index 0000000..8e6c69a
--- /dev/null
+++ b/core/java/android/net/InetAddresses.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 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 libcore.net.InetAddressUtils;
+
+import java.net.InetAddress;
+
+/**
+ * Utility methods for {@link InetAddress} implementations.
+ */
+public class InetAddresses {
+
+ private InetAddresses() {}
+
+ /**
+ * Checks to see if the {@code address} is a numeric address (such as {@code "192.0.2.1"} or
+ * {@code "2001:db8::1:2"}).
+ *
+ * <p>A numeric address is either an IPv4 address containing exactly 4 decimal numbers or an
+ * IPv6 numeric address. IPv4 addresses that consist of either hexadecimal or octal digits or
+ * do not have exactly 4 numbers are not treated as numeric.
+ *
+ * <p>This method will never do a DNS lookup.
+ *
+ * @param address the address to parse.
+ * @return true if the supplied address is numeric, false otherwise.
+ */
+ public static boolean isNumericAddress(String address) {
+ return InetAddressUtils.isNumericAddress(address);
+ }
+
+ /**
+ * Returns an InetAddress corresponding to the given numeric address (such
+ * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
+ *
+ * <p>See {@link #isNumericAddress(String)} (String)} for a definition as to what constitutes a
+ * numeric address.
+ *
+ * <p>This method will never do a DNS lookup.
+ *
+ * @param address the address to parse, must be numeric.
+ * @return an {@link InetAddress} instance corresponding to the address.
+ * @throws IllegalArgumentException if {@code address} is not a numeric address.
+ */
+ public static InetAddress parseNumericAddress(String address) {
+ return InetAddressUtils.parseNumericAddress(address);
+ }
+}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 34e9476..c0aa4a6 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -17,6 +17,7 @@
package android.net;
import android.annotation.UnsupportedAppUsage;
+import android.os.Build;
import android.os.Parcel;
import android.util.Log;
import android.util.Pair;
@@ -294,8 +295,10 @@
* @param addrString
* @return the InetAddress
* @hide
+ * @deprecated Use {@link InetAddresses#parseNumericAddress(String)}, if possible.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+ @Deprecated
public static InetAddress numericToInetAddress(String addrString)
throws IllegalArgumentException {
return InetAddress.parseNumericAddress(addrString);
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index be8cf0e..fdd7488 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -390,7 +390,7 @@
/**
* Setup a new VPN.
*/
- void createVirtualNetwork(int netId, boolean hasDNS, boolean secure);
+ void createVirtualNetwork(int netId, boolean secure);
/**
* Remove a network.
diff --git a/core/java/android/os/NativeHandle.java b/core/java/android/os/NativeHandle.java
index fbecc8e..f7ffc37 100644
--- a/core/java/android/os/NativeHandle.java
+++ b/core/java/android/os/NativeHandle.java
@@ -16,6 +16,8 @@
package android.os;
+import static android.system.OsConstants.F_DUPFD_CLOEXEC;
+
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.system.ErrnoException;
@@ -108,7 +110,10 @@
FileDescriptor[] fds = new FileDescriptor[mFds.length];
try {
for (int i = 0; i < mFds.length; i++) {
- fds[i] = Os.dup(mFds[i]);
+ FileDescriptor newFd = new FileDescriptor();
+ int fdint = Os.fcntlInt(mFds[i], F_DUPFD_CLOEXEC, 0);
+ newFd.setInt$(fdint);
+ fds[i] = newFd;
}
} catch (ErrnoException e) {
e.rethrowAsIOException();
diff --git a/core/java/com/android/server/net/BaseNetdEventCallback.java b/core/java/com/android/server/net/BaseNetdEventCallback.java
index 97247aa..a65214a 100644
--- a/core/java/com/android/server/net/BaseNetdEventCallback.java
+++ b/core/java/com/android/server/net/BaseNetdEventCallback.java
@@ -32,6 +32,12 @@
}
@Override
+ public void onNat64PrefixEvent(int netId, boolean added, String prefixString,
+ int prefixLength) {
+ // default no-op
+ }
+
+ @Override
public void onPrivateDnsValidationEvent(int netId, String ipAddress,
String hostname, boolean validated) {
// default no-op
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 89194e4..66ceae4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5714,7 +5714,6 @@
// This should never fail. Specifying an already in use NetID will cause failure.
if (networkAgent.isVPN()) {
mNMS.createVirtualNetwork(networkAgent.network.netId,
- !networkAgent.linkProperties.getDnsServers().isEmpty(),
(networkAgent.networkMisc == null ||
!networkAgent.networkMisc.allowBypass));
} else {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 0f00c11..00b1320 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -2308,11 +2308,11 @@
}
@Override
- public void createVirtualNetwork(int netId, boolean hasDNS, boolean secure) {
+ public void createVirtualNetwork(int netId, boolean secure) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mNetdService.networkCreateVpn(netId, hasDNS, secure);
+ mNetdService.networkCreateVpn(netId, secure);
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 422f556..e40949b 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -217,6 +217,19 @@
@Override
// Called concurrently by multiple binder threads.
// This method must not block or perform long-running operations.
+ public synchronized void onNat64PrefixEvent(int netId,
+ boolean added, String prefixString, int prefixLength)
+ throws RemoteException {
+ for (INetdEventCallback callback : mNetdEventCallbackList) {
+ if (callback != null) {
+ callback.onNat64PrefixEvent(netId, added, prefixString, prefixLength);
+ }
+ }
+ }
+
+ @Override
+ // Called concurrently by multiple binder threads.
+ // This method must not block or perform long-running operations.
public synchronized void onPrivateDnsValidationEvent(int netId,
String ipAddress, String hostname, boolean validated)
throws RemoteException {
diff --git a/services/net/java/android/net/dhcp/DhcpServer.java b/services/net/java/android/net/dhcp/DhcpServer.java
index cee6fa9..35d29e7 100644
--- a/services/net/java/android/net/dhcp/DhcpServer.java
+++ b/services/net/java/android/net/dhcp/DhcpServer.java
@@ -39,7 +39,6 @@
import android.net.MacAddress;
import android.net.NetworkUtils;
import android.net.TrafficStats;
-import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.Looper;
@@ -85,7 +84,7 @@
@NonNull
private final ServerHandler mHandler;
@NonNull
- private final InterfaceParams mIface;
+ private final String mIfName;
@NonNull
private final DhcpLeaseRepository mLeaseRepo;
@NonNull
@@ -161,20 +160,20 @@
}
}
- public DhcpServer(@NonNull Looper looper, @NonNull InterfaceParams iface,
+ public DhcpServer(@NonNull Looper looper, @NonNull String ifName,
@NonNull DhcpServingParams params, @NonNull SharedLog log) {
- this(looper, iface, params, log, null);
+ this(looper, ifName, params, log, null);
}
@VisibleForTesting
- DhcpServer(@NonNull Looper looper, @NonNull InterfaceParams iface,
+ DhcpServer(@NonNull Looper looper, @NonNull String ifName,
@NonNull DhcpServingParams params, @NonNull SharedLog log,
@Nullable Dependencies deps) {
if (deps == null) {
deps = new DependenciesImpl();
}
mHandler = new ServerHandler(looper);
- mIface = iface;
+ mIfName = ifName;
mServingParams = params;
mLog = log;
mDeps = deps;
@@ -444,7 +443,7 @@
private boolean addArpEntry(@NonNull MacAddress macAddr, @NonNull Inet4Address inetAddr) {
try {
- mDeps.addArpEntry(inetAddr, macAddr, mIface.name, mSocket);
+ mDeps.addArpEntry(inetAddr, macAddr, mIfName, mSocket);
return true;
} catch (IOException e) {
mLog.e("Error adding client to ARP table", e);
@@ -526,7 +525,7 @@
// SO_BINDTODEVICE actually takes a string. This works because the first member
// of struct ifreq is a NULL-terminated interface name.
// TODO: add a setsockoptString()
- Os.setsockoptIfreq(mSocket, SOL_SOCKET, SO_BINDTODEVICE, mIface.name);
+ Os.setsockoptIfreq(mSocket, SOL_SOCKET, SO_BINDTODEVICE, mIfName);
Os.setsockoptInt(mSocket, SOL_SOCKET, SO_BROADCAST, 1);
Os.bind(mSocket, Inet4Address.ANY, DHCP_SERVER);
NetworkUtils.protectFromVpn(mSocket);
diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java
index 823c0a1..493350d 100644
--- a/services/net/java/android/net/ip/IpServer.java
+++ b/services/net/java/android/net/ip/IpServer.java
@@ -138,9 +138,9 @@
return NetdService.getInstance();
}
- public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
+ public DhcpServer makeDhcpServer(Looper looper, String ifName,
DhcpServingParams params, SharedLog log) {
- return new DhcpServer(looper, iface, params, log);
+ return new DhcpServer(looper, ifName, params, log);
}
}
@@ -256,12 +256,6 @@
if (mUsingLegacyDhcp) {
return true;
}
-
- final InterfaceParams ifaceParams = mDeps.getInterfaceParams(mIfaceName);
- if (ifaceParams == null) {
- Log.e(TAG, "Failed to find interface params for DHCPv4");
- return false;
- }
final DhcpServingParams params;
try {
params = new DhcpServingParams.Builder()
@@ -277,7 +271,7 @@
return false;
}
- mDhcpServer = mDeps.makeDhcpServer(getHandler().getLooper(), ifaceParams, params,
+ mDhcpServer = mDeps.makeDhcpServer(getHandler().getLooper(), mIfaceName, params,
mLog.forSubComponent("DHCP"));
mDhcpServer.start();
return true;
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 94879d0..a78f7d5 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -79,6 +79,9 @@
case Instruction::Op::kNew:
out << "kNew";
return out;
+ case Instruction::Op::kCheckCast:
+ out << "kCheckCast";
+ return out;
}
}
@@ -329,6 +332,8 @@
return EncodeBranch(art::Instruction::IF_NEZ, instruction);
case Instruction::Op::kNew:
return EncodeNew(instruction);
+ case Instruction::Op::kCheckCast:
+ return EncodeCast(instruction);
}
}
@@ -422,6 +427,18 @@
Encode21c(::art::Instruction::NEW_INSTANCE, RegisterValue(*instruction.dest()), type.value());
}
+void MethodBuilder::EncodeCast(const Instruction& instruction) {
+ DCHECK_EQ(Instruction::Op::kCheckCast, instruction.opcode());
+ DCHECK(instruction.dest().has_value());
+ DCHECK(instruction.dest()->is_variable());
+ DCHECK_EQ(1, instruction.args().size());
+
+ const Value& type = instruction.args()[0];
+ DCHECK_LT(RegisterValue(*instruction.dest()), 256);
+ DCHECK(type.is_type());
+ Encode21c(::art::Instruction::CHECK_CAST, RegisterValue(*instruction.dest()), type.value());
+}
+
size_t MethodBuilder::RegisterValue(const Value& value) const {
if (value.is_register()) {
return value.value();
diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h
index 45596ac..06059c8 100644
--- a/startop/view_compiler/dex_builder.h
+++ b/startop/view_compiler/dex_builder.h
@@ -142,17 +142,18 @@
// The operation performed by this instruction. These are virtual instructions that do not
// correspond exactly to DEX instructions.
enum class Op {
- kReturn,
- kReturnObject,
- kMove,
- kInvokeVirtual,
- kInvokeDirect,
- kInvokeStatic,
- kInvokeInterface,
kBindLabel,
kBranchEqz,
kBranchNEqz,
- kNew
+ kCheckCast,
+ kInvokeDirect,
+ kInvokeInterface,
+ kInvokeStatic,
+ kInvokeVirtual,
+ kMove,
+ kNew,
+ kReturn,
+ kReturnObject,
};
////////////////////////
@@ -168,6 +169,13 @@
static inline Instruction OpWithArgs(Op opcode, std::optional<const Value> dest, T... args) {
return Instruction{opcode, /*method_id=*/0, /*result_is_object=*/false, dest, args...};
}
+
+ // A cast instruction. Basically, `(type)val`
+ static inline Instruction Cast(Value val, Value type) {
+ DCHECK(type.is_type());
+ return OpWithArgs(Op::kCheckCast, val, type);
+ }
+
// For method calls.
template <typename... T>
static inline Instruction InvokeVirtual(size_t method_id, std::optional<const Value> dest,
@@ -302,6 +310,7 @@
void EncodeInvoke(const Instruction& instruction, ::art::Instruction::Code opcode);
void EncodeBranch(art::Instruction::Code op, const Instruction& instruction);
void EncodeNew(const Instruction& instruction);
+ void EncodeCast(const Instruction& instruction);
// Low-level instruction format encoding. See
// https://source.android.com/devices/tech/dalvik/instruction-formats for documentation of
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
index 1508ad9e..42d4161 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
@@ -20,6 +20,7 @@
import dalvik.system.InMemoryDexClassLoader;
import dalvik.system.PathClassLoader;
import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import org.junit.Assert;
@@ -151,4 +152,23 @@
Method method = clazz.getMethod("invokeVirtualReturnObject", String.class, int.class);
Assert.assertEquals("bc", method.invoke(null, "abc", 1));
}
+
+ @Test
+ public void castObjectToString() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("castObjectToString", Object.class);
+ Assert.assertEquals("abc", method.invoke(null, "abc"));
+ boolean castFailed = false;
+ try {
+ method.invoke(null, 5);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof ClassCastException) {
+ castFailed = true;
+ } else {
+ throw e;
+ }
+ }
+ Assert.assertTrue(castFailed);
+ }
}
diff --git a/startop/view_compiler/dex_testcase_generator.cc b/startop/view_compiler/dex_testcase_generator.cc
index 2781aa5..f62ec5dd 100644
--- a/startop/view_compiler/dex_testcase_generator.cc
+++ b/startop/view_compiler/dex_testcase_generator.cc
@@ -269,6 +269,19 @@
method.Encode();
}(invokeVirtualReturnObject);
+ // Make sure we can cast objects
+ // String castObjectToString(Object o) { return (String)o; }
+ MethodBuilder castObjectToString{cbuilder.CreateMethod(
+ "castObjectToString",
+ Prototype{string_type, TypeDescriptor::FromClassname("java.lang.Object")})};
+ [&](MethodBuilder& method) {
+ const ir::Type* type_def = dex_file.GetOrAddType(string_type.descriptor());
+ method.AddInstruction(
+ Instruction::Cast(Value::Parameter(0), Value::Type(type_def->orig_index)));
+ method.BuildReturn(Value::Parameter(0), /*is_object=*/true);
+ method.Encode();
+ }(castObjectToString);
+
slicer::MemView image{dex_file.CreateImage()};
std::ofstream out_file(outdir + "/simple.dex");
out_file.write(image.ptr<const char>(), image.size());
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index b5a8758..200b540 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -969,7 +969,7 @@
*/
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("[ApnSettingV5] ")
+ sb.append("[ApnSettingV6] ")
.append(mEntryName)
.append(", ").append(mId)
.append(", ").append(mOperatorNumeric)
@@ -996,6 +996,7 @@
sb.append(", ").append(mPermanentFailed);
sb.append(", ").append(mNetworkTypeBitmask);
sb.append(", ").append(mApnSetId);
+ sb.append(", ").append(mCarrierId);
return sb.toString();
}
diff --git a/tests/net/java/android/net/dhcp/DhcpServerTest.java b/tests/net/java/android/net/dhcp/DhcpServerTest.java
index df34c73..ab9bd84 100644
--- a/tests/net/java/android/net/dhcp/DhcpServerTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpServerTest.java
@@ -25,7 +25,6 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -48,7 +47,6 @@
import android.net.dhcp.DhcpLeaseRepository.OutOfAddressesException;
import android.net.dhcp.DhcpServer.Clock;
import android.net.dhcp.DhcpServer.Dependencies;
-import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
@@ -74,9 +72,6 @@
public class DhcpServerTest {
private static final String PROP_DEXMAKER_SHARE_CLASSLOADER = "dexmaker.share_classloader";
private static final String TEST_IFACE = "testiface";
- private static final MacAddress TEST_IFACE_MAC = MacAddress.fromString("11:22:33:44:55:66");
- private static final InterfaceParams TEST_IFACEPARAMS =
- new InterfaceParams(TEST_IFACE, 1, TEST_IFACE_MAC);
private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
private static final LinkAddress TEST_SERVER_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
@@ -149,7 +144,7 @@
.build();
mLooper = new TestLooper();
- mServer = new DhcpServer(mLooper.getLooper(), TEST_IFACEPARAMS, servingParams,
+ mServer = new DhcpServer(mLooper.getLooper(), TEST_IFACE, servingParams,
new SharedLog(DhcpServerTest.class.getSimpleName()), mDeps);
mServer.start();
diff --git a/tests/net/java/android/net/ip/IpServerTest.java b/tests/net/java/android/net/ip/IpServerTest.java
index cff0b54..2c675c6 100644
--- a/tests/net/java/android/net/ip/IpServerTest.java
+++ b/tests/net/java/android/net/ip/IpServerTest.java
@@ -404,7 +404,7 @@
private void assertDhcpStarted(IpPrefix expectedPrefix) {
verify(mDependencies, times(1)).makeDhcpServer(
- eq(mLooper.getLooper()), eq(TEST_IFACE_PARAMS), any(), eq(mSharedLog));
+ eq(mLooper.getLooper()), eq(IFACE_NAME), any(), eq(mSharedLog));
verify(mDhcpServer, times(1)).start();
final DhcpServingParams params = mDhcpParamsCaptor.getValue();
// Last address byte is random
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index bca9be7..e6b43d2 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -240,7 +240,7 @@
}
@Override
- public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
+ public DhcpServer makeDhcpServer(Looper looper, String ifName,
DhcpServingParams params, SharedLog log) {
return mDhcpServer;
}