12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/cloud/user_policy_signin_service.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind_helpers.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/callback.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/user_cloud_policy_manager.h" 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h" 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_details.h" 2058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/public/browser/notification_source.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h" 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace policy { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UserPolicySigninService::UserPolicySigninService( 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Profile* profile, 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PrefService* local_state, 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DeviceManagementService* device_management_service, 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UserCloudPolicyManager* policy_manager, 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SigninManager* signin_manager, 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> system_request_context, 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ProfileOAuth2TokenService* token_service) 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : UserPolicySigninServiceBase(profile, 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) local_state, 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_management_service, 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) policy_manager, 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_manager, 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) system_request_context), 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_(profile), 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) oauth2_token_service_(token_service) { 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // ProfileOAuth2TokenService should not yet have loaded its tokens since this 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // happens in the background after PKS initialization - so this service 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // should always be created before the oauth token is available. 4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!oauth2_token_service_->RefreshTokenIsAvailable( 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_manager->GetAuthenticatedAccountId())); 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Listen for an OAuth token to become available so we can register a client 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if for some reason the client is not already registered (for example, if 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the policy load failed during initial signin). 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) oauth2_token_service_->AddObserver(this); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)UserPolicySigninService::~UserPolicySigninService() { 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void UserPolicySigninService::PrepareForUserCloudPolicyManagerShutdown() { 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Stop any pending registration helper activity. We do this here instead of 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // in the destructor because we want to shutdown the registration helper 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // before UserCloudPolicyManager shuts down the CloudPolicyClient. 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch registration_helper_.reset(); 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UserPolicySigninServiceBase::PrepareForUserCloudPolicyManagerShutdown(); 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void UserPolicySigninService::Shutdown() { 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UserPolicySigninServiceBase::Shutdown(); 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) oauth2_token_service_->RemoveObserver(this); 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void UserPolicySigninService::RegisterForPolicy( 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& username, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& oauth2_refresh_token, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PolicyRegistrationCallback& callback) { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!oauth2_refresh_token.empty()); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create a new CloudPolicyClient for fetching the DMToken. 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<CloudPolicyClient> policy_client = CreateClientForRegistrationOnly( 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) username); 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!policy_client) { 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) callback.Run(std::string(), std::string()); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fire off the registration process. Callback keeps the CloudPolicyClient 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // alive for the length of the registration process. Use the system 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // request context because the user is not signed in to this profile yet 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // (we are just doing a test registration to see if policy is supported for 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // this user). 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch registration_helper_.reset(new CloudPolicyClientRegistrationHelper( 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch policy_client.get(), 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch enterprise_management::DeviceRegisterRequest::BROWSER)); 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch registration_helper_->StartRegistrationWithLoginToken( 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch oauth2_refresh_token, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback, 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Unretained(this), 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Passed(&policy_client), 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback)); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UserPolicySigninService::CallPolicyRegistrationCallback( 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<CloudPolicyClient> client, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyRegistrationCallback callback) { 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registration_helper_.reset(); 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) callback.Run(client->dm_token(), client->client_id()); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void UserPolicySigninService::OnRefreshTokenAvailable( 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& account_id) { 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If using a TestingProfile with no UserCloudPolicyManager, skip 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // initialization. 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!policy_manager()) { 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Skipping initialization for tests due to missing components."; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignore OAuth tokens for any account but the primary one. 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (account_id != signin_manager()->GetAuthenticatedAccountId()) 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // ProfileOAuth2TokenService now has a refresh token so initialize the 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // UserCloudPolicyManager. 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) InitializeForSignedInUser(signin_manager()->GetAuthenticatedUsername(), 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_->GetRequestContext()); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UserPolicySigninService::InitializeUserCloudPolicyManager( 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& username, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<CloudPolicyClient> client) { 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UserPolicySigninServiceBase::InitializeUserCloudPolicyManager(username, 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) client.Pass()); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProhibitSignoutIfNeeded(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UserPolicySigninService::ShutdownUserCloudPolicyManager() { 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UserCloudPolicyManager* manager = policy_manager(); 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Allow the user to signout again. 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (manager) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_manager()->ProhibitSignout(false); 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager(); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UserPolicySigninService::OnInitializationCompleted( 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloudPolicyService* service) { 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UserCloudPolicyManager* manager = policy_manager(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(service, manager->core()->service()); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(service->IsInitializationComplete()); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The service is now initialized - if the client is not yet registered, then 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it means that there is no cached policy and so we need to initiate a new 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // client registration. 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG_IF(1, manager->IsClientRegistered()) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Client already registered - not fetching DMToken"; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!manager->IsClientRegistered()) { 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!oauth2_token_service_->RefreshTokenIsAvailable( 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_manager()->GetAuthenticatedAccountId())) { 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // No token yet - this class listens for OnRefreshTokenAvailable() 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and will re-attempt registration once the token is available. 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download"; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RegisterCloudPolicyService(); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If client is registered now, prohibit signout. 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProhibitSignoutIfNeeded(); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void UserPolicySigninService::RegisterCloudPolicyService() { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!policy_manager()->IsClientRegistered()); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Fetching new DM Token"; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do nothing if already starting the registration process. 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (registration_helper_) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start the process of registering the CloudPolicyClient. Once it completes, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // policy fetch will automatically happen. 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch registration_helper_.reset(new CloudPolicyClientRegistrationHelper( 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) policy_manager()->core()->client(), 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch enterprise_management::DeviceRegisterRequest::BROWSER)); 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) registration_helper_->StartRegistration( 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) oauth2_token_service_, 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_manager()->GetAuthenticatedAccountId(), 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&UserPolicySigninService::OnRegistrationComplete, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UserPolicySigninService::OnRegistrationComplete() { 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProhibitSignoutIfNeeded(); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registration_helper_.reset(); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UserPolicySigninService::ProhibitSignoutIfNeeded() { 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (policy_manager()->IsClientRegistered()) { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "User is registered for policy - prohibiting signout"; 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signin_manager()->ProhibitSignout(true); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace policy 199