blob: e6523e3f999c6ac7adcaab0b5317fff46e668c00 [file] [log] [blame]
//
// 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 "shill/setup_wifi/binder_client.h"
#include <sysexits.h>
#include <android/system/connectivity/shill/IManager.h>
#include <base/bind.h>
#include <base/logging.h>
#include <binderwrapper/binder_wrapper.h>
#include <brillo/daemons/daemon.h>
#include <shill/key_value_store.h>
#include <utils/String16.h>
// TODO(samueltan): remove these includes once b/27270173 is resolved,
// and Manager is no longer reliant on D-Bus service constants.
#if defined(__ANDROID__)
#include <dbus/service_constants.h>
#else
#include <chromeos/dbus/service_constants.h>
#endif // __ANDROID__
using android::IBinder;
using android::os::PersistableBundle;
using android::sp;
using android::String16;
using android::system::connectivity::shill::IManager;
using android::system::connectivity::shill::IService;
using std::string;
namespace {
const int kTimeoutBetweenStateChecksMs = 100;
const char kManagerName[] = "android.system.connectivity.shill.IManager";
} // namespace
namespace setup_wifi {
BinderClient::BinderClient(const string& ssid, const string& psk,
bool is_hex_ssid, int timeout)
: ssid_(ssid), psk_(psk), is_hex_ssid_(is_hex_ssid), timeout_(timeout) {}
int BinderClient::OnInit() {
int ret = Daemon::OnInit();
if (ret != EX_OK) {
return ret;
}
ConfigureAndConnect();
// Timeout if we can't get online.
brillo::MessageLoop::current()->PostDelayedTask(
base::Bind(&BinderClient::Quit, base::Unretained(this)),
base::TimeDelta::FromSeconds(timeout_));
return EX_OK;
}
bool BinderClient::ConfigureAndConnect() {
android::BinderWrapper::Create();
if (!binder_watcher_.Init()) {
LOG(ERROR) << "Binder connection failed.";
return false;
}
sp<IBinder> manager_binder =
android::BinderWrapper::Get()->GetService(kManagerName);
if (!manager_binder.get()) {
LOG(ERROR) << "Manager service not registered.";
return false;
}
sp<IManager> manager = android::interface_cast<IManager>(manager_binder);
if (!manager->ConfigureService(GetServiceConfig(), &shill_service_proxy_)
.isOk()) {
LOG(ERROR) << "Configure service failed.";
return false;
}
if (!shill_service_proxy_->Connect().isOk()) {
LOG(ERROR) << "Connect service failed.";
return false;
}
PostCheckWifiStatusTask();
return true;
}
void BinderClient::PostCheckWifiStatusTask() {
LOG(INFO) << "Sleeping now. Will check wifi status in 100 ms.";
brillo::MessageLoop::current()->PostDelayedTask(
base::Bind(&BinderClient::QuitIfOnline, base::Unretained(this)),
base::TimeDelta::FromMilliseconds(kTimeoutBetweenStateChecksMs));
}
// Check if the device is online. If it is, quit.
void BinderClient::QuitIfOnline() {
if (IsOnline())
Quit();
else
PostCheckWifiStatusTask();
}
bool BinderClient::IsOnline() {
int state;
if (!shill_service_proxy_->GetState(&state).isOk()) {
LOG(ERROR) << "Get state failed.";
PostCheckWifiStatusTask();
return false;
}
return state == android::system::connectivity::shill::IService::STATE_ONLINE;
}
PersistableBundle BinderClient::GetServiceConfig() {
PersistableBundle configure_bundle;
configure_bundle.putString(String16(shill::kTypeProperty),
String16(shill::kTypeWifi));
if (is_hex_ssid_) {
configure_bundle.putString(String16(shill::kWifiHexSsid),
String16(ssid_.c_str()));
} else {
configure_bundle.putString(String16(shill::kSSIDProperty),
String16(ssid_.c_str()));
}
if (!psk_.empty()) {
configure_bundle.putString(String16(shill::kPassphraseProperty),
String16(psk_.c_str()));
configure_bundle.putString(String16(shill::kSecurityProperty),
String16(shill::kSecurityPsk));
}
return configure_bundle;
}
} // namespace setup_wifi