Home | History | Annotate | Download | only in extensions
      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
      3 // found in the LICENSE file.
      4 
      5 // Custom binding for the Media Gallery API.
      6 
      7 var binding = require('binding').Binding.create('mediaGalleries');
      8 var blobNatives = requireNative('blob_natives');
      9 var mediaGalleriesNatives = requireNative('mediaGalleries');
     10 
     11 var blobsAwaitingMetadata = {};
     12 var mediaGalleriesMetadata = {};
     13 
     14 function createFileSystemObjectsAndUpdateMetadata(response) {
     15   var result = [];
     16   mediaGalleriesMetadata = {};  // Clear any previous metadata.
     17   if (response) {
     18     for (var i = 0; i < response.length; i++) {
     19       var filesystem = mediaGalleriesNatives.GetMediaFileSystemObject(
     20           response[i].fsid);
     21       $Array.push(result, filesystem);
     22       var metadata = response[i];
     23       delete metadata.fsid;
     24       mediaGalleriesMetadata[filesystem.name] = metadata;
     25     }
     26   }
     27   return result;
     28 }
     29 
     30 binding.registerCustomHook(function(bindingsAPI, extensionId) {
     31   var apiFunctions = bindingsAPI.apiFunctions;
     32 
     33   // getMediaFileSystems, addUserSelectedFolder, and addScanResults use a
     34   // custom callback so that they can instantiate and return an array of file
     35   // system objects.
     36   apiFunctions.setCustomCallback('getMediaFileSystems',
     37                                  function(name, request, response) {
     38     var result = createFileSystemObjectsAndUpdateMetadata(response);
     39     if (request.callback)
     40       request.callback(result);
     41     request.callback = null;
     42   });
     43 
     44   apiFunctions.setCustomCallback('addScanResults',
     45                                  function(name, request, response) {
     46     var result = createFileSystemObjectsAndUpdateMetadata(response);
     47     if (request.callback)
     48       request.callback(result);
     49     request.callback = null;
     50   });
     51 
     52   apiFunctions.setCustomCallback('addUserSelectedFolder',
     53                                  function(name, request, response) {
     54     var fileSystems = [];
     55     var selectedFileSystemName = "";
     56     if (response && 'mediaFileSystems' in response &&
     57         'selectedFileSystemIndex' in response) {
     58       fileSystems = createFileSystemObjectsAndUpdateMetadata(
     59           response['mediaFileSystems']);
     60       var selectedFileSystemIndex = response['selectedFileSystemIndex'];
     61       if (selectedFileSystemIndex >= 0) {
     62         selectedFileSystemName = fileSystems[selectedFileSystemIndex].name;
     63       }
     64     }
     65     if (request.callback)
     66       request.callback(fileSystems, selectedFileSystemName);
     67     request.callback = null;
     68   });
     69 
     70   apiFunctions.setCustomCallback('dropPermissionForMediaFileSystem',
     71                                  function(name, request, response) {
     72     var galleryId = response;
     73 
     74     if (galleryId) {
     75       for (var key in mediaGalleriesMetadata) {
     76         if (mediaGalleriesMetadata[key].galleryId == galleryId) {
     77           delete mediaGalleriesMetadata[key];
     78           break;
     79         }
     80       }
     81     }
     82     if (request.callback)
     83       request.callback();
     84     request.callback = null;
     85   });
     86 
     87   apiFunctions.setHandleRequest('getMediaFileSystemMetadata',
     88                                 function(filesystem) {
     89     if (filesystem && filesystem.name &&
     90         filesystem.name in mediaGalleriesMetadata) {
     91       return mediaGalleriesMetadata[filesystem.name];
     92     }
     93     return {
     94       'name': '',
     95       'galleryId': '',
     96       'isRemovable': false,
     97       'isMediaDevice': false,
     98       'isAvailable': false,
     99     };
    100   });
    101 
    102   apiFunctions.setUpdateArgumentsPostValidate('getMetadata',
    103       function(mediaFile, options, callback) {
    104     var blobUuid = blobNatives.GetBlobUuid(mediaFile)
    105     // Store the blob in a global object to keep its refcount nonzero -- this
    106     // prevents the object from being garbage collected before any metadata
    107     // parsing gets to occur (see crbug.com/415792).
    108     blobsAwaitingMetadata[blobUuid] = mediaFile;
    109     return [blobUuid, options, callback];
    110   });
    111 
    112   apiFunctions.setCustomCallback('getMetadata',
    113                                  function(name, request, response) {
    114     if (response.attachedImagesBlobInfo) {
    115       for (var i = 0; i < response.attachedImagesBlobInfo.length; i++) {
    116         var blobInfo = response.attachedImagesBlobInfo[i];
    117         var blob = blobNatives.TakeBrowserProcessBlob(
    118             blobInfo.blobUUID, blobInfo.type, blobInfo.size);
    119         response.metadata.attachedImages.push(blob);
    120       }
    121     }
    122 
    123     if (request.callback)
    124       request.callback(response.metadata);
    125     request.callback = null;
    126 
    127     // The UUID was in position 0 in the setUpdateArgumentsPostValidate
    128     // function.
    129     var uuid = request.args[0];
    130     delete blobsAwaitingMetadata[uuid];
    131   });
    132 });
    133 
    134 exports.binding = binding.generate();
    135