1 // Copyright 2013 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.
5 #include "chrome/browser/signin/chrome_signin_helper.h"
7 #include "base/strings/string_util.h"
8 #include "chrome/browser/prefs/incognito_mode_prefs.h"
9 #include "chrome/browser/profiles/profile_io_data.h"
10 #include "chrome/browser/signin/account_reconcilor_factory.h"
11 #include "chrome/browser/signin/chrome_signin_client.h"
12 #include "chrome/browser/tab_contents/tab_util.h"
13 #include "chrome/browser/ui/browser_window.h"
14 #include "chrome/common/url_constants.h"
15 #include "components/signin/core/browser/account_reconcilor.h"
16 #include "components/signin/core/browser/signin_header_helper.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/resource_request_info.h"
19 #include "content/public/browser/web_contents.h"
20 #include "google_apis/gaia/gaia_auth_util.h"
21 #include "net/url_request/url_request.h"
23 #if defined(OS_ANDROID)
24 #include "chrome/browser/android/signin/account_management_screen_helper.h"
26 #include "chrome/browser/ui/browser_commands.h"
27 #include "chrome/browser/ui/browser_finder.h"
28 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
29 #endif // defined(OS_ANDROID)
35 // Processes the mirror response header on the UI thread. Currently depending
36 // on the value of |header_value|, it either shows the profile avatar menu, or
37 // opens an incognito window/tab.
38 void ProcessMirrorHeaderUIThread(int child_id
,
40 ManageAccountsParams manage_accounts_params
) {
41 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
43 GAIAServiceType service_type
= manage_accounts_params
.service_type
;
44 DCHECK_NE(GAIA_SERVICE_TYPE_NONE
, service_type
);
46 content::WebContents
* web_contents
=
47 tab_util::GetWebContentsByID(child_id
, route_id
);
52 Profile::FromBrowserContext(web_contents
->GetBrowserContext());
53 #if !defined(OS_ANDROID)
54 Browser
* browser
= chrome::FindBrowserWithWebContents(web_contents
);
56 BrowserWindow::AvatarBubbleMode bubble_mode
;
57 switch (service_type
) {
58 case GAIA_SERVICE_TYPE_INCOGNITO
:
59 chrome::NewIncognitoWindow(browser
);
61 case GAIA_SERVICE_TYPE_ADDSESSION
:
62 bubble_mode
= BrowserWindow::AVATAR_BUBBLE_MODE_ADD_ACCOUNT
;
64 case GAIA_SERVICE_TYPE_REAUTH
:
65 bubble_mode
= BrowserWindow::AVATAR_BUBBLE_MODE_REAUTH
;
68 bubble_mode
= BrowserWindow::AVATAR_BUBBLE_MODE_ACCOUNT_MANAGEMENT
;
70 signin_metrics::LogAccountReconcilorStateOnGaiaResponse(
71 AccountReconcilorFactory::GetForProfile(profile
)->GetState());
72 browser
->window()->ShowAvatarBubbleFromAvatarButton(bubble_mode
,
73 manage_accounts_params
);
75 #else // defined(OS_ANDROID)
76 if (service_type
== signin::GAIA_SERVICE_TYPE_INCOGNITO
) {
77 GURL
url(manage_accounts_params
.continue_url
.empty()
78 ? chrome::kChromeUINativeNewTabURL
79 : manage_accounts_params
.continue_url
);
80 web_contents
->OpenURL(
81 content::OpenURLParams(url
, content::Referrer(), OFF_THE_RECORD
,
82 ui::PAGE_TRANSITION_AUTO_TOPLEVEL
, false));
84 signin_metrics::LogAccountReconcilorStateOnGaiaResponse(
85 AccountReconcilorFactory::GetForProfile(profile
)->GetState());
86 AccountManagementScreenHelper::OpenAccountManagementScreen(profile
,
89 #endif // !defined(OS_ANDROID)
92 // Returns the parameters contained in the X-Chrome-Manage-Accounts response
94 // If the request does not have a response header or if the header contains
95 // garbage, then |service_type| is set to |GAIA_SERVICE_TYPE_NONE|.
96 // Must be called on IO thread.
97 ManageAccountsParams
BuildManageAccountsParamsHelper(net::URLRequest
* request
,
98 ProfileIOData
* io_data
) {
99 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
101 const content::ResourceRequestInfo
* info
=
102 content::ResourceRequestInfo::ForRequest(request
);
103 if (!(info
&& info
->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME
)) {
104 ManageAccountsParams empty_params
;
105 empty_params
.service_type
= GAIA_SERVICE_TYPE_NONE
;
109 return BuildManageAccountsParamsIfExists(request
, io_data
->IsOffTheRecord());
114 bool AppendMirrorRequestHeaderHelper(net::URLRequest
* request
,
115 const GURL
& redirect_url
,
116 ProfileIOData
* io_data
,
119 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
121 if (io_data
->IsOffTheRecord())
124 #if !defined(OS_ANDROID)
125 extensions::WebViewRendererState::WebViewInfo webview_info
;
126 bool is_guest
= extensions::WebViewRendererState::GetInstance()->GetInfo(
127 child_id
, route_id
, &webview_info
);
128 // Do not set the x-chrome-connected header on requests from a native signin
129 // webview, as identified by an empty extension id which means the webview is
130 // embedded in a webui page, otherwise user may end up with a blank page as
131 // gaia uses the header to decide whether it returns 204 for certain end
133 if (is_guest
&& webview_info
.owner_host
.empty())
135 #endif // !defined(OS_ANDROID)
137 int profile_mode_mask
= PROFILE_MODE_DEFAULT
;
138 if (io_data
->incognito_availibility()->GetValue() ==
139 IncognitoModePrefs::DISABLED
||
140 IncognitoModePrefs::ArePlatformParentalControlsEnabled()) {
141 profile_mode_mask
|= PROFILE_MODE_INCOGNITO_DISABLED
;
144 return AppendMirrorRequestHeaderIfPossible(
145 request
, redirect_url
, io_data
->google_services_account_id()->GetValue(),
146 io_data
->GetCookieSettings(), profile_mode_mask
);
149 void ProcessMirrorResponseHeaderIfExists(net::URLRequest
* request
,
150 ProfileIOData
* io_data
,
153 ManageAccountsParams params
=
154 BuildManageAccountsParamsHelper(request
, io_data
);
155 if (params
.service_type
== GAIA_SERVICE_TYPE_NONE
)
158 params
.child_id
= child_id
;
159 params
.route_id
= route_id
;
160 content::BrowserThread::PostTask(
161 content::BrowserThread::UI
, FROM_HERE
,
162 base::Bind(ProcessMirrorHeaderUIThread
, child_id
, route_id
, params
));
165 } // namespace signin