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
35namespace shill {
36
37class 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