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
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();
+
}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
#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
#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);
};
#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;
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