C++程序  |  235行  |  9.12 KB

//
// Copyright (C) 2014 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 SHILL_CELLULAR_MOBILE_OPERATOR_INFO_IMPL_H_
#define SHILL_CELLULAR_MOBILE_OPERATOR_INFO_IMPL_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <base/cancelable_callback.h>
#include <base/files/file_util.h>
#include <base/memory/scoped_vector.h>
#include <base/memory/weak_ptr.h>
#include <base/observer_list.h>

#include "shill/cellular/mobile_operator_info.h"
#include "shill/event_dispatcher.h"
#include "shill/mobile_operator_db/mobile_operator_db.pb.h"

namespace shill {

class MobileOperatorInfoImpl {
 public:
  typedef
  std::map<std::string,
           std::vector<const mobile_operator_db::MobileNetworkOperator*>>
      StringToMNOListMap;

  MobileOperatorInfoImpl(EventDispatcher* dispatcher,
                         const std::string& info_owner);
  ~MobileOperatorInfoImpl();

  // API functions of the interface.
  // See mobile_operator_info_impl.h for details.
  void ClearDatabasePaths();
  void AddDatabasePath(const base::FilePath& absolute_path);
  bool Init();
  void AddObserver(MobileOperatorInfo::Observer* observer);
  void RemoveObserver(MobileOperatorInfo::Observer* observer);
  bool IsMobileNetworkOperatorKnown() const;
  bool IsMobileVirtualNetworkOperatorKnown() const;
  const std::string& info_owner() const;
  const std::string& uuid() const;
  const std::string& operator_name() const;
  const std::string& country() const;
  const std::string& mccmnc() const;
  const std::string& sid() const;
  const std::string& nid() const;
  const std::vector<std::string>& mccmnc_list() const;
  const std::vector<std::string>& sid_list() const;
  const std::vector<MobileOperatorInfo::LocalizedName>
      &operator_name_list() const;
  const ScopedVector<MobileOperatorInfo::MobileAPN>& apn_list() const;
  const std::vector<MobileOperatorInfo::OnlinePortal>& olp_list() const;
  const std::string& activation_code() const;
  bool requires_roaming() const;
  void Reset();
  void UpdateIMSI(const std::string& imsi);
  void UpdateICCID(const std::string& iccid);
  void UpdateMCCMNC(const std::string& mccmnc);
  void UpdateSID(const std::string& sid);
  void UpdateNID(const std::string& nid);
  void UpdateOperatorName(const std::string& operator_name);
  void UpdateOnlinePortal(const std::string& url,
                          const std::string& method,
                          const std::string& post_data);

 private:
  friend class MobileOperatorInfoInitTest;

  // ///////////////////////////////////////////////////////////////////////////
  // Static variables.
  // Default databases to load.
  static const char* kDefaultDatabasePath;
  // MCCMNC can be of length 5 or 6. When using this constant, keep in mind that
  // the length of MCCMNC can by |kMCCMNCMinLen| or |kMCCMNCMinLen + 1|.
  static const int kMCCMNCMinLen;

  // ///////////////////////////////////////////////////////////////////////////
  // Functions.
  void PreprocessDatabase();
  // This function assumes that duplicate |values| are never inserted for the
  // same |key|. If you do that, the function is too dumb to deduplicate the
  // |value|s, and two copies will get stored.
  void InsertIntoStringToMNOListMap(
      StringToMNOListMap* table,
      const std::string& key,
      const mobile_operator_db::MobileNetworkOperator* value);

  bool UpdateMNO();
  bool UpdateMVNO();
  bool FilterMatches(const shill::mobile_operator_db::Filter& filter);
  const mobile_operator_db::MobileNetworkOperator* PickOneFromDuplicates(
      const std::vector<const mobile_operator_db::MobileNetworkOperator*>
          &duplicates) const;
  // Reloads the information about M[V]NO from the database.
  void RefreshDBInformation();
  void ClearDBInformation();
  // Reload all data from |data|.
  // Semantics: If a field data.x exists, then it *overwrites* the current
  // information gained from data.x. E.g., if |data.name_size() > 0| is true,
  // then we replace *all* names. Otherwise, we leave names untouched.
  // This allows MVNOs to overwrite information obtained from the corresponding
  // MNO.
  void ReloadData(const mobile_operator_db::Data& data);
  // Append candidates recognized by |mccmnc| to the candidate list.
  bool AppendToCandidatesByMCCMNC(const std::string& mccmnc);
  bool AppendToCandidatesBySID(const std::string& sid);
  std::string OperatorCodeString() const;

  // Notifies all observers that the operator has changed.
  void PostNotifyOperatorChanged();
  // The actual notification is sent out here. This should not be called
  // directly from any function.
  void NotifyOperatorChanged();

  // For a property update that does not result in an M[V]NO update, this
  // function determines whether observers should be notified anyway.
  bool ShouldNotifyPropertyUpdate() const;

  // OperatorName comparisons for determining the MNO are done after normalizing
  // the names to ignore case and spaces.
  std::string NormalizeOperatorName(const std::string& name) const;

  // These functions encapsulate the logic to update different properties
  // properly whenever an update is either received from the user or the
  // database.
  void HandleMCCMNCUpdate();
  void HandleOperatorNameUpdate();
  void HandleSIDUpdate();
  void HandleOnlinePortalUpdate();

  // Accessor functions for testing purpose only.
  mobile_operator_db::MobileOperatorDB* database() {
    return database_.get();
  }

  // ///////////////////////////////////////////////////////////////////////////
  // Data.
  // Not owned by MobileOperatorInfoImpl.
  EventDispatcher* const dispatcher_;

  const std::string info_owner_;

  // Owned by MobileOperatorInfoImpl, may be created externally.
  std::vector<base::FilePath> database_paths_;

  // Owned and modified only by MobileOperatorInfoImpl.
  // The observers added to this list are not owned by this object. Moreover,
  // the observer is likely to outlive this object. We do enforce removal of all
  // observers before this object is destroyed.
  base::ObserverList<MobileOperatorInfo::Observer> observers_;
  base::CancelableClosure notify_operator_changed_task_;

  std::unique_ptr<mobile_operator_db::MobileOperatorDB> database_;
  StringToMNOListMap mccmnc_to_mnos_;
  StringToMNOListMap sid_to_mnos_;
  StringToMNOListMap name_to_mnos_;

  // |candidates_by_operator_code| can be determined either using MCCMNC or
  // using SID.  At any one time, we only expect one of these operator codes to
  // be updated by the user. We use |operator_code_type_| to keep track of which
  // update we have received and warn the user if we receive both.
  enum OperatorCodeType {
    kOperatorCodeTypeUnknown = 0,
    kOperatorCodeTypeMCCMNC,
    kOperatorCodeTypeSID,
  };
  OperatorCodeType operator_code_type_;
  std::vector<const mobile_operator_db::MobileNetworkOperator*>
      candidates_by_operator_code_;

  std::vector<const mobile_operator_db::MobileNetworkOperator*>
      candidates_by_name_;
  const mobile_operator_db::MobileNetworkOperator* current_mno_;
  const mobile_operator_db::MobileVirtualNetworkOperator* current_mvno_;

  // These fields are the information expected to be populated by this object
  // after successfully determining the MVNO.
  std::string uuid_;
  std::string operator_name_;
  std::string country_;
  std::string mccmnc_;
  std::string sid_;
  std::string nid_;
  std::vector<std::string> mccmnc_list_;
  std::vector<std::string> sid_list_;
  std::vector<MobileOperatorInfo::LocalizedName> operator_name_list_;
  ScopedVector<MobileOperatorInfo::MobileAPN> apn_list_;
  std::vector<MobileOperatorInfo::OnlinePortal> olp_list_;
  std::vector<mobile_operator_db::OnlinePortal> raw_olp_list_;
  std::string activation_code_;
  bool requires_roaming_;
  // These fields store the data obtained from the Update* methods.
  // The database information is kept separate from the information gathered
  // through the Update* methods, because one or the other may be given
  // precedence in different situations.
  // Note: For simplicity, we do not allow the user to enforce an empty value
  // for these variables. So, if |user_mccmnc_| == "", the |mccmnc_| obtained
  // from the database will be used, even if |user_mccmnc_| was explicitly set
  // by the user.
  std::string user_imsi_;
  std::string user_iccid_;
  std::string user_mccmnc_;
  std::string user_sid_;
  std::string user_nid_;
  std::string user_operator_name_;
  bool user_olp_empty_;
  MobileOperatorInfo::OnlinePortal user_olp_;

  // This must be the last data member of this class.
  base::WeakPtrFactory<MobileOperatorInfoImpl> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(MobileOperatorInfoImpl);
};

}  // namespace shill

#endif  // SHILL_CELLULAR_MOBILE_OPERATOR_INFO_IMPL_H_