| // Copyright 2018 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. |
| |
| #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/weak_ptr.h> |
| #include <base/observer_list.h> |
| #include <google/protobuf/text_format.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: |
| using StringToMNOListMap = |
| std::map<std::string, |
| std::vector<const mobile_operator_db::MobileNetworkOperator*>>; |
| |
| // Delegates to private constructor |
| MobileOperatorInfoImpl(EventDispatcher* dispatcher, |
| const std::string& info_owner); |
| ~MobileOperatorInfoImpl(); |
| |
| // API functions of the interface. |
| // See mobile_operator_info.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 std::vector<MobileOperatorInfo::MobileAPN>& apn_list() const; |
| const std::vector<MobileOperatorInfo::OnlinePortal>& olp_list() const; |
| const std::string& activation_code() const; |
| bool requires_roaming() const; |
| int32_t mtu() 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); |
| void UpdateRequiresRoaming(const MobileOperatorInfo* serving_operator_info); |
| |
| private: |
| friend class MobileOperatorInfoInitTest; |
| friend class MobileOperatorInfoOverrideTest; |
| |
| // /////////////////////////////////////////////////////////////////////////// |
| // Constructor |
| MobileOperatorInfoImpl(EventDispatcher* dispatcher, |
| const std::string& info_owner, |
| const base::FilePath& default_db_path, |
| const base::FilePath& exclusive_override_db_path); |
| MobileOperatorInfoImpl(const MobileOperatorInfoImpl&) = delete; |
| MobileOperatorInfoImpl& operator=(const MobileOperatorInfoImpl&) = delete; |
| |
| // /////////////////////////////////////////////////////////////////////////// |
| // Static variables. |
| // Default databases to load. |
| static const char kDefaultDatabasePath[]; |
| static const char kExclusiveOverrideDatabasePath[]; |
| // 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 class OperatorCodeType { |
| kUnknown, |
| kMCCMNC, |
| kSID, |
| }; |
| 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_; |
| bool prioritizes_db_operator_name_; |
| std::vector<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_; |
| std::vector<mobile_operator_db::Filter> roaming_filter_list_; |
| int32_t mtu_; |
| // 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_; |
| }; |
| |
| } // namespace shill |
| |
| #endif // SHILL_CELLULAR_MOBILE_OPERATOR_INFO_IMPL_H_ |