15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements the Chrome Extensions Media Galleries API.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/media_galleries/media_galleries_api.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "apps/shell_window.h"
14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "apps/shell_window_registry.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/extensions/blob_reader.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/media_file_system_registry.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/media_galleries_dialog_controller.h"
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/media_galleries/media_galleries_histograms.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/media_galleries/media_galleries_preferences.h"
26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/storage_monitor/storage_info.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_select_file_policy.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/media_galleries.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/permissions/media_galleries_permission.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/web_modal/web_contents_modal_dialog_manager.h"
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h"
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/base/mime_sniffer.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using web_modal::WebContentsModalDialogManager;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace MediaGalleries = api::media_galleries;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace GetMediaFileSystems = MediaGalleries::GetMediaFileSystems;
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDisallowedByPolicy[] =
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Media Galleries API is disallowed by policy: ";
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kDeviceIdKey[] = "deviceId";
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kGalleryIdKey[] = "galleryId";
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kIsAvailableKey[] = "isAvailable";
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kIsMediaDeviceKey[] = "isMediaDevice";
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kIsRemovableKey[] = "isRemovable";
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kNameKey[] = "name";
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks whether the MediaGalleries API is currently accessible (it may be
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// disallowed even if an extension has the requisite permission).
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ApiIsAccessible(std::string* error) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ChromeSelectFilePolicy::FileSelectDialogsAllowed()) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = std::string(kDisallowedByPolicy) +
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        prefs::kAllowFileSelectionDialogs;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MediaFileSystemRegistry* media_file_system_registry() {
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return g_browser_process->media_file_system_registry();
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaGalleriesGetMediaFileSystemsFunction::
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~MediaGalleriesGetMediaFileSystemsFunction() {}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MediaGalleriesGetMediaFileSystemsFunction::RunImpl() {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ApiIsAccessible(&error_))
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  media_galleries::UsageCount(media_galleries::GET_MEDIA_FILE_SYSTEMS);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<GetMediaFileSystems::Params> params(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetMediaFileSystems::Params::Create(*args_));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MediaGalleries::GetMediaFileSystemsInteractivity interactive =
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->details.get() && params->details->interactive != MediaGalleries::
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    interactive = params->details->interactive;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MediaGalleriesPreferences* preferences =
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      media_file_system_registry()->GetPreferences(GetProfile());
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  preferences->EnsureInitialized(base::Bind(
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      &MediaGalleriesGetMediaFileSystemsFunction::OnPreferencesInit,
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      this,
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      interactive));
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesGetMediaFileSystemsFunction::OnPreferencesInit(
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleries::GetMediaFileSystemsInteractivity interactive) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (interactive) {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_YES: {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The MediaFileSystemRegistry only updates preferences for extensions
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // that it knows are in use. Since this may be the first call to
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // chrome.getMediaFileSystems for this extension, call
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // GetMediaFileSystemsForExtension() here solely so that
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // MediaFileSystemRegistry will send preference changes.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetMediaFileSystemsForExtension(base::Bind(
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &MediaGalleriesGetMediaFileSystemsFunction::AlwaysShowDialog, this));
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_IF_NEEDED: {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetMediaFileSystemsForExtension(base::Bind(
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries,
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this));
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetAndReturnGalleries();
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleries::GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SendResponse(false);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesGetMediaFileSystemsFunction::AlwaysShowDialog(
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<MediaFileSystemInfo>& /*filesystems*/) {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShowDialog();
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries(
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<MediaFileSystemInfo>& filesystems) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (filesystems.empty())
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShowDialog();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReturnGalleries(filesystems);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaGalleriesGetMediaFileSystemsFunction::GetAndReturnGalleries() {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetMediaFileSystemsForExtension(base::Bind(
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &MediaGalleriesGetMediaFileSystemsFunction::ReturnGalleries, this));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaGalleriesGetMediaFileSystemsFunction::ReturnGalleries(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<MediaFileSystemInfo>& filesystems) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RenderViewHost* rvh = render_view_host();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!rvh) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SendResponse(false);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleriesPermission::CheckParam read_param(
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleriesPermission::kReadPermission);
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool has_read_permission = PermissionsData::CheckAPIPermissionWithParam(
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetExtension(), APIPermission::kMediaGalleries, &read_param);
165558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  MediaGalleriesPermission::CheckParam copy_to_param(
166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      MediaGalleriesPermission::kCopyToPermission);
167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool has_copy_to_permission = PermissionsData::CheckAPIPermissionWithParam(
168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      GetExtension(), APIPermission::kMediaGalleries, &copy_to_param);
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaGalleriesPermission::CheckParam delete_param(
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      MediaGalleriesPermission::kDeletePermission);
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool has_delete_permission = PermissionsData::CheckAPIPermissionWithParam(
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GetExtension(), APIPermission::kMediaGalleries, &delete_param);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int child_id = rvh->GetProcess()->GetID();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ListValue* list = new base::ListValue();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filesystems.size(); i++) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> file_system_dict_value(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new base::DictionaryValue());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the file system id so the renderer can create a valid FileSystem
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // object.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_dict_value->SetStringWithoutPathExpansion(
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "fsid", filesystems[i].fsid);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_dict_value->SetStringWithoutPathExpansion(
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        kNameKey, filesystems[i].name);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_dict_value->SetStringWithoutPathExpansion(
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        kGalleryIdKey,
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Uint64ToString(filesystems[i].pref_id));
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!filesystems[i].transient_device_id.empty()) {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_system_dict_value->SetStringWithoutPathExpansion(
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kDeviceIdKey, filesystems[i].transient_device_id);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_dict_value->SetBooleanWithoutPathExpansion(
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kIsRemovableKey, filesystems[i].removable);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_dict_value->SetBooleanWithoutPathExpansion(
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kIsMediaDeviceKey, filesystems[i].media_device);
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    file_system_dict_value->SetBooleanWithoutPathExpansion(
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        kIsAvailableKey, true);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list->Append(file_system_dict_value.release());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (filesystems[i].path.empty())
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (has_read_permission) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::ChildProcessSecurityPolicy* policy =
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          content::ChildProcessSecurityPolicy::GetInstance();
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      policy->GrantReadFileSystem(child_id, filesystems[i].fsid);
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (has_delete_permission) {
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        policy->GrantDeleteFromFileSystem(child_id, filesystems[i].fsid);
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (has_copy_to_permission) {
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          policy->GrantCopyIntoFileSystem(child_id, filesystems[i].fsid);
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The custom JS binding will use this list to create DOMFileSystem objects.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetResult(list);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaGalleriesGetMediaFileSystemsFunction::ShowDialog() {
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  media_galleries::UsageCount(media_galleries::SHOW_DIALOG);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContents* contents = WebContents::FromRenderViewHost(render_view_host());
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebContentsModalDialogManager::FromWebContents(contents);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!web_contents_modal_dialog_manager) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If there is no WebContentsModalDialogManager, then this contents is
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // probably the background page for an app. Try to find a shell window to
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // host the dialog.
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    apps::ShellWindow* window = apps::ShellWindowRegistry::Get(
2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        GetProfile())->GetCurrentShellWindowForApp(GetExtension()->id());
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!window) {
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      SendResponse(false);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    contents = window->web_contents();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Controller will delete itself.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure cb = base::Bind(
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &MediaGalleriesGetMediaFileSystemsFunction::GetAndReturnGalleries, this);
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  new MediaGalleriesDialogController(contents, *GetExtension(), cb);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesGetMediaFileSystemsFunction::GetMediaFileSystemsForExtension(
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const MediaFileSystemsCallback& cb) {
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!render_view_host()) {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cb.Run(std::vector<MediaFileSystemInfo>());
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaFileSystemRegistry* registry = media_file_system_registry();
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(registry->GetPreferences(GetProfile())->IsInitialized());
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->GetMediaFileSystemsForExtension(
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      render_view_host(), GetExtension(), cb);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MediaGalleriesGetAllMediaFileSystemMetadataFunction::
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ~MediaGalleriesGetAllMediaFileSystemMetadataFunction() {}
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool MediaGalleriesGetAllMediaFileSystemMetadataFunction::RunImpl() {
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!ApiIsAccessible(&error_))
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  media_galleries::UsageCount(
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      media_galleries::GET_ALL_MEDIA_FILE_SYSTEM_METADATA);
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaGalleriesPreferences* preferences =
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      media_file_system_registry()->GetPreferences(GetProfile());
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  preferences->EnsureInitialized(base::Bind(
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnPreferencesInit,
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this));
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnPreferencesInit() {
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaFileSystemRegistry* registry = media_file_system_registry();
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaGalleriesPreferences* prefs = registry->GetPreferences(GetProfile());
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(prefs->IsInitialized());
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaGalleryPrefIdSet permitted_gallery_ids =
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      prefs->GalleriesForExtension(*GetExtension());
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaStorageUtil::DeviceIdSet* device_ids = new MediaStorageUtil::DeviceIdSet;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator it = permitted_gallery_ids.begin();
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       it != permitted_gallery_ids.end(); ++it) {
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MediaGalleriesPrefInfoMap::const_iterator gallery_it = galleries.find(*it);
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(gallery_it != galleries.end());
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    device_ids->insert(gallery_it->second.device_id);
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaStorageUtil::FilterAttachedDevices(
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      device_ids,
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          &MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnGetGalleries,
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          this,
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          permitted_gallery_ids,
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::Owned(device_ids)));
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaGalleriesGetAllMediaFileSystemMetadataFunction::OnGetGalleries(
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const MediaGalleryPrefIdSet& permitted_gallery_ids,
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const MediaStorageUtil::DeviceIdSet* available_devices) {
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaFileSystemRegistry* registry = media_file_system_registry();
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MediaGalleriesPreferences* prefs = registry->GetPreferences(GetProfile());
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ListValue* list = new base::ListValue();
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator it = permitted_gallery_ids.begin();
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       it != permitted_gallery_ids.end(); ++it) {
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MediaGalleriesPrefInfoMap::const_iterator gallery_it = galleries.find(*it);
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(gallery_it != galleries.end());
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery = gallery_it->second;
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MediaGalleries::MediaFileSystemMetadata metadata;
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    metadata.name = base::UTF16ToUTF8(gallery.GetGalleryDisplayName());
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    metadata.gallery_id = base::Uint64ToString(gallery.pref_id);
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    metadata.is_removable = StorageInfo::IsRemovableDevice(gallery.device_id);
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    metadata.is_media_device = StorageInfo::IsMediaDevice(gallery.device_id);
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    metadata.is_available = ContainsKey(*available_devices, gallery.device_id);
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    list->Append(metadata.ToValue().release());
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetResult(list);
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendResponse(true);
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MediaGalleriesGetMetadataFunction::~MediaGalleriesGetMetadataFunction() {}
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool MediaGalleriesGetMetadataFunction::RunImpl() {
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!ApiIsAccessible(&error_))
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string blob_uuid;
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &blob_uuid));
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::Value* options_value = NULL;
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!args_->Get(1, &options_value))
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MediaGalleries::MediaMetadataOptions> options =
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      MediaGalleries::MediaMetadataOptions::FromValue(*options_value);
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!options)
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MediaGalleriesPreferences* preferences =
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      media_file_system_registry()->GetPreferences(GetProfile());
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool mime_type_only = options->metadata_type ==
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      MediaGalleries::GET_METADATA_TYPE_MIMETYPEONLY;
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  preferences->EnsureInitialized(base::Bind(
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &MediaGalleriesGetMetadataFunction::OnPreferencesInit,
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      this, mime_type_only, blob_uuid));
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaGalleriesGetMetadataFunction::OnPreferencesInit(
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool mime_type_only,
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& blob_uuid) {
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // BlobReader is self-deleting.
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BlobReader* reader = new BlobReader(
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetProfile(),
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      blob_uuid,
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&MediaGalleriesGetMetadataFunction::SniffMimeType, this,
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 mime_type_only));
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reader->SetByteRange(0, net::kMaxBytesToSniff);
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reader->Start();
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaGalleriesGetMetadataFunction::SniffMimeType(
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool mime_type_only, scoped_ptr<std::string> blob_header) {
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MediaGalleries::MediaMetadata metadata;
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string mime_type;
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool mime_type_sniffed = net::SniffMimeTypeFromLocalData(
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      blob_header->c_str(), blob_header->size(), &mime_type);
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (mime_type_sniffed)
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    metadata.mime_type = mime_type;
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(tommycli): Kick off SafeMediaMetadataParser if |mime_type_only| false.
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetResult(metadata.ToValue().release());
386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SendResponse(true);
387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
390