1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_ 6 #define CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_ 7 8 #include <string> 9 10 #include "chrome/browser/shell_integration.h" 11 12 class GURL; 13 class PrefRegistrySimple; 14 15 namespace base { 16 class DictionaryValue; 17 } 18 19 class ExternalProtocolHandler { 20 public: 21 enum BlockState { 22 DONT_BLOCK, 23 BLOCK, 24 UNKNOWN, 25 }; 26 27 // Delegate to allow unit testing to provide different behavior. 28 class Delegate { 29 public: 30 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( 31 ShellIntegration::DefaultWebClientObserver* observer, 32 const std::string& protocol) = 0; 33 virtual BlockState GetBlockState(const std::string& scheme) = 0; 34 virtual void BlockRequest() = 0; 35 virtual void RunExternalProtocolDialog(const GURL& url, 36 int render_process_host_id, 37 int routing_id) = 0; 38 virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) = 0; 39 virtual void FinishedProcessingCheck() = 0; ~Delegate()40 virtual ~Delegate() {} 41 }; 42 43 // Returns whether we should block a given scheme. 44 static BlockState GetBlockState(const std::string& scheme); 45 46 // Sets whether we should block a given scheme. 47 static void SetBlockState(const std::string& scheme, BlockState state); 48 49 // Checks to see if the protocol is allowed, if it is whitelisted, 50 // the application associated with the protocol is launched on the io thread, 51 // if it is blacklisted, returns silently. Otherwise, an 52 // ExternalProtocolDialog is created asking the user. If the user accepts, 53 // LaunchUrlWithoutSecurityCheck is called on the io thread and the 54 // application is launched. 55 // Must run on the UI thread. LaunchUrl(const GURL & url,int render_process_host_id,int tab_contents_id)56 static void LaunchUrl(const GURL& url, 57 int render_process_host_id, 58 int tab_contents_id) { 59 LaunchUrlWithDelegate(url, render_process_host_id, tab_contents_id, NULL); 60 } 61 62 // Version of LaunchUrl allowing use of a delegate to facilitate unit 63 // testing. 64 static void LaunchUrlWithDelegate(const GURL& url, 65 int render_process_host_id, 66 int tab_contents_id, 67 Delegate* delegate); 68 69 // Creates and runs a External Protocol dialog box. 70 // |url| - The url of the request. 71 // |render_process_host_id| and |routing_id| are used by 72 // tab_util::GetWebContentsByID to aquire the tab contents associated with 73 // this dialog. 74 // NOTE: There is a race between the Time of Check and the Time Of Use for 75 // the command line. Since the caller (web page) does not have access 76 // to change the command line by itself, we do not do anything special 77 // to protect against this scenario. 78 // This is implemented separately on each platform. 79 static void RunExternalProtocolDialog(const GURL& url, 80 int render_process_host_id, 81 int routing_id); 82 83 // Register the ExcludedSchemes preference. 84 static void RegisterPrefs(PrefRegistrySimple* registry); 85 86 // Starts a url using the external protocol handler with the help 87 // of shellexecute. Should only be called if the protocol is whitelisted 88 // (checked in LaunchUrl) or if the user explicitly allows it. (By selecting 89 // "Launch Application" in an ExternalProtocolDialog.) It is assumed that the 90 // url has already been escaped, which happens in LaunchUrl. 91 // NOTE: You should Not call this function directly unless you are sure the 92 // url you have has been checked against the blacklist, and has been escaped. 93 // All calls to this function should originate in some way from LaunchUrl. 94 static void LaunchUrlWithoutSecurityCheck(const GURL& url, 95 int render_process_host_id, 96 int tab_contents_id); 97 98 // Prepopulates the dictionary with known protocols to deny or allow, if 99 // preferences for them do not already exist. 100 static void PrepopulateDictionary(base::DictionaryValue* win_pref); 101 102 // Allows LaunchUrl to proceed with launching an external protocol handler. 103 // This is typically triggered by a user gesture, but is also called for 104 // each extension API function. Note that each call to LaunchUrl resets 105 // the state to false (not allowed). 106 static void PermitLaunchUrl(); 107 108 private: 109 DISALLOW_COPY_AND_ASSIGN(ExternalProtocolHandler); 110 }; 111 112 #endif // CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_ 113