// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_INCOGNITO_CONNECTABILITY_H_ #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_INCOGNITO_CONNECTABILITY_H_ #include #include "base/memory/weak_ptr.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "url/gurl.h" namespace content { class BrowserContext; class WebContents; } namespace infobars { class InfoBar; class InfoBarManager; } namespace extensions { class Extension; // Tracks the web connectability of domains to extensions in incognito mode. // // The most important functionality is prompting the user to allow or disallow // connections from incognito tabs to extensions or apps. Even if an extension // hasn't been enabled in incognito mode, it's still useful for web sites to be // able to send messages to them, with user constent. For apps, it's essential // we have this functionality because there is no way for them to be enabled in // incognito. class IncognitoConnectability : public BrowserContextKeyedAPI { public: // While in scope, immediately either accepts or denies the alerts that show // up, and counts the number of times it was invoked. class ScopedAlertTracker { public: enum Mode { INTERACTIVE, ALWAYS_ALLOW, ALWAYS_DENY, }; explicit ScopedAlertTracker(Mode mode); ~ScopedAlertTracker(); // Returns the number of times the alert has been shown since // GetAndResetAlertCount was last called. int GetAndResetAlertCount(); private: int last_checked_invocation_count_; }; // Returns the IncognitoConnectability object for |context|. |context| must // be off-the-record. static IncognitoConnectability* Get(content::BrowserContext* context); // Passes true to the provided callback if |url| is allowed to connect from // this profile, false otherwise. If unknown, the user will be prompted before // an answer is returned. void Query(const Extension* extension, content::WebContents* web_contents, const GURL& url, const base::Callback& callback); private: struct TabContext { TabContext(); TabContext(const TabContext& other); ~TabContext(); // The infobar being shown in a given tab. The InfoBarManager maintains // ownership of this object. This struct must always be destroyed before the // infobar it tracks. infobars::InfoBar* infobar; // Connectability queries outstanding on this infobar. std::vector> callbacks; }; friend class BrowserContextKeyedAPIFactory; explicit IncognitoConnectability(content::BrowserContext* context); ~IncognitoConnectability() override; typedef std::map > ExtensionToOriginsMap; typedef std::pair ExtensionOriginPair; typedef std::map PendingOrigin; typedef std::map PendingOriginMap; // Called with the user's selection from the infobar. // |response == INTERACTIVE| indicates that the user closed the infobar // without selecting allow or deny. void OnInteractiveResponse(const std::string& extension_id, const GURL& origin, infobars::InfoBarManager* infobar_manager, ScopedAlertTracker::Mode response); // Returns true if the (|extension|, |origin|) pair appears in the map. bool IsInMap(const Extension* extension, const GURL& origin, const ExtensionToOriginsMap& map); // BrowserContextKeyedAPI implementation. static BrowserContextKeyedAPIFactory* GetFactoryInstance(); static const char* service_name() { return "Messaging.IncognitoConnectability"; } static const bool kServiceHasOwnInstanceInIncognito = true; static const bool kServiceIsCreatedWithBrowserContext = false; // The origins that have been prompted for and either allowed or disallowed. // These are deliberately stored in-memory so that they're reset when the // profile is destroyed (i.e. when the last incognito window is closed). ExtensionToOriginsMap allowed_origins_; ExtensionToOriginsMap disallowed_origins_; // This maps extension/origin pairs to the tabs with an infobar prompting for // incognito connectability on them. This also stores a reference to the // infobar and the set of callbacks (passed to Query) that will be called when // the query is resolved. PendingOriginMap pending_origins_; base::WeakPtrFactory weak_factory_; }; } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_INCOGNITO_CONNECTABILITY_H_