Add libconnectivity_native
The library provides an interface to interface with the
ConnectivityNative service, and implement port blocking APIs.
Bug: 179733303
Test: atest connectivity_native_test
Change-Id: Iad1c84b5eeab835aca14a2db72a900e099aa3c1c
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 8cf46ef..cf2848f 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -69,7 +69,10 @@
"libservice-connectivity",
"libandroid_net_connectivity_com_android_net_module_util_jni",
],
- native_shared_libs: ["libnetd_updatable"],
+ native_shared_libs: [
+ "libcom.android.tethering.connectivity_native",
+ "libnetd_updatable",
+ ],
},
both: {
jni_libs: [
diff --git a/service/Android.bp b/service/Android.bp
index d850015..b13f615 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -22,7 +22,6 @@
aidl_interface {
name: "connectivity_native_aidl_interface",
local_include_dir: "binder",
- vendor_available: true,
srcs: [
"binder/android/net/connectivity/aidl/*.aidl",
],
diff --git a/service/libconnectivity/Android.bp b/service/libconnectivity/Android.bp
new file mode 100644
index 0000000..391ceac
--- /dev/null
+++ b/service/libconnectivity/Android.bp
@@ -0,0 +1,57 @@
+//
+// Copyright (C) 2022 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 {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_shared {
+ name: "libcom.android.tethering.connectivity_native",
+ srcs: [
+ "src/**/*.cpp",
+ ],
+ min_sdk_version: "30",
+ static_libs: [
+ "connectivity_native_aidl_interface-V1-ndk",
+ ],
+ export_include_dirs: ["include"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-error=deprecated-declarations",
+ ],
+
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+ llndk: {
+ symbol_file: "libconnectivity_native.map.txt",
+ },
+ stubs: {
+ symbol_file: "libconnectivity_native.map.txt",
+ versions: [
+ "current",
+ ],
+ },
+ header_abi_checker: {
+ enabled: true,
+ symbol_file: "libconnectivity_native.map.txt",
+ },
+ apex_available: [
+ "com.android.tethering",
+ ],
+}
diff --git a/service/libconnectivity/include/connectivity_native.h b/service/libconnectivity/include/connectivity_native.h
new file mode 100644
index 0000000..5a2509a
--- /dev/null
+++ b/service/libconnectivity/include/connectivity_native.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#ifndef LIBCONNECTIVITY_CONNECTIVITY_NATIVE_H_
+#define LIBCONNECTIVITY_CONNECTIVITY_NATIVE_H_
+
+#include <sys/cdefs.h>
+#include <netinet/in.h>
+
+// For branches that do not yet have __ANDROID_API_U__ defined, like module
+// release branches.
+#ifndef __ANDROID_API_U__
+#define __ANDROID_API_U__ 34
+#endif
+
+__BEGIN_DECLS
+
+/**
+ * Blocks a port from being assigned during bind(). The caller is responsible for updating
+ * /proc/sys/net/ipv4/ip_local_port_range with the port being blocked so that calls to connect()
+ * will not automatically assign one of the blocked ports.
+ * Will return success even if port was already blocked.
+ *
+ * Returns 0 on success, or a POSIX error code (see errno.h) on failure:
+ * - EINVAL for invalid port number
+ * - EPERM if the UID of the client doesn't have network stack permission
+ * - Other errors as per https://man7.org/linux/man-pages/man2/bpf.2.html
+ *
+ * @param port Int corresponding to port number.
+ */
+int AConnectivityNative_blockPortForBind(in_port_t port) __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
+ * Unblocks a port that has previously been blocked.
+ * Will return success even if port was already unblocked.
+ *
+ * Returns 0 on success, or a POSIX error code (see errno.h) on failure:
+ * - EINVAL for invalid port number
+ * - EPERM if the UID of the client doesn't have network stack permission
+ * - Other errors as per https://man7.org/linux/man-pages/man2/bpf.2.html
+ *
+ * @param port Int corresponding to port number.
+ */
+int AConnectivityNative_unblockPortForBind(in_port_t port) __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
+ * Unblocks all ports that have previously been blocked.
+ *
+ * Returns 0 on success, or a POSIX error code (see errno.h) on failure:
+ * - EINVAL for invalid port number
+ * - EPERM if the UID of the client doesn't have network stack permission
+ * - Other errors as per https://man7.org/linux/man-pages/man2/bpf.2.html
+ */
+int AConnectivityNative_unblockAllPortsForBind() __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
+ * Gets the list of ports that have been blocked.
+ *
+ * Returns 0 on success, or a POSIX error code (see errno.h) on failure:
+ * - EINVAL for invalid port number
+ * - EPERM if the UID of the client doesn't have network stack permission
+ * - Other errors as per https://man7.org/linux/man-pages/man2/bpf.2.html
+ *
+ * @param ports Array of ports that will be filled with the port numbers.
+ * @param count Pointer to the size of the ports array; the value will be set to the total number of
+ * blocked ports, which may be larger than the ports array that was filled.
+ */
+int AConnectivityNative_getPortsBlockedForBind(in_port_t *ports, size_t *count)
+ __INTRODUCED_IN(__ANDROID_API_U__);
+
+__END_DECLS
+
+
+#endif
diff --git a/service/libconnectivity/libconnectivity_native.map.txt b/service/libconnectivity/libconnectivity_native.map.txt
new file mode 100644
index 0000000..19b1074
--- /dev/null
+++ b/service/libconnectivity/libconnectivity_native.map.txt
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2022 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.
+#
+LIBCONNECTIVITY_NATIVE {
+ global:
+ AConnectivityNative_blockPortForBind; # apex llndk
+ AConnectivityNative_getPortsBlockedForBind; # apex llndk
+ AConnectivityNative_unblockPortForBind; # apex llndk
+ AConnectivityNative_unblockAllPortsForBind; # apex llndk
+ local:
+ *;
+};
diff --git a/service/libconnectivity/src/connectivity_native.cpp b/service/libconnectivity/src/connectivity_native.cpp
new file mode 100644
index 0000000..9545ed1
--- /dev/null
+++ b/service/libconnectivity/src/connectivity_native.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include "connectivity_native.h"
+
+#include <android/binder_manager.h>
+#include <aidl/android/net/connectivity/aidl/ConnectivityNative.h>
+
+using aidl::android::net::connectivity::aidl::IConnectivityNative;
+
+
+static std::shared_ptr<IConnectivityNative> getBinder() {
+ static ndk::SpAIBinder sBinder = ndk::SpAIBinder(reinterpret_cast<AIBinder*>(
+ AServiceManager_getService("connectivity_native")));
+ return aidl::android::net::connectivity::aidl::IConnectivityNative::fromBinder(sBinder);
+}
+
+static int getErrno(const ::ndk::ScopedAStatus& status) {
+ switch (status.getExceptionCode()) {
+ case EX_NONE:
+ return 0;
+ case EX_ILLEGAL_ARGUMENT:
+ return EINVAL;
+ case EX_SECURITY:
+ return EPERM;
+ case EX_SERVICE_SPECIFIC:
+ return status.getServiceSpecificError();
+ default:
+ return EPROTO;
+ }
+}
+
+int AConnectivityNative_blockPortForBind(in_port_t port) {
+ std::shared_ptr<IConnectivityNative> c = getBinder();
+ return getErrno(c->blockPortForBind(port));
+}
+
+int AConnectivityNative_unblockPortForBind(in_port_t port) {
+ std::shared_ptr<IConnectivityNative> c = getBinder();
+ return getErrno(c->unblockPortForBind(port));
+}
+
+int AConnectivityNative_unblockAllPortsForBind() {
+ std::shared_ptr<IConnectivityNative> c = getBinder();
+ return getErrno(c->unblockAllPortsForBind());
+}
+
+int AConnectivityNative_getPortsBlockedForBind(in_port_t *ports, size_t *count) {
+ std::shared_ptr<IConnectivityNative> c = getBinder();
+ std::vector<int32_t> actualBlockedPorts;
+ int err = getErrno(c->getPortsBlockedForBind(&actualBlockedPorts));
+ if (err) {
+ return err;
+ }
+
+ for (int i = 0; i < *count && i < actualBlockedPorts.size(); i++) {
+ ports[i] = actualBlockedPorts[i];
+ }
+ *count = actualBlockedPorts.size();
+ return 0;
+}
diff --git a/tests/native/connectivity_native_test/Android.bp b/tests/native/connectivity_native_test/Android.bp
index 7d43aa8..8825aa4 100644
--- a/tests/native/connectivity_native_test/Android.bp
+++ b/tests/native/connectivity_native_test/Android.bp
@@ -10,7 +10,7 @@
"vts",
],
test_config_template: "AndroidTestTemplate.xml",
- min_sdk_version: "31",
+ min_sdk_version: "34",
tidy: false,
srcs: [
"connectivity_native_test.cpp",
diff --git a/tests/native/connectivity_native_test/connectivity_native_test.cpp b/tests/native/connectivity_native_test/connectivity_native_test.cpp
index 3db5265..27a9d35 100644
--- a/tests/native/connectivity_native_test/connectivity_native_test.cpp
+++ b/tests/native/connectivity_native_test/connectivity_native_test.cpp
@@ -14,62 +14,81 @@
* limitations under the License.
*/
-#include <aidl/android/net/connectivity/aidl/ConnectivityNative.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <android-modules-utils/sdk_level.h>
#include <cutils/misc.h> // FIRST_APPLICATION_UID
+#include <dlfcn.h>
#include <gtest/gtest.h>
#include <netinet/in.h>
#include "bpf/BpfUtils.h"
-using aidl::android::net::connectivity::aidl::IConnectivityNative;
+typedef int (*GetPortsBlockedForBind)(in_port_t*, size_t*);
+GetPortsBlockedForBind getPortsBlockedForBind;
+typedef int (*BlockPortForBind)(in_port_t);
+BlockPortForBind blockPortForBind;
+typedef int (*UnblockPortForBind)(in_port_t);
+UnblockPortForBind unblockPortForBind;
+typedef int (*UnblockAllPortsForBind)();
+UnblockAllPortsForBind unblockAllPortsForBind;
class ConnectivityNativeBinderTest : public ::testing::Test {
public:
- std::vector<int32_t> mActualBlockedPorts;
-
- ConnectivityNativeBinderTest() {
- AIBinder* binder = AServiceManager_getService("connectivity_native");
- ndk::SpAIBinder sBinder = ndk::SpAIBinder(binder);
- mService = aidl::android::net::connectivity::aidl::IConnectivityNative::fromBinder(sBinder);
- }
+ in_port_t mActualBlockedPorts[65535];
+ size_t mActualBlockedPortsCount = 65535;
+ bool restoreBlockedPorts;
void SetUp() override {
- // Skip test case if not on T.
- if (!android::modules::sdklevel::IsAtLeastT()) GTEST_SKIP() <<
+ restoreBlockedPorts = false;
+ // Skip test case if not on U.
+ if (!android::modules::sdklevel::IsAtLeastU()) GTEST_SKIP() <<
"Should be at least T device.";
// Skip test case if not on 5.4 kernel which is required by bpf prog.
if (!android::bpf::isAtLeastKernelVersion(5, 4, 0)) GTEST_SKIP() <<
"Kernel should be at least 5.4.";
- ASSERT_NE(nullptr, mService.get());
+ // Necessary to use dlopen/dlsym since the lib is only available on U and there
+ // is no Sdk34ModuleController in tradefed yet.
+ // TODO: link against the library directly and add Sdk34ModuleController to
+ // AndroidTest.txml when available.
+ void* nativeLib = dlopen("libcom.android.tethering.connectivity_native.so", RTLD_NOW);
+ ASSERT_NE(nullptr, nativeLib);
+ getPortsBlockedForBind = reinterpret_cast<GetPortsBlockedForBind>(
+ dlsym(nativeLib, "AConnectivityNative_getPortsBlockedForBind"));
+ ASSERT_NE(nullptr, getPortsBlockedForBind);
+ blockPortForBind = reinterpret_cast<BlockPortForBind>(
+ dlsym(nativeLib, "AConnectivityNative_blockPortForBind"));
+ ASSERT_NE(nullptr, blockPortForBind);
+ unblockPortForBind = reinterpret_cast<UnblockPortForBind>(
+ dlsym(nativeLib, "AConnectivityNative_unblockPortForBind"));
+ ASSERT_NE(nullptr, unblockPortForBind);
+ unblockAllPortsForBind = reinterpret_cast<UnblockAllPortsForBind>(
+ dlsym(nativeLib, "AConnectivityNative_unblockAllPortsForBind"));
+ ASSERT_NE(nullptr, unblockAllPortsForBind);
// If there are already ports being blocked on device unblockAllPortsForBind() store
// the currently blocked ports and add them back at the end of the test. Do this for
// every test case so additional test cases do not forget to add ports back.
- ndk::ScopedAStatus status = mService->getPortsBlockedForBind(&mActualBlockedPorts);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
-
+ int err = getPortsBlockedForBind(mActualBlockedPorts, &mActualBlockedPortsCount);
+ EXPECT_EQ(err, 0);
+ restoreBlockedPorts = true;
}
void TearDown() override {
- ndk::ScopedAStatus status;
- if (mActualBlockedPorts.size() > 0) {
- for (int i : mActualBlockedPorts) {
- mService->blockPortForBind(i);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
+ int err;
+ if (mActualBlockedPortsCount > 0 && restoreBlockedPorts) {
+ for (int i=0; i < mActualBlockedPortsCount; i++) {
+ err = blockPortForBind(mActualBlockedPorts[i]);
+ EXPECT_EQ(err, 0);
}
}
}
protected:
- std::shared_ptr<IConnectivityNative> mService;
-
void runSocketTest (sa_family_t family, const int type, bool blockPort) {
- ndk::ScopedAStatus status;
+ int err;
in_port_t port = 0;
int sock, sock2;
// Open two sockets with SO_REUSEADDR and expect they can both bind to port.
@@ -79,16 +98,16 @@
int blockedPort = 0;
if (blockPort) {
blockedPort = ntohs(port);
- status = mService->blockPortForBind(blockedPort);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
+ err = blockPortForBind(blockedPort);
+ EXPECT_EQ(err, 0);
}
int sock3 = openSocket(&port, family, type, blockPort /* expectBindFail */);
if (blockPort) {
EXPECT_EQ(-1, sock3);
- status = mService->unblockPortForBind(blockedPort);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
+ err = unblockPortForBind(blockedPort);
+ EXPECT_EQ(err, 0);
} else {
EXPECT_NE(-1, sock3);
}
@@ -177,110 +196,74 @@
}
TEST_F(ConnectivityNativeBinderTest, BlockPortTwice) {
- ndk::ScopedAStatus status = mService->blockPortForBind(5555);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
- status = mService->blockPortForBind(5555);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
- status = mService->unblockPortForBind(5555);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
+ int err = blockPortForBind(5555);
+ EXPECT_EQ(err, 0);
+ err = blockPortForBind(5555);
+ EXPECT_EQ(err, 0);
+ err = unblockPortForBind(5555);
+ EXPECT_EQ(err, 0);
}
TEST_F(ConnectivityNativeBinderTest, GetBlockedPorts) {
- ndk::ScopedAStatus status;
- std::vector<int> blockedPorts{1, 100, 1220, 1333, 2700, 5555, 5600, 65000};
- for (int i : blockedPorts) {
- status = mService->blockPortForBind(i);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
+ int err;
+ in_port_t blockedPorts[8] = {1, 100, 1220, 1333, 2700, 5555, 5600, 65000};
+
+ if (mActualBlockedPortsCount > 0) {
+ err = unblockAllPortsForBind();
}
- std::vector<int32_t> actualBlockedPorts;
- status = mService->getPortsBlockedForBind(&actualBlockedPorts);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
- EXPECT_FALSE(actualBlockedPorts.empty());
- EXPECT_EQ(blockedPorts, actualBlockedPorts);
+
+ for (int i : blockedPorts) {
+ err = blockPortForBind(i);
+ EXPECT_EQ(err, 0);
+ }
+ size_t actualBlockedPortsCount = 8;
+ in_port_t actualBlockedPorts[actualBlockedPortsCount];
+ err = getPortsBlockedForBind((in_port_t*) actualBlockedPorts, &actualBlockedPortsCount);
+ EXPECT_EQ(err, 0);
+ EXPECT_NE(actualBlockedPortsCount, 0);
+ for (int i=0; i < actualBlockedPortsCount; i++) {
+ EXPECT_EQ(blockedPorts[i], actualBlockedPorts[i]);
+ }
// Remove the ports we added.
- status = mService->unblockAllPortsForBind();
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
- status = mService->getPortsBlockedForBind(&actualBlockedPorts);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
- EXPECT_TRUE(actualBlockedPorts.empty());
+ err = unblockAllPortsForBind();
+ EXPECT_EQ(err, 0);
+ err = getPortsBlockedForBind(actualBlockedPorts, &actualBlockedPortsCount);
+ EXPECT_EQ(err, 0);
+ EXPECT_EQ(actualBlockedPortsCount, 0);
}
TEST_F(ConnectivityNativeBinderTest, UnblockAllPorts) {
- ndk::ScopedAStatus status;
- std::vector<int> blockedPorts{1, 100, 1220, 1333, 2700, 5555, 5600, 65000};
+ int err;
+ in_port_t blockedPorts[8] = {1, 100, 1220, 1333, 2700, 5555, 5600, 65000};
- if (mActualBlockedPorts.size() > 0) {
- status = mService->unblockAllPortsForBind();
+ if (mActualBlockedPortsCount > 0) {
+ err = unblockAllPortsForBind();
}
for (int i : blockedPorts) {
- status = mService->blockPortForBind(i);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
+ err = blockPortForBind(i);
+ EXPECT_EQ(err, 0);
}
- std::vector<int32_t> actualBlockedPorts;
- status = mService->getPortsBlockedForBind(&actualBlockedPorts);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
- EXPECT_FALSE(actualBlockedPorts.empty());
+ size_t actualBlockedPortsCount = 8;
+ in_port_t actualBlockedPorts[actualBlockedPortsCount];
+ err = getPortsBlockedForBind((in_port_t*) actualBlockedPorts, &actualBlockedPortsCount);
+ EXPECT_EQ(err, 0);
+ EXPECT_EQ(actualBlockedPortsCount, 8);
- status = mService->unblockAllPortsForBind();
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
- status = mService->getPortsBlockedForBind(&actualBlockedPorts);
- EXPECT_TRUE(status.isOk()) << status.getDescription ();
- EXPECT_TRUE(actualBlockedPorts.empty());
+ err = unblockAllPortsForBind();
+ EXPECT_EQ(err, 0);
+ err = getPortsBlockedForBind((in_port_t*) actualBlockedPorts, &actualBlockedPortsCount);
+ EXPECT_EQ(err, 0);
+ EXPECT_EQ(actualBlockedPortsCount, 0);
// If mActualBlockedPorts is not empty, ports will be added back in teardown.
}
-TEST_F(ConnectivityNativeBinderTest, BlockNegativePort) {
- int retry = 0;
- ndk::ScopedAStatus status;
- do {
- status = mService->blockPortForBind(-1);
- // TODO: find out why transaction failed is being thrown on the first attempt.
- } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
- EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
-}
-
-TEST_F(ConnectivityNativeBinderTest, UnblockNegativePort) {
- int retry = 0;
- ndk::ScopedAStatus status;
- do {
- status = mService->unblockPortForBind(-1);
- // TODO: find out why transaction failed is being thrown on the first attempt.
- } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
- EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
-}
-
-TEST_F(ConnectivityNativeBinderTest, BlockMaxPort) {
- int retry = 0;
- ndk::ScopedAStatus status;
- do {
- status = mService->blockPortForBind(65536);
- // TODO: find out why transaction failed is being thrown on the first attempt.
- } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
- EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
-}
-
-TEST_F(ConnectivityNativeBinderTest, UnblockMaxPort) {
- int retry = 0;
- ndk::ScopedAStatus status;
- do {
- status = mService->unblockPortForBind(65536);
- // TODO: find out why transaction failed is being thrown on the first attempt.
- } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
- EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
-}
-
TEST_F(ConnectivityNativeBinderTest, CheckPermission) {
- int retry = 0;
int curUid = getuid();
EXPECT_EQ(0, seteuid(FIRST_APPLICATION_UID + 2000)) << "seteuid failed: " << strerror(errno);
- ndk::ScopedAStatus status;
- do {
- status = mService->blockPortForBind(5555);
- // TODO: find out why transaction failed is being thrown on the first attempt.
- } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
- EXPECT_EQ(EX_SECURITY, status.getExceptionCode());
+ int err = blockPortForBind((in_port_t) 5555);
+ EXPECT_EQ(EPERM, err);
EXPECT_EQ(0, seteuid(curUid)) << "seteuid failed: " << strerror(errno);
}