1 // Copyright 2018 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_WEB_APPLICATIONS_WEB_APP_TAB_HELPER_H_ 6 #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_TAB_HELPER_H_ 7 8 #include "base/scoped_observer.h" 9 #include "base/unguessable_token.h" 10 #include "chrome/browser/web_applications/components/app_registrar.h" 11 #include "chrome/browser/web_applications/components/app_registrar_observer.h" 12 #include "chrome/browser/web_applications/components/web_app_id.h" 13 #include "chrome/browser/web_applications/components/web_app_tab_helper_base.h" 14 #include "content/public/browser/web_contents_observer.h" 15 16 namespace content { 17 class WebContents; 18 } 19 20 namespace web_app { 21 22 class WebAppProviderBase; 23 24 // Per-tab web app helper. Allows to associate a tab (web page) with a web app 25 // (or legacy bookmark app). 26 class WebAppTabHelper : public WebAppTabHelperBase, 27 public content::WebContentsObserver, 28 public AppRegistrarObserver { 29 public: 30 static void CreateForWebContents(content::WebContents* contents); 31 32 explicit WebAppTabHelper(content::WebContents* web_contents); 33 WebAppTabHelper(const WebAppTabHelper&) = delete; 34 WebAppTabHelper& operator=(const WebAppTabHelper&) = delete; 35 ~WebAppTabHelper() override; 36 37 // WebAppTabHelperBase: 38 const AppId& GetAppId() const override; 39 void SetAppId(const AppId& app_id) override; 40 const base::UnguessableToken& GetAudioFocusGroupIdForTesting() const override; 41 bool HasLoadedNonAboutBlankPage() const override; 42 43 // content::WebContentsObserver: 44 void ReadyToCommitNavigation( 45 content::NavigationHandle* navigation_handle) override; 46 void DidFinishNavigation( 47 content::NavigationHandle* navigation_handle) override; 48 void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override; 49 void DidCloneToNewWebContents( 50 content::WebContents* old_web_contents, 51 content::WebContents* new_web_contents) override; 52 53 private: 54 friend class WebAppAudioFocusBrowserTest; 55 friend class content::WebContentsUserData<WebAppTabHelper>; 56 57 // Returns whether the associated web contents belongs to an app window. 58 bool IsInAppWindow() const; 59 60 // AppRegistrarObserver: 61 void OnWebAppInstalled(const AppId& installed_app_id) override; 62 void OnWebAppUninstalled(const AppId& uninstalled_app_id) override; 63 void OnAppRegistrarShutdown() override; 64 void OnAppRegistrarDestroyed() override; 65 66 void ResetAppId(); 67 68 // Runs any logic when the associated app either changes or is removed. 69 void OnAssociatedAppChanged(const AppId& previous_app_id, 70 const AppId& new_app_id); 71 72 // Updates the audio focus group id based on the current web app. 73 void UpdateAudioFocusGroupId(); 74 75 // Triggers a reinstall of a placeholder app for |url|. 76 void ReinstallPlaceholderAppIfNecessary(const GURL& url); 77 78 AppId FindAppIdWithUrlInScope(const GURL& url) const; 79 80 // WebApp associated with this tab. Empty string if no app associated. 81 AppId app_id_; 82 83 // Indicates if the current page is an error page (e.g. the page failed to 84 // load). We store this because it isn't accessible off a |WebContents| or a 85 // |RenderFrameHost|. 86 bool is_error_page_ = false; 87 88 // The audio focus group id is used to group media sessions together for apps. 89 // We store the applied group id locally on the helper for testing. 90 base::UnguessableToken audio_focus_group_id_ = base::UnguessableToken::Null(); 91 92 bool has_loaded_non_about_blank_page_ = false; 93 94 ScopedObserver<AppRegistrar, AppRegistrarObserver> observer_{this}; 95 WebAppProviderBase* provider_ = nullptr; 96 97 }; 98 99 } // namespace web_app 100 101 #endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_TAB_HELPER_H_ 102