OSDN Git Service

Expose IPC interfaces to create/destroy AP interfaces
authorChristopher Wiley <wiley@google.com>
Thu, 23 Jun 2016 00:20:04 +0000 (17:20 -0700)
committerChristopher Wiley <wiley@google.com>
Fri, 24 Jun 2016 20:40:53 +0000 (13:40 -0700)
Bug: 29579539
Change-Id: I49e050a6c806a5841931b1c2cddfbba7925f744a
Test: Unit, integration tests pass

Android.mk
aidl/android/net/wifi/IWificond.aidl
ap_interface_binder.cpp [new file with mode: 0644]
ap_interface_binder.h [new file with mode: 0644]
ap_interface_impl.cpp [new file with mode: 0644]
ap_interface_impl.h [new file with mode: 0644]
server.cpp
server.h
tests/integration/life_cycle_test.cpp

index c3e425d..e799f69 100644 (file)
@@ -40,6 +40,8 @@ include $(CLEAR_VARS)
 LOCAL_MODULE := libwificond
 LOCAL_CPPFLAGS := $(wificond_cpp_flags)
 LOCAL_SRC_FILES := \
+    ap_interface_binder.cpp \
+    ap_interface_impl.cpp \
     client_interface.cpp \
     looper_backed_event_loop.cpp \
     server.cpp
index 483a3fb..9b20843 100644 (file)
 
 package android.net.wifi;
 
+import android.net.wifi.IApInterface;
+
 // Service interface that exposes primitives for controlling the WiFi
 // subsystems of a device.
 interface IWificond {
 
+  // Create a network interface suitable for use as an AP.
+  IApInterface CreateApInterface();
+
+  // Tear down all existing interfaces.  This should enable clients to create
+  // future interfaces immediately after this method returns.
+  void TearDownInterfaces();
+
 }
diff --git a/ap_interface_binder.cpp b/ap_interface_binder.cpp
new file mode 100644 (file)
index 0000000..8f3a135
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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 "ap_interface_binder.h"
+
+namespace android {
+namespace wificond {
+
+ApInterfaceBinder::ApInterfaceBinder(ApInterfaceImpl* impl) : impl_{impl} {
+}
+
+ApInterfaceBinder::~ApInterfaceBinder() {
+}
+
+}  // namespace wificond
+}  // namespace android
diff --git a/ap_interface_binder.h b/ap_interface_binder.h
new file mode 100644 (file)
index 0000000..ace244f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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 WIFICOND_AP_INTERFACE_BINDER_H_
+#define WIFICOND_AP_INTERFACE_BINDER_H_
+
+#include <android-base/macros.h>
+
+#include "android/net/wifi/BnApInterface.h"
+
+namespace android {
+namespace wificond {
+
+class ApInterfaceImpl;
+
+class ApInterfaceBinder : public android::net::wifi::BnApInterface {
+ public:
+  explicit ApInterfaceBinder(ApInterfaceImpl* impl);
+  ~ApInterfaceBinder() override;
+
+  // Called by |impl_| its destruction.
+  // This informs the binder proxy that no future manipulations of |impl_|
+  // by remote processes are possible.
+  void NotifyImplDead() { impl_ = nullptr; }
+
+ private:
+  ApInterfaceImpl* impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(ApInterfaceBinder);
+};
+
+}  // namespace wificond
+}  // namespace android
+
+#endif  // WIFICOND_AP_INTERFACE_BINDER_H_
diff --git a/ap_interface_impl.cpp b/ap_interface_impl.cpp
new file mode 100644 (file)
index 0000000..c7974a7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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 "ap_interface_impl.h"
+
+#include "ap_interface_binder.h"
+
+using android::net::wifi::IApInterface;
+
+namespace android {
+namespace wificond {
+
+ApInterfaceImpl::ApInterfaceImpl() {
+  binder_ = new ApInterfaceBinder(this);
+}
+
+ApInterfaceImpl::~ApInterfaceImpl() {
+  binder_->NotifyImplDead();
+}
+
+sp<IApInterface> ApInterfaceImpl::GetBinder() const {
+  return binder_;
+}
+
+}  // namespace wificond
+}  // namespace android
diff --git a/ap_interface_impl.h b/ap_interface_impl.h
new file mode 100644 (file)
index 0000000..7dff654
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 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 WIFICOND_AP_INTERFACE_IMPL_H_
+#define WIFICOND_AP_INTERFACE_IMPL_H_
+
+#include <android-base/macros.h>
+
+#include "android/net/wifi/IApInterface.h"
+
+namespace android {
+namespace wificond {
+
+class ApInterfaceBinder;
+
+// Holds the guts of how we control network interfaces capable of exposing an AP
+// via hostapd.  Because remote processes may hold on to the corresponding
+// binder object past the lifetime of the local object, we are forced to
+// keep this object separate from the binder representation of itself.
+class ApInterfaceImpl {
+ public:
+  ApInterfaceImpl();
+  ~ApInterfaceImpl();
+
+  // Get a pointer to the binder representing this ApInterfaceImpl.
+  android::sp<android::net::wifi::IApInterface> GetBinder() const;
+
+ private:
+  android::sp<ApInterfaceBinder> binder_;
+
+  DISALLOW_COPY_AND_ASSIGN(ApInterfaceImpl);
+};
+
+}  // namespace wificond
+}  // namespace android
+
+#endif  // WIFICOND_AP_INTERFACE_IMPL_H_
index 94454ea..444cf8e 100644 (file)
 
 #include "server.h"
 
+using android::binder::Status;
+using android::sp;
+using android::IBinder;
+using std::vector;
+using std::unique_ptr;
+using android::net::wifi::IApInterface;
+
 namespace android {
 namespace wificond {
 
-Server::Server() {
+Status Server::CreateApInterface(sp<IApInterface>* created_interface) {
+  if (!ap_interfaces_.empty()) {
+    // In the future we may support multiple interfaces at once.  However,
+    // today, we support just one.
+    return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+  }
+
+  unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl);
+  *created_interface = ap_interface->GetBinder();
+  ap_interfaces_.push_back(std::move(ap_interface));
+  return Status::ok();
+}
+
+Status Server::TearDownInterfaces() {
+  ap_interfaces_.clear();
+  return Status::ok();
 }
 
 }  // namespace wificond
index c236c21..189abb9 100644 (file)
--- a/server.h
+++ b/server.h
 #ifndef WIFICOND_SERVER_H_
 #define WIFICOND_SERVER_H_
 
+#include <memory>
+#include <vector>
+
 #include <android-base/macros.h>
 
 #include "android/net/wifi/BnWificond.h"
 
+#include "ap_interface_impl.h"
+
 namespace android {
 namespace wificond {
 
 class Server : public android::net::wifi::BnWificond {
  public:
-  Server();
+  Server() = default;
   ~Server() override = default;
 
+  android::binder::Status CreateApInterface(
+      android::sp<android::net::wifi::IApInterface>* created_interface) override;
+
+  android::binder::Status TearDownInterfaces() override;
+
  private:
+  std::vector<std::unique_ptr<ApInterfaceImpl>> ap_interfaces_;
+
   DISALLOW_COPY_AND_ASSIGN(Server);
 };
 
index ad4e5a4..095ee61 100644 (file)
 #include <utils/String16.h>
 #include <utils/StrongPointer.h>
 
+#include "android/net/wifi/IApInterface.h"
 #include "android/net/wifi/IWificond.h"
 #include "tests/shell_utils.h"
 
 using android::String16;
 using android::base::Trim;
+using android::net::wifi::IApInterface;
 using android::net::wifi::IWificond;
 using android::wificond::tests::integration::RunShellCommand;
 
@@ -89,5 +91,26 @@ TEST(LifeCycleTest, ProcessStartsUp) {
   EXPECT_TRUE(WaitForTrue(IsRegistered, kWificondStartTimeoutSeconds));
 }
 
+TEST(LifeCycleTest, CanCreateApInterfaces) {
+  // Restart wificond and wait for it to come back.
+  RunShellCommand("stop wificond");
+  RunShellCommand("start wificond");
+  EXPECT_TRUE(WaitForTrue(IsRegistered, kWificondStartTimeoutSeconds));
+
+  sp<IWificond> service;
+  ASSERT_EQ(getService(String16(kWificondServiceName), &service), NO_ERROR);
+
+  // We should be able to create an AP interface.
+  sp<IApInterface> ap_interface;
+  ASSERT_TRUE(service->CreateApInterface(&ap_interface).isOk());
+
+  // We should not be able to create two AP interfaces.
+  sp<IApInterface> ap_interface2;
+  ASSERT_FALSE(service->CreateApInterface(&ap_interface2).isOk());
+
+  // We can tear down the created interface.
+  ASSERT_TRUE(service->TearDownInterfaces().isOk());
+}
+
 }  // namespace wificond
 }  // namespace android