OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium 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 "chrome/browser/services/gcm/push_messaging_application_id.h" | |
6 | |
7 #include "base/guid.h" | |
8 #include "base/logging.h" | |
9 #include "base/prefs/pref_service.h" | |
10 #include "base/prefs/scoped_user_pref_update.h" | |
11 #include "base/strings/string_number_conversions.h" | |
12 #include "base/strings/string_split.h" | |
13 #include "base/values.h" | |
14 #include "chrome/browser/profiles/profile.h" | |
15 #include "chrome/common/pref_names.h" | |
16 #include "components/pref_registry/pref_registry_syncable.h" | |
17 | |
18 namespace { | |
19 const char kSeparator = '#'; // Ok as only the origin of the url is used. | |
20 } // namespace | |
21 | |
22 namespace gcm { | |
23 | |
24 const char kPushMessagingApplicationIdPrefix[] = "wp:"; | |
25 | |
26 // static | |
27 void PushMessagingApplicationId::RegisterProfilePrefs( | |
28 user_prefs::PrefRegistrySyncable* registry) { | |
29 registry->RegisterDictionaryPref( | |
30 prefs::kPushMessagingApplicationIdMap, | |
31 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
32 } | |
33 | |
34 // static | |
35 PushMessagingApplicationId PushMessagingApplicationId::Generate( | |
36 const GURL& origin, int64 service_worker_registration_id) | |
37 { | |
38 // TODO(johnme): Does GenerateGUID produce good enough random numbers? | |
39 std::string guid = base::GenerateGUID(); | |
40 CHECK(!guid.empty()); | |
41 std::string app_id_guid = | |
42 kPushMessagingApplicationIdPrefix + guid; | |
43 | |
44 PushMessagingApplicationId application_id(app_id_guid, origin, | |
45 service_worker_registration_id); | |
46 DCHECK(application_id.IsValid()); | |
47 return application_id; | |
48 } | |
49 | |
50 // static | |
51 PushMessagingApplicationId PushMessagingApplicationId::Get( | |
52 Profile* profile, const std::string& app_id_guid) { | |
53 const base::DictionaryValue* map = | |
54 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingApplicationIdMap); | |
55 | |
56 std::string origin_and_sw_id; | |
57 if (!map->GetStringWithoutPathExpansion(app_id_guid, &origin_and_sw_id)) | |
58 return PushMessagingApplicationId(); | |
59 | |
60 std::vector<std::string> parts; | |
61 base::SplitString(origin_and_sw_id, kSeparator, &parts); | |
62 if (parts.size() != 2) | |
63 return PushMessagingApplicationId(); | |
64 | |
65 GURL origin = GURL(parts[0]); | |
66 | |
67 int64 service_worker_registration_id; | |
68 if (!base::StringToInt64(parts[1], &service_worker_registration_id)) | |
69 return PushMessagingApplicationId(); | |
70 | |
71 PushMessagingApplicationId application_id(app_id_guid, origin, | |
72 service_worker_registration_id); | |
73 DCHECK(application_id.IsValid()); | |
74 return application_id; | |
75 } | |
76 | |
77 // static | |
78 PushMessagingApplicationId PushMessagingApplicationId::Get( | |
79 Profile* profile, const GURL& origin, int64 service_worker_registration_id) | |
80 { | |
81 base::StringValue origin_and_sw_id = base::StringValue(origin.spec() + | |
82 kSeparator + base::Int64ToString(service_worker_registration_id)); | |
83 | |
84 const base::DictionaryValue* map = | |
85 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingApplicationIdMap); | |
86 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd(); | |
87 it.Advance()) { | |
88 if (it.value().Equals(&origin_and_sw_id)) | |
89 return Get(profile, it.key()); | |
90 } | |
91 return PushMessagingApplicationId(); | |
92 } | |
93 | |
94 // static | |
95 std::vector<PushMessagingApplicationId> PushMessagingApplicationId::GetAll( | |
96 Profile* profile) { | |
97 std::vector<PushMessagingApplicationId> result; | |
98 | |
99 const base::DictionaryValue* map = | |
100 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingApplicationIdMap); | |
101 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd(); | |
102 it.Advance()) { | |
103 result.push_back(Get(profile, it.key())); | |
104 } | |
105 | |
106 return result; | |
107 } | |
108 | |
109 void PushMessagingApplicationId::PersistToDisk(Profile* profile) const { | |
110 DCHECK(IsValid()); | |
111 | |
112 DictionaryPrefUpdate update(profile->GetPrefs(), | |
113 prefs::kPushMessagingApplicationIdMap); | |
114 base::DictionaryValue* map = update.Get(); | |
115 | |
116 // Delete any stale entry with the same origin and Service Worker | |
117 // registration id (hence we ensure there is a 1:1 not 1:many mapping). | |
118 PushMessagingApplicationId old = Get(profile, origin_, | |
119 service_worker_registration_id_); | |
120 if (old.IsValid()) | |
121 map->RemoveWithoutPathExpansion(old.app_id_guid_, nullptr); | |
122 | |
123 std::string origin_and_sw_id = origin_.spec() + kSeparator + | |
124 base::Int64ToString(service_worker_registration_id_); | |
125 map->SetStringWithoutPathExpansion(app_id_guid_, origin_and_sw_id); | |
126 } | |
127 | |
128 void PushMessagingApplicationId::DeleteFromDisk(Profile* profile) const { | |
129 DCHECK(IsValid()); | |
130 | |
131 DictionaryPrefUpdate update(profile->GetPrefs(), | |
132 prefs::kPushMessagingApplicationIdMap); | |
133 base::DictionaryValue* map = update.Get(); | |
134 map->RemoveWithoutPathExpansion(app_id_guid_, nullptr); | |
135 } | |
136 | |
137 PushMessagingApplicationId::PushMessagingApplicationId() | |
138 : origin_(GURL::EmptyGURL()), | |
139 service_worker_registration_id_(-1) { | |
140 } | |
141 | |
142 PushMessagingApplicationId::PushMessagingApplicationId( | |
143 const std::string& app_id_guid, | |
144 const GURL& origin, | |
145 int64 service_worker_registration_id) | |
146 : app_id_guid_(app_id_guid), | |
147 origin_(origin), | |
148 service_worker_registration_id_(service_worker_registration_id) { | |
149 } | |
150 | |
151 PushMessagingApplicationId::~PushMessagingApplicationId() { | |
152 } | |
153 | |
154 bool PushMessagingApplicationId::IsValid() const { | |
155 const size_t prefix_len = strlen(kPushMessagingApplicationIdPrefix); | |
156 return origin_.is_valid() && origin_.GetOrigin() == origin_ | |
157 && service_worker_registration_id_ >= 0 | |
158 && !app_id_guid_.compare(0, prefix_len, kPushMessagingApplicationIdPrefix) | |
159 && base::IsValidGUID(app_id_guid_.substr(prefix_len, std::string::npos)); | |
160 } | |
161 | |
162 } // namespace gcm | |
OLD | NEW |