blob: cf6fab76709a89d86046dce593e578e2a5046d4a [file] [log] [blame]
Chris Masone52cd19b2011-06-29 17:23:04 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/profile.h"
6
Chris Masone6791a432011-07-12 13:23:19 -07007#include <map>
Chris Masone52cd19b2011-06-29 17:23:04 -07008#include <string>
Chris Masone6791a432011-07-12 13:23:19 -07009#include <vector>
Chris Masone52cd19b2011-06-29 17:23:04 -070010
11#include <base/logging.h>
Chris Masone6791a432011-07-12 13:23:19 -070012#include <base/stl_util-inl.h>
Darin Petkova4766822011-07-07 10:42:22 -070013#include <base/string_util.h>
Chris Masone6791a432011-07-12 13:23:19 -070014#include <base/stringprintf.h>
Chris Masone88cbd5f2011-07-03 14:30:04 -070015#include <chromeos/dbus/service_constants.h>
Chris Masone52cd19b2011-06-29 17:23:04 -070016
17#include "shill/adaptor_interfaces.h"
18#include "shill/control_interface.h"
Chris Masone6791a432011-07-12 13:23:19 -070019#include "shill/manager.h"
Chris Masone52cd19b2011-06-29 17:23:04 -070020#include "shill/property_accessor.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070021#include "shill/service.h"
Chris Masone52cd19b2011-06-29 17:23:04 -070022
Chris Masone6791a432011-07-12 13:23:19 -070023using std::map;
Chris Masone52cd19b2011-06-29 17:23:04 -070024using std::string;
Chris Masone6791a432011-07-12 13:23:19 -070025using std::vector;
Chris Masone52cd19b2011-06-29 17:23:04 -070026
27namespace shill {
Darin Petkova4766822011-07-07 10:42:22 -070028
29const char Profile::kGlobalStorageDir[] = "/var/cache/flimflam";
30const char Profile::kUserStorageDirFormat[] = "/home/%s/user/flimflam";
31
32Profile::Profile(ControlInterface *control_interface,
Chris Masone6791a432011-07-12 13:23:19 -070033 GLib *glib,
34 Manager *manager)
35 : manager_(manager),
36 adaptor_(control_interface->CreateProfileAdaptor(this)),
Darin Petkova4766822011-07-07 10:42:22 -070037 storage_(glib) {
Chris Masone88cbd5f2011-07-03 14:30:04 -070038 // flimflam::kCheckPortalListProperty: Registered in DefaultProfile
39 // flimflam::kCountryProperty: Registered in DefaultProfile
40 store_.RegisterConstString(flimflam::kNameProperty, &name_);
41
42 // flimflam::kOfflineModeProperty: Registered in DefaultProfile
43 // flimflam::kPortalURLProperty: Registered in DefaultProfile
44
Chris Masone6791a432011-07-12 13:23:19 -070045 HelpRegisterDerivedStrings(flimflam::kServicesProperty,
46 &Profile::EnumerateAvailableServices,
47 NULL);
Chris Masone88cbd5f2011-07-03 14:30:04 -070048 // HelpRegisterDerivedStrings(flimflam::kEntriesProperty,
Chris Masone6791a432011-07-12 13:23:19 -070049 // &Profile::EnumerateEntries,
Chris Masone88cbd5f2011-07-03 14:30:04 -070050 // NULL);
Chris Masone52cd19b2011-06-29 17:23:04 -070051}
52
53Profile::~Profile() {}
54
Chris Masone6791a432011-07-12 13:23:19 -070055bool Profile::AdoptService(const ServiceRefPtr &service) {
56 if (ContainsKey(services_, service->UniqueName()))
57 return false;
58 service->set_profile(this);
59 services_[service->UniqueName()] = service;
60 return true;
61}
62
63bool Profile::AbandonService(const string &name) {
64 map<string, ServiceRefPtr>::iterator to_abandon = services_.find(name);
65 if (to_abandon != services_.end()) {
66 services_.erase(to_abandon);
67 return true;
68 }
69 return false;
70}
71
72bool Profile::DemoteService(const string &name) {
73 map<string, ServiceRefPtr>::iterator to_demote = services_.find(name);
74 if (to_demote == services_.end())
75 return false;
76 return true; // TODO(cmasone): mark |to_demote| as inactive or something.
77}
78
79bool Profile::MergeService(const ServiceRefPtr &service) {
80 map<string, ServiceRefPtr>::iterator it;
81 for (it = services_.begin(); it != services_.end(); ++it) {
82 if (Mergeable(it->second, service))
83 return true; // TODO(cmasone): Perform merge.
84 }
85 return false;
86}
87
88ServiceRefPtr Profile::FindService(const std::string& name) {
89 if (ContainsKey(services_, name))
90 return services_[name];
91 return NULL;
92}
93
94void Profile::Finalize() {
95 // TODO(cmasone): Flush all of |services_| to disk if needed.
96 services_.clear();
Chris Masone7aa5f902011-07-11 11:13:35 -070097}
98
Darin Petkova4766822011-07-07 10:42:22 -070099bool Profile::IsValidIdentifierToken(const std::string &token) {
100 if (token.empty()) {
101 return false;
102 }
103 for (string::const_iterator it = token.begin(); it != token.end(); ++it) {
104 if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it)) {
105 return false;
106 }
107 }
108 return true;
109}
110
111bool Profile::ParseIdentifier(const string &raw, Identifier *parsed) {
112 if (raw.empty()) {
113 return false;
114 }
115 if (raw[0] == '~') {
116 // Format: "~user/identifier".
117 size_t slash = raw.find('/');
118 if (slash == string::npos) {
119 return false;
120 }
121 string user(raw.begin() + 1, raw.begin() + slash);
122 string identifier(raw.begin() + slash + 1, raw.end());
123 if (!IsValidIdentifierToken(user) || !IsValidIdentifierToken(identifier)) {
124 return false;
125 }
126 parsed->user = user;
127 parsed->identifier = identifier;
128 return true;
129 }
130
131 // Format: "identifier".
132 if (!IsValidIdentifierToken(raw)) {
133 return false;
134 }
135 parsed->user = "";
136 parsed->identifier = raw;
137 return true;
138}
139
140string Profile::GetRpcPath(const Identifier &identifier) {
141 string user = identifier.user.empty() ? "" : identifier.user + "/";
142 return "/profile/" + user + identifier.identifier;
143}
144
145bool Profile::GetStoragePath(const Identifier &identifier, FilePath *path) {
146 FilePath dir(
147 identifier.user.empty() ?
148 kGlobalStorageDir :
149 base::StringPrintf(kUserStorageDirFormat, identifier.user.c_str()));
150 // TODO(petkov): Validate the directory permissions, etc.
151 *path = dir.Append(base::StringPrintf("%s.profile",
152 identifier.identifier.c_str()));
153 return true;
154}
155
Chris Masone6791a432011-07-12 13:23:19 -0700156vector<string> Profile::EnumerateAvailableServices() {
157 return manager_->EnumerateAvailableServices();
158}
159
160vector<string> Profile::EnumerateEntries() {
161 vector<string> rpc_ids;
162 map<string, ServiceRefPtr>::const_iterator it;
163 for (it = services_.begin(); it != services_.end(); ++it) {
164 rpc_ids.push_back(it->second->GetRpcIdentifier());
165 }
166 return rpc_ids;
167}
168
169void Profile::HelpRegisterDerivedStrings(const string &name,
170 Strings(Profile::*get)(void),
171 bool(Profile::*set)(const Strings&)) {
172 store_.RegisterDerivedStrings(
173 name,
174 StringsAccessor(new CustomAccessor<Profile, Strings>(this, get, set)));
175}
176
Chris Masone52cd19b2011-06-29 17:23:04 -0700177} // namespace shill