| 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/file_system/file_system_api.h" | 5 #include "chrome/browser/extensions/api/file_system/file_system_api.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <vector> |
| 8 | 9 |
| 9 #include "apps/saved_files_service.h" | 10 #include "apps/saved_files_service.h" |
| 10 #include "base/bind.h" | 11 #include "base/bind.h" |
| 11 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 12 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/linked_ptr.h" |
| 14 #include "base/path_service.h" | 16 #include "base/path_service.h" |
| 15 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 16 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 17 #include "base/strings/sys_string_conversions.h" | 19 #include "base/strings/sys_string_conversions.h" |
| 18 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 19 #include "base/value_conversions.h" | 21 #include "base/value_conversions.h" |
| 20 #include "base/values.h" | 22 #include "base/values.h" |
| 21 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" | 23 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" |
| 22 #include "chrome/browser/extensions/extension_service.h" | 24 #include "chrome/browser/extensions/extension_service.h" |
| 23 #include "chrome/browser/extensions/extension_util.h" | 25 #include "chrome/browser/extensions/extension_util.h" |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 callback.Run(CONSENT_IMPOSSIBLE); | 345 callback.Run(CONSENT_IMPOSSIBLE); |
| 344 break; | 346 break; |
| 345 case ui::DIALOG_BUTTON_OK: | 347 case ui::DIALOG_BUTTON_OK: |
| 346 callback.Run(CONSENT_GRANTED); | 348 callback.Run(CONSENT_GRANTED); |
| 347 break; | 349 break; |
| 348 case ui::DIALOG_BUTTON_CANCEL: | 350 case ui::DIALOG_BUTTON_CANCEL: |
| 349 callback.Run(CONSENT_REJECTED); | 351 callback.Run(CONSENT_REJECTED); |
| 350 break; | 352 break; |
| 351 } | 353 } |
| 352 } | 354 } |
| 355 |
| 356 ConsentProviderDelegate::ConsentProviderDelegate(Profile* profile, |
| 357 content::RenderViewHost* host) |
| 358 : profile_(profile), host_(host) { |
| 359 DCHECK(profile_); |
| 360 DCHECK(host_); |
| 361 } |
| 362 |
| 363 ConsentProviderDelegate::~ConsentProviderDelegate() { |
| 364 } |
| 365 |
| 366 // static |
| 367 void ConsentProviderDelegate::SetAutoDialogButtonForTest( |
| 368 ui::DialogButton button) { |
| 369 g_auto_dialog_button_for_test = button; |
| 370 } |
| 371 |
| 372 void ConsentProviderDelegate::ShowDialog( |
| 373 const extensions::Extension& extension, |
| 374 base::WeakPtr<file_manager::Volume> volume, |
| 375 bool writable, |
| 376 const file_system_api::ConsentProvider::ShowDialogCallback& callback) { |
| 377 content::WebContents* const foreground_contents = |
| 378 GetWebContentsForRenderViewHost(profile_, host_); |
| 379 // If there is no web contents handle, then the method is most probably |
| 380 // executed from a background page. Find an app window to host the dialog. |
| 381 content::WebContents* const web_contents = |
| 382 foreground_contents ? foreground_contents |
| 383 : GetWebContentsForAppId(profile_, extension.id()); |
| 384 if (!web_contents) { |
| 385 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 386 FROM_HERE, base::Bind(callback, ui::DIALOG_BUTTON_NONE)); |
| 387 return; |
| 388 } |
| 389 |
| 390 // Short circuit the user consent dialog for tests. This is far from a pretty |
| 391 // code design. |
| 392 if (g_auto_dialog_button_for_test != ui::DIALOG_BUTTON_NONE) { |
| 393 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 394 FROM_HERE, |
| 395 base::Bind(callback, g_auto_dialog_button_for_test /* result */)); |
| 396 return; |
| 397 } |
| 398 |
| 399 RequestFileSystemDialogView::ShowDialog(web_contents, extension, volume, |
| 400 writable, base::Bind(callback)); |
| 401 } |
| 402 |
| 403 bool ConsentProviderDelegate::IsAutoLaunched( |
| 404 const extensions::Extension& extension) { |
| 405 chromeos::KioskAppManager::App app_info; |
| 406 return chromeos::KioskAppManager::Get()->GetApp(extension.id(), &app_info) && |
| 407 app_info.was_auto_launched_with_zero_delay; |
| 408 } |
| 409 |
| 410 bool ConsentProviderDelegate::IsWhitelistedComponent( |
| 411 const extensions::Extension& extension) { |
| 412 for (const auto& whitelisted_id : kRequestFileSystemComponentWhitelist) { |
| 413 if (extension.id().compare(whitelisted_id) == 0) |
| 414 return true; |
| 415 } |
| 416 return false; |
| 417 } |
| 418 |
| 353 #endif | 419 #endif |
| 354 | 420 |
| 355 } // namespace file_system_api | 421 } // namespace file_system_api |
| 356 | 422 |
| 357 #if defined(OS_CHROMEOS) | 423 #if defined(OS_CHROMEOS) |
| 358 using file_system_api::ConsentProvider; | 424 using file_system_api::ConsentProvider; |
| 359 #endif | 425 #endif |
| 360 | 426 |
| 361 bool FileSystemGetDisplayPathFunction::RunSync() { | 427 bool FileSystemGetDisplayPathFunction::RunSync() { |
| 362 std::string filesystem_name; | 428 std::string filesystem_name; |
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 #if !defined(OS_CHROMEOS) | 1194 #if !defined(OS_CHROMEOS) |
| 1129 ExtensionFunction::ResponseAction FileSystemRequestFileSystemFunction::Run() { | 1195 ExtensionFunction::ResponseAction FileSystemRequestFileSystemFunction::Run() { |
| 1130 using extensions::api::file_system::RequestFileSystem::Params; | 1196 using extensions::api::file_system::RequestFileSystem::Params; |
| 1131 const scoped_ptr<Params> params(Params::Create(*args_)); | 1197 const scoped_ptr<Params> params(Params::Create(*args_)); |
| 1132 EXTENSION_FUNCTION_VALIDATE(params); | 1198 EXTENSION_FUNCTION_VALIDATE(params); |
| 1133 | 1199 |
| 1134 NOTIMPLEMENTED(); | 1200 NOTIMPLEMENTED(); |
| 1135 return RespondNow(Error(kNotSupportedOnCurrentPlatformError)); | 1201 return RespondNow(Error(kNotSupportedOnCurrentPlatformError)); |
| 1136 } | 1202 } |
| 1137 | 1203 |
| 1204 ExtensionFunction::ResponseAction FileSystemGetVolumeListFunction::Run() { |
| 1205 NOTIMPLEMENTED(); |
| 1206 return RespondNow(Error(kNotSupportedOnCurrentPlatformError)); |
| 1207 } |
| 1138 #else | 1208 #else |
| 1209 |
| 1139 FileSystemRequestFileSystemFunction::FileSystemRequestFileSystemFunction() | 1210 FileSystemRequestFileSystemFunction::FileSystemRequestFileSystemFunction() |
| 1140 : chrome_details_(this), consent_provider_(this) { | 1211 : chrome_details_(this) { |
| 1141 } | 1212 } |
| 1142 | 1213 |
| 1143 FileSystemRequestFileSystemFunction::~FileSystemRequestFileSystemFunction() { | 1214 FileSystemRequestFileSystemFunction::~FileSystemRequestFileSystemFunction() { |
| 1144 } | 1215 } |
| 1145 | 1216 |
| 1146 ExtensionFunction::ResponseAction FileSystemRequestFileSystemFunction::Run() { | 1217 ExtensionFunction::ResponseAction FileSystemRequestFileSystemFunction::Run() { |
| 1147 using extensions::api::file_system::RequestFileSystem::Params; | 1218 using extensions::api::file_system::RequestFileSystem::Params; |
| 1148 const scoped_ptr<Params> params(Params::Create(*args_)); | 1219 const scoped_ptr<Params> params(Params::Create(*args_)); |
| 1149 EXTENSION_FUNCTION_VALIDATE(params); | 1220 EXTENSION_FUNCTION_VALIDATE(params); |
| 1150 | 1221 |
| 1151 // Only kiosk apps in kiosk sessions can use this API. | 1222 // Only kiosk apps in kiosk sessions can use this API. |
| 1152 // Additionally whitelisted component extensions and apps. | 1223 // Additionally it is enabled for whitelisted component extensions and apps. |
| 1153 if (!consent_provider_.IsGrantable(*extension())) | 1224 file_system_api::ConsentProviderDelegate consent_provider_delegate( |
| 1225 chrome_details_.GetProfile(), render_view_host()); |
| 1226 file_system_api::ConsentProvider consent_provider(&consent_provider_delegate); |
| 1227 |
| 1228 if (!consent_provider.IsGrantable(*extension())) |
| 1154 return RespondNow(Error(kNotSupportedOnNonKioskSessionError)); | 1229 return RespondNow(Error(kNotSupportedOnNonKioskSessionError)); |
| 1155 | 1230 |
| 1156 using file_manager::VolumeManager; | 1231 using file_manager::VolumeManager; |
| 1157 using file_manager::Volume; | 1232 using file_manager::Volume; |
| 1158 VolumeManager* const volume_manager = | 1233 VolumeManager* const volume_manager = |
| 1159 VolumeManager::Get(chrome_details_.GetProfile()); | 1234 VolumeManager::Get(chrome_details_.GetProfile()); |
| 1160 DCHECK(volume_manager); | 1235 DCHECK(volume_manager); |
| 1161 | 1236 |
| 1162 const bool writable = | 1237 const bool writable = |
| 1163 params->options.writable.get() && *params->options.writable.get(); | 1238 params->options.writable.get() && *params->options.writable.get(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1180 file_system_context->external_backend(); | 1255 file_system_context->external_backend(); |
| 1181 DCHECK(backend); | 1256 DCHECK(backend); |
| 1182 | 1257 |
| 1183 base::FilePath virtual_path; | 1258 base::FilePath virtual_path; |
| 1184 if (!backend->GetVirtualPath(volume->mount_path(), &virtual_path)) | 1259 if (!backend->GetVirtualPath(volume->mount_path(), &virtual_path)) |
| 1185 return RespondNow(Error(kSecurityError)); | 1260 return RespondNow(Error(kSecurityError)); |
| 1186 | 1261 |
| 1187 if (writable && (volume->is_read_only())) | 1262 if (writable && (volume->is_read_only())) |
| 1188 return RespondNow(Error(kSecurityError)); | 1263 return RespondNow(Error(kSecurityError)); |
| 1189 | 1264 |
| 1190 consent_provider_.RequestConsent( | 1265 consent_provider.RequestConsent( |
| 1191 *extension(), volume, writable, | 1266 *extension(), volume, writable, |
| 1192 base::Bind(&FileSystemRequestFileSystemFunction::OnConsentReceived, this, | 1267 base::Bind(&FileSystemRequestFileSystemFunction::OnConsentReceived, this, |
| 1193 volume, writable)); | 1268 volume, writable)); |
| 1194 return RespondLater(); | 1269 return RespondLater(); |
| 1195 } | 1270 } |
| 1196 | 1271 |
| 1197 // static | |
| 1198 void FileSystemRequestFileSystemFunction::SetAutoDialogButtonForTest( | |
| 1199 ui::DialogButton button) { | |
| 1200 g_auto_dialog_button_for_test = button; | |
| 1201 } | |
| 1202 | |
| 1203 void FileSystemRequestFileSystemFunction::ShowDialog( | |
| 1204 const extensions::Extension& extension, | |
| 1205 base::WeakPtr<file_manager::Volume> volume, | |
| 1206 bool writable, | |
| 1207 const file_system_api::ConsentProvider::ShowDialogCallback& callback) { | |
| 1208 content::WebContents* const foreground_contents = | |
| 1209 GetWebContentsForRenderViewHost(chrome_details_.GetProfile(), | |
| 1210 render_view_host()); | |
| 1211 // If there is no web contents handle, then the method is most probably | |
| 1212 // executed from a background page. Find an app window to host the dialog. | |
| 1213 content::WebContents* const web_contents = | |
| 1214 foreground_contents ? foreground_contents | |
| 1215 : GetWebContentsForAppId(chrome_details_.GetProfile(), | |
| 1216 extension_id()); | |
| 1217 if (!web_contents) { | |
| 1218 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 1219 FROM_HERE, base::Bind(callback, ui::DIALOG_BUTTON_NONE)); | |
| 1220 return; | |
| 1221 } | |
| 1222 | |
| 1223 // Short circuit the user consent dialog for tests. This is far from a pretty | |
| 1224 // code design. | |
| 1225 if (g_auto_dialog_button_for_test != ui::DIALOG_BUTTON_NONE) { | |
| 1226 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 1227 FROM_HERE, | |
| 1228 base::Bind(callback, g_auto_dialog_button_for_test /* result */)); | |
| 1229 return; | |
| 1230 } | |
| 1231 | |
| 1232 RequestFileSystemDialogView::ShowDialog(web_contents, extension, volume, | |
| 1233 writable, base::Bind(callback)); | |
| 1234 } | |
| 1235 | |
| 1236 bool FileSystemRequestFileSystemFunction::IsAutoLaunched( | |
| 1237 const extensions::Extension& extension) { | |
| 1238 chromeos::KioskAppManager::App app_info; | |
| 1239 return chromeos::KioskAppManager::Get()->GetApp(extension.id(), &app_info) && | |
| 1240 app_info.was_auto_launched_with_zero_delay; | |
| 1241 } | |
| 1242 | |
| 1243 bool FileSystemRequestFileSystemFunction::IsWhitelistedComponent( | |
| 1244 const extensions::Extension& extension) { | |
| 1245 for (const auto& whitelisted_id : kRequestFileSystemComponentWhitelist) { | |
| 1246 if (extension.id().compare(whitelisted_id) == 0) | |
| 1247 return true; | |
| 1248 } | |
| 1249 return false; | |
| 1250 } | |
| 1251 | |
| 1252 void FileSystemRequestFileSystemFunction::OnConsentReceived( | 1272 void FileSystemRequestFileSystemFunction::OnConsentReceived( |
| 1253 base::WeakPtr<file_manager::Volume> volume, | 1273 base::WeakPtr<file_manager::Volume> volume, |
| 1254 bool writable, | 1274 bool writable, |
| 1255 ConsentProvider::Consent result) { | 1275 ConsentProvider::Consent result) { |
| 1256 using file_manager::VolumeManager; | 1276 using file_manager::VolumeManager; |
| 1257 using file_manager::Volume; | 1277 using file_manager::Volume; |
| 1258 | 1278 |
| 1259 switch (result) { | 1279 switch (result) { |
| 1260 case ConsentProvider::CONSENT_REJECTED: | 1280 case ConsentProvider::CONSENT_REJECTED: |
| 1261 SetError(kSecurityError); | 1281 SetError(kSecurityError); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 render_view_host()->GetProcess()->GetID(), file_system_id); | 1364 render_view_host()->GetProcess()->GetID(), file_system_id); |
| 1345 } | 1365 } |
| 1346 | 1366 |
| 1347 base::DictionaryValue* const dict = new base::DictionaryValue(); | 1367 base::DictionaryValue* const dict = new base::DictionaryValue(); |
| 1348 dict->SetString("file_system_id", file_system_id); | 1368 dict->SetString("file_system_id", file_system_id); |
| 1349 dict->SetString("file_system_path", register_name); | 1369 dict->SetString("file_system_path", register_name); |
| 1350 | 1370 |
| 1351 SetResult(dict); | 1371 SetResult(dict); |
| 1352 SendResponse(true); | 1372 SendResponse(true); |
| 1353 } | 1373 } |
| 1374 |
| 1375 FileSystemGetVolumeListFunction::FileSystemGetVolumeListFunction() |
| 1376 : chrome_details_(this) { |
| 1377 } |
| 1378 |
| 1379 FileSystemGetVolumeListFunction::~FileSystemGetVolumeListFunction() { |
| 1380 } |
| 1381 |
| 1382 ExtensionFunction::ResponseAction FileSystemGetVolumeListFunction::Run() { |
| 1383 // Only kiosk apps in kiosk sessions can use this API. |
| 1384 // Additionally it is enabled for whitelisted component extensions and apps. |
| 1385 file_system_api::ConsentProviderDelegate consent_provider_delegate( |
| 1386 chrome_details_.GetProfile(), render_view_host()); |
| 1387 file_system_api::ConsentProvider consent_provider(&consent_provider_delegate); |
| 1388 |
| 1389 if (!consent_provider.IsGrantable(*extension())) |
| 1390 return RespondNow(Error(kNotSupportedOnNonKioskSessionError)); |
| 1391 |
| 1392 using file_manager::VolumeManager; |
| 1393 VolumeManager* const volume_manager = |
| 1394 VolumeManager::Get(chrome_details_.GetProfile()); |
| 1395 DCHECK(volume_manager); |
| 1396 |
| 1397 using extensions::api::file_system::Volume; |
| 1398 const auto& volume_list = volume_manager->GetVolumeList(); |
| 1399 std::vector<linked_ptr<Volume>> result_volume_list; |
| 1400 // Convert volume_list to result_volume_list. |
| 1401 for (const auto& volume : volume_list) { |
| 1402 const linked_ptr<Volume> result_volume(new Volume); |
| 1403 result_volume->volume_id = volume->volume_id(); |
| 1404 result_volume->writable = !volume->is_read_only(); |
| 1405 result_volume_list.push_back(result_volume); |
| 1406 } |
| 1407 |
| 1408 return RespondNow( |
| 1409 ArgumentList(extensions::api::file_system::GetVolumeList::Results::Create( |
| 1410 result_volume_list).Pass())); |
| 1411 } |
| 1354 #endif | 1412 #endif |
| 1355 | 1413 |
| 1356 } // namespace extensions | 1414 } // namespace extensions |
| OLD | NEW |