OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/app/app_api.h" | 5 #include "chrome/browser/extensions/api/app_runtime/app_runtime_api.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
| 8 #include "base/string16.h" |
8 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
9 #include "base/time.h" | |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "chrome/browser/extensions/app_notification_manager.h" | |
13 #include "chrome/browser/extensions/event_router.h" | 12 #include "chrome/browser/extensions/event_router.h" |
14 #include "chrome/browser/extensions/extension_service.h" | |
15 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/common/chrome_notification_types.h" | |
17 #include "chrome/common/extensions/extension.h" | 14 #include "chrome/common/extensions/extension.h" |
18 #include "chrome/common/extensions/extension_constants.h" | |
19 #include "content/public/browser/notification_service.h" | |
20 #include "googleurl/src/gurl.h" | 15 #include "googleurl/src/gurl.h" |
21 #include "webkit/glue/web_intent_data.h" | 16 #include "webkit/glue/web_intent_data.h" |
22 | 17 |
23 namespace { | 18 namespace { |
24 | 19 |
25 const char kBodyTextKey[] = "bodyText"; | 20 const char kOnLaunchedEvent[] = "app.runtime.onLaunched"; |
26 const char kExtensionIdKey[] = "extensionId"; | |
27 const char kLinkTextKey[] = "linkText"; | |
28 const char kLinkUrlKey[] = "linkUrl"; | |
29 const char kTitleKey[] = "title"; | |
30 | |
31 const char kInvalidExtensionIdError[] = | |
32 "Invalid extension id"; | |
33 const char kMissingLinkTextError[] = | |
34 "You must specify linkText if you use linkUrl"; | |
35 const char kOnLaunchedEvent[] = "experimental.app.onLaunched"; | |
36 | 21 |
37 } // anonymous namespace | 22 } // anonymous namespace |
38 | 23 |
39 namespace extensions { | 24 namespace extensions { |
40 | 25 |
41 bool AppNotifyFunction::RunImpl() { | |
42 if (!include_incognito() && profile_->IsOffTheRecord()) { | |
43 error_ = extension_misc::kAppNotificationsIncognitoError; | |
44 return false; | |
45 } | |
46 | |
47 DictionaryValue* details; | |
48 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); | |
49 EXTENSION_FUNCTION_VALIDATE(details != NULL); | |
50 | |
51 // TODO(asargent) remove this before the API leaves experimental. | |
52 std::string id = extension_id(); | |
53 if (details->HasKey(kExtensionIdKey)) { | |
54 EXTENSION_FUNCTION_VALIDATE(details->GetString(kExtensionIdKey, &id)); | |
55 if (!profile()->GetExtensionService()->GetExtensionById(id, true)) { | |
56 error_ = kInvalidExtensionIdError; | |
57 return false; | |
58 } | |
59 } | |
60 | |
61 std::string title; | |
62 if (details->HasKey(kTitleKey)) | |
63 EXTENSION_FUNCTION_VALIDATE(details->GetString(kTitleKey, &title)); | |
64 | |
65 std::string body; | |
66 if (details->HasKey(kBodyTextKey)) | |
67 EXTENSION_FUNCTION_VALIDATE(details->GetString(kBodyTextKey, &body)); | |
68 | |
69 scoped_ptr<AppNotification> item(new AppNotification( | |
70 true, base::Time::Now(), "", id, title, body)); | |
71 | |
72 if (details->HasKey(kLinkUrlKey)) { | |
73 std::string link_url; | |
74 EXTENSION_FUNCTION_VALIDATE(details->GetString(kLinkUrlKey, &link_url)); | |
75 item->set_link_url(GURL(link_url)); | |
76 if (!item->link_url().is_valid()) { | |
77 error_ = "Invalid url: " + link_url; | |
78 return false; | |
79 } | |
80 if (!details->HasKey(kLinkTextKey)) { | |
81 error_ = kMissingLinkTextError; | |
82 return false; | |
83 } | |
84 std::string link_text; | |
85 EXTENSION_FUNCTION_VALIDATE(details->GetString(kLinkTextKey, | |
86 &link_text)); | |
87 item->set_link_text(link_text); | |
88 } | |
89 | |
90 AppNotificationManager* manager = | |
91 profile()->GetExtensionService()->app_notification_manager(); | |
92 | |
93 // TODO(beaudoin) We should probably report an error if Add returns false. | |
94 manager->Add(item.release()); | |
95 | |
96 return true; | |
97 } | |
98 | |
99 bool AppClearAllNotificationsFunction::RunImpl() { | |
100 if (!include_incognito() && profile_->IsOffTheRecord()) { | |
101 error_ = extension_misc::kAppNotificationsIncognitoError; | |
102 return false; | |
103 } | |
104 | |
105 std::string id = extension_id(); | |
106 DictionaryValue* details = NULL; | |
107 if (args_->GetDictionary(0, &details) && details->HasKey(kExtensionIdKey)) { | |
108 EXTENSION_FUNCTION_VALIDATE(details->GetString(kExtensionIdKey, &id)); | |
109 if (!profile()->GetExtensionService()->GetExtensionById(id, true)) { | |
110 error_ = kInvalidExtensionIdError; | |
111 return false; | |
112 } | |
113 } | |
114 | |
115 AppNotificationManager* manager = | |
116 profile()->GetExtensionService()->app_notification_manager(); | |
117 manager->ClearAll(id); | |
118 return true; | |
119 } | |
120 | |
121 // static. | 26 // static. |
122 void AppEventRouter::DispatchOnLaunchedEvent( | 27 void AppEventRouter::DispatchOnLaunchedEvent( |
123 Profile* profile, const Extension* extension) { | 28 Profile* profile, const Extension* extension) { |
124 scoped_ptr<ListValue> arguments(new ListValue()); | 29 scoped_ptr<ListValue> arguments(new ListValue()); |
125 profile->GetExtensionEventRouter()->DispatchEventToExtension( | 30 profile->GetExtensionEventRouter()->DispatchEventToExtension( |
126 extension->id(), kOnLaunchedEvent, arguments.Pass(), NULL, GURL()); | 31 extension->id(), kOnLaunchedEvent, arguments.Pass(), NULL, GURL()); |
127 } | 32 } |
128 | 33 |
129 // static. | 34 // static. |
130 void AppEventRouter::DispatchOnLaunchedEventWithFileEntry( | 35 void AppEventRouter::DispatchOnLaunchedEventWithFileEntry( |
131 Profile* profile, const Extension* extension, const string16& action, | 36 Profile* profile, const Extension* extension, const string16& action, |
132 const std::string& file_system_id, const std::string& base_name) { | 37 const std::string& file_system_id, const std::string& base_name) { |
133 scoped_ptr<ListValue> args(new ListValue()); | 38 scoped_ptr<ListValue> args(new ListValue()); |
134 DictionaryValue* launch_data = new DictionaryValue(); | 39 DictionaryValue* launch_data = new DictionaryValue(); |
135 DictionaryValue* intent = new DictionaryValue(); | 40 DictionaryValue* intent = new DictionaryValue(); |
136 intent->SetString("action", UTF16ToUTF8(action)); | 41 intent->SetString("action", UTF16ToUTF8(action)); |
137 intent->SetString("type", "chrome-extension://fileentry"); | 42 intent->SetString("type", "chrome-extension://fileentry"); |
138 launch_data->Set("intent", intent); | 43 launch_data->Set("intent", intent); |
139 args->Append(launch_data); | 44 args->Append(launch_data); |
140 DictionaryValue* intent_data = new DictionaryValue(); | 45 DictionaryValue* intent_data = new DictionaryValue(); |
141 intent_data->SetString("format", "fileEntry"); | 46 intent_data->SetString("format", "fileEntry"); |
142 intent_data->SetString("fileSystemId", file_system_id); | 47 intent_data->SetString("fileSystemId", file_system_id); |
143 intent_data->SetString("baseName", base_name); | 48 intent_data->SetString("baseName", base_name); |
| 49 // NOTE: This second argument is dropped before being dispatched to the client |
| 50 // code. |
144 args->Append(intent_data); | 51 args->Append(intent_data); |
145 profile->GetExtensionEventRouter()->DispatchEventToExtension( | 52 profile->GetExtensionEventRouter()->DispatchEventToExtension( |
146 extension->id(), kOnLaunchedEvent, args.Pass(), NULL, GURL()); | 53 extension->id(), kOnLaunchedEvent, args.Pass(), NULL, GURL()); |
147 } | 54 } |
148 | 55 |
149 // static. | 56 // static. |
150 void AppEventRouter::DispatchOnLaunchedEventWithWebIntent( | 57 void AppEventRouter::DispatchOnLaunchedEventWithWebIntent( |
151 Profile* profile, const Extension* extension, | 58 Profile* profile, const Extension* extension, |
152 const webkit_glue::WebIntentData web_intent_data) { | 59 const webkit_glue::WebIntentData web_intent_data) { |
153 scoped_ptr<ListValue> args(new ListValue()); | 60 scoped_ptr<ListValue> args(new ListValue()); |
154 DictionaryValue* launch_data = new DictionaryValue(); | 61 DictionaryValue* launch_data = new DictionaryValue(); |
155 DictionaryValue* intent = new DictionaryValue(); | 62 DictionaryValue* intent = new DictionaryValue(); |
156 intent->SetString("action", UTF16ToUTF8(web_intent_data.action)); | 63 intent->SetString("action", UTF16ToUTF8(web_intent_data.action)); |
157 intent->SetString("type", UTF16ToUTF8(web_intent_data.type)); | 64 intent->SetString("type", UTF16ToUTF8(web_intent_data.type)); |
158 launch_data->Set("intent", intent); | 65 launch_data->Set("intent", intent); |
159 args->Append(launch_data); | 66 args->Append(launch_data); |
160 DictionaryValue* intent_data; | 67 DictionaryValue* intent_data; |
161 switch (web_intent_data.data_type) { | 68 switch (web_intent_data.data_type) { |
162 case webkit_glue::WebIntentData::SERIALIZED: | 69 case webkit_glue::WebIntentData::SERIALIZED: |
163 intent_data = new DictionaryValue(); | 70 intent_data = new DictionaryValue(); |
164 intent_data->SetString("format", "serialized"); | 71 intent_data->SetString("format", "serialized"); |
165 intent_data->SetString("data", UTF16ToUTF8(web_intent_data.data)); | 72 intent_data->SetString("data", UTF16ToUTF8(web_intent_data.data)); |
| 73 // NOTE: This second argument is dropped before being dispatched to the |
| 74 // client code. |
166 args->Append(intent_data); | 75 args->Append(intent_data); |
167 break; | 76 break; |
168 case webkit_glue::WebIntentData::UNSERIALIZED: | 77 case webkit_glue::WebIntentData::UNSERIALIZED: |
169 intent->SetString("data", UTF16ToUTF8(web_intent_data.unserialized_data)); | 78 intent->SetString("data", UTF16ToUTF8(web_intent_data.unserialized_data)); |
170 break; | 79 break; |
171 case webkit_glue::WebIntentData::BLOB: | 80 case webkit_glue::WebIntentData::BLOB: |
172 intent_data = new DictionaryValue(); | 81 intent_data = new DictionaryValue(); |
173 intent_data->SetString("format", "blob"); | 82 intent_data->SetString("format", "blob"); |
174 intent_data->SetString("blobFileName", web_intent_data.blob_file.value()); | 83 intent_data->SetString("blobFileName", web_intent_data.blob_file.value()); |
175 intent_data->SetString("blobLength", | 84 intent_data->SetString("blobLength", |
176 base::Int64ToString(web_intent_data.blob_length)); | 85 base::Int64ToString(web_intent_data.blob_length)); |
| 86 // NOTE: This second argument is dropped before being dispatched to the |
| 87 // client code. |
177 args->Append(intent_data); | 88 args->Append(intent_data); |
178 break; | 89 break; |
179 default: | 90 default: |
180 NOTREACHED(); | 91 NOTREACHED(); |
181 break; | 92 break; |
182 } | 93 } |
183 profile->GetExtensionEventRouter()->DispatchEventToExtension( | 94 profile->GetExtensionEventRouter()->DispatchEventToExtension( |
184 extension->id(), kOnLaunchedEvent, args.Pass(), NULL, GURL()); | 95 extension->id(), kOnLaunchedEvent, args.Pass(), NULL, GURL()); |
185 } | 96 } |
186 | 97 |
187 } // namespace extensions | 98 } // namespace extensions |
OLD | NEW |