shill: cellular: Add MobileOperatorInfo.

MobileOperatorInfo is a new event based object to get information about
mobile operators. It will replace CellularOperatorInfo and mobile_provider_db.
In addition to accessing the mobile oprator database, this object wraps the
logic required to determine the mobile operator given identifying information,
and exposes an Observer interface for other objects to be notified whenever the
mobile operator has been successfully identified.

This CL specifically:
- Adds the |MobileOperatorInfo| interface object. This is the object exposed to
  clients.
- Creates |MobileOperatorInfo| objects and decides ownership.
- Implements |MobileOperatorInfoImpl|, the internal object that
  |MobileOperatorInfo| forwards all requests to. It receives updates
  from the |Capability*| classes, and having determined an M[V]NO, notfies the
  |Observer| objects created by |Cellular|.
- Wires up the cellular objects to
  - Send updates to the two |MobileOperatorInfo| objects from the capabilities.
  - Use observers in |Cellular| to act whenever an M[V]NO is determined.

Note that the old code paths for determining the MNO, that are spread over the
|Cellular|, |Capability*|, and the |CellularService| classes still exist, so
that |Cellular| will recieve duplicate updates about |home_provider| and
|serving_operator|. These old code paths will be removed in a following CL.

BUG=chromium:352237
TEST=(1) Shill unittests.
     (2) Manual testing of cellular device on e362, gobi modems, alt3100, y3400,
         and some cellular dongles.
CQ-DEPEND=CL:190188

Change-Id: I2d5af413110cdd5a4f71389f3f3c79b846a97c2a
Reviewed-on: https://chromium-review.googlesource.com/192145
Tested-by: Prathmesh Prabhu <pprabhu@chromium.org>
Reviewed-by: Thieu Le <thieule@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Commit-Queue: Ben Chan <benchan@chromium.org>
diff --git a/mobile_operator_info.cc b/mobile_operator_info.cc
new file mode 100644
index 0000000..79577cd
--- /dev/null
+++ b/mobile_operator_info.cc
@@ -0,0 +1,238 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/mobile_operator_info.h"
+
+#include <sstream>
+
+#include "shill/logging.h"
+#include "shill/mobile_operator_info_impl.h"
+
+namespace shill {
+
+using base::FilePath;
+using std::string;
+using std::stringstream;
+using std::vector;
+
+// /////////////////////////////////////////////////////////////////////////////
+// MobileOperatorInfo implementation note:
+// MobileOperatorInfo simply forwards all operations to |impl_|.
+// It also logs the functions/arguments/results at sane log levels. So the
+// implementation need not leave a trace itself.
+
+MobileOperatorInfo::MobileOperatorInfo(EventDispatcher *dispatcher)
+    : impl_(new MobileOperatorInfoImpl(dispatcher)) {}
+
+MobileOperatorInfo::~MobileOperatorInfo() {}
+
+void MobileOperatorInfo::ClearDatabasePaths() {
+  SLOG(Cellular, 3) << __func__;
+  impl_->ClearDatabasePaths();
+}
+
+void MobileOperatorInfo::AddDatabasePath(const FilePath &absolute_path) {
+  SLOG(Cellular, 3) << __func__ << "(" << absolute_path.value() << ")";
+  impl_->AddDatabasePath(absolute_path);
+}
+
+bool MobileOperatorInfo::Init() {
+  auto result = impl_->Init();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+void MobileOperatorInfo::AddObserver(MobileOperatorInfo::Observer *observer) {
+  SLOG(Cellular, 3) << __func__;
+  impl_->AddObserver(observer);
+}
+
+void MobileOperatorInfo::RemoveObserver(
+    MobileOperatorInfo::Observer *observer) {
+  SLOG(Cellular, 3) << __func__;
+  impl_->RemoveObserver(observer);
+}
+
+bool MobileOperatorInfo::IsMobileNetworkOperatorKnown() const {
+  auto result = impl_->IsMobileNetworkOperatorKnown();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+bool MobileOperatorInfo::IsMobileVirtualNetworkOperatorKnown() const {
+  auto result = impl_->IsMobileVirtualNetworkOperatorKnown();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+const string &MobileOperatorInfo::uuid() const {
+  const auto &result = impl_->uuid();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+const string &MobileOperatorInfo::operator_name() const {
+  const auto &result = impl_->operator_name();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+const string &MobileOperatorInfo::country() const {
+  const auto &result = impl_->country();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+const string &MobileOperatorInfo::mccmnc() const {
+  const auto &result = impl_->mccmnc();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+const string &MobileOperatorInfo::sid() const {
+  const auto &result = impl_->sid();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+const string &MobileOperatorInfo::nid() const {
+  const auto &result = impl_->nid();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+const vector<string> &MobileOperatorInfo::mccmnc_list() const {
+  const auto &result = impl_->mccmnc_list();
+  if (SLOG_IS_ON(Cellular, 3)) {
+    stringstream pp_result;
+    for (const auto &mccmnc : result) {
+      pp_result << mccmnc << " ";
+    }
+    SLOG(Cellular, 3) << __func__ << ": Result[" << pp_result.str() << "]";
+  }
+  return result;
+}
+
+const vector<string> &MobileOperatorInfo::sid_list() const {
+  const auto &result = impl_->sid_list();
+  if (SLOG_IS_ON(Cellular, 3)) {
+    stringstream pp_result;
+    for (const auto &sid : result) {
+      pp_result << sid << " ";
+    }
+    SLOG(Cellular, 3) << __func__ << ": Result[" << pp_result.str() << "]";
+  }
+  return result;
+}
+
+const vector<MobileOperatorInfo::LocalizedName> &
+MobileOperatorInfo::operator_name_list() const {
+  const auto &result = impl_->operator_name_list();
+  if (SLOG_IS_ON(Cellular, 3)) {
+    stringstream pp_result;
+    for (const auto &operator_name : result) {
+      pp_result << "(" << operator_name.name << ", "
+        << operator_name.language << ") ";
+    }
+    SLOG(Cellular, 3) << __func__ << ": Result[" << pp_result.str() << "]";
+  }
+  return result;
+}
+
+const ScopedVector<MobileOperatorInfo::MobileAPN> &
+MobileOperatorInfo::apn_list() const {
+  const auto &result = impl_->apn_list();
+  if (SLOG_IS_ON(Cellular, 3)) {
+    stringstream pp_result;
+    for (const auto &mobile_apn : result) {
+      pp_result << "(apn: " << mobile_apn->apn
+        << ", username: " << mobile_apn->username
+        << ", password: " << mobile_apn->password;
+      pp_result << ", operator_name_list: '";
+      for (const auto &operator_name : mobile_apn->operator_name_list) {
+        pp_result << "(" << operator_name.name << ", "
+          << operator_name.language << ") ";
+      }
+      pp_result << "') ";
+    }
+    SLOG(Cellular, 3) << __func__ << ": Result[" << pp_result.str() << "]";
+  }
+  return result;
+}
+
+const vector<MobileOperatorInfo::OnlinePortal> &
+MobileOperatorInfo::olp_list() const {
+  const auto &result = impl_->olp_list();
+  if (SLOG_IS_ON(Cellular, 3)) {
+    stringstream pp_result;
+    for (const auto &olp : result) {
+      pp_result << "(url: " << olp.url
+        << ", method: " << olp.method
+        << ", post_data: " << olp.post_data
+        << ") ";
+    }
+    SLOG(Cellular, 3) << __func__ << ": Result[" << pp_result.str() << "]";
+  }
+  return result;
+}
+
+const string &MobileOperatorInfo::activation_code() const {
+  const auto &result = impl_->activation_code();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+bool MobileOperatorInfo::requires_roaming() const {
+  auto result = impl_->requires_roaming();
+  SLOG(Cellular, 3) << __func__ << ": Result[" << result << "]";
+  return result;
+}
+
+void MobileOperatorInfo::UpdateIMSI(const string &imsi) {
+  SLOG(Cellular, 3) << __func__ << "(" << imsi << ")";
+  impl_->UpdateIMSI(imsi);
+}
+
+void MobileOperatorInfo::UpdateICCID(const string &iccid) {
+  SLOG(Cellular, 3) << __func__ << "(" << iccid << ")";
+  impl_->UpdateICCID(iccid);
+}
+
+void MobileOperatorInfo::UpdateMCCMNC(const string &mccmnc) {
+  SLOG(Cellular, 3) << __func__ << "(" << mccmnc << ")";
+  impl_->UpdateMCCMNC(mccmnc);
+}
+
+void MobileOperatorInfo::UpdateSID(const string &sid) {
+  SLOG(Cellular, 3) << __func__ << "(" << sid << ")";
+  impl_->UpdateSID(sid);
+}
+
+void MobileOperatorInfo::UpdateNID(const string &nid) {
+  SLOG(Cellular, 3) << __func__ << "(" << nid << ")";
+  impl_->UpdateNID(nid);
+}
+
+void MobileOperatorInfo::UpdateOperatorName(const string &operator_name) {
+  SLOG(Cellular, 3) << __func__ << "(" << operator_name << ")";
+  impl_->UpdateOperatorName(operator_name);
+}
+
+void MobileOperatorInfo::UpdateOnlinePortal(const string &url,
+                                            const string &method,
+                                            const string &post_data) {
+  SLOG(Cellular, 3) << __func__
+                    << "(" << url
+                    << ", " << method
+                    << ", " << post_data
+                    << ")";
+  impl_->UpdateOnlinePortal(url, method, post_data);
+}
+
+void MobileOperatorInfo::Reset() {
+  SLOG(Cellular ,3) << __func__;
+  impl_->Reset();
+}
+
+}  // namespace shill