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// File contains the fileBrowserHandlerInternal.selectFile extension function. 6// The function prompts user to select a file path to be used by the caller. It 7// will fail if it isn't invoked by a user gesture (e.g. a mouse click or a 8// keyboard key press). 9// Note that the target file is never actually created by this function, even 10// if the selected path doesn't exist. 11 12#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_BROWSER_HANDLER_API_H_ 13#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_BROWSER_HANDLER_API_H_ 14 15#include <string> 16#include <vector> 17 18#include "base/files/file_path.h" 19#include "chrome/browser/extensions/extension_function.h" 20 21class Browser; 22class FileBrowserHandlerInternalSelectFileFunction; 23 24namespace file_manager { 25 26// Interface that is used by FileBrowserHandlerInternalSelectFileFunction to 27// select the file path that should be reported back to the extension function 28// caller. Nobody will take the ownership of the interface implementation, so 29// it should delete itself once it's done. 30class FileSelector { 31 public: 32 virtual ~FileSelector() {} 33 34 // Starts the file selection. It should prompt user to select a file path. 35 // Once the selection is made it should asynchronously call 36 // |function_->OnFilePathSelected| with the selection information. 37 // User should be initially suggested to select file named |suggested_name|. 38 // |allowed_extensions| specifies the file extensions allowed to be shown, 39 // and selected. Extensions should not include '.'. This spec comes from 40 // ui::SelectFileDialog() which takes extensions without '.'. 41 // 42 // Selection UI should be displayed using |browser|. |browser| should outlive 43 // the interface implementation. 44 // |function| if the extension function that called the method and needs to 45 // be notified of user action. The interface implementation should keep a 46 // reference to the function until it is notified (extension function 47 // implementations are ref counted). 48 // |SelectFile| will be called at most once by a single extension function. 49 // The interface implementation should delete itself after the extension 50 // function is notified of file selection result. 51 virtual void SelectFile( 52 const base::FilePath& suggested_name, 53 const std::vector<std::string>& allowed_extensions, 54 Browser* browser, 55 FileBrowserHandlerInternalSelectFileFunction* function) = 0; 56}; 57 58// Interface that is used by FileBrowserHandlerInternalSelectFileFunction to 59// create a FileSelector it can use to select a file path. 60class FileSelectorFactory { 61 public: 62 virtual ~FileSelectorFactory() {} 63 64 // Creates a FileSelector instance for the 65 // FileBrowserHandlerInternalSelectFileFunction. 66 virtual FileSelector* CreateFileSelector() const = 0; 67}; 68 69} // namespace file_manager 70 71 72// Note that this class is not in 'file_manager' class to be consistent with 73// all other extension functions registered in 74// chrome/common/extensions/api/generated_api.cc being in the global namespace. 75// 76// The fileBrowserHandlerInternal.selectFile extension function implementation. 77// See the file description for more info. 78class FileBrowserHandlerInternalSelectFileFunction 79 : public AsyncExtensionFunction { 80 public: 81 // Default constructor used in production code. 82 // It will create its own FileSelectorFactory implementation, and set the 83 // value of |user_gesture_check_enabled| to true. 84 FileBrowserHandlerInternalSelectFileFunction(); 85 86 // This constructor should be used only in tests to inject test file selector 87 // factory and to allow extension function to run even if it hasn't been 88 // invoked by user gesture. 89 // Created object will take the ownership of the |file_selector_factory|. 90 FileBrowserHandlerInternalSelectFileFunction( 91 file_manager::FileSelectorFactory* file_selector_factory, 92 bool enable_user_gesture_check); 93 94 // Called by FileSelector implementation when the user selects the file's 95 // file path. File access permissions for the selected file are granted and 96 // caller is notified of the selection result after this method is called. 97 // |success| Whether the path was selected. 98 // |full_path| The selected file path if one was selected. It is ignored if 99 // the selection did not succeed. 100 void OnFilePathSelected(bool success, const base::FilePath& full_path); 101 102 protected: 103 // The class is ref counted, so destructor should not be public. 104 virtual ~FileBrowserHandlerInternalSelectFileFunction(); 105 106 // AsyncExtensionFunction implementation. 107 // Runs the extension function implementation. 108 virtual bool RunImpl() OVERRIDE; 109 110 private: 111 // Called when the external file system is opened for the extension function 112 // caller in the browser context. It saves opened file system's parameters. 113 // The file system is needed to create FileEntry object for the selection 114 // result. 115 // |success| Whether the file system has been opened successfully. 116 // |file_system_name| The file system's name. 117 // |file_system_root| The file system's root url. 118 void OnFileSystemOpened(bool success, 119 const std::string& file_system_name, 120 const GURL& file_system_root); 121 122 // Grants file access permissions for the created file to the caller. 123 // Inside this method, |virtual_path_| value is set. 124 void GrantPermissions(); 125 126 // Creates dictionary value that will be used to as the extension function's 127 // callback argument and ends extension function execution by calling 128 // |SendResponse(true)|. 129 // The |results_| value will be set to dictionary containing two properties: 130 // * boolean 'success', which will be equal to |success|. 131 // * object 'entry', which will be set only when |success| if true and 132 // will contain information needed to create a FileEntry object for the 133 // selected file. It contains following properties: 134 // * 'file_system_name' set to |file_system_name_| 135 // * 'file_system_root' set to |file_system_root_| 136 // * 'file_full_path' set to |virtual_path_| (with leading '/') 137 // * 'file_is_directory' set to |false|. 138 // |file_system_name_|, |file_system_root_| and |virtual_path_| are ignored 139 // if |success| if false. 140 void Respond(bool success); 141 142 // Factory used to create FileSelector to be used for prompting user to select 143 // file. 144 scoped_ptr<file_manager::FileSelectorFactory> file_selector_factory_; 145 // Whether user gesture check is disabled. This should be true only in tests. 146 bool user_gesture_check_enabled_; 147 148 // Full file system path of the selected file. 149 base::FilePath full_path_; 150 // Selected file's virtual path in extension function caller's file system. 151 base::FilePath virtual_path_; 152 // Extension function caller's file system name. 153 std::string file_system_name_; 154 // Extension function caller's file system root URL. 155 GURL file_system_root_; 156 157 // List of permissions and paths that have to be granted for the selected 158 // files. 159 std::vector<std::pair<base::FilePath, int> > permissions_to_grant_; 160 161 DECLARE_EXTENSION_FUNCTION("fileBrowserHandlerInternal.selectFile", 162 FILEBROWSERHANDLERINTERNAL_SELECTFILE) 163}; 164 165#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_BROWSER_HANDLER_API_H_ 166