• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
database()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