Home | History | Annotate | Download | only in cellular
      1 //
      2 // Copyright (C) 2014 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef SHILL_CELLULAR_MOBILE_OPERATOR_INFO_IMPL_H_
     18 #define SHILL_CELLULAR_MOBILE_OPERATOR_INFO_IMPL_H_
     19 
     20 #include <map>
     21 #include <memory>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include <base/cancelable_callback.h>
     26 #include <base/files/file_util.h>
     27 #include <base/memory/scoped_vector.h>
     28 #include <base/memory/weak_ptr.h>
     29 #include <base/observer_list.h>
     30 
     31 #include "shill/cellular/mobile_operator_info.h"
     32 #include "shill/event_dispatcher.h"
     33 #include "shill/mobile_operator_db/mobile_operator_db.pb.h"
     34 
     35 namespace shill {
     36 
     37 class MobileOperatorInfoImpl {
     38  public:
     39   typedef
     40   std::map<std::string,
     41            std::vector<const mobile_operator_db::MobileNetworkOperator*>>
     42       StringToMNOListMap;
     43 
     44   MobileOperatorInfoImpl(EventDispatcher* dispatcher,
     45                          const std::string& info_owner);
     46   ~MobileOperatorInfoImpl();
     47 
     48   // API functions of the interface.
     49   // See mobile_operator_info_impl.h for details.
     50   void ClearDatabasePaths();
     51   void AddDatabasePath(const base::FilePath& absolute_path);
     52   bool Init();
     53   void AddObserver(MobileOperatorInfo::Observer* observer);
     54   void RemoveObserver(MobileOperatorInfo::Observer* observer);
     55   bool IsMobileNetworkOperatorKnown() const;
     56   bool IsMobileVirtualNetworkOperatorKnown() const;
     57   const std::string& info_owner() const;
     58   const std::string& uuid() const;
     59   const std::string& operator_name() const;
     60   const std::string& country() const;
     61   const std::string& mccmnc() const;
     62   const std::string& sid() const;
     63   const std::string& nid() const;
     64   const std::vector<std::string>& mccmnc_list() const;
     65   const std::vector<std::string>& sid_list() const;
     66   const std::vector<MobileOperatorInfo::LocalizedName>
     67       &operator_name_list() const;
     68   const ScopedVector<MobileOperatorInfo::MobileAPN>& apn_list() const;
     69   const std::vector<MobileOperatorInfo::OnlinePortal>& olp_list() const;
     70   const std::string& activation_code() const;
     71   bool requires_roaming() const;
     72   void Reset();
     73   void UpdateIMSI(const std::string& imsi);
     74   void UpdateICCID(const std::string& iccid);
     75   void UpdateMCCMNC(const std::string& mccmnc);
     76   void UpdateSID(const std::string& sid);
     77   void UpdateNID(const std::string& nid);
     78   void UpdateOperatorName(const std::string& operator_name);
     79   void UpdateOnlinePortal(const std::string& url,
     80                           const std::string& method,
     81                           const std::string& post_data);
     82 
     83  private:
     84   friend class MobileOperatorInfoInitTest;
     85 
     86   // ///////////////////////////////////////////////////////////////////////////
     87   // Static variables.
     88   // Default databases to load.
     89   static const char* kDefaultDatabasePath;
     90   // MCCMNC can be of length 5 or 6. When using this constant, keep in mind that
     91   // the length of MCCMNC can by |kMCCMNCMinLen| or |kMCCMNCMinLen + 1|.
     92   static const int kMCCMNCMinLen;
     93 
     94   // ///////////////////////////////////////////////////////////////////////////
     95   // Functions.
     96   void PreprocessDatabase();
     97   // This function assumes that duplicate |values| are never inserted for the
     98   // same |key|. If you do that, the function is too dumb to deduplicate the
     99   // |value|s, and two copies will get stored.
    100   void InsertIntoStringToMNOListMap(
    101       StringToMNOListMap* table,
    102       const std::string& key,
    103       const mobile_operator_db::MobileNetworkOperator* value);
    104 
    105   bool UpdateMNO();
    106   bool UpdateMVNO();
    107   bool FilterMatches(const shill::mobile_operator_db::Filter& filter);
    108   const mobile_operator_db::MobileNetworkOperator* PickOneFromDuplicates(
    109       const std::vector<const mobile_operator_db::MobileNetworkOperator*>
    110           &duplicates) const;
    111   // Reloads the information about M[V]NO from the database.
    112   void RefreshDBInformation();
    113   void ClearDBInformation();
    114   // Reload all data from |data|.
    115   // Semantics: If a field data.x exists, then it *overwrites* the current
    116   // information gained from data.x. E.g., if |data.name_size() > 0| is true,
    117   // then we replace *all* names. Otherwise, we leave names untouched.
    118   // This allows MVNOs to overwrite information obtained from the corresponding
    119   // MNO.
    120   void ReloadData(const mobile_operator_db::Data& data);
    121   // Append candidates recognized by |mccmnc| to the candidate list.
    122   bool AppendToCandidatesByMCCMNC(const std::string& mccmnc);
    123   bool AppendToCandidatesBySID(const std::string& sid);
    124   std::string OperatorCodeString() const;
    125 
    126   // Notifies all observers that the operator has changed.
    127   void PostNotifyOperatorChanged();
    128   // The actual notification is sent out here. This should not be called
    129   // directly from any function.
    130   void NotifyOperatorChanged();
    131 
    132   // For a property update that does not result in an M[V]NO update, this
    133   // function determines whether observers should be notified anyway.
    134   bool ShouldNotifyPropertyUpdate() const;
    135 
    136   // OperatorName comparisons for determining the MNO are done after normalizing
    137   // the names to ignore case and spaces.
    138   std::string NormalizeOperatorName(const std::string& name) const;
    139 
    140   // These functions encapsulate the logic to update different properties
    141   // properly whenever an update is either received from the user or the
    142   // database.
    143   void HandleMCCMNCUpdate();
    144   void HandleOperatorNameUpdate();
    145   void HandleSIDUpdate();
    146   void HandleOnlinePortalUpdate();
    147 
    148   // Accessor functions for testing purpose only.
    149   mobile_operator_db::MobileOperatorDB* database() {
    150     return database_.get();
    151   }
    152 
    153   // ///////////////////////////////////////////////////////////////////////////
    154   // Data.
    155   // Not owned by MobileOperatorInfoImpl.
    156   EventDispatcher* const dispatcher_;
    157 
    158   const std::string info_owner_;
    159 
    160   // Owned by MobileOperatorInfoImpl, may be created externally.
    161   std::vector<base::FilePath> database_paths_;
    162 
    163   // Owned and modified only by MobileOperatorInfoImpl.
    164   // The observers added to this list are not owned by this object. Moreover,
    165   // the observer is likely to outlive this object. We do enforce removal of all
    166   // observers before this object is destroyed.
    167   base::ObserverList<MobileOperatorInfo::Observer> observers_;
    168   base::CancelableClosure notify_operator_changed_task_;
    169 
    170   std::unique_ptr<mobile_operator_db::MobileOperatorDB> database_;
    171   StringToMNOListMap mccmnc_to_mnos_;
    172   StringToMNOListMap sid_to_mnos_;
    173   StringToMNOListMap name_to_mnos_;
    174 
    175   // |candidates_by_operator_code| can be determined either using MCCMNC or
    176   // using SID.  At any one time, we only expect one of these operator codes to
    177   // be updated by the user. We use |operator_code_type_| to keep track of which
    178   // update we have received and warn the user if we receive both.
    179   enum OperatorCodeType {
    180     kOperatorCodeTypeUnknown = 0,
    181     kOperatorCodeTypeMCCMNC,
    182     kOperatorCodeTypeSID,
    183   };
    184   OperatorCodeType operator_code_type_;
    185   std::vector<const mobile_operator_db::MobileNetworkOperator*>
    186       candidates_by_operator_code_;
    187 
    188   std::vector<const mobile_operator_db::MobileNetworkOperator*>
    189       candidates_by_name_;
    190   const mobile_operator_db::MobileNetworkOperator* current_mno_;
    191   const mobile_operator_db::MobileVirtualNetworkOperator* current_mvno_;
    192 
    193   // These fields are the information expected to be populated by this object
    194   // after successfully determining the MVNO.
    195   std::string uuid_;
    196   std::string operator_name_;
    197   std::string country_;
    198   std::string mccmnc_;
    199   std::string sid_;
    200   std::string nid_;
    201   std::vector<std::string> mccmnc_list_;
    202   std::vector<std::string> sid_list_;
    203   std::vector<MobileOperatorInfo::LocalizedName> operator_name_list_;
    204   ScopedVector<MobileOperatorInfo::MobileAPN> apn_list_;
    205   std::vector<MobileOperatorInfo::OnlinePortal> olp_list_;
    206   std::vector<mobile_operator_db::OnlinePortal> raw_olp_list_;
    207   std::string activation_code_;
    208   bool requires_roaming_;
    209   // These fields store the data obtained from the Update* methods.
    210   // The database information is kept separate from the information gathered
    211   // through the Update* methods, because one or the other may be given
    212   // precedence in different situations.
    213   // Note: For simplicity, we do not allow the user to enforce an empty value
    214   // for these variables. So, if |user_mccmnc_| == "", the |mccmnc_| obtained
    215   // from the database will be used, even if |user_mccmnc_| was explicitly set
    216   // by the user.
    217   std::string user_imsi_;
    218   std::string user_iccid_;
    219   std::string user_mccmnc_;
    220   std::string user_sid_;
    221   std::string user_nid_;
    222   std::string user_operator_name_;
    223   bool user_olp_empty_;
    224   MobileOperatorInfo::OnlinePortal user_olp_;
    225 
    226   // This must be the last data member of this class.
    227   base::WeakPtrFactory<MobileOperatorInfoImpl> weak_ptr_factory_;
    228 
    229   DISALLOW_COPY_AND_ASSIGN(MobileOperatorInfoImpl);
    230 };
    231 
    232 }  // namespace shill
    233 
    234 #endif  // SHILL_CELLULAR_MOBILE_OPERATOR_INFO_IMPL_H_
    235