15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 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)#ifndef CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/shell_integration.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GURL;
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PrefRegistrySimple;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExternalProtocolHandler {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum BlockState {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DONT_BLOCK,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BLOCK,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNKNOWN,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delegate to allow unit testing to provide different behavior.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Delegate {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ShellIntegration::DefaultWebClientObserver* observer,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const std::string& protocol) = 0;
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    virtual BlockState GetBlockState(const std::string& scheme) = 0;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void BlockRequest() = 0;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void RunExternalProtocolDialog(const GURL& url,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int render_process_host_id,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int routing_id) = 0;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) = 0;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void FinishedProcessingCheck() = 0;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Delegate() {}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns whether we should block a given scheme.
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static BlockState GetBlockState(const std::string& scheme);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets whether we should block a given scheme.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetBlockState(const std::string& scheme, BlockState state);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Checks to see if the protocol is allowed, if it is whitelisted,
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // the application associated with the protocol is launched on the io thread,
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // if it is blacklisted, returns silently. Otherwise, an
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // ExternalProtocolDialog is created asking the user. If the user accepts,
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // LaunchUrlWithoutSecurityCheck is called on the io thread and the
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // application is launched.
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Must run on the UI thread.
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void LaunchUrl(const GURL& url,
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        int render_process_host_id,
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        int tab_contents_id) {
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LaunchUrlWithDelegate(url, render_process_host_id, tab_contents_id, NULL);
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Version of LaunchUrl allowing use of a delegate to facilitate unit
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // testing.
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void LaunchUrlWithDelegate(const GURL& url,
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    int render_process_host_id,
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    int tab_contents_id,
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    Delegate* delegate);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates and runs a External Protocol dialog box.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |url| - The url of the request.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |render_process_host_id| and |routing_id| are used by
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // tab_util::GetWebContentsByID to aquire the tab contents associated with
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this dialog.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: There is a race between the Time of Check and the Time Of Use for
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       the command line. Since the caller (web page) does not have access
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       to change the command line by itself, we do not do anything special
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       to protect against this scenario.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is implemented separately on each platform.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunExternalProtocolDialog(const GURL& url,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int render_process_host_id,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int routing_id);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register the ExcludedSchemes preference.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void RegisterPrefs(PrefRegistrySimple* registry);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts a url using the external protocol handler with the help
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of shellexecute. Should only be called if the protocol is whitelisted
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (checked in LaunchUrl) or if the user explicitly allows it. (By selecting
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "Launch Application" in an ExternalProtocolDialog.) It is assumed that the
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url has already been escaped, which happens in LaunchUrl.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: You should Not call this function directly unless you are sure the
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url you have has been checked against the blacklist, and has been escaped.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All calls to this function should originate in some way from LaunchUrl.
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static void LaunchUrlWithoutSecurityCheck(const GURL& url,
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            int render_process_host_id,
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            int tab_contents_id);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prepopulates the dictionary with known protocols to deny or allow, if
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preferences for them do not already exist.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void PrepopulateDictionary(base::DictionaryValue* win_pref);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Allows LaunchUrl to proceed with launching an external protocol handler.
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // This is typically triggered by a user gesture, but is also called for
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // each extension API function. Note that each call to LaunchUrl resets
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // the state to false (not allowed).
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void PermitLaunchUrl();
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private:
109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ExternalProtocolHandler);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_
113