diff --git a/DEPS b/DEPS
index 9eb1a52..3973fb1 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '8a3760f8b2ce8ded477ba90dd8e1522b1df441b8',
+  'skia_revision': 'c2e2977014c4581aed5da435fc2b7eba38e777b6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '71a9d8208741b6f34dda1196254af27d29c16908',
+  'v8_revision': 'b8500e4dc91d04675e9a044317576359290dff2b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -51,7 +51,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '8182049470aa3ba0c9f7c54ef965bf1877df08cb',
+  'angle_revision': 'a5f64de71469f43d7d67b816646c96509bc0df3f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 8ad3b459..96cfaa0 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -1035,6 +1035,9 @@
         }
 
         setNewAwContents(popupNativeAwContents);
+        // We defer loading any URL on the popup until it has been properly intialized (through
+        // setNewAwContents). We resume the load here.
+        nativeResumeLoadingCreatedPopupWebContents(mNativeAwContents);
 
         // Finally refresh all view state for mContentViewCore and mNativeAwContents.
         if (!wasPaused) onResume();
@@ -3235,4 +3238,5 @@
     private native void nativeCreateMessageChannel(long nativeAwContents, AwMessagePort[] ports);
 
     private native void nativeGrantFileSchemeAccesstoChildProcess(long nativeAwContents);
+    private native void nativeResumeLoadingCreatedPopupWebContents(long nativeAwContents);
 }
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index e10eab62..2512d69 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -1223,6 +1223,11 @@
       web_contents_->GetRenderProcessHost()->GetID(), url::kFileScheme);
 }
 
+void AwContents::ResumeLoadingCreatedPopupWebContents(JNIEnv* env,
+                                                      jobject obj) {
+  web_contents_->ResumeLoadingCreatedWebContents();
+}
+
 void SetShouldDownloadFavicons(JNIEnv* env,
                                const JavaParamRef<jclass>& jclazz) {
   g_should_download_favicons = true;
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index 8edd1c08..af9e8819d 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -244,6 +244,8 @@
 
   void GrantFileSchemeAccesstoChildProcess(JNIEnv* env, jobject obj);
 
+  void ResumeLoadingCreatedPopupWebContents(JNIEnv* env, jobject obj);
+
  private:
   void InitAutofillIfNecessary(bool enabled);
 
diff --git a/android_webview/native/aw_web_contents_delegate.cc b/android_webview/native/aw_web_contents_delegate.cc
index 55170f0..d8f85cf 100644
--- a/android_webview/native/aw_web_contents_delegate.cc
+++ b/android_webview/native/aw_web_contents_delegate.cc
@@ -218,6 +218,13 @@
   }
 }
 
+bool AwWebContentsDelegate::ShouldResumeRequestsForCreatedWindow() {
+  // Always return false here since we need to defer loading the created window
+  // until after we have attached a new delegate to the new webcontents (which
+  // happens asynchronously).
+  return false;
+}
+
 void AwWebContentsDelegate::RequestMediaAccessPermission(
     WebContents* web_contents,
     const content::MediaStreamRequest& request,
diff --git a/android_webview/native/aw_web_contents_delegate.h b/android_webview/native/aw_web_contents_delegate.h
index 81695d08..e9f7f697 100644
--- a/android_webview/native/aw_web_contents_delegate.h
+++ b/android_webview/native/aw_web_contents_delegate.h
@@ -51,6 +51,7 @@
   void ActivateContents(content::WebContents* contents) override;
   void LoadingStateChanged(content::WebContents* source,
                            bool to_different_document) override;
+  bool ShouldResumeRequestsForCreatedWindow() override;
   void RequestMediaAccessPermission(
       content::WebContents* web_contents,
       const content::MediaStreamRequest& request,
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 6f5e693..8aaa1c0 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -27,6 +27,7 @@
     "//base/third_party/dynamic_annotations",
     "//cc",
     "//components/device_event_log",
+    "//components/signin/core/account_id",
     "//components/user_manager",
     "//components/wallpaper",
     "//content/public/browser",
diff --git a/ash/DEPS b/ash/DEPS
index 8952c301..0e0ff3d 100644
--- a/ash/DEPS
+++ b/ash/DEPS
@@ -2,6 +2,7 @@
   "+device/bluetooth",
   "+cc/debug",
   "+chromeos",
+  "+components/signin/core/account_id",
   "+components/user_manager",
   "+components/wallpaper",
   "+gpu/config",
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 20960ee..a775584 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -949,6 +949,7 @@
         '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
         '../cc/cc.gyp:cc',
         '../components/components.gyp:device_event_log_component',
+        '../components/components.gyp:signin_core_account_id',
         '../components/components.gyp:user_manager',
         '../components/components.gyp:wallpaper',
         '../content/content.gyp:content_browser',
@@ -1145,6 +1146,7 @@
         '../base/base.gyp:base',
         '../base/base.gyp:test_support_base',
         '../chrome/chrome_resources.gyp:packed_resources',
+        '../components/components.gyp:signin_core_account_id',
         '../components/components.gyp:user_manager',
         '../content/content.gyp:content_browser',
         '../content/content_shell_and_tests.gyp:test_support_content',
diff --git a/ash/display/display_color_manager_chromeos.cc b/ash/display/display_color_manager_chromeos.cc
index 060ee62..1ee0a51 100644
--- a/ash/display/display_color_manager_chromeos.cc
+++ b/ash/display/display_color_manager_chromeos.cc
@@ -18,7 +18,6 @@
 #include "base/task_runner_util.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chromeos/chromeos_paths.h"
-#include "chromeos/chromeos_switches.h"
 #include "third_party/qcms/src/qcms.h"
 #include "ui/display/types/display_snapshot.h"
 #include "ui/display/types/gamma_ramp_rgb_entry.h"
@@ -67,17 +66,6 @@
 }
 
 base::FilePath PathForDisplaySnapshot(const ui::DisplaySnapshot* snapshot) {
-  if (gfx::Display::IsInternalDisplayId(snapshot->display_id())) {
-    const base::CommandLine* command_line =
-        base::CommandLine::ForCurrentProcess();
-    if (command_line->HasSwitch(
-            chromeos::switches::kInternalDisplayColorProfileFile)) {
-      const base::FilePath& path = command_line->GetSwitchValuePath(
-          chromeos::switches::kInternalDisplayColorProfileFile);
-      return base::FilePath(path);
-    }
-  }
-
   base::FilePath path;
   CHECK(
       PathService::Get(chromeos::DIR_DEVICE_COLOR_CALIBRATION_PROFILES, &path));
diff --git a/ash/system/DEPS b/ash/system/DEPS
index abf5b5f..1121c69 100644
--- a/ash/system/DEPS
+++ b/ash/system/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   "-chromeos",
+  "+components/signin/core/account_id",
 ]
diff --git a/ash/system/chromeos/network/vpn_delegate.h b/ash/system/chromeos/network/vpn_delegate.h
index aaf76a3..fd6fe72 100644
--- a/ash/system/chromeos/network/vpn_delegate.h
+++ b/ash/system/chromeos/network/vpn_delegate.h
@@ -91,7 +91,7 @@
   void NotifyObservers();
 
  private:
-  base::ObserverList<Observer, true> observer_list_;
+  base::ObserverList<Observer> observer_list_;
 
   DISALLOW_COPY_AND_ASSIGN(VPNDelegate);
 };
diff --git a/ash/system/chromeos/network/vpn_list_view.cc b/ash/system/chromeos/network/vpn_list_view.cc
index d3f3061..a80853bc 100644
--- a/ash/system/chromeos/network/vpn_list_view.cc
+++ b/ash/system/chromeos/network/vpn_list_view.cc
@@ -239,10 +239,14 @@
 }
 
 VPNListView::~VPNListView() {
-  Shell::GetInstance()
-      ->system_tray_delegate()
-      ->GetVPNDelegate()
-      ->RemoveObserver(this);
+  // We need the check as on shell destruction, the delegate is destroyed first.
+  SystemTrayDelegate* const system_tray_delegate =
+      Shell::GetInstance()->system_tray_delegate();
+  if (system_tray_delegate) {
+    VPNDelegate* const vpn_delegate = system_tray_delegate->GetVPNDelegate();
+    if (vpn_delegate)
+      vpn_delegate->RemoveObserver(this);
+  }
 }
 
 void VPNListView::Update() {
diff --git a/ash/system/user/tray_user.cc b/ash/system/user/tray_user.cc
index fd101e7..06d1823 100644
--- a/ash/system/user/tray_user.cc
+++ b/ash/system/user/tray_user.cc
@@ -20,6 +20,7 @@
 #include "ash/system/user/user_view.h"
 #include "base/logging.h"
 #include "base/strings/string16.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_info.h"
 #include "grit/ash_strings.h"
 #include "ui/aura/window.h"
@@ -112,13 +113,13 @@
 }
 
 views::View* TrayUser::CreateDetailedView(user::LoginStatus status) {
-  std::string user_id = Shell::GetInstance()
-                            ->session_state_delegate()
-                            ->GetUserInfo(0)
-                            ->GetUserID();
+  const AccountId account_id = Shell::GetInstance()
+                                   ->session_state_delegate()
+                                   ->GetUserInfo(0)
+                                   ->GetAccountId();
   tray::UserAccountsDelegate* delegate =
       Shell::GetInstance()->system_tray_delegate()->GetUserAccountsDelegate(
-          user_id);
+          account_id.GetUserEmail());
   if (!delegate)
     return nullptr;
   return new tray::AccountsDetailedView(this, status, delegate);
diff --git a/ash/system/user/tray_user_unittest.cc b/ash/system/user/tray_user_unittest.cc
index 5d9d3d3..ee1a92a 100644
--- a/ash/system/user/tray_user_unittest.cc
+++ b/ash/system/user/tray_user_unittest.cc
@@ -17,6 +17,7 @@
 #include "ash/test/test_session_state_delegate.h"
 #include "ash/test/test_shell_delegate.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_info.h"
 #include "ui/accessibility/ax_view_state.h"
 #include "ui/events/test/event_generator.h"
@@ -272,10 +273,11 @@
   ClickUserItem(&generator, 1);
   const user_manager::UserInfo* active_user = delegate()->GetActiveUserInfo();
   const user_manager::UserInfo* second_user = delegate()->GetUserInfo(1);
-  EXPECT_EQ(active_user->GetUserID(), second_user->GetUserID());
+  EXPECT_EQ(active_user->GetAccountId(), second_user->GetAccountId());
   // Since the name is capitalized, the email should be different then the
   // user_id.
-  EXPECT_NE(active_user->GetUserID(), second_user->GetEmail());
+  EXPECT_NE(active_user->GetAccountId().GetUserEmail(),
+            second_user->GetEmail());
   tray()->CloseSystemBubble();
 }
 
diff --git a/ash/system/user/user_view.cc b/ash/system/user/user_view.cc
index 7f7ece5..0c48ca99 100644
--- a/ash/system/user/user_view.cc
+++ b/ash/system/user/user_view.cc
@@ -19,6 +19,7 @@
 #include "ash/system/user/config.h"
 #include "ash/system/user/rounded_image_view.h"
 #include "ash/system/user/user_card_view.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_info.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
@@ -77,7 +78,8 @@
       ash::Shell::GetInstance()->session_state_delegate();
   ash::MultiProfileUMA::RecordSwitchActiveUser(
       ash::MultiProfileUMA::SWITCH_ACTIVE_USER_BY_TRAY);
-  delegate->SwitchActiveUser(delegate->GetUserInfo(user_index)->GetUserID());
+  delegate->SwitchActiveUser(
+      delegate->GetUserInfo(user_index)->GetAccountId().GetUserEmail());
 }
 
 class LogoutButton : public TrayPopupLabelButton {
diff --git a/ash/test/test_session_state_delegate.cc b/ash/test/test_session_state_delegate.cc
index 7f2e648d..bd0bdd3 100644
--- a/ash/test/test_session_state_delegate.cc
+++ b/ash/test/test_session_state_delegate.cc
@@ -12,6 +12,7 @@
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -20,18 +21,20 @@
 
 namespace {
 
-// The the "canonicalized" user ID from a given |email| address.
-std::string GetUserIDFromEmail(const std::string& email) {
+// The the "canonicalized" Account ID from a given |email| address.
+AccountId GetAccountIdFromEmail(const std::string& email) {
   std::string user_id = email;
   std::transform(user_id.begin(), user_id.end(), user_id.begin(), ::tolower);
-  return user_id;
+  return AccountId::FromUserEmail(user_id);
 }
 
 }  // namespace
 
 class MockUserInfo : public user_manager::UserInfo {
  public:
-  explicit MockUserInfo(const std::string& id) : email_(id) {}
+  explicit MockUserInfo(const std::string& display_email)
+      : display_email_(display_email),
+        account_id_(GetAccountIdFromEmail(display_email)) {}
   ~MockUserInfo() override {}
 
   void SetUserImage(const gfx::ImageSkia& user_image) {
@@ -46,18 +49,17 @@
     return base::UTF8ToUTF16("Über Über Über Über");
   }
 
-  std::string GetEmail() const override { return email_; }
+  std::string GetEmail() const override { return display_email_; }
 
-  std::string GetUserID() const override {
-    return GetUserIDFromEmail(GetEmail());
-  }
+  AccountId GetAccountId() const override { return account_id_; }
 
   const gfx::ImageSkia& GetImage() const override { return user_image_; }
 
   // A test user image.
   gfx::ImageSkia user_image_;
 
-  std::string email_;
+  std::string display_email_;
+  const AccountId account_id_;
 
   DISALLOW_COPY_AND_ASSIGN(MockUserInfo);
 };
@@ -215,18 +217,19 @@
 }
 
 void TestSessionStateDelegate::SwitchActiveUser(const std::string& user_id) {
+  const AccountId account_id(GetAccountIdFromEmail(user_id));
   // Make sure this is a user id and not an email address.
-  EXPECT_EQ(user_id, GetUserIDFromEmail(user_id));
+  EXPECT_EQ(user_id, account_id.GetUserEmail());
   active_user_index_ = 0;
   for (std::vector<MockUserInfo*>::iterator iter = user_list_.begin();
        iter != user_list_.end();
        ++iter) {
-    if ((*iter)->GetUserID() == user_id) {
+    if ((*iter)->GetAccountId() == account_id) {
       active_user_index_ = iter - user_list_.begin();
       return;
     }
   }
-  NOTREACHED() << "Unknown user:" << user_id;
+  NOTREACHED() << "Unknown user:" << account_id.GetUserEmail();
 }
 
 void TestSessionStateDelegate::CycleActiveUser(CycleUser cycle_user) {
diff --git a/base/test/launcher/unit_test_launcher.cc b/base/test/launcher/unit_test_launcher.cc
index 761dcfd..9cd7d712 100644
--- a/base/test/launcher/unit_test_launcher.cc
+++ b/base/test/launcher/unit_test_launcher.cc
@@ -158,7 +158,7 @@
 
   std::string switch_value =
       CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name);
-  if (!StringToInt(switch_value, result) || *result < 1) {
+  if (!StringToInt(switch_value, result) || *result < 0) {
     LOG(ERROR) << "Invalid value for " << switch_name << ": " << switch_value;
     return false;
   }
@@ -168,6 +168,7 @@
 
 int LaunchUnitTestsInternal(const RunTestSuiteCallback& run_test_suite,
                             int default_jobs,
+                            int default_batch_limit,
                             bool use_job_objects,
                             const Closure& gtest_init) {
 #if defined(OS_ANDROID)
@@ -210,7 +211,7 @@
   gtest_init.Run();
   TestTimeouts::Initialize();
 
-  int batch_limit = kDefaultTestBatchLimit;
+  int batch_limit = default_batch_limit;
   if (!GetSwitchValueAsInt(switches::kTestLauncherBatchLimit, &batch_limit))
     return 1;
 
@@ -435,16 +436,40 @@
                     char** argv,
                     const RunTestSuiteCallback& run_test_suite) {
   CommandLine::Init(argc, argv);
-  return LaunchUnitTestsInternal(run_test_suite, SysInfo::NumberOfProcessors(),
-                                 true, Bind(&InitGoogleTestChar, &argc, argv));
+  return LaunchUnitTestsInternal(
+      run_test_suite,
+      SysInfo::NumberOfProcessors(),
+      kDefaultTestBatchLimit,
+      true,
+      Bind(&InitGoogleTestChar, &argc, argv));
 }
 
 int LaunchUnitTestsSerially(int argc,
                             char** argv,
                             const RunTestSuiteCallback& run_test_suite) {
   CommandLine::Init(argc, argv);
-  return LaunchUnitTestsInternal(run_test_suite, 1, true,
-                                 Bind(&InitGoogleTestChar, &argc, argv));
+  return LaunchUnitTestsInternal(
+      run_test_suite,
+      1,
+      kDefaultTestBatchLimit,
+      true,
+      Bind(&InitGoogleTestChar, &argc, argv));
+}
+
+int LaunchUnitTestsWithOptions(
+    int argc,
+    char** argv,
+    int default_jobs,
+    int default_batch_limit,
+    bool use_job_objects,
+    const RunTestSuiteCallback& run_test_suite) {
+  CommandLine::Init(argc, argv);
+  return LaunchUnitTestsInternal(
+      run_test_suite,
+      default_jobs,
+      default_batch_limit,
+      use_job_objects,
+      Bind(&InitGoogleTestChar, &argc, argv));
 }
 
 #if defined(OS_WIN)
@@ -454,9 +479,12 @@
                     const RunTestSuiteCallback& run_test_suite) {
   // Windows CommandLine::Init ignores argv anyway.
   CommandLine::Init(argc, NULL);
-  return LaunchUnitTestsInternal(run_test_suite, SysInfo::NumberOfProcessors(),
-                                 use_job_objects,
-                                 Bind(&InitGoogleTestWChar, &argc, argv));
+  return LaunchUnitTestsInternal(
+      run_test_suite,
+      SysInfo::NumberOfProcessors(),
+      kDefaultTestBatchLimit,
+      use_job_objects,
+      Bind(&InitGoogleTestWChar, &argc, argv));
 }
 #endif  // defined(OS_WIN)
 
diff --git a/base/test/launcher/unit_test_launcher.h b/base/test/launcher/unit_test_launcher.h
index d5ba153..83e5eaf 100644
--- a/base/test/launcher/unit_test_launcher.h
+++ b/base/test/launcher/unit_test_launcher.h
@@ -24,6 +24,19 @@
                             char** argv,
                             const RunTestSuiteCallback& run_test_suite);
 
+// Launches unit tests in given test suite. Returns exit code.
+// |default_jobs| is the default number of parallel test jobs.
+// |default_batch_limit| is the default size of test batch
+// (use 0 to disable batching).
+// |use_job_objects| determines whether to use job objects.
+int LaunchUnitTestsWithOptions(
+    int argc,
+    char** argv,
+    int default_jobs,
+    int default_batch_limit,
+    bool use_job_objects,
+    const RunTestSuiteCallback& run_test_suite);
+
 #if defined(OS_WIN)
 // Launches unit tests in given test suite. Returns exit code.
 // |use_job_objects| determines whether to use job objects.
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index a6a3b41..d939eea 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -150,20 +150,23 @@
 
 // Enable the core dump providers.
 #if !defined(OS_NACL)
-  RegisterDumpProvider(ProcessMemoryTotalsDumpProvider::GetInstance());
+  RegisterDumpProvider(ProcessMemoryTotalsDumpProvider::GetInstance(),
+                       "ProcessMemoryTotals", nullptr);
 #endif
 
 #if defined(OS_LINUX) || defined(OS_ANDROID)
-  RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance());
-  RegisterDumpProvider(MallocDumpProvider::GetInstance());
+  RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance(),
+                       "ProcessMemoryMaps", nullptr);
+  RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr);
 #endif
 
 #if defined(OS_ANDROID)
-  RegisterDumpProvider(JavaHeapDumpProvider::GetInstance());
+  RegisterDumpProvider(JavaHeapDumpProvider::GetInstance(), "JavaHeap",
+                       nullptr);
 #endif
 
 #if defined(OS_WIN)
-  RegisterDumpProvider(WinHeapDumpProvider::GetInstance());
+  RegisterDumpProvider(WinHeapDumpProvider::GetInstance(), "WinHeap", nullptr);
 #endif
 
   // If tracing was enabled before initializing MemoryDumpManager, we missed the
@@ -199,16 +202,6 @@
     mdp->OnHeapProfilingEnabled(true);
 }
 
-void MemoryDumpManager::RegisterDumpProvider(
-    MemoryDumpProvider* mdp,
-    const scoped_refptr<SingleThreadTaskRunner>& task_runner) {
-  RegisterDumpProvider(mdp, "unknown", task_runner);
-}
-
-void MemoryDumpManager::RegisterDumpProvider(MemoryDumpProvider* mdp) {
-  RegisterDumpProvider(mdp, nullptr);
-}
-
 void MemoryDumpManager::UnregisterDumpProvider(MemoryDumpProvider* mdp) {
   AutoLock lock(lock_);
 
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h
index ed386aa..8b90ca42 100644
--- a/base/trace_event/memory_dump_manager.h
+++ b/base/trace_event/memory_dump_manager.h
@@ -71,13 +71,6 @@
       const scoped_refptr<SingleThreadTaskRunner>& task_runner);
   void UnregisterDumpProvider(MemoryDumpProvider* mdp);
 
-  // TODO(primiano): Remove these two after all the existing dump provider have
-  // been converted.
-  void RegisterDumpProvider(
-      MemoryDumpProvider* mdp,
-      const scoped_refptr<SingleThreadTaskRunner>& task_runner);
-  void RegisterDumpProvider(MemoryDumpProvider* mdp);
-
   // Requests a memory dump. The dump might happen or not depending on the
   // filters and categories specified when enabling tracing.
   // The optional |callback| is executed asynchronously, on an arbitrary thread,
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
index 42b1b75..15ae424 100644
--- a/base/trace_event/memory_dump_manager_unittest.cc
+++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -43,7 +43,7 @@
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   MemoryDumpManager* mdm = MemoryDumpManager::GetInstance();
   mdm->set_dumper_registrations_ignored_for_testing(false);
-  mdm->RegisterDumpProvider(mdp, task_runner);
+  mdm->RegisterDumpProvider(mdp, "TestDumpProvider", task_runner);
   mdm->set_dumper_registrations_ignored_for_testing(true);
 }
 
diff --git a/base/trace_event/memory_profiler_allocation_context.cc b/base/trace_event/memory_profiler_allocation_context.cc
index c7b8549..bafbf7f 100644
--- a/base/trace_event/memory_profiler_allocation_context.cc
+++ b/base/trace_event/memory_profiler_allocation_context.cc
@@ -153,19 +153,6 @@
   tracker->pseudo_stack_.pop(frame);
 }
 
-// static
-void AllocationContextTracker::SetContextField(const char* key,
-                                               const char* value) {
-  auto tracker = AllocationContextTracker::GetThreadLocalTracker();
-  tracker->context_[key] = value;
-}
-
-// static
-void AllocationContextTracker::UnsetContextField(const char* key) {
-  auto tracker = AllocationContextTracker::GetThreadLocalTracker();
-  tracker->context_.erase(key);
-}
-
 // Returns a pointer past the end of the fixed-size array |array| of |T| of
 // length |N|, identical to C++11 |std::end|.
 template <typename T, int N>
@@ -194,22 +181,6 @@
     std::fill(dst, dst_end, nullptr);
   }
 
-  // Fill the context fields.
-  {
-    auto src = tracker->context_.begin();
-    auto dst = ctx.fields;
-    auto src_end = tracker->context_.end();
-    auto dst_end = End(ctx.fields);
-
-    // Copy as much (key, value) pairs as possible.
-    for (; src != src_end && dst != dst_end; src++, dst++)
-      *dst = *src;
-
-    // If there is room for more, fill the remaining slots with nullptr keys.
-    for (; dst != dst_end; dst++)
-      dst->first = nullptr;
-  }
-
   return ctx;
 }
 
diff --git a/base/trace_event/memory_profiler_allocation_context.h b/base/trace_event/memory_profiler_allocation_context.h
index ef68283..4e08c50 100644
--- a/base/trace_event/memory_profiler_allocation_context.h
+++ b/base/trace_event/memory_profiler_allocation_context.h
@@ -5,12 +5,12 @@
 #ifndef BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_
 #define BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_
 
+#include <map>
 #include <string>
 #include <vector>
 
 #include "base/atomicops.h"
 #include "base/base_export.h"
-#include "base/containers/small_map.h"
 #include "base/trace_event/trace_event_impl.h"
 
 namespace base {
@@ -141,18 +141,13 @@
 // must have static lifetime.
 struct BASE_EXPORT AllocationContext {
   Backtrace backtrace;
-
-  // There is room for two arbitrary context fields, which can be set by the
-  // |TRACE_ALLOCATION_CONTEXT| macro. A nullptr key indicates that the field is
-  // unused.
-  std::pair<const char*, const char*> fields[2];
 };
 
 // The allocation context tracker keeps track of thread-local context for heap
-// profiling. It includes a pseudo stack of trace events, and it might contain
-// arbitrary (key, value) context. On every allocation the tracker provides a
-// snapshot of its context in the form of an |AllocationContext| that is to be
-// stored together with the allocation details.
+// profiling. It includes a pseudo stack of trace events. On every allocation
+// the tracker provides a snapshot of its context in the form of an
+// |AllocationContext| that is to be stored together with the allocation
+// details.
 class BASE_EXPORT AllocationContextTracker {
  public:
   // Globally enables capturing allocation context.
@@ -181,13 +176,6 @@
   // Pops a frame from the thread-local pseudo stack.
   static void PopPseudoStackFrame(StackFrame frame);
 
-  // Sets a thread-local (key, value) pair.
-  static void SetContextField(const char* key, const char* value);
-
-  // Removes the (key, value) pair with the specified key from the thread-local
-  // context.
-  static void UnsetContextField(const char* key);
-
   // Returns a snapshot of the current thread-local context.
   static AllocationContext GetContextSnapshot();
 
@@ -203,9 +191,6 @@
   // The pseudo stack where frames are |TRACE_EVENT| names.
   AllocationStack pseudo_stack_;
 
-  // A dictionary of arbitrary context.
-  SmallMap<std::map<const char*, const char*>> context_;
-
   DISALLOW_COPY_AND_ASSIGN(AllocationContextTracker);
 };
 
diff --git a/base/trace_event/memory_profiler_allocation_register_unittest.cc b/base/trace_event/memory_profiler_allocation_register_unittest.cc
index 0c976c4..bb5aeb3 100644
--- a/base/trace_event/memory_profiler_allocation_register_unittest.cc
+++ b/base/trace_event/memory_profiler_allocation_register_unittest.cc
@@ -50,7 +50,7 @@
 
 TEST_F(AllocationRegisterTest, InsertRemove) {
   AllocationRegister reg;
-  AllocationContext ctx;
+  AllocationContext ctx = {};
 
   EXPECT_EQ(0u, OrAllAddresses(reg));
 
@@ -81,7 +81,7 @@
 
 TEST_F(AllocationRegisterTest, DoubleFreeIsAllowed) {
   AllocationRegister reg;
-  AllocationContext ctx;
+  AllocationContext ctx = {};
 
   reg.Insert(reinterpret_cast<void*>(1), 0, ctx);
   reg.Insert(reinterpret_cast<void*>(2), 0, ctx);
@@ -96,7 +96,7 @@
   // TODO(ruuda): Although double insert happens in practice, it should not.
   // Find out the cause and ban double insert if possible.
   AllocationRegister reg;
-  AllocationContext ctx;
+  AllocationContext ctx = {};
   StackFrame frame1 = "Foo";
   StackFrame frame2 = "Bar";
 
@@ -124,7 +124,7 @@
 TEST_F(AllocationRegisterTest, InsertRemoveCollisions) {
   size_t expected_sum = 0;
   AllocationRegister reg;
-  AllocationContext ctx;
+  AllocationContext ctx = {};
 
   // By inserting 100 more entries than the number of buckets, there will be at
   // least 100 collisions.
@@ -161,7 +161,7 @@
 TEST_F(AllocationRegisterTest, InsertRemoveRandomOrder) {
   size_t expected_sum = 0;
   AllocationRegister reg;
-  AllocationContext ctx;
+  AllocationContext ctx = {};
 
   uintptr_t generator = 3;
   uintptr_t prime = 1013;
@@ -203,7 +203,7 @@
 #if GTEST_HAS_DEATH_TEST
 TEST_F(AllocationRegisterTest, OverflowDeathTest) {
   AllocationRegister reg;
-  AllocationContext ctx;
+  AllocationContext ctx = {};
   uintptr_t i;
 
   // Fill up all of the memory allocated for the register. |kNumCells| minus 1
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h
index 3ce9c43..a997c69 100644
--- a/base/trace_event/process_memory_dump.h
+++ b/base/trace_event/process_memory_dump.h
@@ -20,7 +20,9 @@
 
 // Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the
 // resident memory.
-#if defined(OS_POSIX) && !defined(OS_NACL)
+// TODO(crbug.com/542671): COUNT_RESIDENT_BYTES_SUPPORTED is disabled on iOS
+// as it cause memory corruption on iOS 9.0+ devices.
+#if defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_IOS)
 #define COUNT_RESIDENT_BYTES_SUPPORTED
 #endif
 
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
index d5a02dd..70dec1d 100644
--- a/base/trace_event/trace_log.cc
+++ b/base/trace_event/trace_log.cc
@@ -261,7 +261,7 @@
 
   // This is to report the local memory usage when memory-infra is enabled.
   MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this, ThreadTaskRunnerHandle::Get());
+      this, "ThreadLocalEventBuffer", ThreadTaskRunnerHandle::Get());
 
   AutoLock lock(trace_log->lock_);
   trace_log->thread_message_loops_.insert(message_loop);
@@ -396,7 +396,8 @@
 
   logged_events_.reset(CreateTraceBuffer());
 
-  MemoryDumpManager::GetInstance()->RegisterDumpProvider(this);
+  MemoryDumpManager::GetInstance()->RegisterDumpProvider(this, "TraceLog",
+                                                         nullptr);
 }
 
 TraceLog::~TraceLog() {}
diff --git a/build/android/apksize.py b/build/android/apksize.py
new file mode 100755
index 0000000..ae5462b
--- /dev/null
+++ b/build/android/apksize.py
@@ -0,0 +1,228 @@
+#!/usr/bin/env python
+# Copyright 2015 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.
+
+import argparse
+import collections
+import json
+import logging
+import os
+import sys
+import zipfile
+
+_BASE_CHART = {
+    'format_version': '0.1',
+    'benchmark_name': 'apk_size',
+    'benchmark_description': 'APK size information.',
+    'trace_rerun_options': [],
+    'charts': {}
+}
+
+
+# TODO(rnephew): Add support for split apks.
+class ApkSizeInfo(object):
+
+  def __init__(self, path):
+    """ApkSizeInfo constructor.
+
+    Args:
+      path: Path to apk.
+    """
+    if not os.path.isfile(path):
+      raise IOError('Not a valid file path for apk.')
+    if not os.access(path, os.R_OK):
+      raise IOError('File is not readable.')
+    if not zipfile.is_zipfile(path):
+      raise TypeError('Not a valid apk')
+    logging.info('APK: %s', path)
+    self._apk_size = os.path.getsize(path)
+    self._zipfile = zipfile.ZipFile(path, 'r')
+    self._processed_files = None
+    self._compressed_size = 0
+    self._total_files = 0
+    self._uncompressed_size = 0
+    self._ProcessFiles()
+
+  def _ProcessFiles(self):
+    """Uses zipinfo to process apk file information."""
+    INITIAL_FILE_EXTENSION_INFO = {
+        'number': 0,
+        'compressed_bytes': 0,
+        'uncompressed_bytes': 0
+    }
+    self._processed_files = collections.defaultdict(
+        lambda: dict(INITIAL_FILE_EXTENSION_INFO))
+
+    for f in self._zipfile.infolist():
+      _, file_ext = os.path.splitext(f.filename)
+      file_ext = file_ext[1:] # Drop . from extension.
+
+      self._compressed_size += f.compress_size
+      self._total_files += 1
+      self._uncompressed_size += f.file_size
+      self._processed_files[file_ext]['number'] += 1
+      self._processed_files[file_ext]['compressed_bytes'] += f.compress_size
+      self._processed_files[file_ext]['uncompressed_bytes'] += f.file_size
+    return self._processed_files
+
+  def Compare(self, other_apk):
+    """Compares size information of two apks.
+
+    Args:
+      other_apk: ApkSizeInfo instance to compare size against.
+
+    Returns:
+      Dictionary of comparision results.
+    """
+    if not isinstance(other_apk, type(self)):
+      raise TypeError('Must pass it an ApkSizeInfo object')
+
+    other_lib_compressed = other_apk.processed_files['so']['compressed_bytes']
+    other_lib_uncompressed = (
+        other_apk.processed_files['so']['uncompressed_bytes'])
+    this_lib_compressed = self._processed_files['so']['compressed_bytes']
+    this_lib_uncompressed = self._processed_files['so']['uncompressed_bytes']
+
+    # TODO(rnephew) This will be made obsolete with modern and legacy apks being
+    # separate, a new method to compare will be required eventually.
+    return collections.OrderedDict([
+        ('APK_size_reduction',
+            other_apk.compressed_size - self.compressed_size),
+        ('ARM32_Legacy_install_or_upgrade_reduction',
+            (other_lib_compressed - this_lib_compressed) +
+            (other_lib_uncompressed - this_lib_uncompressed)),
+        ('ARM32_Legacy_system_image_reduction',
+            other_lib_compressed - this_lib_compressed),
+        ('ARM32_Modern_ARM64_install_or_upgrade_reduction',
+            other_lib_uncompressed - this_lib_uncompressed),
+        ('ARM32_Modern_ARM64_system_image_reduction',
+            other_lib_uncompressed - this_lib_uncompressed),
+    ])
+
+  @property
+  def apk_size(self):
+    return self._apk_size
+
+  @property
+  def compressed_size(self):
+    return self._compressed_size
+
+  @property
+  def total_files(self):
+    return self._total_files
+
+  @property
+  def uncompressed_size(self):
+    return self._uncompressed_size
+
+  @property
+  def processed_files(self):
+    return self._processed_files
+
+def add_value(chart_data, graph_title, trace_title, value, units,
+              improvement_direction='down', important=True):
+  chart_data['charts'].setdefault(graph_title, {})
+  chart_data['charts'][graph_title][trace_title] = {
+      'type': 'scalar',
+      'value': value,
+      'units': units,
+      'imporvement_direction': improvement_direction,
+      'important': important
+  }
+
+def chartjson_size_info(apk, output_dir):
+  """Sends size information to perf dashboard.
+
+  Args:
+    apk: ApkSizeInfo object
+  """
+  data = _BASE_CHART.copy()
+  files = apk.processed_files
+  add_value(data, 'files', 'total', apk.total_files, 'count')
+  add_value(data, 'size', 'total_size_compressed', apk.compressed_size, 'bytes')
+  add_value(data, 'size', 'total_size_uncompressed', apk.uncompressed_size,
+            'bytes')
+  add_value(data, 'size', 'apk_overhead', apk.apk_size - apk.compressed_size,
+           'bytes')
+  for ext in files:
+    add_value(data, 'files', ext, files[ext]['number'], 'count')
+    add_value(data, 'size_compressed', ext, files[ext]['compressed_bytes'],
+              'bytes')
+    add_value(data, 'size_uncompressed', ext, files[ext]['uncompressed_bytes'],
+              'bytes')
+
+  logging.info('Outputing data to json file %s', output_dir)
+  with open(os.path.join(output_dir, 'results-chart.json'), 'w') as json_file:
+    json.dump(data, json_file)
+
+def print_human_readable_size_info(apk):
+  """Prints size information in human readable format.
+
+  Args:
+    apk: ApkSizeInfo object
+  """
+  files = apk.processed_files
+  logging.critical('Stats for files as they exist within the apk:')
+  for ext in files:
+    logging.critical('  %-8s %s bytes in %s files', ext,
+                     files[ext]['compressed_bytes'], files[ext]['number'])
+  logging.critical('--------------------------------------')
+  logging.critical(
+      'All Files: %s bytes in %s files', apk.compressed_size, apk.total_files)
+  logging.critical('APK Size: %s', apk.apk_size)
+  logging.critical('APK overhead: %s', apk.apk_size - apk.compressed_size)
+  logging.critical('--------------------------------------')
+  logging.critical('Stats for files when extracted from the apk:')
+  for ext in files:
+    logging.critical('  %-8s %s bytes in %s files', ext,
+                     files[ext]['uncompressed_bytes'], files[ext]['number'])
+  logging.critical('--------------------------------------')
+  logging.critical(
+      'All Files: %s bytes in %s files', apk.uncompressed_size, apk.total_files)
+
+def chartjson_compare(compare_dict, output_dir):
+  """Sends size comparison between two apks to perf dashboard.
+
+  Args:
+    compare_dict: Dictionary returned from APkSizeInfo.Compare()
+  """
+  data = _BASE_CHART.copy()
+  for key, value in compare_dict.iteritems():
+    add_value(data, 'compare', key, value, 'bytes')
+
+  logging.info('Outputing data to json file %s', output_dir)
+  with open(os.path.join(output_dir, 'results-chart.json'), 'w') as json_file:
+    json.dump(data, json_file)
+
+def print_human_readable_compare(compare_dict):
+  """Prints size comparison between two apks in human readable format.
+
+  Args:
+    compare_dict: Dictionary returned from ApkSizeInfo.Compare()
+  """
+  for key, value in compare_dict.iteritems():
+    logging.critical('  %-50s %s bytes', key, value)
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('file_path')
+  parser.add_argument('-c', '--compare', help='APK to compare against.')
+  parser.add_argument('-o', '--output-dir',
+                      help='Sets it to return data in bot readable format')
+  parser.add_argument('-d', '--device', help='Dummy option for perf runner.')
+  args = parser.parse_args()
+
+  apk = ApkSizeInfo(args.file_path)
+  if args.compare:
+    compare_dict = apk.Compare(ApkSizeInfo(args.compare))
+    print_human_readable_compare(compare_dict)
+    if args.output_dir:
+      chartjson_compare(compare_dict, args.output_dir)
+  else:
+    print_human_readable_size_info(apk)
+    if args.output_dir:
+       chartjson_size_info(apk, args.output_dir)
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 872db91..cb8bc3ac 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -80,6 +80,7 @@
  public:
   PictureLayerImplTestSettings() {
     layer_transforms_should_scale_layer_contents = true;
+    verify_property_trees = true;
   }
 };
 
@@ -148,7 +149,13 @@
                                invalidation);
   }
 
+  void RebuildPropertyTreesOnPendingTree() {
+    host_impl_.pending_tree()->property_trees()->needs_rebuild = true;
+    host_impl_.pending_tree()->BuildPropertyTreesForTesting();
+  }
+
   void ActivateTree() {
+    RebuildPropertyTreesOnPendingTree();
     host_impl_.ActivateSyncTree();
     CHECK(!host_impl_.pending_tree());
     CHECK(host_impl_.recycle_tree());
@@ -258,6 +265,7 @@
 
     // Add tilings/tiles for the layer.
     bool update_lcd_text = false;
+    RebuildPropertyTreesOnPendingTree();
     host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
   }
 
@@ -1357,7 +1365,7 @@
   pending_layer_->SetMaskLayer(mask_ptr.Pass());
   pending_layer_->SetHasRenderSurface(true);
 
-  host_impl_.pending_tree()->BuildPropertyTreesForTesting();
+  RebuildPropertyTreesOnPendingTree();
   host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
   bool update_lcd_text = false;
   host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -1486,7 +1494,7 @@
   pending_layer_->SetMaskLayer(mask_ptr.Pass());
   pending_layer_->SetHasRenderSurface(true);
 
-  host_impl_.pending_tree()->BuildPropertyTreesForTesting();
+  RebuildPropertyTreesOnPendingTree();
   host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
   bool update_lcd_text = false;
   host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -3972,6 +3980,7 @@
   layer1->SetContentsOpaque(true);
   layer1->SetPosition(occluding_layer_position);
 
+  RebuildPropertyTreesOnPendingTree();
   host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
   bool update_lcd_text = false;
   host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -3996,6 +4005,7 @@
   // Full occlusion.
   layer1->SetPosition(gfx::PointF());
 
+  RebuildPropertyTreesOnPendingTree();
   host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
   host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
 
@@ -4064,6 +4074,7 @@
   layer1->SetContentsOpaque(true);
   layer1->SetPosition(occluding_layer_position);
 
+  RebuildPropertyTreesOnPendingTree();
   host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
   bool update_lcd_text = false;
   host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -4101,6 +4112,7 @@
   // Full occlusion.
   layer1->SetPosition(gfx::PointF());
 
+  RebuildPropertyTreesOnPendingTree();
   host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
   host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
 
@@ -4166,6 +4178,7 @@
   pending_layer_->AddTiling(1.0f)->set_resolution(HIGH_RESOLUTION);
   pending_layer_->AddTiling(2.0f)->set_resolution(HIGH_RESOLUTION);
 
+  RebuildPropertyTreesOnPendingTree();
   host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
   // UpdateDrawProperties with the occluding layer.
   bool update_lcd_text = false;
@@ -4343,6 +4356,7 @@
   EXPECT_EQ(1u, pending_layer_->num_tilings());
   EXPECT_EQ(2u, active_layer_->num_tilings());
 
+  RebuildPropertyTreesOnPendingTree();
   host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
   // UpdateDrawProperties with the occluding layer.
   bool update_lcd_text = false;
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
index e7c4e9310..d41c195 100644
--- a/cc/output/output_surface.cc
+++ b/cc/output/output_surface.cc
@@ -230,7 +230,7 @@
     // thread's task runner. This will overwrite any previous dump provider
     // registered.
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "OutputSurface", base::ThreadTaskRunnerHandle::Get());
   }
 
   return success;
diff --git a/cc/raster/one_copy_tile_task_worker_pool.cc b/cc/raster/one_copy_tile_task_worker_pool.cc
index 18be9c28..5e31746 100644
--- a/cc/raster/one_copy_tile_task_worker_pool.cc
+++ b/cc/raster/one_copy_tile_task_worker_pool.cc
@@ -216,7 +216,7 @@
       weak_ptr_factory_(this),
       task_set_finished_weak_ptr_factory_(this) {
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this, base::ThreadTaskRunnerHandle::Get());
+      this, "OneCopyTileTaskWorkerPool", base::ThreadTaskRunnerHandle::Get());
   reduce_memory_usage_callback_ =
       base::Bind(&OneCopyTileTaskWorkerPool::ReduceMemoryUsage,
                  weak_ptr_factory_.GetWeakPtr());
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc
index 1a24ef57..57db90ed 100644
--- a/cc/resources/resource_pool.cc
+++ b/cc/resources/resource_pool.cc
@@ -69,7 +69,7 @@
           base::TimeDelta::FromMilliseconds(kResourceExpirationDelayMs)),
       weak_ptr_factory_(this) {
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this, task_runner_.get());
+      this, "cc::ResourcePool", task_runner_.get());
 }
 
 ResourcePool::~ResourcePool() {
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 4c2a1c3..2f5b0a9d 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -1036,7 +1036,7 @@
   // TODO(ericrk): Get this working in Android Webview. crbug.com/517156
   if (base::ThreadTaskRunnerHandle::IsSet()) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "cc::ResourceProvider", base::ThreadTaskRunnerHandle::Get());
   }
 
   GLES2Interface* gl = ContextGL();
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index e02cf8b2..5fcf03d 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -2434,6 +2434,7 @@
     bool subtree_visible_from_ancestor,
     const bool can_render_to_separate_surface,
     const int current_render_surface_layer_list_id,
+    const int max_texture_size,
     const bool verify_property_trees) {
   // This calculates top level Render Surface Layer List, and Layer List for all
   // Render Surfaces.
@@ -2529,7 +2530,7 @@
         child_layer, property_trees, render_surface_layer_list, descendants,
         nearest_occlusion_immune_ancestor, layer_is_drawn,
         can_render_to_separate_surface, current_render_surface_layer_list_id,
-        verify_property_trees);
+        max_texture_size, verify_property_trees);
 
     // If the child is its own render target, then it has a render surface.
     if (child_layer->render_target() == child_layer &&
@@ -2583,6 +2584,12 @@
             surface_content_rect.Intersect(surface_clip_rect);
           }
         }
+        // The RenderSurfaceImpl backing texture cannot exceed the maximum
+        // supported texture size.
+        surface_content_rect.set_width(
+            std::min(surface_content_rect.width(), max_texture_size));
+        surface_content_rect.set_height(
+            std::min(surface_content_rect.height(), max_texture_size));
         layer->render_surface()->SetContentRectFromPropertyTrees(
             surface_content_rect);
       }
@@ -2645,7 +2652,7 @@
       inputs->root_layer, inputs->property_trees,
       inputs->render_surface_layer_list, nullptr, nullptr,
       subtree_visible_from_ancestor, inputs->can_render_to_separate_surface,
-      inputs->current_render_surface_layer_list_id,
+      inputs->current_render_surface_layer_list_id, inputs->max_texture_size,
       inputs->verify_property_trees);
 }
 
diff --git a/chrome/android/java/res/layout/new_tab_page_incognito.xml b/chrome/android/java/res/layout/new_tab_page_incognito.xml
index 17a0eae..9bbd65e6 100644
--- a/chrome/android/java/res/layout/new_tab_page_incognito.xml
+++ b/chrome/android/java/res/layout/new_tab_page_incognito.xml
@@ -50,6 +50,7 @@
                 android:textSize="24sp" />
 
             <TextView
+                android:id="@+id/new_tab_incognito_message"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="32dp"
diff --git a/chrome/android/java/res/layout/web_notification.xml b/chrome/android/java/res/layout/web_notification.xml
index 4d88fd04..1b1f1e3 100644
--- a/chrome/android/java/res/layout/web_notification.xml
+++ b/chrome/android/java/res/layout/web_notification.xml
@@ -65,8 +65,9 @@
         android:layout_toEndOf="@id/icon_frame"
         android:layout_alignParentEnd="true"
         android:layout_below="@id/body"
+        android:layout_marginEnd="8dp"
         android:singleLine="true"
-        android:ellipsize="end"
+        android:ellipsize="start"
         style="@style/WebNotificationOrigin"/>
 
 </RelativeLayout>
diff --git a/chrome/android/java/res/layout/web_notification_big.xml b/chrome/android/java/res/layout/web_notification_big.xml
index ebf07b28..e77e0b7 100644
--- a/chrome/android/java/res/layout/web_notification_big.xml
+++ b/chrome/android/java/res/layout/web_notification_big.xml
@@ -107,12 +107,13 @@
 
         <TextView
             android:id="@+id/origin"
-            style="@style/WebNotificationOrigin"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginBottom="10dp"
+            android:layout_marginEnd="8dp"
             android:singleLine="true"
-            android:ellipsize="end"/>
+            android:ellipsize="start"
+            style="@style/WebNotificationOrigin"/>
 
     </LinearLayout>
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java
index 27ed1dd7..6665a28 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java
@@ -140,7 +140,7 @@
     }
 
     /**
-     * Builds a String that strips down the URL to the its scheme, host, and port.
+     * Builds a String that strips down the URL to its scheme, host, and port.
      * @param uri URI to break down.
      * @param showScheme Whether or not to show the scheme.  If the URL can't be parsed, this value
      *                   is ignored.
@@ -148,14 +148,25 @@
      *         it fails to parse it.
      */
     public static String formatUrlForSecurityDisplay(URI uri, boolean showScheme) {
-        if (showScheme) {
-            return nativeFormatUrlForSecurityDisplay(uri.toString());
-        } else {
-            return nativeFormatUrlForSecurityDisplayOmitScheme(uri.toString());
-        }
+        return formatUrlForSecurityDisplay(uri.toString(), showScheme);
     }
 
     /**
+     * Builds a String that strips down |url| to its scheme, host, and port.
+     * @param uri The URI to break down.
+     * @param showScheme Whether or not to show the scheme.  If the URL can't be parsed, this value
+     *                   is ignored.
+     * @return Stripped-down String containing the essential bits of the URL, or the original URL if
+     *         it fails to parse it.
+     */
+    public static String formatUrlForSecurityDisplay(String uri, boolean showScheme) {
+        if (showScheme) {
+            return nativeFormatUrlForSecurityDisplay(uri);
+        } else {
+            return nativeFormatUrlForSecurityDisplayOmitScheme(uri);
+        }
+    }
+    /**
      * Determines whether or not the given URLs belong to the same broad domain or host.
      * "Broad domain" is defined as the TLD + 1 or the host.
      *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
index f4aa8fe..4d52412 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
@@ -10,7 +10,10 @@
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanelAnimation;
 import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
+import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
+import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content.browser.ContentViewCore;
+import org.chromium.ui.resources.ResourceManager;
 
 /**
  * Controls the Overlay Panel.
@@ -79,6 +82,11 @@
      */
     private OverlayPanelContent mContent;
 
+    /**
+     * The {@link OverlayPanelHost} used to communicate with the supported layout.
+     */
+    private OverlayPanelHost mOverlayPanelHost;
+
     // ============================================================================================
     // Constructor
     // ============================================================================================
@@ -122,6 +130,18 @@
         return doesPanelHeightMatchState(PanelState.EXPANDED);
     }
 
+    @Override
+    public void closePanel(StateChangeReason reason, boolean animate) {
+        super.closePanel(reason, animate);
+
+        // If the close action is animated, the Layout will be hidden when
+        // the animation is finished, so we should only hide the Layout
+        // here when not animating.
+        if (!animate && mOverlayPanelHost != null) {
+            mOverlayPanelHost.hideLayout(true);
+        }
+    }
+
     /**
      * @param url The URL that the panel should load.
      */
@@ -194,6 +214,22 @@
     }
 
     /**
+     * Updates the top controls state for the base tab.  As these values are set at the renderer
+     * level, there is potential for this impacting other tabs that might share the same
+     * process. See {@link Tab#updateTopControlsState(int current, boolean animate)}
+     * @param current The desired current state for the controls.  Pass
+     *                {@link TopControlsState#BOTH} to preserve the current position.
+     * @param animate Whether the controls should animate to the specified ending condition or
+     *                should jump immediately.
+     */
+    public void updateTopControlsState(int current, boolean animate) {
+        Tab currentTab = mActivity.getActivityTab();
+        if (currentTab != null) {
+            currentTab.updateTopControlsState(current, animate);
+        }
+    }
+
+    /**
      * Sets the top control state based on the internals of the panel.
      */
     public void updateTopControlsState() {
@@ -232,6 +268,32 @@
     }
 
     // ============================================================================================
+    // Animation Handling
+    // ============================================================================================
+
+    @Override
+    protected void onAnimationFinished() {
+        super.onAnimationFinished();
+
+        if (shouldHideOverlayPanelLayout()) {
+            if (mOverlayPanelHost != null) {
+                mOverlayPanelHost.hideLayout(false);
+            }
+        }
+    }
+
+    /**
+     * Whether the Overlay Panel Layout should be hidden.
+     *
+     * @return Whether the Overlay Panel Layout should be hidden.
+     */
+    private boolean shouldHideOverlayPanelLayout() {
+        final PanelState state = getPanelState();
+        return (state == PanelState.PEEKED || state == PanelState.CLOSED)
+                && getHeight() == getPanelHeightFromState(state);
+    }
+
+    // ============================================================================================
     // ContextualSearchPanelBase methods.
     // ============================================================================================
 
@@ -243,6 +305,32 @@
     }
 
     // ============================================================================================
+    // Layout Integration
+    // ============================================================================================
+
+    /**
+     * Sets the {@OverlayPanelHost} used to communicate with the supported layout.
+     * @param host The {@OverlayPanelHost}.
+     */
+    public void setHost(OverlayPanelHost host) {
+        mOverlayPanelHost = host;
+    }
+
+    /**
+     * @return The scene layer used to draw this panel.
+     */
+    public SceneLayer getSceneLayer() {
+        return null;
+    }
+
+    /**
+     * Update this panel's scene layer. This should be implemented by each panel type.
+     * @param resourceManager Used to access static resources.
+     */
+    public void updateSceneLayer(ResourceManager resourceManager) {
+    }
+
+    // ============================================================================================
     // Generic Event Handling
     // ============================================================================================
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelHost.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelHost.java
similarity index 69%
rename from chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelHost.java
rename to chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelHost.java
index 26b8cf4..a182af3f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelHost.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelHost.java
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.compositor.bottombar.contextualsearch;
+package org.chromium.chrome.browser.compositor.bottombar;
 
 /**
  * Interface that allows {@link ContextualSearchPanel} to communicate with its host Layout.
  */
-public interface ContextualSearchPanelHost {
+public interface OverlayPanelHost {
     /**
-     * Hides the Contextual Search Supported Layout.
+     * Hides the Overlay Panel Supported Layout.
      * @param immediately Whether it should be hidden immediately.
      */
     void hideLayout(boolean immediately);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
index 5449b4b..0457f9e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -13,9 +13,12 @@
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelContent;
 import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
+import org.chromium.chrome.browser.compositor.scene_layer.ContextualSearchSceneLayer;
+import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.content.browser.ContentViewClient;
+import org.chromium.ui.resources.ResourceManager;
 
 /**
  * Controls the Contextual Search Panel.
@@ -38,11 +41,6 @@
     private boolean mShouldPromoteToTabAfterMaximizing;
 
     /**
-     * The {@link ContextualSearchPanelHost} used to communicate with the supported layout.
-     */
-    private ContextualSearchPanelHost mSearchPanelHost;
-
-    /**
      * Used for logging state changes.
      */
     private final ContextualSearchPanelMetrics mPanelMetrics;
@@ -57,6 +55,11 @@
      */
     private boolean mHasContentBeenTouched;
 
+    /**
+     * The compositor layer used for drawing the panel.
+     */
+    private ContextualSearchSceneLayer mSceneLayer;
+
     // ============================================================================================
     // Constructor
     // ============================================================================================
@@ -67,6 +70,7 @@
      */
     public ContextualSearchPanel(Context context, LayoutUpdateHost updateHost) {
         super(context, updateHost);
+        mSceneLayer = createNewContextualSearchSceneLayer();
         mPanelMetrics = new ContextualSearchPanelMetrics();
     }
 
@@ -142,6 +146,29 @@
     }
 
     // ============================================================================================
+    // Scene layer
+    // ============================================================================================
+
+    @Override
+    public SceneLayer getSceneLayer() {
+        return mSceneLayer;
+    }
+
+    @Override
+    public void updateSceneLayer(ResourceManager resourceManager) {
+        if (mSceneLayer == null) return;
+
+        mSceneLayer.update(resourceManager, this);
+    }
+
+    /**
+     * Create a new scene layer for this panel. This should be overridden by tests as necessary.
+     */
+    protected ContextualSearchSceneLayer createNewContextualSearchSceneLayer() {
+        return new ContextualSearchSceneLayer(mContext.getResources().getDisplayMetrics().density);
+    }
+
+    // ============================================================================================
     // Contextual Search Manager Integration
     // ============================================================================================
 
@@ -214,18 +241,6 @@
     }
 
     // ============================================================================================
-    // Layout Integration
-    // ============================================================================================
-
-    /**
-     * Sets the {@ContextualSearchPanelHost} used to communicate with the supported layout.
-     * @param host The {@ContextualSearchPanelHost}.
-     */
-    public void setHost(ContextualSearchPanelHost host) {
-        mSearchPanelHost = host;
-    }
-
-    // ============================================================================================
     // Contextual Search Manager Integration
     // ============================================================================================
 
@@ -301,30 +316,12 @@
     protected void onAnimationFinished() {
         super.onAnimationFinished();
 
-        if (shouldHideContextualSearchLayout()) {
-            if (mSearchPanelHost != null) {
-                mSearchPanelHost.hideLayout(false);
-            }
-        }
-
         if (mShouldPromoteToTabAfterMaximizing && getPanelState() == PanelState.MAXIMIZED) {
             mShouldPromoteToTabAfterMaximizing = false;
             mManagementDelegate.promoteToTab();
         }
     }
 
-    /**
-    * Whether the Contextual Search Layout should be hidden.
-    *
-    * @return Whether the Contextual Search Layout should be hidden.
-    */
-    private boolean shouldHideContextualSearchLayout() {
-        final PanelState state = getPanelState();
-
-        return (state == PanelState.PEEKED || state == PanelState.CLOSED)
-                && getHeight() == getPanelHeightFromState(state);
-    }
-
     @Override
     public void setProperty(Property prop, float value) {
         super.setProperty(prop, value);
@@ -407,14 +404,6 @@
     @Override
     public void closePanel(StateChangeReason reason, boolean animate) {
         super.closePanel(reason, animate);
-
-        // If the close action is animated, the Layout will be hidden when
-        // the animation is finished, so we should only hide the Layout
-        // here when not animating.
-        if (!animate && mSearchPanelHost != null) {
-            mSearchPanelHost.hideLayout(true);
-        }
-
         mHasContentBeenTouched = false;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ContextualSearchSupportedLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ContextualSearchSupportedLayout.java
index 49ae494..8071843 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ContextualSearchSupportedLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ContextualSearchSupportedLayout.java
@@ -10,11 +10,10 @@
 import android.view.ViewGroup;
 
 import org.chromium.chrome.browser.compositor.LayerTitleCache;
-import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel;
-import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanelHost;
+import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
+import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelHost;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
-import org.chromium.chrome.browser.compositor.scene_layer.ContextualSearchSceneLayer;
 import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
 import org.chromium.content.browser.ContentViewCore;
@@ -25,23 +24,19 @@
 /**
  * A {@link Layout} that can show a Contextual Search overlay that shows at the
  * bottom and can be swiped upwards.
+ * TODO(mdjones): Rename this class to OverlayPanelSupportedLayout.
  */
 public abstract class ContextualSearchSupportedLayout extends Layout {
     /**
-     * The {@link ContextualSearchPanelHost} that allows the {@link ContextualSearchPanel} to
+     * The {@link OverlayPanelHost} that allows the {@link OverlayPanel} to
      * communicate back to the Layout.
      */
-    protected final ContextualSearchPanelHost mContextualSearchPanelHost;
+    protected final OverlayPanelHost mOverlayPanelHost;
 
     /**
-     * The {@link ContextualSearchPanel} that represents the Contextual Search UI.
+     * The {@link OverlayPanel} that represents the Contextual Search UI.
      */
-    protected final ContextualSearchPanel mSearchPanel;
-
-    /**
-     * The {@link SceneLayer} that renders contextual search UI.
-     */
-    private final ContextualSearchSceneLayer mContextualSearchSceneLayer;
+    protected final OverlayPanel mSearchPanel;
 
     /**
      * Size of half pixel in dps.
@@ -53,13 +48,13 @@
      * @param updateHost The {@link LayoutUpdateHost} view for this layout.
      * @param renderHost The {@link LayoutRenderHost} view for this layout.
      * @param eventFilter The {@link EventFilter} that is needed for this view.
-     * @param panel The {@link ContextualSearchPanel} that represents the Contextual Search UI.
+     * @param panel The {@link OverlayPanel} that represents the Contextual Search UI.
      */
     public ContextualSearchSupportedLayout(Context context, LayoutUpdateHost updateHost,
-            LayoutRenderHost renderHost, EventFilter eventFilter, ContextualSearchPanel panel) {
+            LayoutRenderHost renderHost, EventFilter eventFilter, OverlayPanel panel) {
         super(context, updateHost, renderHost, eventFilter);
 
-        mContextualSearchPanelHost = new ContextualSearchPanelHost() {
+        mOverlayPanelHost = new OverlayPanelHost() {
             @Override
             public void hideLayout(boolean immediately) {
                 ContextualSearchSupportedLayout.this.hideContextualSearch(immediately);
@@ -69,7 +64,6 @@
         mSearchPanel = panel;
         float dpToPx = context.getResources().getDisplayMetrics().density;
         mHalfPixelDp = 0.5f / dpToPx;
-        mContextualSearchSceneLayer = new ContextualSearchSceneLayer(dpToPx, panel);
     }
 
     @Override
@@ -81,7 +75,7 @@
     public void getAllViews(List<View> views) {
         // TODO(dtrainor): If we move ContextualSearch to an overlay, pull the views from there
         // instead in Layout.java.
-        if (mSearchPanel != null && mSearchPanel.getManagementDelegate() != null) {
+        if (mSearchPanel != null) {
             ContentViewCore content = mSearchPanel.getContentViewCore();
             if (content != null) views.add(content.getContainerView());
         }
@@ -92,7 +86,7 @@
     public void getAllContentViewCores(List<ContentViewCore> contents) {
         // TODO(dtrainor): If we move ContextualSearch to an overlay, pull the content from there
         // instead in Layout.java.
-        if (mSearchPanel != null && mSearchPanel.getManagementDelegate() != null) {
+        if (mSearchPanel != null) {
             ContentViewCore content =
                     mSearchPanel.getContentViewCore();
             if (content != null) contents.add(content);
@@ -102,7 +96,7 @@
 
     @Override
     public void show(long time, boolean animate) {
-        mSearchPanel.setHost(mContextualSearchPanelHost);
+        mSearchPanel.setHost(mOverlayPanelHost);
         super.show(time, animate);
     }
 
@@ -135,7 +129,7 @@
 
     @Override
     protected SceneLayer getSceneLayer() {
-        return mContextualSearchSceneLayer;
+        return mSearchPanel.getSceneLayer();
     }
 
     @Override
@@ -146,12 +140,6 @@
                 resourceManager, fullscreenManager);
         if (!mSearchPanel.isShowing()) return;
 
-        if (mContextualSearchSceneLayer == null || mSearchPanel.getManagementDelegate() == null) {
-            return;
-        }
-
-        ContentViewCore contentViewCore =
-                mSearchPanel.getContentViewCore();
-        mContextualSearchSceneLayer.update(contentViewCore, resourceManager);
+        mSearchPanel.updateSceneLayer(resourceManager);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/ContextualSearchLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/ContextualSearchLayout.java
index f31e91ad..8d42cff5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/ContextualSearchLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/ContextualSearchLayout.java
@@ -99,12 +99,13 @@
         // if the SearchContentView's vertical scroll position is zero. Otherwise the
         // ContentView will appear to jump in the screen. Coordinate with @dtrainor to solve
         // this problem.
-        mSearchPanel.getManagementDelegate().updateTopControlsState(TopControlsState.BOTH, false);
+        mSearchPanel.updateTopControlsState(TopControlsState.BOTH, false);
         return true;
     }
 
     @Override
     public void show(long time, boolean animate) {
+        mTabListSceneLayer.setContentTree(super.getSceneLayer());
         super.show(time, animate);
 
         resetLayout();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java
index 02606d8..250c6d6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java
@@ -12,8 +12,6 @@
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.ui.resources.ResourceManager;
 
-import javax.annotation.Nullable;
-
 /**
  * A SceneLayer to render layers for ContextualSearchLayout.
  */
@@ -24,28 +22,24 @@
     private long mNativePtr;
 
     private final float mDpToPx;
-    private final ContextualSearchPanel mSearchPanel;
 
-    public ContextualSearchSceneLayer(float dpToPx, ContextualSearchPanel searchPanel) {
+    public ContextualSearchSceneLayer(float dpToPx) {
         mDpToPx = dpToPx;
-        mSearchPanel = searchPanel;
     }
 
     /**
-     * Update contextual search's layer tree using the parameters.
-     *
-     * @param contentViewCore The CVC, may be null if only updating the bar.
-     * @param resourceManager
+     * This class is used for SceneLayers that are frequently updated.
      */
-    public void update(@Nullable ContentViewCore contentViewCore, ResourceManager resourceManager) {
-        int searchContextViewId = mSearchPanel.getSearchContextViewId();
-        int searchTermViewId = mSearchPanel.getSearchTermViewId();
+    public void update(ResourceManager resourceManager,
+            ContextualSearchPanel panel) {
+        int searchContextViewId = panel.getSearchContextViewId();
+        int searchTermViewId = panel.getSearchTermViewId();
 
-        boolean searchPromoVisible = mSearchPanel.getPromoVisible();
-        float searchPromoHeightPx = mSearchPanel.getPromoHeightPx();
-        float searchPromoOpacity = mSearchPanel.getPromoOpacity();
+        boolean searchPromoVisible = panel.getPromoVisible();
+        float searchPromoHeightPx = panel.getPromoHeightPx();
+        float searchPromoOpacity = panel.getPromoOpacity();
 
-        ContextualSearchPeekPromoControl peekPromoControl = mSearchPanel.getPeekPromoControl();
+        ContextualSearchPeekPromoControl peekPromoControl = panel.getPeekPromoControl();
         int searchPeekPromoTextViewId = peekPromoControl.getViewId();
         boolean searchPeekPromoVisible = peekPromoControl.isVisible();
         float searchPeekPromoHeightPx = peekPromoControl.getHeightPx();
@@ -54,38 +48,37 @@
         float searchPeekPromoRippleOpacity = peekPromoControl.getRippleOpacity();
         float searchPeekPromoTextOpacity = peekPromoControl.getTextOpacity();
 
-        float searchPanelX = mSearchPanel.getOffsetX();
-        float searchPanelY = mSearchPanel.getOffsetY();
-        float searchPanelWidth = mSearchPanel.getWidth();
-        float searchPanelHeight = mSearchPanel.getHeight();
+        float searchPanelX = panel.getOffsetX();
+        float searchPanelY = panel.getOffsetY();
+        float searchPanelWidth = panel.getWidth();
+        float searchPanelHeight = panel.getHeight();
 
-        float searchBarMarginSide = mSearchPanel.getSearchBarMarginSide();
-        float searchBarHeight = mSearchPanel.getSearchBarHeight();
-        float searchContextOpacity = mSearchPanel.getSearchBarContextOpacity();
-        float searchTermOpacity = mSearchPanel.getSearchBarTermOpacity();
+        float searchBarMarginSide = panel.getSearchBarMarginSide();
+        float searchBarHeight = panel.getSearchBarHeight();
+        float searchContextOpacity = panel.getSearchBarContextOpacity();
+        float searchTermOpacity = panel.getSearchBarTermOpacity();
 
-        boolean searchBarBorderVisible = mSearchPanel.isSearchBarBorderVisible();
-        float searchBarBorderHeight = mSearchPanel.getSearchBarBorderHeight();
+        boolean searchBarBorderVisible = panel.isSearchBarBorderVisible();
+        float searchBarBorderHeight = panel.getSearchBarBorderHeight();
 
-        boolean searchBarShadowVisible = mSearchPanel.getSearchBarShadowVisible();
-        float searchBarShadowOpacity = mSearchPanel.getSearchBarShadowOpacity();
+        boolean searchBarShadowVisible = panel.getSearchBarShadowVisible();
+        float searchBarShadowOpacity = panel.getSearchBarShadowOpacity();
 
-        ContextualSearchIconSpriteControl spriteControl =
-                mSearchPanel.getIconSpriteControl();
+        ContextualSearchIconSpriteControl spriteControl = panel.getIconSpriteControl();
         boolean searchProviderIconSpriteVisible = spriteControl.isVisible();
         float searchProviderIconCompletionPercentage = spriteControl.getCompletionPercentage();
         float searchProviderIconSpriteSize = spriteControl.getSizePx();
 
-        float arrowIconOpacity = mSearchPanel.getArrowIconOpacity();
-        float arrowIconRotation = mSearchPanel.getArrowIconRotation();
+        float arrowIconOpacity = panel.getArrowIconOpacity();
+        float arrowIconRotation = panel.getArrowIconRotation();
 
-        float closeIconOpacity = mSearchPanel.getCloseIconOpacity();
+        float closeIconOpacity = panel.getCloseIconOpacity();
 
-        boolean isProgressBarVisible = mSearchPanel.isProgressBarVisible();
+        boolean isProgressBarVisible = panel.isProgressBarVisible();
 
-        float progressBarHeight = mSearchPanel.getProgressBarHeight();
-        float progressBarOpacity = mSearchPanel.getProgressBarOpacity();
-        int progressBarCompletion = mSearchPanel.getProgressBarCompletion();
+        float progressBarHeight = panel.getProgressBarHeight();
+        float progressBarOpacity = panel.getProgressBarOpacity();
+        int progressBarCompletion = panel.getProgressBarCompletion();
 
         nativeUpdateContextualSearchLayer(mNativePtr,
                 R.drawable.contextual_search_bar_background,
@@ -102,7 +95,7 @@
                 searchPeekPromoTextViewId,
                 R.drawable.google_icon_sprite,
                 R.raw.google_icon_sprite,
-                contentViewCore,
+                panel.getContentViewCore(),
                 searchPromoVisible,
                 searchPromoHeightPx,
                 searchPromoOpacity,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java
index ce31158..b587693 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java
@@ -8,8 +8,6 @@
 import org.chromium.chrome.browser.compositor.bottombar.OverlayContentDelegate;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason;
 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.content_public.common.TopControlsState;
 
 /**
  * The delegate that provides global management functionality for Contextual Search.
@@ -37,17 +35,6 @@
     void logPromoOutcome();
 
     /**
-     * Updates the top controls state for the base tab.  As these values are set at the renderer
-     * level, there is potential for this impacting other tabs that might share the same
-     * process. See {@link Tab#updateTopControlsState(int current, boolean animate)}
-     * @param current The desired current state for the controls.  Pass
-     *                {@link TopControlsState#BOTH} to preserve the current position.
-     * @param animate Whether the controls should animate to the specified ending condition or
-     *                should jump immediately.
-     */
-    void updateTopControlsState(int current, boolean animate);
-
-    /**
      * Promotes the current Content View Core in the Contextual Search Panel to its own Tab.
      */
     void promoteToTab();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
index e7439c2..8f28b28 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -554,14 +554,6 @@
         }
     }
 
-    @Override
-    public void updateTopControlsState(int current, boolean animate) {
-        Tab currentTab = mActivity.getActivityTab();
-        if (currentTab != null) {
-            currentTab.updateTopControlsState(current, animate);
-        }
-    }
-
     /**
      * Accessor for the {@code InfoBarContainer} currently attached to the {@code Tab}.
      */
@@ -1092,7 +1084,7 @@
     @Override
     public void onSelectionChanged(String selection) {
         mSelectionController.handleSelectionChanged(selection);
-        updateTopControlsState(TopControlsState.BOTH, true);
+        mSearchPanel.updateTopControlsState(TopControlsState.BOTH, true);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastRouteController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastRouteController.java
index f9a24a0..e776aeb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastRouteController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastRouteController.java
@@ -81,6 +81,9 @@
 
         @Override
         public void onMessageReceived(CastDevice castDevice, String namespace, String message) {
+            Log.d(TAG, "Received message from Cast device: namespace=\"" + namespace
+                       + "\" message=\"" + message + "\"");
+
             if (MEDIA_NAMESPACE.equals(namespace) || RECEIVER_NAMESPACE.equals(namespace)) {
                 mSession.onMessage("v2_message", message);
             } else {
@@ -339,7 +342,7 @@
             jsonMessage.put("message", message);
             onMessage("app_message", jsonMessage.toString());
         } catch (JSONException e) {
-            Log.d(TAG, "Failed to create the message wrapper", e);
+            Log.e(TAG, "Failed to create the message wrapper", e);
         }
     }
 
@@ -386,7 +389,7 @@
             } else if ("app_message".equals(messageType)) {
                 success = handleAppMessage(message, jsonMessage);
             } else {
-                Log.d(TAG, "Unsupported message: %s", message);
+                Log.e(TAG, "Unsupported message: %s", message);
                 return false;
             }
         } catch (JSONException e) {
@@ -425,6 +428,8 @@
             throws JSONException {
         assert "v2_message".equals(jsonMessage.getString("type"));
 
+        Log.d(TAG, "Received message from client: " + jsonMessage);
+
         String clientId = jsonMessage.getString("clientId");
         if (!mClients.contains(clientId)) return false;
 
@@ -517,6 +522,8 @@
         // See: https://crbug.com/548822
         if (!message.has("requestId")) message.put("requestId", 0);
 
+        Log.d(TAG, "Sending message to Cast device: " + message);
+
         try {
             Cast.CastApi.sendMessage(mApiClient, namespace, message.toString())
                     .setResultCallback(
@@ -583,6 +590,8 @@
             Log.e(TAG, "Failed to build the reply: " + e);
         }
 
+        Log.d(TAG, "Sending message to client: " + json);
+
         return json.toString();
     }
 
@@ -598,7 +607,7 @@
                         "update_session", buildSessionMessage(), clientId, -1));
             }
         } catch (IllegalStateException e) {
-            Log.d(TAG, "Can't get application status", e);
+            Log.e(TAG, "Can't get application status", e);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
index 7a08f9c4..b51a946 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
@@ -26,6 +26,7 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.UrlUtilities;
 import org.chromium.chrome.browser.preferences.Preferences;
 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
 import org.chromium.chrome.browser.preferences.website.SingleCategoryPreferences;
@@ -437,7 +438,8 @@
                         NotificationConstants.ACTION_CLOSE_NOTIFICATION,
                         persistentNotificationId, origin, tag, -1 /* actionIndex */))
                 .setTicker(createTickerText(title, body))
-                .setOrigin(origin);
+                .setOrigin(UrlUtilities.formatUrlForSecurityDisplay(
+                        origin, false /* showScheme */));
 
         for (int actionIndex = 0; actionIndex < actionTitles.length; actionIndex++) {
             notificationBuilder.addAction(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java
index 16fcbf3..df7984c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java
@@ -8,6 +8,7 @@
 import android.graphics.Canvas;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.TextView;
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.VisibleForTesting;
@@ -17,6 +18,7 @@
 import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider;
 import org.chromium.chrome.browser.help.HelpAndFeedback;
 import org.chromium.chrome.browser.ntp.IncognitoNewTabPageView.IncognitoNewTabPageManager;
+import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.profiles.Profile;
 
 /**
@@ -68,6 +70,13 @@
         mIncognitoNewTabPageView =
                 (IncognitoNewTabPageView) inflater.inflate(R.layout.new_tab_page_incognito, null);
         mIncognitoNewTabPageView.initialize(mIncognitoNewTabPageManager);
+
+        if (OfflinePageBridge.isEnabled()) {
+            TextView newTabIncognitoMessage = (TextView) mIncognitoNewTabPageView.findViewById(
+                    R.id.new_tab_incognito_message);
+            newTabIncognitoMessage.setText(activity.getResources().getString(
+                    R.string.offline_pages_new_tab_incognito_message));
+        }
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java
index 0159d18fd..7fe59b31 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/accessibility/AccessibilityTabModelListItem.java
@@ -41,7 +41,7 @@
     private static final int CLOSE_ANIMATION_DURATION_MS = 100;
     private static final int DEFAULT_ANIMATION_DURATION_MS = 300;
     private static final int VELOCITY_SCALING_FACTOR = 150;
-    private static final int CLOSE_TIMEOUT_MS = 2000;
+    private static final int CLOSE_TIMEOUT_MS = 4000;
 
     private int mCloseAnimationDurationMs;
     private int mDefaultAnimationDurationMs;
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 549d208..84b49fe9 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2169,6 +2169,11 @@
 
 However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your internet service provider, or the websites you visit.
       </message>
+      <message name="IDS_OFFLINE_PAGES_NEW_TAB_INCOGNITO_MESSAGE" desc="Message shown when a user opens an incognito tab explaining incognito mode">
+        Pages you view in incognito tabs won’t stick around in your browser’s history, cookie store, or search history after you’ve closed all of your incognito tabs. Any downloaded files or saved pages will be kept.
+
+However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your internet service provider, or the websites you visit.
+      </message>
 
       <!-- Contextual Search -->
       <message name="IDS_CONTEXTUAL_SEARCH_NETWORK_UNAVAILABLE" desc="Tells the user the network is not accessible.">
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchEventFilterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchEventFilterTest.java
index 304c8e8..95bc4cc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchEventFilterTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchEventFilterTest.java
@@ -20,6 +20,7 @@
 import org.chromium.chrome.browser.compositor.layouts.eventfilter.ContextualSearchEventFilter;
 import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilterHost;
 import org.chromium.chrome.browser.compositor.layouts.eventfilter.GestureHandler;
+import org.chromium.chrome.browser.compositor.scene_layer.ContextualSearchSceneLayer;
 
 /**
  * Class responsible for testing the ContextualSearchEventFilter.
@@ -139,6 +140,11 @@
             return new MockOverlayPanelContent();
         }
 
+        @Override
+        protected ContextualSearchSceneLayer createNewContextualSearchSceneLayer() {
+            return null;
+        }
+
         /**
          * Override creation and destruction of the ContentViewCore as they rely on native methods.
          */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java
index 792375e..05dae12 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationUIManagerTest.java
@@ -20,6 +20,7 @@
 import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.UrlUtilities;
 import org.chromium.chrome.browser.preferences.website.ContentSetting;
 import org.chromium.chrome.browser.preferences.website.PushNotificationInfo;
 import org.chromium.chrome.browser.widget.RoundedIconGenerator;
@@ -157,7 +158,8 @@
         // Validate the contents of the notification.
         assertEquals("MyNotification", notification.extras.getString(Notification.EXTRA_TITLE));
         assertEquals("Hello", notification.extras.getString(Notification.EXTRA_TEXT));
-        assertEquals(getOrigin(), notification.extras.getString(Notification.EXTRA_SUB_TEXT));
+        assertEquals(UrlUtilities.formatUrlForSecurityDisplay(getOrigin(), false /* showScheme */),
+                notification.extras.getString(Notification.EXTRA_SUB_TEXT));
 
         // Verify that the ticker text contains the notification's title and body.
         String tickerText = notification.tickerText.toString();
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 979e6a7..1e32cde 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -9290,10 +9290,10 @@
         This webpage is not available
       </message>
       <message name="IDS_ERRORPAGES_SUMMARY_SSL_VERSION_OR_CIPHER_MISMATCH" desc="Summary in the error page for SSL cipher and version errors.">
-        A secure connection cannot be established because this site uses an unsupported protocol.
+        A secure connection cannot be established because this site uses an unsupported protocol or cipher suite. This is usually caused when the server needs RC4 support, which has been removed.
       </message>
       <message name="IDS_ERRORPAGES_DETAILS_SSL_VERSION_OR_CIPHER_MISMATCH" desc="The error message displayed for SSL cipher and version errors.">
-        The client and server don't support a common SSL protocol version or cipher suite. This is usually caused when the server needs SSLv3 support, which has been removed.
+        The client and server don't support a common SSL protocol version or cipher suite. This is usually caused when the server needs RC4 support, which has been removed.
       </message>
 
       <message name="IDS_ERRORPAGES_HEADING_PINNING_FAILURE" desc="Title of the error page for a certificate which doesn't match the built-in pins for that name">
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index a7a47d1..cbaaa50 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -72,6 +72,7 @@
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/mock_cryptohome_client.h"
+#include "components/signin/core/account_id/account_id.h"
 #endif
 
 #if defined(ENABLE_EXTENSIONS)
@@ -2018,7 +2019,8 @@
   chromeos::ScopedTestCrosSettings test_cros_settings;
   chromeos::MockUserManager* mock_user_manager =
       new testing::NiceMock<chromeos::MockUserManager>();
-  mock_user_manager->SetActiveUser("test@example.com");
+  mock_user_manager->SetActiveUser(
+      AccountId::FromUserEmail("test@example.com"));
   chromeos::ScopedUserManagerEnabler user_manager_enabler(mock_user_manager);
 
   scoped_ptr<chromeos::DBusThreadManagerSetter> dbus_setter =
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
index 0aeb557ba..36e7713 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
@@ -261,6 +261,9 @@
   content::NotificationRegistrar registrar_;
 
   MockBrailleController braille_controller_;
+
+  const AccountId test_account_id_ = AccountId::FromUserEmail(kTestUserName);
+
   DISALLOW_COPY_AND_ASSIGN(AccessibilityManagerTest);
 };
 
@@ -274,8 +277,8 @@
   EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay());
 
   // Logs in.
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that the features still disabled just after login.
   EXPECT_FALSE(IsLargeCursorEnabled());
@@ -336,8 +339,8 @@
 
 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, TypePref) {
   // Logs in.
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
   user_manager::UserManager::Get()->SessionStarted();
 
   // Confirms that the features are disabled just after login.
@@ -396,8 +399,8 @@
 
 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, ResumeSavedPref) {
   // Loads the profile of the user.
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Sets the pref to enable large cursor before login.
   SetLargeCursorEnabledPref(true);
@@ -441,8 +444,8 @@
   MockAccessibilityObserver observer;
 
   // Logs in.
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
   user_manager::UserManager::Get()->SessionStarted();
 
   EXPECT_FALSE(observer.observed());
@@ -501,8 +504,8 @@
   MockAccessibilityObserver observer;
 
   // Logs in.
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
   user_manager::UserManager::Get()->SessionStarted();
 
   EXPECT_FALSE(observer.observed());
@@ -593,8 +596,9 @@
   EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelay());
 
   // Logs in.
-  const char* user_name = GetParam();
-  user_manager::UserManager::Get()->UserLoggedIn(user_name, user_name, true);
+  const AccountId account_id = AccountId::FromUserEmail(GetParam());
+  user_manager::UserManager::Get()->UserLoggedIn(
+      account_id, account_id.GetUserEmail(), true);
 
   // Confirms that the features are still enabled just after login.
   EXPECT_TRUE(IsLargeCursorEnabled());
@@ -622,8 +626,9 @@
 
 IN_PROC_BROWSER_TEST_P(AccessibilityManagerUserTypeTest, BrailleWhenLoggedIn) {
   // Logs in.
-  const char* user_name = GetParam();
-  user_manager::UserManager::Get()->UserLoggedIn(user_name, user_name, true);
+  const AccountId account_id = AccountId::FromUserEmail(GetParam());
+  user_manager::UserManager::Get()->UserLoggedIn(
+      account_id, account_id.GetUserEmail(), true);
   user_manager::UserManager::Get()->SessionStarted();
   // This object watches for IME preference changes and reflects those in
   // the IME framework state.
@@ -668,8 +673,8 @@
 
 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, AccessibilityMenuVisibility) {
   // Log in.
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
   user_manager::UserManager::Get()->SessionStarted();
 
   // Confirms that the features are disabled.
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc
index 970973c..2cec6c3 100644
--- a/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc
@@ -91,11 +91,12 @@
   return prefs()->GetBoolean(prefs::kAccessibilityScreenMagnifierEnabled);
 }
 
-// Creates and logs into a profile with account |name|, and makes sure that
-// the profile is regarded as "non new" in the next login. This is used in
+// Creates and logs into a profile with account |account_id|, and makes sure
+// that the profile is regarded as "non new" in the next login. This is used in
 // PRE_XXX cases so that in the main XXX case we can test non new profiles.
-void PrepareNonNewProfile(const std::string& name) {
-  user_manager::UserManager::Get()->UserLoggedIn(name, name, true);
+void PrepareNonNewProfile(const AccountId& account_id) {
+  user_manager::UserManager::Get()->UserLoggedIn(
+      account_id, account_id.GetUserEmail(), true);
   // To prepare a non-new profile for tests, we must ensure the profile
   // directory and the preference files are created, because that's what
   // Profile::IsNewProfile() checks. UserLoggedIn(), however, does not yet
@@ -163,12 +164,14 @@
         ProfileManager::GetActiveUserProfile());
   }
 
+  const AccountId test_account_id_ = AccountId::FromUserEmail(kTestUserName);
+
   DISALLOW_COPY_AND_ASSIGN(MagnificationManagerTest);
 };
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginOffToOff) {
   // Create a new profile once, to run the test with non-new profile.
-  PrepareNonNewProfile(kTestUserName);
+  PrepareNonNewProfile(test_account_id_);
 
   // Sets pref to explicitly disable the magnifier.
   SetScreenMagnifierEnabledPref(false);
@@ -183,8 +186,8 @@
   EXPECT_FALSE(IsMagnifierEnabled());
 
   // Logs in with existing profile.
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that magnifier is still disabled just after login.
   EXPECT_FALSE(IsMagnifierEnabled());
@@ -204,7 +207,7 @@
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToOff) {
   // Create a new profile once, to run the test with non-new profile.
-  PrepareNonNewProfile(kTestUserName);
+  PrepareNonNewProfile(test_account_id_);
 
   // Sets pref to explicitly disable the magnifier.
   SetScreenMagnifierEnabledPref(false);
@@ -223,8 +226,8 @@
   EXPECT_EQ(2.5, GetFullScreenMagnifierScale());
 
   // Logs in (but the session is not started yet).
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that magnifier is keeping enabled.
   EXPECT_TRUE(IsMagnifierEnabled());
@@ -239,7 +242,7 @@
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginOffToFull) {
   // Create a new profile once, to run the test with non-new profile.
-  PrepareNonNewProfile(kTestUserName);
+  PrepareNonNewProfile(test_account_id_);
 
   // Sets prefs to explicitly enable the magnifier.
   SetScreenMagnifierEnabledPref(true);
@@ -253,8 +256,8 @@
   EXPECT_FALSE(IsMagnifierEnabled());
 
   // Logs in (but the session is not started yet).
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that magnifier is keeping disabled.
   EXPECT_FALSE(IsMagnifierEnabled());
@@ -271,7 +274,7 @@
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToFull) {
   // Create a new profile once, to run the test with non-new profile.
-  PrepareNonNewProfile(kTestUserName);
+  PrepareNonNewProfile(test_account_id_);
 
   // Sets prefs to explicitly enable the magnifier.
   SetScreenMagnifierEnabledPref(true);
@@ -289,8 +292,8 @@
   EXPECT_EQ(3.0, GetFullScreenMagnifierScale());
 
   // Logs in (but the session is not started yet).
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that magnifier is keeping enabled.
   EXPECT_TRUE(IsMagnifierEnabled());
@@ -308,7 +311,7 @@
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToUnset) {
   // Creates a new profile once, to run the test with non-new profile.
-  PrepareNonNewProfile(kTestUserName);
+  PrepareNonNewProfile(test_account_id_);
 }
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginFullToUnset) {
@@ -319,8 +322,8 @@
   EXPECT_EQ(ui::MAGNIFIER_FULL, GetMagnifierType());
 
   // Logs in (but the session is not started yet).
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that magnifier is keeping enabled.
   EXPECT_TRUE(IsMagnifierEnabled());
@@ -341,8 +344,8 @@
   SetMagnifierEnabled(false);
 
   // Logs in (but the session is not started yet).
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that magnifier is keeping disabled.
   EXPECT_FALSE(IsMagnifierEnabled());
@@ -364,8 +367,8 @@
   EXPECT_EQ(2.5, GetFullScreenMagnifierScale());
 
   // Logs in (but the session is not started yet).
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that magnifier is keeping enabled.
   EXPECT_TRUE(IsMagnifierEnabled());
@@ -385,8 +388,8 @@
   EXPECT_FALSE(IsMagnifierEnabled());
 
   // Logs in (but the session is not started yet).
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
 
   // Confirms that magnifier is keeping disabled.
   EXPECT_FALSE(IsMagnifierEnabled());
@@ -457,8 +460,8 @@
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, TypePref) {
   // Logs in
-  user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+  user_manager::UserManager::Get()->UserLoggedIn(test_account_id_,
+                                                 kTestUserName, true);
   user_manager::UserManager::Get()->SessionStarted();
 
   // Confirms that magnifier is disabled just after login.
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
index bb339fe..0dd9f22d 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -38,6 +38,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "components/ownership/owner_key_util.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/common/extension_urls.h"
@@ -640,9 +641,9 @@
   const user_manager::User* active_user =
       user_manager::UserManager::Get()->GetActiveUser();
   if (active_user) {
-    std::string active_user_id = active_user->GetUserID();
+    const AccountId active_account_id = active_user->GetAccountId();
     for (const auto& it : old_apps) {
-      if (it.second->user_id() == active_user_id) {
+      if (it.second->user_id() == active_account_id.GetUserEmail()) {
         VLOG(1) << "Currently running kiosk app removed from policy, exiting";
         cryptohomes_barrier_closure = BarrierClosure(
             old_apps.size(), base::Bind(&chrome::AttemptUserExit));
diff --git a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc
index 638fdb0..5612da0 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc
@@ -158,7 +158,7 @@
   // we switch this back to the demo user name to correctly identify this
   // user as a demo user.
   UserContext context = user_context;
-  if (context.GetUserID() == chromeos::login::kGuestUserName)
+  if (context.GetAccountId() == login::GuestAccountId())
     context.SetUserID(login::DemoAccountId().GetUserEmail());
   UserSessionManager::GetInstance()->StartSession(
       context, UserSessionManager::PRIMARY_USER_SESSION,
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
index 21dd3c5..839e172 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
+++ b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc
@@ -50,7 +50,7 @@
         is_permitted_by_user_(true),
         is_in_supported_mode_(true) {
     // Configure a user for the mock user manager.
-    mock_user_manager_.SetActiveUser(kTestEmail);
+    mock_user_manager_.SetActiveUser(AccountId::FromUserEmail(kTestEmail));
   }
   ~FakeDelegate() override {}
 
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 66e0040..f88e8b82 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -469,12 +469,13 @@
   ChromeBrowserMainPartsLinux::PreProfileInit();
 
   if (immediate_login) {
-    const std::string user_id = login::CanonicalizeUserID(
+    const std::string user_email = login::CanonicalizeUserID(
         parsed_command_line().GetSwitchValueASCII(switches::kLoginUser));
     user_manager::UserManager* user_manager = user_manager::UserManager::Get();
 
-    if (policy::IsDeviceLocalAccountUser(user_id, NULL) &&
-        !user_manager->IsKnownUser(user_id)) {
+    const AccountId account_id(AccountId::FromUserEmail(user_email));
+    if (policy::IsDeviceLocalAccountUser(account_id.GetUserEmail(), NULL) &&
+        !user_manager->IsKnownUser(account_id)) {
       // When a device-local account is removed, its policy is deleted from disk
       // immediately. If a session using this account happens to be in progress,
       // the session is allowed to continue with policy served from an in-memory
@@ -488,8 +489,8 @@
     // In case of multi-profiles --login-profile will contain user_id_hash.
     std::string user_id_hash =
         parsed_command_line().GetSwitchValueASCII(switches::kLoginProfile);
-    user_manager->UserLoggedIn(user_id, user_id_hash, true);
-    VLOG(1) << "Relaunching browser for user: " << user_id
+    user_manager->UserLoggedIn(account_id, user_id_hash, true);
+    VLOG(1) << "Relaunching browser for user: " << user_email
             << " with hash: " << user_id_hash;
   }
 }
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
index 2790dbf..143abd9 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
@@ -153,7 +153,7 @@
       chromeos::ProfileHelper::Get()->GetUserByProfile(GetProfile());
   if (user) {
     user_manager::UserManager::Get()->SaveUserOAuthStatus(
-        user->email(), user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
+        user->GetAccountId(), user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
   }
 
   chrome::AttemptUserExit();
diff --git a/chrome/browser/chromeos/extensions/users_private/users_private_api.cc b/chrome/browser/chromeos/extensions/users_private/users_private_api.cc
index b33dff6..7fd1286 100644
--- a/chrome/browser/chromeos/extensions/users_private/users_private_api.cc
+++ b/chrome/browser/chromeos/extensions/users_private/users_private_api.cc
@@ -170,7 +170,8 @@
   PrefsUtil* prefs_util = delegate->GetPrefsUtil();
   bool removed = prefs_util->RemoveFromListCrosSetting(
       chromeos::kAccountsPrefUsers, canonical_email);
-  user_manager::UserManager::Get()->RemoveUser(parameters->email, NULL);
+  user_manager::UserManager::Get()->RemoveUser(
+      AccountId::FromUserEmail(parameters->email), NULL);
   return RespondNow(OneArgument(new base::FundamentalValue(removed)));
 }
 
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
index 16843b7c..ff3e942 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "ui/aura/test/test_windows.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
@@ -34,6 +35,9 @@
  protected:
   FakeChromeUserManager* fake_user_manager() { return fake_user_manager_; }
 
+  const AccountId test_account_id1_ = AccountId::FromUserEmail(kTestAccount1);
+  const AccountId test_account_id2_ = AccountId::FromUserEmail(kTestAccount2);
+
  private:
   FakeChromeUserManager* fake_user_manager_;
   ScopedUserManagerEnabler scoped_user_manager_;
@@ -69,7 +73,7 @@
 }  // namespace
 
 TEST_F(WallpaperPrivateApiUnittest, HideAndRestoreWindows) {
-  fake_user_manager()->AddUser(kTestAccount1);
+  fake_user_manager()->AddUser(test_account_id1_);
   scoped_ptr<aura::Window> window4(CreateTestWindowInShellWithId(4));
   scoped_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
   scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
@@ -132,7 +136,7 @@
 // 2. If some windows are manually unminimized, the following call will minimize
 // all the unminimized windows.
 TEST_F(WallpaperPrivateApiUnittest, HideAndManualUnminimizeWindows) {
-  fake_user_manager()->AddUser(kTestAccount1);
+  fake_user_manager()->AddUser(test_account_id1_);
   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
 
@@ -196,10 +200,10 @@
 
  protected:
   void SetUpMultiUserWindowManager(
-      const std::string& active_user_id,
+      const AccountId& active_account_id,
       chrome::MultiUserWindowManager::MultiProfileMode mode);
 
-  void SwitchActiveUser(const std::string& active_user_id);
+  void SwitchActiveUser(const AccountId& active_account_id);
 
   chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager() {
     return multi_user_window_manager_;
@@ -218,8 +222,8 @@
   session_state_delegate_ =
       static_cast<ash::test::TestSessionStateDelegate*> (
           ash::Shell::GetInstance()->session_state_delegate());
-  fake_user_manager()->AddUser(kTestAccount1);
-  fake_user_manager()->AddUser(kTestAccount2);
+  fake_user_manager()->AddUser(test_account_id1_);
+  fake_user_manager()->AddUser(test_account_id2_);
 }
 
 void WallpaperPrivateApiMultiUserUnittest::TearDown() {
@@ -229,10 +233,10 @@
 }
 
 void WallpaperPrivateApiMultiUserUnittest::SetUpMultiUserWindowManager(
-    const std::string& active_user_id,
+    const AccountId& active_account_id,
     chrome::MultiUserWindowManager::MultiProfileMode mode) {
-  multi_user_window_manager_ =
-      new chrome::MultiUserWindowManagerChromeOS(active_user_id);
+  multi_user_window_manager_ = new chrome::MultiUserWindowManagerChromeOS(
+      active_account_id.GetUserEmail());
   multi_user_window_manager_->Init();
   chrome::MultiUserWindowManager::SetInstanceForTest(
       multi_user_window_manager_, mode);
@@ -243,16 +247,18 @@
 }
 
 void WallpaperPrivateApiMultiUserUnittest::SwitchActiveUser(
-    const std::string& active_user_id) {
-  fake_user_manager()->SwitchActiveUser(active_user_id);
-  multi_user_window_manager_->ActiveUserChanged(active_user_id);
+    const AccountId& active_account_id) {
+  fake_user_manager()->SwitchActiveUser(active_account_id);
+  multi_user_window_manager_->ActiveUserChanged(
+      active_account_id.GetUserEmail());
 }
 
 // In multi profile mode, user may open wallpaper picker in one profile and
 // then switch to a different profile and open another wallpaper picker
 // without closing the first one.
 TEST_F(WallpaperPrivateApiMultiUserUnittest, HideAndRestoreWindowsTwoUsers) {
-  SetUpMultiUserWindowManager(kTestAccount1,
+  SetUpMultiUserWindowManager(
+      test_account_id1_,
       chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED);
 
   scoped_ptr<aura::Window> window4(CreateTestWindowInShellWithId(4));
@@ -267,13 +273,18 @@
   ash::wm::WindowState* window3_state = ash::wm::GetWindowState(window3.get());
   ash::wm::WindowState* window4_state = ash::wm::GetWindowState(window4.get());
 
-  multi_user_window_manager()->SetWindowOwner(window0.get(), kTestAccount1);
-  multi_user_window_manager()->SetWindowOwner(window1.get(), kTestAccount1);
+  multi_user_window_manager()->SetWindowOwner(window0.get(),
+                                              test_account_id1_.GetUserEmail());
+  multi_user_window_manager()->SetWindowOwner(window1.get(),
+                                              test_account_id1_.GetUserEmail());
 
   // Set some windows to an inactive owner.
-  multi_user_window_manager()->SetWindowOwner(window2.get(), kTestAccount2);
-  multi_user_window_manager()->SetWindowOwner(window3.get(), kTestAccount2);
-  multi_user_window_manager()->SetWindowOwner(window4.get(), kTestAccount2);
+  multi_user_window_manager()->SetWindowOwner(window2.get(),
+                                              test_account_id2_.GetUserEmail());
+  multi_user_window_manager()->SetWindowOwner(window3.get(),
+                                              test_account_id2_.GetUserEmail());
+  multi_user_window_manager()->SetWindowOwner(window4.get(),
+                                              test_account_id2_.GetUserEmail());
 
   EXPECT_FALSE(window0_state->IsMinimized());
   EXPECT_FALSE(window1_state->IsMinimized());
@@ -299,7 +310,7 @@
   EXPECT_FALSE(window4_state->IsMinimized());
 
   // Activate kTestAccount2. kTestAccount1 becomes inactive user.
-  SwitchActiveUser(kTestAccount2);
+  SwitchActiveUser(test_account_id2_);
 
   window2_state->Activate();
   EXPECT_TRUE(window2_state->IsActive());
@@ -337,7 +348,7 @@
   EXPECT_FALSE(window0_state->IsMinimized());
   EXPECT_TRUE(window1_state->IsMinimized());
 
-  SwitchActiveUser(kTestAccount1);
+  SwitchActiveUser(test_account_id1_);
 
   // Then we destroy window 0 and call the restore function.
   window0.reset();
@@ -352,7 +363,8 @@
 // In multi profile mode, user may teleport windows. Teleported window should
 // also be minimized when open wallpaper picker.
 TEST_F(WallpaperPrivateApiMultiUserUnittest, HideTeleportedWindow) {
-  SetUpMultiUserWindowManager(kTestAccount1,
+  SetUpMultiUserWindowManager(
+      AccountId::FromUserEmail(kTestAccount1),
       chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_MIXED);
 
   scoped_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
@@ -365,15 +377,20 @@
   ash::wm::WindowState* window2_state = ash::wm::GetWindowState(window2.get());
   ash::wm::WindowState* window3_state = ash::wm::GetWindowState(window3.get());
 
-  multi_user_window_manager()->SetWindowOwner(window0.get(), kTestAccount1);
-  multi_user_window_manager()->SetWindowOwner(window1.get(), kTestAccount1);
+  multi_user_window_manager()->SetWindowOwner(window0.get(),
+                                              test_account_id1_.GetUserEmail());
+  multi_user_window_manager()->SetWindowOwner(window1.get(),
+                                              test_account_id1_.GetUserEmail());
 
   // Set some windows to an inactive owner.
-  multi_user_window_manager()->SetWindowOwner(window2.get(), kTestAccount2);
-  multi_user_window_manager()->SetWindowOwner(window3.get(), kTestAccount2);
+  multi_user_window_manager()->SetWindowOwner(window2.get(),
+                                              test_account_id2_.GetUserEmail());
+  multi_user_window_manager()->SetWindowOwner(window3.get(),
+                                              test_account_id2_.GetUserEmail());
 
   // Teleport window2 to kTestAccount1.
-  multi_user_window_manager()->ShowWindowForUser(window2.get(), kTestAccount1);
+  multi_user_window_manager()->ShowWindowForUser(
+      window2.get(), test_account_id1_.GetUserEmail());
 
   // Initial window state. All windows shouldn't be minimized.
   EXPECT_FALSE(window0_state->IsMinimized());
diff --git a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
index fd2d19e..ad0e0691 100644
--- a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
+++ b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
@@ -567,7 +567,8 @@
     base::FilePath user_data_directory;
     PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
     user_manager::UserManager::Get()->UserLoggedIn(
-        kSecondProfileAccount, kSecondProfileHash, false);
+        AccountId::FromUserEmail(kSecondProfileAccount), kSecondProfileHash,
+        false);
     // Set up the secondary profile.
     base::FilePath profile_dir =
         user_data_directory.Append(
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index faae428..d66547df 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -609,9 +609,10 @@
   void AddUser(const TestAccountInfo& info, bool log_in) {
     user_manager::UserManager* const user_manager =
         user_manager::UserManager::Get();
+    const AccountId account_id(AccountId::FromUserEmail(info.email));
     if (log_in)
-      user_manager->UserLoggedIn(info.email, info.hash, false);
-    user_manager->SaveUserDisplayName(info.email,
+      user_manager->UserLoggedIn(account_id, info.hash, false);
+    user_manager->SaveUserDisplayName(account_id,
                                       base::UTF8ToUTF16(info.display_name));
     SigninManagerFactory::GetForProfile(
         chromeos::ProfileHelper::GetProfileByUserIdHash(info.hash))
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc b/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
index 1d1f838..9bca244f 100644
--- a/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
@@ -70,7 +70,8 @@
     profile_ = profile_manager_->CreateTestingProfile("testing-profile");
     user_manager_ = new FakeChromeUserManager();
     user_manager_enabler_.reset(new ScopedUserManagerEnabler(user_manager_));
-    user_manager_->AddUser(profile_->GetProfileUserName());
+    user_manager_->AddUser(
+        AccountId::FromUserEmail(profile_->GetProfileUserName()));
     file_system_provider_service_ = Service::Get(profile_);
     file_system_provider_service_->SetFileSystemFactoryForTesting(
         base::Bind(&FakeProvidedFileSystem::Create));
diff --git a/chrome/browser/chromeos/file_system_provider/service_unittest.cc b/chrome/browser/chromeos/file_system_provider/service_unittest.cc
index 6a8fe39b..8e108ce 100644
--- a/chrome/browser/chromeos/file_system_provider/service_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/service_unittest.cc
@@ -191,7 +191,8 @@
     ASSERT_TRUE(profile_manager_->SetUp());
     profile_ = profile_manager_->CreateTestingProfile("test-user@example.com");
     user_manager_ = new FakeChromeUserManager();
-    user_manager_->AddUser(profile_->GetProfileUserName());
+    user_manager_->AddUser(
+        AccountId::FromUserEmail(profile_->GetProfileUserName()));
     user_manager_enabler_.reset(new ScopedUserManagerEnabler(user_manager_));
     extension_registry_.reset(new extensions::ExtensionRegistry(profile_));
 
diff --git a/chrome/browser/chromeos/input_method/input_method_persistence_unittest.cc b/chrome/browser/chromeos/input_method/input_method_persistence_unittest.cc
index 4811cac..ad88581f 100644
--- a/chrome/browser/chromeos/input_method/input_method_persistence_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_persistence_unittest.cc
@@ -43,13 +43,14 @@
     ASSERT_TRUE(mock_profile_manager_.SetUp());
 
     // Add a user.
-    const char kTestUserName[] = "test-user@example.com";
-    fake_user_manager_->AddUser(kTestUserName);
-    fake_user_manager_->LoginUser(kTestUserName);
+    const AccountId test_account_id(
+        AccountId::FromUserEmail("test-user@example.com"));
+    fake_user_manager_->AddUser(test_account_id);
+    fake_user_manager_->LoginUser(test_account_id);
 
     // Create a valid profile for the user.
-    TestingProfile* mock_profile =
-        mock_profile_manager_.CreateTestingProfile(kTestUserName);
+    TestingProfile* mock_profile = mock_profile_manager_.CreateTestingProfile(
+        test_account_id.GetUserEmail());
     mock_profile_manager_.SetLoggedIn(true);
     EXPECT_TRUE(ProfileManager::GetActiveUserProfile() == mock_profile);
 
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc
index eb33f14..6bbea04 100644
--- a/chrome/browser/chromeos/login/app_launch_controller.cc
+++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -322,7 +322,7 @@
     return true;
   }
 
-  return !user_manager::UserManager::Get()->GetOwnerEmail().empty();
+  return user_manager::UserManager::Get()->GetOwnerAccountId().is_valid();
 }
 
 bool AppLaunchController::NeedOwnerAuthToConfigureNetwork() {
diff --git a/chrome/browser/chromeos/login/app_launch_signin_screen.cc b/chrome/browser/chromeos/login/app_launch_signin_screen.cc
index 8affe30..b841c3d 100644
--- a/chrome/browser/chromeos/login/app_launch_signin_screen.cc
+++ b/chrome/browser/chromeos/login/app_launch_signin_screen.cc
@@ -42,7 +42,8 @@
 
 void AppLaunchSigninScreen::InitOwnerUserList() {
   user_manager::UserManager* user_manager = GetUserManager();
-  const std::string& owner_email = user_manager->GetOwnerEmail();
+  const std::string& owner_email =
+      user_manager->GetOwnerAccountId().GetUserEmail();
   const user_manager::UserList& all_users = user_manager->GetUsers();
 
   owner_user_list_.clear();
diff --git a/chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc b/chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc
index 97b24d2..869f4240 100644
--- a/chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc
+++ b/chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc
@@ -26,7 +26,7 @@
 }
 
 bool ChromeCryptohomeAuthenticator::IsKnownUser(const UserContext& context) {
-  return user_manager::UserManager::Get()->IsKnownUser(context.GetUserID());
+  return user_manager::UserManager::Get()->IsKnownUser(context.GetAccountId());
 }
 
 bool ChromeCryptohomeAuthenticator::IsSafeMode() {
diff --git a/chrome/browser/chromeos/login/auth/chrome_login_performer.cc b/chrome/browser/chromeos/login/auth/chrome_login_performer.cc
index e913bc1..e912445 100644
--- a/chrome/browser/chromeos/login/auth/chrome_login_performer.cc
+++ b/chrome/browser/chromeos/login/auth/chrome_login_performer.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "components/signin/core/account_id/account_id.h"
 
 namespace chromeos {
 
@@ -130,7 +131,8 @@
     const UserContext& user_context) {
   SupervisedUserAuthentication* authentication =
       ChromeUserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
-  return authentication->GetPasswordSchema(user_context.GetUserID()) ==
+  return authentication->GetPasswordSchema(
+             user_context.GetAccountId().GetUserEmail()) ==
          SupervisedUserAuthentication::SCHEMA_SALT_HASHED;
 }
 
@@ -143,12 +145,15 @@
 
 void ChromeLoginPerformer::SetupSupervisedUserFlow(const std::string& user_id) {
   SupervisedUserLoginFlow* new_flow = new SupervisedUserLoginFlow(user_id);
-  new_flow->SetHost(ChromeUserManager::Get()->GetUserFlow(user_id)->host());
-  ChromeUserManager::Get()->SetUserFlow(user_id, new_flow);
+  new_flow->SetHost(ChromeUserManager::Get()
+                        ->GetUserFlow(AccountId::FromUserEmail(user_id))
+                        ->host());
+  ChromeUserManager::Get()->SetUserFlow(AccountId::FromUserEmail(user_id),
+                                        new_flow);
 }
 
 void ChromeLoginPerformer::SetupEasyUnlockUserFlow(const std::string& user_id) {
-  ChromeUserManager::Get()->SetUserFlow(user_id,
+  ChromeUserManager::Get()->SetUserFlow(AccountId::FromUserEmail(user_id),
                                         new EasyUnlockUserLoginFlow(user_id));
 }
 
diff --git a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
index c96e922a..9a5385f4 100644
--- a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
+++ b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
@@ -131,7 +131,7 @@
 class CryptohomeAuthenticatorTest : public testing::Test {
  public:
   CryptohomeAuthenticatorTest()
-      : user_context_("me@nowhere.org"),
+      : user_context_(AccountId::FromUserEmail("me@nowhere.org")),
         user_manager_(new user_manager::FakeUserManager()),
         user_manager_enabler_(user_manager_),
         mock_caller_(NULL),
@@ -142,8 +142,8 @@
     user_context_.SetKey(Key("fakepass"));
     user_context_.SetUserIDHash("me_nowhere_com_hash");
     const user_manager::User* user =
-        user_manager_->AddUser(user_context_.GetUserID());
-    profile_.set_profile_name(user_context_.GetUserID());
+        user_manager_->AddUser(user_context_.GetAccountId());
+    profile_.set_profile_name(user_context_.GetAccountId().GetUserEmail());
 
     ProfileHelper::Get()->SetUserToProfileMappingForTesting(user, &profile_);
 
@@ -264,13 +264,12 @@
           cryptohome::KeyDefinition::ProviderData("salt"));
       key_definition.provider_data.back().bytes = salt.Pass();
     }
-    EXPECT_CALL(*mock_homedir_methods_, GetKeyDataEx(
-        cryptohome::Identification(user_context_.GetUserID()),
-        kCryptohomeGAIAKeyLabel,
-        _))
+    EXPECT_CALL(*mock_homedir_methods_,
+                GetKeyDataEx(cryptohome::Identification(
+                                 user_context_.GetAccountId().GetUserEmail()),
+                             kCryptohomeGAIAKeyLabel, _))
         .WillOnce(WithArg<2>(Invoke(
-            this,
-            &CryptohomeAuthenticatorTest::InvokeGetDataExCallback)));
+            this, &CryptohomeAuthenticatorTest::InvokeGetDataExCallback)));
   }
 
   void ExpectMountExCall(bool expect_create_attempt) {
@@ -285,10 +284,9 @@
           cryptohome::PRIV_DEFAULT));
     }
     EXPECT_CALL(*mock_homedir_methods_,
-                MountEx(cryptohome::Identification(user_context_.GetUserID()),
-                        cryptohome::Authorization(auth_key),
-                        mount,
-                        _))
+                MountEx(cryptohome::Identification(
+                            user_context_.GetAccountId().GetUserEmail()),
+                        cryptohome::Authorization(auth_key), mount, _))
         .Times(1)
         .RetiresOnSaturation();
   }
@@ -562,7 +560,8 @@
   // Set up mock async method caller to respond successfully to a cryptohome
   // remove attempt.
   mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
-  EXPECT_CALL(*mock_caller_, AsyncRemove(user_context_.GetUserID(), _))
+  EXPECT_CALL(*mock_caller_,
+              AsyncRemove(user_context_.GetAccountId().GetUserEmail(), _))
       .Times(1)
       .RetiresOnSaturation();
 
@@ -584,7 +583,8 @@
 
   // Set up mock async method caller to fail a cryptohome remove attempt.
   mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_NONE);
-  EXPECT_CALL(*mock_caller_, AsyncRemove(user_context_.GetUserID(), _))
+  EXPECT_CALL(*mock_caller_,
+              AsyncRemove(user_context_.GetAccountId().GetUserEmail(), _))
       .Times(1)
       .RetiresOnSaturation();
 
@@ -614,10 +614,9 @@
 
   // Set up mock async method caller to respond successfully to a key migration.
   mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
-  EXPECT_CALL(
-      *mock_caller_,
-      AsyncMigrateKey(
-          user_context_.GetUserID(), _, transformed_key_.GetSecret(), _))
+  EXPECT_CALL(*mock_caller_,
+              AsyncMigrateKey(user_context_.GetAccountId().GetUserEmail(), _,
+                              transformed_key_.GetSecret(), _))
       .Times(1)
       .RetiresOnSaturation();
 
@@ -640,10 +639,9 @@
   // Set up mock async method caller to fail a key migration attempt,
   // asserting that the wrong password was used.
   mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_KEY_FAILURE);
-  EXPECT_CALL(
-      *mock_caller_,
-      AsyncMigrateKey(
-          user_context_.GetUserID(), _, transformed_key_.GetSecret(), _))
+  EXPECT_CALL(*mock_caller_,
+              AsyncMigrateKey(user_context_.GetAccountId().GetUserEmail(), _,
+                              transformed_key_.GetSecret(), _))
       .Times(1)
       .RetiresOnSaturation();
 
@@ -732,7 +730,8 @@
   // Set up mock async method caller to respond successfully to a cryptohome
   // key-check attempt.
   mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
-  EXPECT_CALL(*mock_caller_, AsyncCheckKey(user_context_.GetUserID(), _, _))
+  EXPECT_CALL(*mock_caller_,
+              AsyncCheckKey(user_context_.GetAccountId().GetUserEmail(), _, _))
       .Times(1)
       .RetiresOnSaturation();
 
diff --git a/chrome/browser/chromeos/login/easy_unlock/bootstrap_browsertest.cc b/chrome/browser/chromeos/login/easy_unlock/bootstrap_browsertest.cc
index 1b20386..70d612e 100644
--- a/chrome/browser/chromeos/login/easy_unlock/bootstrap_browsertest.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/bootstrap_browsertest.cc
@@ -156,7 +156,8 @@
 }
 
 IN_PROC_BROWSER_TEST_F(BootstrapTest, CleanUpFailedUser) {
-  EXPECT_FALSE(user_manager::UserManager::Get()->IsKnownUser(kFakeUser));
+  EXPECT_FALSE(user_manager::UserManager::Get()->IsKnownUser(
+      AccountId::FromUserEmail(kFakeUser)));
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/easy_unlock/bootstrap_user_context_initializer.cc b/chrome/browser/chromeos/login/easy_unlock/bootstrap_user_context_initializer.cc
index 9d66402..d42c5df 100644
--- a/chrome/browser/chromeos/login/easy_unlock/bootstrap_user_context_initializer.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/bootstrap_user_context_initializer.cc
@@ -68,10 +68,9 @@
 }
 
 void BootstrapUserContextInitializer::StartCheckExistingKeys() {
-  const std::string& user_id = user_context_.GetUserID();
-
   // Use random key for the first time user.
-  if (!user_manager::UserManager::Get()->IsKnownUser(user_id)) {
+  if (!user_manager::UserManager::Get()->IsKnownUser(
+          user_context_.GetAccountId())) {
     CreateRandomKey();
     return;
   }
@@ -79,7 +78,7 @@
   EasyUnlockKeyManager* key_manager =
       UserSessionManager::GetInstance()->GetEasyUnlockKeyManager();
   key_manager->GetDeviceDataList(
-      UserContext(user_id),
+      UserContext(user_context_.GetAccountId()),
       base::Bind(&BootstrapUserContextInitializer::OnGetEasyUnlockData,
                  weak_ptr_factory_.GetWeakPtr()));
 }
@@ -99,7 +98,7 @@
   service->AddObserver(this);
 
   static_cast<EasyUnlockServiceSignin*>(service)
-      ->SetCurrentUser(user_context_.GetUserID());
+      ->SetCurrentUser(user_context_.GetAccountId().GetUserEmail());
   OnScreenlockStateChanged(service->GetScreenlockState());
 }
 
@@ -203,7 +202,7 @@
   service->RemoveObserver(this);
 
   service->AttemptAuth(
-      user_context_.GetUserID(),
+      user_context_.GetAccountId().GetUserEmail(),
       base::Bind(&BootstrapUserContextInitializer::OnEasyUnlockAuthenticated,
                  weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/chrome/browser/chromeos/login/easy_unlock/bootstrap_user_flow.cc b/chrome/browser/chromeos/login/easy_unlock/bootstrap_user_flow.cc
index 64a6b33a..acf5cf5 100644
--- a/chrome/browser/chromeos/login/easy_unlock/bootstrap_user_flow.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/bootstrap_user_flow.cc
@@ -14,19 +14,20 @@
 #include "chrome/browser/signin/easy_unlock_service.h"
 #include "chrome/browser/signin/easy_unlock_service_regular.h"
 #include "components/proximity_auth/screenlock_bridge.h"
+#include "components/signin/core/account_id/account_id.h"
 
 namespace chromeos {
 
 BootstrapUserFlow::BootstrapUserFlow(const UserContext& user_context,
                                      bool is_new_account)
-    : ExtendedUserFlow(user_context.GetUserID()),
+    : ExtendedUserFlow(user_context.GetAccountId().GetUserEmail()),
       user_context_(user_context),
       is_new_account_(is_new_account),
       finished_(false),
       user_profile_(nullptr),
       weak_ptr_factory_(this) {
   ChromeUserManager::Get()->GetBootstrapManager()->AddPendingBootstrap(
-      user_context_.GetUserID());
+      user_context_.GetAccountId().GetUserEmail());
 }
 
 BootstrapUserFlow::~BootstrapUserFlow() {
@@ -110,7 +111,7 @@
   finished_ = true;
 
   ChromeUserManager::Get()->GetBootstrapManager()->FinishPendingBootstrap(
-      user_context_.GetUserID());
+      user_context_.GetAccountId().GetUserEmail());
   UserSessionManager::GetInstance()->DoBrowserLaunch(user_profile_, host());
 
   user_profile_ = nullptr;
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_create_keys_operation.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_create_keys_operation.cc
index 4d5f15c..878eab7a 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_create_keys_operation.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_create_keys_operation.cc
@@ -346,8 +346,8 @@
       kEasyUnlockKeyMetaNameWrappedSecret, device->wrapped_secret));
 
   // Add cryptohome key.
-  std::string canonicalized =
-      gaia::CanonicalizeEmail(user_context_.GetUserID());
+  const std::string canonicalized =
+      gaia::CanonicalizeEmail(user_context_.GetAccountId().GetUserEmail());
   cryptohome::Identification id(canonicalized);
 
   scoped_ptr<Key> auth_key(new Key(*user_context_.GetKey()));
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_get_keys_operation.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_get_keys_operation.cc
index e0789c8..7e625679 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_get_keys_operation.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_get_keys_operation.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 
 namespace chromeos {
@@ -32,8 +33,8 @@
 }
 
 void EasyUnlockGetKeysOperation::GetKeyData() {
-  std::string canonicalized =
-      gaia::CanonicalizeEmail(user_context_.GetUserID());
+  const std::string canonicalized =
+      gaia::CanonicalizeEmail(user_context_.GetAccountId().GetUserEmail());
   cryptohome::Identification id(canonicalized);
   cryptohome::HomedirMethods::GetInstance()->GetKeyDataEx(
       id,
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc
index c1ba482f..3cfa4bc 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc
@@ -11,6 +11,7 @@
 #include "base/values.h"
 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.h"
 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.h"
+#include "components/signin/core/account_id/account_id.h"
 
 namespace chromeos {
 
@@ -52,7 +53,7 @@
 
   EasyUnlockTpmKeyManager* tpm_key_manager =
       EasyUnlockTpmKeyManagerFactory::GetInstance()->GetForUser(
-          user_context.GetUserID());
+          user_context.GetAccountId().GetUserEmail());
   if (!tpm_key_manager) {
     LOG(ERROR) << "No TPM key manager.";
     callback.Run(false);
@@ -81,9 +82,9 @@
     const RefreshKeysCallback& callback) {
   EasyUnlockTpmKeyManager* tpm_key_manager =
       EasyUnlockTpmKeyManagerFactory::GetInstance()->GetForUser(
-          user_context.GetUserID());
-  std::string tpm_public_key =
-      tpm_key_manager->GetPublicTpmKey(user_context.GetUserID());
+          user_context.GetAccountId().GetUserEmail());
+  const std::string tpm_public_key = tpm_key_manager->GetPublicTpmKey(
+      user_context.GetAccountId().GetUserEmail());
 
   EasyUnlockDeviceKeyDataList devices;
   if (!RemoteDeviceListToDeviceDataList(*remote_devices, &devices))
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.cc
index 795db23d..9ead3ef 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.cc
@@ -47,8 +47,8 @@
 }
 
 void EasyUnlockRemoveKeysOperation::RemoveKey() {
-  std::string canonicalized =
-      gaia::CanonicalizeEmail(user_context_.GetUserID());
+  const std::string canonicalized =
+      gaia::CanonicalizeEmail(user_context_.GetAccountId().GetUserEmail());
   cryptohome::Identification id(canonicalized);
   const Key* const auth_key = user_context_.GetKey();
   cryptohome::Authorization auth(auth_key->GetSecret(), auth_key->GetLabel());
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc
index 00d1d0e..ebce3abcc 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 
 namespace {
@@ -36,8 +37,8 @@
 
 EasyUnlockTpmKeyManager* EasyUnlockTpmKeyManagerFactory::GetForUser(
     const std::string& user_id) {
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id);
+  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+      AccountId::FromUserEmail(user_id));
   if (!user)
     return NULL;
   Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user);
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc
index 40462b3f..ef61f00 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc
@@ -202,7 +202,8 @@
 
   void SetUp() override {
     ASSERT_TRUE(profile_manager_.SetUp());
-    const user_manager::User* user = user_manager_->AddUser(kTestUserId);
+    const user_manager::User* user =
+        user_manager_->AddUser(AccountId::FromUserEmail(kTestUserId));
     username_hash_ = user->username_hash();
 
     signin_profile_ = profile_manager_.CreateTestingProfile(
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 2ba77ed..94c54bab 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -125,7 +125,8 @@
   if (user_context.GetUserType() == user_manager::USER_TYPE_REGULAR &&
       user_context.GetAuthFlow() == UserContext::AUTH_FLOW_OFFLINE &&
       easy_unlock_service) {
-    easy_unlock_service->RecordPasswordLoginEvent(user_context.GetUserID());
+    easy_unlock_service->RecordPasswordLoginEvent(
+        user_context.GetAccountId().GetUserEmail());
   }
 }
 
@@ -355,7 +356,7 @@
     LoginPerformer::AuthorizationMode auth_mode) {
   VLOG(1) << "Setting flow from PerformLogin";
   ChromeUserManager::Get()
-      ->GetUserFlow(user_context.GetUserID())
+      ->GetUserFlow(user_context.GetAccountId())
       ->SetHost(host_);
 
   BootTimesRecorder::Get()->RecordLoginAttempted();
@@ -368,7 +369,7 @@
     login_performer_.reset(new ChromeLoginPerformer(this));
   }
 
-  if (gaia::ExtractDomainName(user_context.GetUserID()) ==
+  if (gaia::ExtractDomainName(user_context.GetAccountId().GetUserEmail()) ==
       chromeos::login::kSupervisedUserDomain) {
     login_performer_->LoginAsSupervisedUser(user_context);
   } else {
@@ -509,7 +510,7 @@
   PerformLoginFinishedActions(false /* don't start public session timer */);
 
   if (ChromeUserManager::Get()
-          ->GetUserFlow(last_login_attempt_username_)
+          ->GetUserFlow(last_login_attempt_account_id_)
           ->HandleLoginFailure(failure)) {
     return;
   }
@@ -524,15 +525,15 @@
         base::TimeDelta::FromMilliseconds(kSafeModeRestartUiDelayMs));
   } else if (failure.reason() == AuthFailure::TPM_ERROR) {
     ShowTPMError();
-  } else if (last_login_attempt_username_ == chromeos::login::kGuestUserName) {
+  } else if (last_login_attempt_account_id_ == login::GuestAccountId()) {
     // Show no errors, just re-enable input.
     login_display_->ClearAndEnablePassword();
     StartPublicSessionAutoLoginTimer();
   } else {
     // Check networking after trying to login in case user is
     // cached locally or the local admin account.
-    bool is_known_user = user_manager::UserManager::Get()->IsKnownUser(
-        last_login_attempt_username_);
+    const bool is_known_user = user_manager::UserManager::Get()->IsKnownUser(
+        last_login_attempt_account_id_);
     if (!network_state_helper_->IsConnected()) {
       if (is_known_user)
         ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
@@ -557,7 +558,7 @@
 
   // Reset user flow to default, so that special flow will not affect next
   // attempt.
-  ChromeUserManager::Get()->ResetUserFlow(last_login_attempt_username_);
+  ChromeUserManager::Get()->ResetUserFlow(last_login_attempt_account_id_);
 
   if (auth_status_consumer_)
     auth_status_consumer_->OnAuthFailure(failure);
@@ -568,7 +569,7 @@
   // TODO(ginkage): Fix this case once crbug.com/469990 is ready.
   /*
     if (failure.reason() == AuthFailure::COULD_NOT_MOUNT_CRYPTOHOME) {
-      RecordReauthReason(last_login_attempt_username_,
+      RecordReauthReason(last_login_attempt_account_id_,
                          ReauthReason::MISSING_CRYPTOHOME);
     }
   */
@@ -584,7 +585,7 @@
   auth_mode_ = login_performer_->auth_mode();
 
   ChromeUserManager::Get()
-      ->GetUserFlow(user_context.GetUserID())
+      ->GetUserFlow(user_context.GetAccountId())
       ->HandleLoginSuccess(user_context);
 
   StopPublicSessionAutoLoginTimer();
@@ -616,7 +617,7 @@
   // Update user's displayed email.
   if (!display_email_.empty()) {
     user_manager::UserManager::Get()->SaveUserDisplayEmail(
-        user_context.GetUserID(), display_email_);
+        user_context.GetAccountId(), display_email_);
     display_email_.clear();
   }
 }
@@ -632,8 +633,8 @@
   // Inform |auth_status_consumer_| about successful login.
   // TODO(nkostylev): Pass UserContext back crbug.com/424550
   if (auth_status_consumer_) {
-    auth_status_consumer_->
-        OnAuthSuccess(UserContext(last_login_attempt_username_));
+    auth_status_consumer_->OnAuthSuccess(
+        UserContext(last_login_attempt_account_id_));
   }
 }
 
@@ -663,7 +664,7 @@
   }
 
   if (ChromeUserManager::Get()
-          ->GetUserFlow(last_login_attempt_username_)
+          ->GetUserFlow(last_login_attempt_account_id_)
           ->HandlePasswordChangeDetected()) {
     return;
   }
@@ -760,7 +761,7 @@
   // If there is no public account with the given user ID, logging in is not
   // possible.
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
+      user_manager::UserManager::Get()->FindUser(user_context.GetAccountId());
   if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
     PerformLoginFinishedActions(true /* start public session timer */);
     return;
@@ -773,11 +774,15 @@
     // whether a list of recommended locales was set by policy. If so, use its
     // first entry. Otherwise, |locale| will remain blank, indicating that the
     // public session should use the current UI locale.
-    const policy::PolicyMap::Entry* entry = g_browser_process->platform_part()->
-        browser_policy_connector_chromeos()->
-            GetDeviceLocalAccountPolicyService()->
-                GetBrokerForUser(user_context.GetUserID())->core()->store()->
-                    policy_map().Get(policy::key::kSessionLocales);
+    const policy::PolicyMap::Entry* entry =
+        g_browser_process->platform_part()
+            ->browser_policy_connector_chromeos()
+            ->GetDeviceLocalAccountPolicyService()
+            ->GetBrokerForUser(user_context.GetAccountId().GetUserEmail())
+            ->core()
+            ->store()
+            ->policy_map()
+            .Get(policy::key::kSessionLocales);
     base::ListValue const* list = NULL;
     if (entry &&
         entry->level == policy::POLICY_LEVEL_RECOMMENDED &&
@@ -843,7 +848,7 @@
   }
 
   const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
-      public_session_auto_login_username_);
+      AccountId::FromUserEmail(public_session_auto_login_username_));
   if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
     public_session_auto_login_username_.clear();
 
@@ -929,7 +934,7 @@
     if (num_login_attempts_ > 1) {
       const user_manager::User* user =
           user_manager::UserManager::Get()->FindUser(
-              last_login_attempt_username_);
+              last_login_attempt_account_id_);
       if (user && (user->GetType() == user_manager::USER_TYPE_SUPERVISED))
         error_id = IDS_LOGIN_ERROR_AUTHENTICATING_2ND_TIME_SUPERVISED;
     }
@@ -980,8 +985,8 @@
   // Disable clicking on other windows and status tray.
   login_display_->SetUIEnabled(false);
 
-  if (last_login_attempt_username_ != user_context.GetUserID()) {
-    last_login_attempt_username_ = user_context.GetUserID();
+  if (last_login_attempt_account_id_ != user_context.GetAccountId()) {
+    last_login_attempt_account_id_ = user_context.GetAccountId();
     num_login_attempts_ = 0;
   }
 
@@ -1061,11 +1066,11 @@
   UserContext user_context = user_context_wo_device_id;
   std::string device_id =
       user_manager::UserManager::Get()->GetKnownUserDeviceId(
-          user_context.GetUserID());
+          user_context.GetAccountId());
   if (device_id.empty()) {
-    bool is_ephemeral =
-        ChromeUserManager::Get()->AreEphemeralUsersEnabled() &&
-        user_context.GetUserID() != ChromeUserManager::Get()->GetOwnerEmail();
+    bool is_ephemeral = ChromeUserManager::Get()->AreEphemeralUsersEnabled() &&
+                        user_context.GetAccountId() !=
+                            ChromeUserManager::Get()->GetOwnerAccountId();
     device_id = SigninClient::GenerateSigninScopedDeviceID(is_ephemeral);
   }
   user_context.SetDeviceId(device_id);
@@ -1073,7 +1078,7 @@
   const std::string& gaps_cookie = user_context.GetGAPSCookie();
   if (!gaps_cookie.empty()) {
     user_manager::UserManager::Get()->SetKnownUserGAPSCookie(
-        user_context.GetUserID(), gaps_cookie);
+        user_context.GetAccountId(), gaps_cookie);
   }
 
   PerformPreLoginActions(user_context);
@@ -1145,7 +1150,8 @@
   }
 
   if (user_context.GetUserType() == user_manager::USER_TYPE_KIOSK_APP) {
-    LoginAsKioskApp(user_context.GetUserID(), specifics.kiosk_diagnostic_mode);
+    LoginAsKioskApp(user_context.GetAccountId().GetUserEmail(),
+                    specifics.kiosk_diagnostic_mode);
     return;
   }
 
@@ -1176,7 +1182,7 @@
   // Setting a customized login user flow to perform additional initializations
   // for bootstrap after the user session is started.
   ChromeUserManager::Get()->SetUserFlow(
-      user_context.GetUserID(),
+      user_context.GetAccountId(),
       new BootstrapUserFlow(
           user_context,
           bootstrap_user_context_initializer_->random_key_used()));
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h
index ea8d1966..d9c7a503 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.h
+++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -254,8 +254,8 @@
   // Tests can use this to receive authentication status events.
   AuthStatusConsumer* auth_status_consumer_;
 
-  // Username of the last login attempt.
-  std::string last_login_attempt_username_;
+  // AccountId of the last login attempt.
+  AccountId last_login_attempt_account_id_ = EmptyAccountId();
 
   // OOBE/login display host.
   LoginDisplayHost* host_;
diff --git a/chrome/browser/chromeos/login/existing_user_controller_auto_login_unittest.cc b/chrome/browser/chromeos/login/existing_user_controller_auto_login_unittest.cc
index 0725453..3d6ff7f 100644
--- a/chrome/browser/chromeos/login/existing_user_controller_auto_login_unittest.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller_auto_login_unittest.cc
@@ -30,7 +30,6 @@
 
 namespace {
 
-const char kAutoLoginAccountId[] = "public_session_user@localhost";
 // These values are only used to test the configuration.  They don't
 // delay the test.
 const int kAutoLoginDelay1 = 60000;
@@ -41,14 +40,10 @@
 class ExistingUserControllerAutoLoginTest : public ::testing::Test {
  protected:
   ExistingUserControllerAutoLoginTest()
-      : auto_login_user_id_(policy::GenerateDeviceLocalAccountUserId(
-            kAutoLoginAccountId,
-            policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
-        ui_thread_(content::BrowserThread::UI, &message_loop_),
+      : ui_thread_(content::BrowserThread::UI, &message_loop_),
         local_state_(TestingBrowserProcess::GetGlobal()),
         mock_user_manager_(new MockUserManager()),
-        scoped_user_manager_(mock_user_manager_) {
-  }
+        scoped_user_manager_(mock_user_manager_) {}
 
   void SetUp() override {
     mock_login_display_host_.reset(new MockLoginDisplayHost);
@@ -61,17 +56,16 @@
     EXPECT_CALL(*mock_user_manager_, Shutdown()).Times(AnyNumber());
     EXPECT_CALL(*mock_user_manager_, FindUser(_))
         .WillRepeatedly(ReturnNull());
-    EXPECT_CALL(*mock_user_manager_, FindUser(auto_login_user_id_))
-        .WillRepeatedly(Return(
-            mock_user_manager_->CreatePublicAccountUser(auto_login_user_id_)));
+    EXPECT_CALL(*mock_user_manager_, FindUser(auto_login_account_id_))
+        .WillRepeatedly(Return(mock_user_manager_->CreatePublicAccountUser(
+            auto_login_account_id_)));
 
     existing_user_controller_.reset(
         new ExistingUserController(mock_login_display_host_.get()));
 
     scoped_ptr<base::DictionaryValue> account(new base::DictionaryValue);
     account->SetStringWithoutPathExpansion(
-        kAccountsPrefDeviceLocalAccountsKeyId,
-        kAutoLoginAccountId);
+        kAccountsPrefDeviceLocalAccountsKeyId, auto_login_user_id_);
     account->SetIntegerWithoutPathExpansion(
         kAccountsPrefDeviceLocalAccountsKeyType,
         policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
@@ -94,10 +88,9 @@
     return ExistingUserController::current_controller();
   }
 
-  void SetAutoLoginSettings(const std::string& account_id, int delay) {
-    CrosSettings::Get()->SetString(
-        kAccountsPrefDeviceLocalAccountAutoLoginId,
-        account_id);
+  void SetAutoLoginSettings(const std::string& user_id, int delay) {
+    CrosSettings::Get()->SetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
+                                   user_id);
     CrosSettings::Get()->SetInteger(
         kAccountsPrefDeviceLocalAccountAutoLoginDelay,
         delay);
@@ -133,7 +126,13 @@
     existing_user_controller()->ConfigurePublicSessionAutoLogin();
   }
 
-  const std::string auto_login_user_id_;
+  const std::string auto_login_user_id_ =
+      std::string("public_session_user@localhost");
+
+  const AccountId auto_login_account_id_ =
+      AccountId::FromUserEmail(policy::GenerateDeviceLocalAccountUserId(
+          auto_login_user_id_,
+          policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION));
 
  private:
   // |mock_login_display_| is owned by the ExistingUserController, which calls
@@ -158,7 +157,7 @@
 
 TEST_F(ExistingUserControllerAutoLoginTest, StartAutoLoginTimer) {
   // Timer shouldn't start until signin screen is ready.
-  set_auto_login_username(auto_login_user_id_);
+  set_auto_login_username(auto_login_account_id_.GetUserEmail());
   set_auto_login_delay(kAutoLoginDelay2);
   existing_user_controller()->StartPublicSessionAutoLoginTimer();
   EXPECT_FALSE(auto_login_timer());
@@ -170,7 +169,7 @@
   EXPECT_FALSE(auto_login_timer());
 
   // Timer shouldn't fire in the middle of a login attempt.
-  set_auto_login_username(auto_login_user_id_);
+  set_auto_login_username(auto_login_account_id_.GetUserEmail());
   set_is_login_in_progress(true);
   existing_user_controller()->StartPublicSessionAutoLoginTimer();
   EXPECT_FALSE(auto_login_timer());
@@ -186,7 +185,7 @@
 
 TEST_F(ExistingUserControllerAutoLoginTest, StopAutoLoginTimer) {
   existing_user_controller()->OnSigninScreenReady();
-  set_auto_login_username(auto_login_user_id_);
+  set_auto_login_username(auto_login_account_id_.GetUserEmail());
   set_auto_login_delay(kAutoLoginDelay2);
 
   existing_user_controller()->StartPublicSessionAutoLoginTimer();
@@ -200,7 +199,7 @@
 
 TEST_F(ExistingUserControllerAutoLoginTest, ResetAutoLoginTimer) {
   existing_user_controller()->OnSigninScreenReady();
-  set_auto_login_username(auto_login_user_id_);
+  set_auto_login_username(auto_login_account_id_.GetUserEmail());
 
   // Timer starts off not running.
   EXPECT_FALSE(auto_login_timer());
@@ -244,24 +243,24 @@
   EXPECT_EQ(auto_login_username(), "");
 
   // Timer should start when the account ID is set.
-  SetAutoLoginSettings(kAutoLoginAccountId, kAutoLoginDelay1);
+  SetAutoLoginSettings(auto_login_user_id_, kAutoLoginDelay1);
   ConfigureAutoLogin();
   ASSERT_TRUE(auto_login_timer());
   EXPECT_TRUE(auto_login_timer()->IsRunning());
   EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
             kAutoLoginDelay1);
   EXPECT_EQ(auto_login_delay(), kAutoLoginDelay1);
-  EXPECT_EQ(auto_login_username(), auto_login_user_id_);
+  EXPECT_EQ(auto_login_username(), auto_login_account_id_.GetUserEmail());
 
   // Timer should restart when the delay is changed.
-  SetAutoLoginSettings(kAutoLoginAccountId, kAutoLoginDelay2);
+  SetAutoLoginSettings(auto_login_user_id_, kAutoLoginDelay2);
   ConfigureAutoLogin();
   ASSERT_TRUE(auto_login_timer());
   EXPECT_TRUE(auto_login_timer()->IsRunning());
   EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
             kAutoLoginDelay2);
   EXPECT_EQ(auto_login_delay(), kAutoLoginDelay2);
-  EXPECT_EQ(auto_login_username(), auto_login_user_id_);
+  EXPECT_EQ(auto_login_username(), auto_login_account_id_.GetUserEmail());
 
   // Timer should stop when the account ID is unset.
   SetAutoLoginSettings("", kAutoLoginDelay2);
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
index babb4225..fec9718c 100644
--- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -76,7 +76,7 @@
 const char kSupervisedUserID[] = "supervised_user@locally-managed.localhost";
 const char kPassword[] = "test_password";
 
-const char kPublicSessionAccountId[] = "public_session_user@localhost";
+const char kPublicSessionUserEmail[] = "public_session_user@localhost";
 const int kAutoLoginNoDelay = 0;
 const int kAutoLoginShortDelay = 1;
 const int kAutoLoginLongDelay = 10000;
@@ -105,7 +105,7 @@
 
 class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest {
  protected:
-  ExistingUserControllerTest() : mock_login_display_(NULL) {}
+  ExistingUserControllerTest() {}
 
   ExistingUserController* existing_user_controller() {
     return ExistingUserController::current_controller();
@@ -196,8 +196,9 @@
     return existing_user_controller()->auto_login_timer_.get();
   }
 
-  const std::string& auto_login_username() const {
-    return existing_user_controller()->public_session_auto_login_username_;
+  AccountId auto_login_account_id() const {
+    return AccountId::FromUserEmail(
+        existing_user_controller()->public_session_auto_login_username_);
   }
 
   int auto_login_delay() const {
@@ -212,27 +213,29 @@
 
   // |mock_login_display_| is owned by the ExistingUserController, which calls
   // CreateLoginDisplay() on the |mock_login_display_host_| to get it.
-  MockLoginDisplay* mock_login_display_;
+  MockLoginDisplay* mock_login_display_ = nullptr;
   scoped_ptr<MockLoginDisplayHost> mock_login_display_host_;
 
   // Mock URLFetcher.
   MockURLFetcherFactory<SuccessFetcher> factory_;
 
+  const AccountId account_id_ = AccountId::FromUserEmail(kUsername);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(ExistingUserControllerTest);
 };
 
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, PRE_ExistingUserLogin) {
-  RegisterUser(kUsername);
+  RegisterUser(account_id_.GetUserEmail());
 }
 
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ExistingUserLogin) {
   EXPECT_CALL(*mock_login_display_, SetUIEnabled(false))
       .Times(2);
-  UserContext user_context(kUsername);
+  UserContext user_context(account_id_);
   user_context.SetGaiaID(kGaiaID);
   user_context.SetKey(Key(kPassword));
-  user_context.SetUserIDHash(kUsername);
+  user_context.SetUserIDHash(account_id_.GetUserEmail());
   test::UserSessionManagerTestApi session_manager_test_api(
       UserSessionManager::GetInstance());
   session_manager_test_api.InjectStubUserContext(user_context);
@@ -280,19 +283,19 @@
 
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerUntrustedTest,
                        ExistingUserLoginForbidden) {
-  UserContext user_context(kUsername);
+  UserContext user_context(account_id_);
   user_context.SetGaiaID(kGaiaID);
   user_context.SetKey(Key(kPassword));
-  user_context.SetUserIDHash(kUsername);
+  user_context.SetUserIDHash(account_id_.GetUserEmail());
   existing_user_controller()->Login(user_context, SigninSpecifics());
 }
 
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerUntrustedTest,
                        NewUserLoginForbidden) {
-  UserContext user_context(kUsername);
+  UserContext user_context(account_id_);
   user_context.SetGaiaID(kGaiaID);
   user_context.SetKey(Key(kPassword));
-  user_context.SetUserIDHash(kUsername);
+  user_context.SetUserIDHash(account_id_.GetUserEmail());
   existing_user_controller()->CompleteLogin(user_context);
 }
 
@@ -305,9 +308,9 @@
 
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerUntrustedTest,
                        SupervisedUserLoginForbidden) {
-  UserContext user_context(kSupervisedUserID);
+  UserContext user_context(AccountId::FromUserEmail(kSupervisedUserID));
   user_context.SetKey(Key(kPassword));
-  user_context.SetUserIDHash(kUsername);
+  user_context.SetUserIDHash(account_id_.GetUserEmail());
   existing_user_controller()->Login(user_context, SigninSpecifics());
 }
 
@@ -318,7 +321,8 @@
   SupervisedUserCreationScreen supervised_user_creation_screen(
       &mock_base_screen_delegate, &supervised_user_creation_screen_handler);
 
-  supervised_user_creation_screen.AuthenticateManager(kUsername, kPassword);
+  supervised_user_creation_screen.AuthenticateManager(
+      account_id_.GetUserEmail(), kPassword);
 }
 
 MATCHER_P(HasDetails, expected, "") {
@@ -328,23 +332,20 @@
 class ExistingUserControllerPublicSessionTest
     : public ExistingUserControllerTest {
  protected:
-  ExistingUserControllerPublicSessionTest()
-      : public_session_user_id_(policy::GenerateDeviceLocalAccountUserId(
-            kPublicSessionAccountId,
-            policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)) {
-  }
+  ExistingUserControllerPublicSessionTest() {}
 
   void SetUpOnMainThread() override {
     ExistingUserControllerTest::SetUpOnMainThread();
 
     // Wait for the public session user to be created.
     if (!user_manager::UserManager::Get()->IsKnownUser(
-            public_session_user_id_)) {
+            public_session_account_id_)) {
       content::WindowedNotificationObserver(
           chrome::NOTIFICATION_USER_LIST_CHANGED,
           base::Bind(&user_manager::UserManager::IsKnownUser,
                      base::Unretained(user_manager::UserManager::Get()),
-                     public_session_user_id_)).Wait();
+                     public_session_account_id_))
+          .Wait();
     }
 
     // Wait for the device local account policy to be installed.
@@ -353,7 +354,7 @@
             ->platform_part()
             ->browser_policy_connector_chromeos()
             ->GetDeviceLocalAccountPolicyService()
-            ->GetBrokerForUser(public_session_user_id_)
+            ->GetBrokerForUser(public_session_account_id_.GetUserEmail())
             ->core()
             ->store();
     if (!store->has_policy()) {
@@ -376,7 +377,7 @@
     em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
     em::DeviceLocalAccountInfoProto* account =
         proto.mutable_device_local_accounts()->add_account();
-    account->set_account_id(kPublicSessionAccountId);
+    account->set_account_id(kPublicSessionUserEmail);
     account->set_type(
         em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION);
     RefreshDevicePolicy();
@@ -384,15 +385,14 @@
     // Setup the device local account policy.
     policy::UserPolicyBuilder device_local_account_policy;
     device_local_account_policy.policy_data().set_username(
-        kPublicSessionAccountId);
+        kPublicSessionUserEmail);
     device_local_account_policy.policy_data().set_policy_type(
         policy::dm_protocol::kChromePublicAccountPolicyType);
     device_local_account_policy.policy_data().set_settings_entity_id(
-        kPublicSessionAccountId);
+        kPublicSessionUserEmail);
     device_local_account_policy.Build();
     session_manager_client()->set_device_local_account_policy(
-        kPublicSessionAccountId,
-        device_local_account_policy.GetBlob());
+        kPublicSessionUserEmail, device_local_account_policy.GetBlob());
   }
 
   void SetUpLoginDisplay() override {
@@ -431,7 +431,7 @@
     EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)).Times(AnyNumber());
   }
 
-  void SetAutoLoginPolicy(const std::string& username, int delay) {
+  void SetAutoLoginPolicy(const std::string& user_email, int delay) {
     // Wait until ExistingUserController has finished auto-login
     // configuration by observing the same settings that trigger
     // ConfigurePublicSessionAutoLogin.
@@ -444,7 +444,7 @@
     scoped_ptr<CrosSettings::ObserverSubscription> subscription1;
     if (!proto.has_device_local_accounts() ||
         !proto.device_local_accounts().has_auto_login_id() ||
-        proto.device_local_accounts().auto_login_id() != username) {
+        proto.device_local_accounts().auto_login_id() != user_email) {
       runner1 = new content::MessageLoopRunner;
       subscription1 = chromeos::CrosSettings::Get()->AddSettingsObserver(
           chromeos::kAccountsPrefDeviceLocalAccountAutoLoginId,
@@ -462,7 +462,7 @@
     }
 
     // Update the policy.
-    proto.mutable_device_local_accounts()->set_auto_login_id(username);
+    proto.mutable_device_local_accounts()->set_auto_login_id(user_email);
     proto.mutable_device_local_accounts()->set_auto_login_delay(delay);
     RefreshDevicePolicy();
 
@@ -491,7 +491,10 @@
     run_loop.Run();
   }
 
-  const std::string public_session_user_id_;
+  const AccountId public_session_account_id_ =
+      AccountId::FromUserEmail(policy::GenerateDeviceLocalAccountUserId(
+          kPublicSessionUserEmail,
+          policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ExistingUserControllerPublicSessionTest);
@@ -500,20 +503,20 @@
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest,
                        ConfigureAutoLoginUsingPolicy) {
   existing_user_controller()->OnSigninScreenReady();
-  EXPECT_EQ("", auto_login_username());
+  EXPECT_TRUE(!auto_login_account_id().is_valid());
   EXPECT_EQ(0, auto_login_delay());
   EXPECT_FALSE(auto_login_timer());
 
   // Set the policy.
-  SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay);
-  EXPECT_EQ(public_session_user_id_, auto_login_username());
+  SetAutoLoginPolicy(kPublicSessionUserEmail, kAutoLoginLongDelay);
+  EXPECT_EQ(public_session_account_id_, auto_login_account_id());
   EXPECT_EQ(kAutoLoginLongDelay, auto_login_delay());
   ASSERT_TRUE(auto_login_timer());
   EXPECT_TRUE(auto_login_timer()->IsRunning());
 
   // Unset the policy.
   SetAutoLoginPolicy("", 0);
-  EXPECT_EQ("", auto_login_username());
+  EXPECT_TRUE(!auto_login_account_id().is_valid());
   EXPECT_EQ(0, auto_login_delay());
   ASSERT_TRUE(auto_login_timer());
   EXPECT_FALSE(auto_login_timer()->IsRunning());
@@ -523,13 +526,13 @@
                        AutoLoginNoDelay) {
   // Set up mocks to check login success.
   UserContext user_context(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
-                           public_session_user_id_);
-  user_context.SetUserIDHash(user_context.GetUserID());
+                           public_session_account_id_.GetUserEmail());
+  user_context.SetUserIDHash(user_context.GetAccountId().GetUserEmail());
   ExpectSuccessfulLogin(user_context);
   existing_user_controller()->OnSigninScreenReady();
 
   // Start auto-login and wait for login tasks to complete.
-  SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginNoDelay);
+  SetAutoLoginPolicy(kPublicSessionUserEmail, kAutoLoginNoDelay);
   content::RunAllPendingInMessageLoop();
 }
 
@@ -537,8 +540,8 @@
                        AutoLoginShortDelay) {
   // Set up mocks to check login success.
   UserContext user_context(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
-                           public_session_user_id_);
-  user_context.SetUserIDHash(user_context.GetUserID());
+                           public_session_account_id_.GetUserEmail());
+  user_context.SetUserIDHash(user_context.GetAccountId().GetUserEmail());
   ExpectSuccessfulLogin(user_context);
   existing_user_controller()->OnSigninScreenReady();
 
@@ -546,7 +549,7 @@
       chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
       content::NotificationService::AllSources());
 
-  SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginShortDelay);
+  SetAutoLoginPolicy(kPublicSessionUserEmail, kAutoLoginShortDelay);
   ASSERT_TRUE(auto_login_timer());
   // Don't assert that timer is running: with the short delay sometimes
   // the trigger happens before the assert.  We've already tested that
@@ -569,14 +572,14 @@
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest,
                        LoginStopsAutoLogin) {
   // Set up mocks to check login success.
-  UserContext user_context(kUsername);
+  UserContext user_context(account_id_);
   user_context.SetGaiaID(kGaiaID);
   user_context.SetKey(Key(kPassword));
-  user_context.SetUserIDHash(user_context.GetUserID());
+  user_context.SetUserIDHash(user_context.GetAccountId().GetUserEmail());
   ExpectSuccessfulLogin(user_context);
 
   existing_user_controller()->OnSigninScreenReady();
-  SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay);
+  SetAutoLoginPolicy(kPublicSessionUserEmail, kAutoLoginLongDelay);
   EXPECT_TRUE(auto_login_timer());
 
   content::WindowedNotificationObserver profile_prepared_observer(
@@ -603,7 +606,7 @@
                        GuestModeLoginStopsAutoLogin) {
   EXPECT_CALL(*mock_login_display_, SetUIEnabled(false))
       .Times(2);
-  UserContext user_context(kUsername);
+  UserContext user_context(account_id_);
   user_context.SetGaiaID(kGaiaID);
   user_context.SetKey(Key(kPassword));
   test::UserSessionManagerTestApi session_manager_test_api(
@@ -611,7 +614,7 @@
   session_manager_test_api.InjectStubUserContext(user_context);
 
   existing_user_controller()->OnSigninScreenReady();
-  SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay);
+  SetAutoLoginPolicy(kPublicSessionUserEmail, kAutoLoginLongDelay);
   EXPECT_TRUE(auto_login_timer());
 
   // Login and check that it stopped the timer.
@@ -633,16 +636,16 @@
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest,
                        CompleteLoginStopsAutoLogin) {
   // Set up mocks to check login success.
-  UserContext user_context(kUsername);
+  UserContext user_context(account_id_);
   user_context.SetGaiaID(kGaiaID);
   user_context.SetKey(Key(kPassword));
-  user_context.SetUserIDHash(user_context.GetUserID());
+  user_context.SetUserIDHash(user_context.GetAccountId().GetUserEmail());
   ExpectSuccessfulLogin(user_context);
   EXPECT_CALL(*mock_login_display_host_, OnCompleteLogin())
       .Times(1);
 
   existing_user_controller()->OnSigninScreenReady();
-  SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay);
+  SetAutoLoginPolicy(kPublicSessionUserEmail, kAutoLoginLongDelay);
   EXPECT_TRUE(auto_login_timer());
 
   content::WindowedNotificationObserver profile_prepared_observer(
@@ -668,11 +671,11 @@
                        PublicSessionLoginStopsAutoLogin) {
   // Set up mocks to check login success.
   UserContext user_context(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
-                           public_session_user_id_);
-  user_context.SetUserIDHash(user_context.GetUserID());
+                           public_session_account_id_.GetUserEmail());
+  user_context.SetUserIDHash(user_context.GetAccountId().GetUserEmail());
   ExpectSuccessfulLogin(user_context);
   existing_user_controller()->OnSigninScreenReady();
-  SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay);
+  SetAutoLoginPolicy(kPublicSessionUserEmail, kAutoLoginLongDelay);
   EXPECT_TRUE(auto_login_timer());
 
   content::WindowedNotificationObserver profile_prepared_observer(
@@ -682,7 +685,7 @@
   // Login and check that it stopped the timer.
   existing_user_controller()->Login(
       UserContext(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
-                  public_session_user_id_),
+                  public_session_account_id_.GetUserEmail()),
       SigninSpecifics());
 
   EXPECT_TRUE(is_login_in_progress());
@@ -706,17 +709,17 @@
 
   // Check that the attempt to start a public session fails with an error.
   ExpectLoginFailure();
-  UserContext user_context(kUsername);
+  UserContext user_context(account_id_);
   user_context.SetGaiaID(kGaiaID);
   user_context.SetKey(Key(kPassword));
-  user_context.SetUserIDHash(user_context.GetUserID());
+  user_context.SetUserIDHash(user_context.GetAccountId().GetUserEmail());
   existing_user_controller()->Login(user_context, SigninSpecifics());
 }
 
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerPublicSessionTest,
                        NoAutoLoginWhenUntrusted) {
   // Start the public session timer.
-  SetAutoLoginPolicy(kPublicSessionAccountId, kAutoLoginLongDelay);
+  SetAutoLoginPolicy(kPublicSessionUserEmail, kAutoLoginLongDelay);
   existing_user_controller()->OnSigninScreenReady();
   EXPECT_TRUE(auto_login_timer());
 
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc
index 7b80284..f045f45 100644
--- a/chrome/browser/chromeos/login/kiosk_browsertest.cc
+++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -451,7 +451,6 @@
  public:
   KioskTest()
       : settings_helper_(false),
-        use_consumer_kiosk_mode_(true),
         fake_cws_(new FakeCWS) {
     set_exit_when_last_browser_closes(false);
   }
@@ -704,7 +703,7 @@
   }
 
   void RunAppLaunchNetworkDownTest() {
-    mock_user_manager()->SetActiveUser(kTestOwnerEmail);
+    mock_user_manager()->SetActiveUser(test_owner_account_id_);
     AppLaunchSigninScreen::SetUserManagerForTesting(mock_user_manager());
 
     // Mock network could be configured with owner's password.
@@ -788,8 +787,11 @@
   ScopedCrosSettingsTestHelper settings_helper_;
   scoped_ptr<FakeOwnerSettingsService> owner_settings_service_;
 
+  const AccountId test_owner_account_id_ =
+      AccountId::FromUserEmail(kTestOwnerEmail);
+
  private:
-  bool use_consumer_kiosk_mode_;
+  bool use_consumer_kiosk_mode_ = true;
   std::string test_app_id_;
   std::string test_app_version_;
   std::string test_crx_file_;
@@ -2017,7 +2019,7 @@
 
   void SetUpInProcessBrowserTestFixture() override {
     policy::DevicePolicyCrosTestHelper::MarkAsEnterpriseOwnedBy(
-        kTestOwnerEmail);
+        test_owner_account_id_.GetUserEmail());
     settings_helper_.SetCurrentUserIsOwner(false);
 
     KioskTest::SetUpInProcessBrowserTestFixture();
@@ -2228,7 +2230,7 @@
 IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest, AutolaunchWarning) {
   // Add a device owner.
   FakeChromeUserManager* user_manager = new FakeChromeUserManager();
-  user_manager->AddUser(kTestOwnerEmail);
+  user_manager->AddUser(test_owner_account_id_);
   ScopedUserManagerEnabler enabler(user_manager);
 
   // Set kiosk app to autolaunch.
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc
index eea1b56b..38514038a 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -197,7 +197,7 @@
 void ScreenLocker::OnAuthSuccess(const UserContext& user_context) {
   incorrect_passwords_count_ = 0;
   if (authentication_start_time_.is_null()) {
-    if (!user_context.GetUserID().empty())
+    if (user_context.GetAccountId().is_valid())
       LOG(ERROR) << "Start time is not set at authentication success";
   } else {
     base::TimeDelta delta = base::Time::Now() - authentication_start_time_;
@@ -206,12 +206,12 @@
   }
 
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
+      user_manager::UserManager::Get()->FindUser(user_context.GetAccountId());
   if (user) {
     if (!user->is_active()) {
       saved_ime_state_ = NULL;
       user_manager::UserManager::Get()->SwitchActiveUser(
-          user_context.GetUserID());
+          user_context.GetAccountId());
     }
     UserSessionManager::GetInstance()->UpdateEasyUnlockKeys(user_context);
   } else {
@@ -250,7 +250,7 @@
 }
 
 void ScreenLocker::Authenticate(const UserContext& user_context) {
-  LOG_ASSERT(IsUserLoggedIn(user_context.GetUserID()))
+  LOG_ASSERT(IsUserLoggedIn(user_context.GetAccountId().GetUserEmail()))
       << "Invalid user trying to unlock.";
 
   authentication_start_time_ = base::Time::Now();
@@ -259,7 +259,7 @@
 
   // Special case: supervised users. Use special authenticator.
   if (const user_manager::User* user =
-          FindUnlockUser(user_context.GetUserID())) {
+          FindUnlockUser(user_context.GetAccountId().GetUserEmail())) {
     if (user->GetType() == user_manager::USER_TYPE_SUPERVISED) {
       UserContext updated_context = ChromeUserManager::Get()
                                         ->GetSupervisedUserManager()
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
index c3bbabe..6632afe2 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
+++ b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
@@ -155,7 +155,7 @@
   EXPECT_GT(lock_bounds.width(), 10);
   EXPECT_GT(lock_bounds.height(), 10);
 
-  UserContext user_context(chromeos::login::kStubUser);
+  UserContext user_context(login::StubAccountId());
   user_context.SetKey(Key("pass"));
   tester->InjectStubUserContext(user_context);
   EXPECT_TRUE(tester->IsLocked());
@@ -212,7 +212,7 @@
     EXPECT_FALSE(window_state->hide_shelf_when_fullscreen());
     EXPECT_TRUE(tester->IsLocked());
   }
-  UserContext user_context(chromeos::login::kStubUser);
+  UserContext user_context(login::StubAccountId());
   user_context.SetKey(Key("pass"));
   tester->InjectStubUserContext(user_context);
   tester->EnterPassword("pass");
diff --git a/chrome/browser/chromeos/login/login_browsertest.cc b/chrome/browser/chromeos/login/login_browsertest.cc
index a43297d0..3e8ef591 100644
--- a/chrome/browser/chromeos/login/login_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_browsertest.cc
@@ -161,7 +161,7 @@
 
     StartGaiaAuthOffline();
 
-    UserContext user_context(kTestUser);
+    UserContext user_context(AccountId::FromUserEmail(kTestUser));
     user_context.SetGaiaID(kGaiaId);
     user_context.SetKey(Key(kPassword));
     SetExpectedCredentials(user_context);
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc
index d2430746a..5266a31 100644
--- a/chrome/browser/chromeos/login/login_manager_test.cc
+++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -48,7 +48,8 @@
 const char kTestRefreshToken2[] = "fake-refresh-token-2";
 
 UserContext CreateUserContext(const std::string& user_id) {
-  UserContext user_context(user_id);
+  UserContext user_context(AccountId::FromUserEmailGaiaId(
+      user_id, LoginManagerTest::GetGaiaIDForUserID(user_id)));
   user_context.SetGaiaID(LoginManagerTest::GetGaiaIDForUserID(user_id));
   user_context.SetKey(Key("password"));
   if (user_id == LoginManagerTest::kEnterpriseUser1) {
@@ -168,7 +169,7 @@
     return false;
   if (const user_manager::User* active_user =
           user_manager::UserManager::Get()->GetActiveUser())
-    return active_user->email() == user_context.GetUserID();
+    return active_user->GetAccountId() == user_context.GetAccountId();
   return false;
 }
 
@@ -189,7 +190,7 @@
   for (user_manager::UserList::const_iterator it = logged_users.begin();
        it != logged_users.end();
        ++it) {
-    if ((*it)->email() == user_context.GetUserID())
+    if ((*it)->GetAccountId() == user_context.GetAccountId())
       return true;
   }
   return false;
diff --git a/chrome/browser/chromeos/login/reauth_stats.cc b/chrome/browser/chromeos/login/reauth_stats.cc
index f442c974..f3924659 100644
--- a/chrome/browser/chromeos/login/reauth_stats.cc
+++ b/chrome/browser/chromeos/login/reauth_stats.cc
@@ -9,26 +9,26 @@
 
 namespace chromeos {
 
-void RecordReauthReason(const std::string& user_id, ReauthReason reason) {
+void RecordReauthReason(const AccountId& account_id, ReauthReason reason) {
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
   int old_reason;
   // We record only the first value, skipping everything else, except "none"
   // value, which is used to reset the current state.
-  if (!user_manager->FindReauthReason(user_id, &old_reason) ||
+  if (!user_manager->FindReauthReason(account_id, &old_reason) ||
       (static_cast<ReauthReason>(old_reason) == ReauthReason::NONE &&
        reason != ReauthReason::NONE)) {
-    user_manager->UpdateReauthReason(user_id, static_cast<int>(reason));
+    user_manager->UpdateReauthReason(account_id, static_cast<int>(reason));
   }
 }
 
-void SendReauthReason(const std::string& user_id) {
+void SendReauthReason(const AccountId& account_id) {
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
   int reauth_reason;
-  if (user_manager->FindReauthReason(user_id, &reauth_reason) &&
+  if (user_manager->FindReauthReason(account_id, &reauth_reason) &&
       static_cast<ReauthReason>(reauth_reason) != ReauthReason::NONE) {
     UMA_HISTOGRAM_ENUMERATION("Login.ReauthReason", reauth_reason,
                               NUM_REAUTH_FLOW_REASONS);
-    user_manager->UpdateReauthReason(user_id,
+    user_manager->UpdateReauthReason(account_id,
                                      static_cast<int>(ReauthReason::NONE));
   }
 }
diff --git a/chrome/browser/chromeos/login/reauth_stats.h b/chrome/browser/chromeos/login/reauth_stats.h
index 99bd159..d62489f 100644
--- a/chrome/browser/chromeos/login/reauth_stats.h
+++ b/chrome/browser/chromeos/login/reauth_stats.h
@@ -7,6 +7,8 @@
 
 #include <string>
 
+class AccountId;
+
 namespace chromeos {
 
 // Track all the ways a user may be sent through the re-auth flow.
@@ -51,8 +53,8 @@
   NUM_REAUTH_FLOW_REASONS,
 };
 
-void RecordReauthReason(const std::string& user_id, ReauthReason reason);
-void SendReauthReason(const std::string& user_id);
+void RecordReauthReason(const AccountId& account_id, ReauthReason reason);
+void SendReauthReason(const AccountId& account_id);
 
 }  // namespace chromeos
 
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index f1349d56..6c88365 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -968,11 +968,13 @@
 
   // Pretend that the test users' OAuth tokens are valid.
   user_manager::UserManager::Get()->SaveUserOAuthStatus(
-      kFirstSAMLUserEmail, user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
+      AccountId::FromUserEmail(kFirstSAMLUserEmail),
+      user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
   user_manager::UserManager::Get()->SaveUserOAuthStatus(
-      kNonSAMLUserEmail, user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
+      AccountId::FromUserEmail(kNonSAMLUserEmail),
+      user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
   user_manager::UserManager::Get()->SaveUserOAuthStatus(
-      kDifferentDomainSAMLUserEmail,
+      AccountId::FromUserEmail(kDifferentDomainSAMLUserEmail),
       user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
 
   // Set up fake networks.
diff --git a/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.cc b/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.cc
index 826aa1c..ede2bee 100644
--- a/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.cc
+++ b/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.cc
@@ -45,14 +45,14 @@
     NOTREACHED();
     return;
   }
-  const std::string& user_id = user->email();
+  const AccountId account_id = user->GetAccountId();
 
   if (auth_flow == UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML) {
     // The user went through online authentication and GAIA did not redirect to
     // a SAML IdP. No limit applies in this case. Clear the time of last login
     // with SAML and the flag enforcing online login, then return.
     prefs->ClearPref(prefs::kSAMLLastGAIASignInTime);
-    user_manager::UserManager::Get()->SaveForceOnlineSignin(user_id, false);
+    user_manager::UserManager::Get()->SaveForceOnlineSignin(account_id, false);
     return;
   }
 
@@ -62,7 +62,7 @@
     // enforcing online login. The flag will be set again when the limit
     // expires. If the limit already expired (e.g. because it was set to zero),
     // the flag will be set again immediately.
-    user_manager::UserManager::Get()->SaveForceOnlineSignin(user_id, false);
+    user_manager::UserManager::Get()->SaveForceOnlineSignin(account_id, false);
     prefs->SetInt64(prefs::kSAMLLastGAIASignInTime,
                     clock_->Now().ToInternalValue());
   }
@@ -143,8 +143,9 @@
     return;
   }
 
-  user_manager::UserManager::Get()->SaveForceOnlineSignin(user->email(), true);
-  RecordReauthReason(user->email(), ReauthReason::SAML_REAUTH_POLICY);
+  user_manager::UserManager::Get()->SaveForceOnlineSignin(user->GetAccountId(),
+                                                          true);
+  RecordReauthReason(user->GetAccountId(), ReauthReason::SAML_REAUTH_POLICY);
   offline_signin_limit_timer_.reset();
 }
 
diff --git a/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_unittest.cc b/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_unittest.cc
index c82a3985..bf8fbfe 100644
--- a/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_unittest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_unittest.cc
@@ -46,6 +46,9 @@
   void CreateLimiter();
 
   void SetUpUserManager();
+
+  const AccountId test_account_id_ = AccountId::FromUserEmail(kTestUser);
+
   TestingPrefServiceSimple* GetTestingLocalState();
 
   scoped_refptr<base::TestSimpleTaskRunner> runner_;
@@ -69,8 +72,7 @@
       runner_handle_(runner_),
       user_manager_(new MockUserManager),
       user_manager_enabler_(user_manager_),
-      limiter_(NULL) {
-}
+      limiter_(NULL) {}
 
 SAMLOfflineSigninLimiterTest::~SAMLOfflineSigninLimiterTest() {
   DestroyLimiter();
@@ -103,7 +105,7 @@
   profile_.reset(new TestingProfile);
 
   SAMLOfflineSigninLimiterFactory::SetClockForTesting(&clock_);
-  user_manager_->AddUser(kTestUser);
+  user_manager_->AddUser(test_account_id_);
   profile_->set_profile_name(kTestUser);
   clock_.Advance(base::TimeDelta::FromHours(1));
 
@@ -129,8 +131,10 @@
   // Authenticate against GAIA without SAML. Verify that the flag enforcing
   // online login and the time of last login with SAML are cleared.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
 
   const PrefService::Preference* pref =
@@ -149,8 +153,10 @@
   CreateLimiter();
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_OFFLINE);
 
   pref = prefs->FindPreference(prefs::kSAMLLastGAIASignInTime);
@@ -174,8 +180,10 @@
   // Authenticate against GAIA without SAML. Verify that the flag enforcing
   // online login and the time of last login with SAML are cleared.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
 
   const PrefService::Preference* pref =
@@ -194,8 +202,10 @@
   CreateLimiter();
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_OFFLINE);
 
   pref = prefs->FindPreference(prefs::kSAMLLastGAIASignInTime);
@@ -219,8 +229,10 @@
   // Authenticate against GAIA without SAML. Verify that the flag enforcing
   // online login and the time of last login with SAML are cleared.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
 
   const PrefService::Preference* pref =
@@ -239,8 +251,10 @@
   CreateLimiter();
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_OFFLINE);
 
   pref = prefs->FindPreference(prefs::kSAMLLastGAIASignInTime);
@@ -264,8 +278,10 @@
   // Authenticate against GAIA without SAML. Verify that the flag enforcing
   // online login and the time of last login with SAML are cleared.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
 
   const PrefService::Preference* pref =
@@ -293,8 +309,10 @@
   // Authenticate against GAIA without SAML. Verify that the flag enforcing
   // online login and the time of last login with SAML are cleared.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
 
   const PrefService::Preference* pref =
@@ -325,8 +343,10 @@
   // Authenticate against GAIA without SAML. Verify that the flag enforcing
   // online login and the time of last login with SAML are cleared.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
 
   const PrefService::Preference* pref =
@@ -344,8 +364,10 @@
   // Authenticate against GAIA with SAML. Verify that the flag enforcing online
   // login is cleared and the time of last login with SAML is set.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITH_SAML);
 
   base::Time last_gaia_signin_time = base::Time::FromInternalValue(
@@ -366,8 +388,10 @@
   CreateLimiter();
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITH_SAML);
 
   last_gaia_signin_time = base::Time::FromInternalValue(
@@ -389,8 +413,10 @@
   CreateLimiter();
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_OFFLINE);
 
   last_gaia_signin_time = base::Time::FromInternalValue(
@@ -407,8 +433,10 @@
   // set.
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(1);
   runner_->RunPendingTasks();
 }
 
@@ -421,8 +449,10 @@
   // Authenticate against GAIA with SAML. Verify that the flag enforcing online
   // login is cleared and the time of last login with SAML is set.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITH_SAML);
 
   base::Time last_gaia_signin_time = base::Time::FromInternalValue(
@@ -443,8 +473,10 @@
   CreateLimiter();
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITH_SAML);
 
   last_gaia_signin_time = base::Time::FromInternalValue(
@@ -466,8 +498,10 @@
   CreateLimiter();
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_OFFLINE);
 
   last_gaia_signin_time = base::Time::FromInternalValue(
@@ -489,10 +523,10 @@
   // last login with SAML is set.
   CreateLimiter();
   Sequence sequence;
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false))
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
       .Times(1)
       .InSequence(sequence);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true))
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
       .Times(1)
       .InSequence(sequence);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITH_SAML);
@@ -511,8 +545,10 @@
   // Authenticate against GAIA with SAML. Verify that the flag enforcing online
   // login is cleared and the time of last login with SAML is set.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITH_SAML);
 
   const base::Time last_gaia_signin_time = base::Time::FromInternalValue(
@@ -525,8 +561,10 @@
   // Set a zero time limit. Verify that the flag enforcing online login is set.
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(1);
   prefs->SetInteger(prefs::kSAMLOfflineSigninTimeLimit, 0);
 }
 
@@ -536,8 +574,10 @@
   // Authenticate against GAIA with SAML. Verify that the flag enforcing online
   // login is cleared and the time of last login with SAML is set.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITH_SAML);
 
   const base::Time last_gaia_signin_time = base::Time::FromInternalValue(
@@ -554,8 +594,10 @@
   // changed.
   Mock::VerifyAndClearExpectations(user_manager_);
   SetUpUserManager();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   runner_->RunUntilIdle();
 }
 
@@ -572,8 +614,10 @@
   // Authenticate against GAIA with SAML. Verify that the flag enforcing online
   // login is cleared and the time of last login with SAML is updated.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(1);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(0);
   limiter_->SignedIn(UserContext::AUTH_FLOW_GAIA_WITH_SAML);
 
   const base::Time last_gaia_signin_time = base::Time::FromInternalValue(
@@ -598,8 +642,10 @@
   // Authenticate offline. Verify that the flag enforcing online login is
   // set and the time of last login with SAML is not changed.
   CreateLimiter();
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, false)).Times(0);
-  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(kTestUser, true)).Times(1);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, false))
+      .Times(0);
+  EXPECT_CALL(*user_manager_, SaveForceOnlineSignin(test_account_id_, true))
+      .Times(1);
   limiter_->SignedIn(UserContext::AUTH_FLOW_OFFLINE);
 
   const base::Time last_gaia_signin_time = base::Time::FromInternalValue(
diff --git a/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.cc b/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.cc
index 37737c7c..e309e136 100644
--- a/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.cc
+++ b/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.cc
@@ -21,6 +21,7 @@
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/policy_types.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "components/user_manager/user_type.h"
@@ -50,7 +51,7 @@
   for (user_manager::UserList::const_iterator it = users.begin();
        it != users.end(); ++it) {
     if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT)
-      OnPolicyUpdated((*it)->GetUserID());
+      OnPolicyUpdated((*it)->GetAccountId().GetUserEmail());
   }
 }
 
@@ -143,8 +144,8 @@
 
 void ChromeUserSelectionScreen::SetPublicSessionDisplayName(
     const std::string& user_id) {
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id);
+  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+      AccountId::FromUserEmail(user_id));
   if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
     return;
 
diff --git a/chrome/browser/chromeos/login/screens/user_image_screen.cc b/chrome/browser/chromeos/login/screens/user_image_screen.cc
index 7805543..091e8e73 100644
--- a/chrome/browser/chromeos/login/screens/user_image_screen.cc
+++ b/chrome/browser/chromeos/login/screens/user_image_screen.cc
@@ -111,7 +111,7 @@
 void UserImageScreen::HideCurtain() {
   // Skip user image selection for ephemeral users.
   if (user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
-          GetUser()->GetUserID())) {
+          GetUser()->GetAccountId())) {
     ExitScreen();
   }
   if (view_)
@@ -227,7 +227,8 @@
 }
 
 UserImageManager* UserImageScreen::GetUserImageManager() {
-  return ChromeUserManager::Get()->GetUserImageManager(GetUser()->email());
+  return ChromeUserManager::Get()->GetUserImageManager(
+      GetUser()->GetAccountId());
 }
 
 UserImageSyncObserver* UserImageScreen::GetSyncObserver() {
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
index df270c44..37bb77b 100644
--- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc
+++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
@@ -22,7 +22,7 @@
 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
 #include "components/proximity_auth/screenlock_bridge.h"
-#include "components/user_manager/user_id.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #include "components/user_manager/user_type.h"
 #include "ui/base/user_activity/user_activity_detector.h"
@@ -142,14 +142,13 @@
     AuthType auth_type,
     const std::vector<std::string>* public_session_recommended_locales,
     base::DictionaryValue* user_dict) {
-  const user_manager::UserID user_id = user->email();
   const bool is_public_session =
       user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
   const bool is_legacy_supervised_user =
       user->GetType() == user_manager::USER_TYPE_SUPERVISED;
   const bool is_child_user = user->GetType() == user_manager::USER_TYPE_CHILD;
 
-  user_dict->SetString(kKeyUsername, user_id);
+  user_dict->SetString(kKeyUsername, user->GetAccountId().GetUserEmail());
   user_dict->SetString(kKeyEmailAddress, user->display_email());
   user_dict->SetString(kKeyDisplayName, user->GetDisplayName());
   user_dict->SetBoolean(kKeyPublicAccount, is_public_session);
@@ -173,7 +172,8 @@
 void UserSelectionScreen::FillKnownUserPrefs(user_manager::User* user,
                                              base::DictionaryValue* user_dict) {
   std::string gaia_id;
-  if (user_manager::UserManager::Get()->FindGaiaID(user->email(), &gaia_id)) {
+  if (user_manager::UserManager::Get()->FindGaiaID(user->GetAccountId(),
+                                                   &gaia_id)) {
     user_dict->SetString(kKeyGaiaID, gaia_id);
   }
 }
@@ -239,7 +239,7 @@
   // At this point the reason for invalid token should be already set. If not,
   // this might be a leftover from an old version.
   if (token_status == user_manager::User::OAUTH2_TOKEN_STATUS_INVALID)
-    RecordReauthReason(user->email(), ReauthReason::OTHER);
+    RecordReauthReason(user->GetAccountId(), ReauthReason::OTHER);
 
   return user->force_online_signin() ||
          (token_status == user_manager::User::OAUTH2_TOKEN_STATUS_INVALID) ||
@@ -404,7 +404,7 @@
   SendUserList();
 }
 
-void UserSelectionScreen::CheckUserStatus(const std::string& user_id) {
+void UserSelectionScreen::CheckUserStatus(const std::string& user_email) {
   // No checks on lock screen.
   if (ScreenLocker::default_screen_locker())
     return;
@@ -414,20 +414,21 @@
         new TokenHandleUtil(user_manager::UserManager::Get()));
   }
 
-  if (token_handle_util_->HasToken(user_id)) {
+  const AccountId account_id = AccountId::FromUserEmail(user_email);
+  if (token_handle_util_->HasToken(account_id)) {
     token_handle_util_->CheckToken(
-        user_id, base::Bind(&UserSelectionScreen::OnUserStatusChecked,
-                            weak_factory_.GetWeakPtr()));
+        account_id, base::Bind(&UserSelectionScreen::OnUserStatusChecked,
+                               weak_factory_.GetWeakPtr()));
   }
 }
 
 void UserSelectionScreen::OnUserStatusChecked(
-    const user_manager::UserID& user_id,
+    const AccountId& account_id,
     TokenHandleUtil::TokenHandleStatus status) {
   if (status == TokenHandleUtil::INVALID) {
-    RecordReauthReason(user_id, ReauthReason::INVALID_TOKEN_HANDLE);
-    token_handle_util_->MarkHandleInvalid(user_id);
-    SetAuthType(user_id, ONLINE_SIGN_IN, base::string16());
+    RecordReauthReason(account_id, ReauthReason::INVALID_TOKEN_HANDLE);
+    token_handle_util_->MarkHandleInvalid(account_id);
+    SetAuthType(account_id.GetUserEmail(), ONLINE_SIGN_IN, base::string16());
   }
 }
 
@@ -498,7 +499,7 @@
                                             const std::string& key_label) {
   DCHECK_EQ(GetScreenType(), SIGNIN_SCREEN);
 
-  UserContext user_context(user_id);
+  UserContext user_context(AccountId::FromUserEmail(user_id));
   user_context.SetAuthFlow(UserContext::AUTH_FLOW_EASY_UNLOCK);
   user_context.SetKey(Key(secret));
   user_context.GetKey()->SetLabel(key_label);
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.h b/chrome/browser/chromeos/login/screens/user_selection_screen.h
index f52657a..0c2879b5 100644
--- a/chrome/browser/chromeos/login/screens/user_selection_screen.h
+++ b/chrome/browser/chromeos/login/screens/user_selection_screen.h
@@ -17,9 +17,9 @@
 #include "chrome/browser/chromeos/login/ui/models/user_board_model.h"
 #include "components/proximity_auth/screenlock_bridge.h"
 #include "components/user_manager/user.h"
-#include "components/user_manager/user_id.h"
 #include "ui/base/user_activity/user_activity_observer.h"
 
+class AccountId;
 class EasyUnlockService;
 
 namespace chromeos {
@@ -122,7 +122,7 @@
   EasyUnlockService* GetEasyUnlockServiceForUser(
       const std::string& user_id) const;
 
-  void OnUserStatusChecked(const user_manager::UserID& user_id,
+  void OnUserStatusChecked(const AccountId& account_id,
                            TokenHandleUtil::TokenHandleStatus status);
 
   // Whether to show guest login.
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 1efaa70..7c2aa36 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -452,7 +452,8 @@
   delegate_ = delegate;
   start_session_type_ = start_session_type;
 
-  VLOG(1) << "Starting session for " << user_context.GetUserID();
+  VLOG(1) << "Starting session for "
+          << user_context.GetAccountId().GetUserEmail();
 
   PreStartSession();
   CreateUserSession(user_context, has_auth_cookies);
@@ -466,7 +467,7 @@
 
   if (!user_context.GetDeviceId().empty()) {
     user_manager::UserManager::Get()->SetKnownUserDeviceId(
-        user_context.GetUserID(), user_context.GetDeviceId());
+        user_context.GetAccountId(), user_context.GetDeviceId());
   }
 
   PrepareProfile();
@@ -702,7 +703,7 @@
 }
 
 bool UserSessionManager::NeedsToUpdateEasyUnlockKeys() const {
-  return !user_context_.GetUserID().empty() &&
+  return user_context_.GetAccountId().is_valid() &&
          user_manager::User::TypeHasGaiaAccount(user_context_.GetUserType()) &&
          user_context_.GetKey() && !user_context_.GetKey()->GetSecret().empty();
 }
@@ -760,7 +761,7 @@
   if (!connection_error) {
     // We are in one of "done" states here.
     user_manager::UserManager::Get()->SaveUserOAuthStatus(
-        user_manager::UserManager::Get()->GetLoggedInUser()->email(),
+        user_manager::UserManager::Get()->GetLoggedInUser()->GetAccountId(),
         user_status);
   }
 
@@ -863,7 +864,7 @@
 void UserSessionManager::StoreUserContextDataBeforeProfileIsCreated() {
   // Store obfuscated GAIA ID.
   if (!user_context_.GetGaiaID().empty()) {
-    user_manager::UserManager::Get()->UpdateGaiaID(user_context_.GetUserID(),
+    user_manager::UserManager::Get()->UpdateGaiaID(user_context_.GetAccountId(),
                                                    user_context_.GetGaiaID());
   }
 }
@@ -871,8 +872,8 @@
 void UserSessionManager::StartCrosSession() {
   BootTimesRecorder* btl = BootTimesRecorder::Get();
   btl->AddLoginTimeMarker("StartSession-Start", false);
-  DBusThreadManager::Get()->GetSessionManagerClient()->
-      StartSession(user_context_.GetUserID());
+  DBusThreadManager::Get()->GetSessionManagerClient()->StartSession(
+      user_context_.GetAccountId().GetUserEmail());
   btl->AddLoginTimeMarker("StartSession-End", false);
 }
 
@@ -880,15 +881,14 @@
   BootTimesRecorder* btl = BootTimesRecorder::Get();
   btl->AddLoginTimeMarker("UserLoggedIn-Start", false);
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
-  user_manager->UserLoggedIn(user_context_.GetUserID(),
-                             user_context_.GetUserIDHash(),
-                             false);
+  user_manager->UserLoggedIn(user_context_.GetAccountId(),
+                             user_context_.GetUserIDHash(), false);
   btl->AddLoginTimeMarker("UserLoggedIn-End", false);
 }
 
 void UserSessionManager::PrepareProfile() {
-  bool is_demo_session =
-      DemoAppLauncher::IsDemoAppSession(user_context_.GetUserID());
+  const bool is_demo_session = DemoAppLauncher::IsDemoAppSession(
+      user_context_.GetAccountId().GetUserEmail());
 
   // TODO(nkostylev): Figure out whether demo session is using the right profile
   // path or not. See https://codereview.chromium.org/171423009
@@ -914,9 +914,8 @@
       // Profile is created, extensions and promo resources are initialized.
       // At this point all other Chrome OS services will be notified that it is
       // safe to use this profile.
-      UserProfileInitialized(profile,
-                             is_incognito_profile,
-                             user_context.GetUserID());
+      UserProfileInitialized(profile, is_incognito_profile,
+                             user_context.GetAccountId());
       break;
     case Profile::CREATE_STATUS_LOCAL_FAIL:
     case Profile::CREATE_STATUS_REMOTE_FAIL:
@@ -966,8 +965,8 @@
     if (gaia_id.empty()) {
       AccountTrackerService* account_tracker =
           AccountTrackerServiceFactory::GetForProfile(profile);
-      AccountInfo info =
-          account_tracker->FindAccountInfoByEmail(user_context.GetUserID());
+      const AccountInfo info = account_tracker->FindAccountInfoByEmail(
+          user_context.GetAccountId().GetUserEmail());
       gaia_id = info.gaia;
       DCHECK(!gaia_id.empty());
     }
@@ -977,22 +976,22 @@
     // profiles that might not have it set yet).
     SigninManagerBase* signin_manager =
         SigninManagerFactory::GetForProfile(profile);
-    signin_manager->SetAuthenticatedAccountInfo(gaia_id,
-                                                user_context.GetUserID());
+    signin_manager->SetAuthenticatedAccountInfo(
+        gaia_id, user_context.GetAccountId().GetUserEmail());
 
     // Backfill GAIA ID in user prefs stored in Local State.
     std::string tmp_gaia_id;
     user_manager::UserManager* user_manager = user_manager::UserManager::Get();
-    if (!user_manager->FindGaiaID(user_context.GetUserID(), &tmp_gaia_id) &&
+    if (!user_manager->FindGaiaID(user_context.GetAccountId(), &tmp_gaia_id) &&
         !gaia_id.empty()) {
-      user_manager->UpdateGaiaID(user_context.GetUserID(), gaia_id);
+      user_manager->UpdateGaiaID(user_context.GetAccountId(), gaia_id);
     }
   }
 }
 
 void UserSessionManager::UserProfileInitialized(Profile* profile,
                                                 bool is_incognito_profile,
-                                                const std::string& user_id) {
+                                                const AccountId& account_id) {
   // Demo user signed in.
   if (is_incognito_profile) {
     profile->OnLogin();
@@ -1019,9 +1018,10 @@
     // first.
     bool transfer_saml_auth_cookies_on_subsequent_login = false;
     if (has_auth_cookies_ &&
-        g_browser_process->platform_part()->
-            browser_policy_connector_chromeos()->GetUserAffiliation(user_id) ==
-                policy::USER_AFFILIATION_MANAGED) {
+        g_browser_process->platform_part()
+                ->browser_policy_connector_chromeos()
+                ->GetUserAffiliation(account_id.GetUserEmail()) ==
+            policy::USER_AFFILIATION_MANAGED) {
       CrosSettings::Get()->GetBoolean(
           kAccountsPrefTransferSAMLCookies,
           &transfer_saml_auth_cookies_on_subsequent_login);
@@ -1090,7 +1090,7 @@
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
   if (user_manager->IsLoggedInAsUserWithGaiaAccount()) {
     if (user_context_.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML)
-      user_manager->UpdateUsingSAML(user_context_.GetUserID(), true);
+      user_manager->UpdateUsingSAML(user_context_.GetAccountId(), true);
     SAMLOfflineSigninLimiter* saml_offline_signin_limiter =
         SAMLOfflineSigninLimiterFactory::GetForProfile(profile);
     if (saml_offline_signin_limiter)
@@ -1123,10 +1123,10 @@
   user_context_.ClearSecrets();
   if (TokenHandlesEnabled()) {
     CreateTokenUtilIfMissing();
-    if (token_handle_util_->ShouldObtainHandle(user->GetUserID())) {
+    if (token_handle_util_->ShouldObtainHandle(user->GetAccountId())) {
       if (!token_handle_fetcher_.get()) {
         token_handle_fetcher_.reset(new TokenHandleFetcher(
-            token_handle_util_.get(), user->GetUserID()));
+            token_handle_util_.get(), user->GetAccountId()));
         token_handle_fetcher_->BackfillToken(
             profile, base::Bind(&UserSessionManager::OnTokenHandleObtained,
                                 weak_factory_.GetWeakPtr()));
@@ -1438,7 +1438,7 @@
   DCHECK(!user_already_logged_in);
 
   if (!user_already_logged_in) {
-    UserContext user_context(user_id);
+    UserContext user_context(AccountId::FromUserEmail(user_id));
     user_context.SetUserIDHash(user_id_hash);
     user_context.SetIsUsingOAuth(false);
 
@@ -1476,7 +1476,7 @@
   // TODO(xiyuan): Fix inconsistency user type of |user_context| introduced in
   // authenticator.
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
+      user_manager::UserManager::Get()->FindUser(user_context.GetAccountId());
   if (!user || !user->HasGaiaAccount())
     return;
 
@@ -1501,7 +1501,7 @@
   key_manager->RefreshKeys(
       user_context, *device_list,
       base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished, AsWeakPtr(),
-                 user_context.GetUserID()));
+                 user_context.GetAccountId().GetUserEmail()));
 }
 
 net::URLRequestContextGetter*
@@ -1562,8 +1562,8 @@
   if (!easy_unlock_key_ops_finished_callback_.is_null())
     easy_unlock_key_ops_finished_callback_.Run();
 
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id);
+  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+      AccountId::FromUserEmail(user_id));
   EasyUnlockService* easy_unlock_service =
         EasyUnlockService::GetForUser(*user);
   easy_unlock_service->CheckCryptohomeKeysAndMaybeHardlock();
@@ -1724,9 +1724,9 @@
 void UserSessionManager::OnOAuth2TokensFetched(UserContext context) {
   if (StartupUtils::IsWebviewSigninEnabled() && TokenHandlesEnabled()) {
     CreateTokenUtilIfMissing();
-    if (token_handle_util_->ShouldObtainHandle(context.GetUserID())) {
+    if (token_handle_util_->ShouldObtainHandle(context.GetAccountId())) {
       token_handle_fetcher_.reset(new TokenHandleFetcher(
-          token_handle_util_.get(), context.GetUserID()));
+          token_handle_util_.get(), context.GetAccountId()));
       token_handle_fetcher_->FillForNewUser(
           context.GetAccessToken(),
           base::Bind(&UserSessionManager::OnTokenHandleObtained,
@@ -1735,7 +1735,7 @@
   }
 }
 
-void UserSessionManager::OnTokenHandleObtained(const user_manager::UserID& id,
+void UserSessionManager::OnTokenHandleObtained(const AccountId& account_id,
                                                bool success) {
   if (!success)
     LOG(ERROR) << "OAuth2 token handle fetch failed.";
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.h b/chrome/browser/chromeos/login/session/user_session_manager.h
index dee2273..755132cd 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.h
+++ b/chrome/browser/chromeos/login/session/user_session_manager.h
@@ -24,6 +24,7 @@
 #include "net/base/network_change_notifier.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 
+class AccountId;
 class GURL;
 class PrefRegistrySimple;
 class PrefService;
@@ -300,7 +301,7 @@
   // Profile is created, extensions and promo resources are initialized.
   void UserProfileInitialized(Profile* profile,
                               bool is_incognito_profile,
-                              const std::string& user_id);
+                              const AccountId& account_id);
 
   // Callback to resume profile creation after transferring auth data from
   // the authentication profile.
@@ -368,7 +369,7 @@
       const locale_util::LanguageSwitchResult& result);
 
   // Callback invoked when |token_handle_util_| has finished.
-  void OnTokenHandleObtained(const user_manager::UserID& id, bool success);
+  void OnTokenHandleObtained(const AccountId& account_id, bool success);
 
   // Returns |true| if token handles should be used on this device.
   bool TokenHandlesEnabled();
diff --git a/chrome/browser/chromeos/login/signin/auth_sync_observer.cc b/chrome/browser/chromeos/login/signin/auth_sync_observer.cc
index 8fa57495..99b50e53 100644
--- a/chrome/browser/chromeos/login/signin/auth_sync_observer.cc
+++ b/chrome/browser/chromeos/login/signin/auth_sync_observer.cc
@@ -62,14 +62,14 @@
     // TODO(nkostylev): Remove after crosbug.com/25978 is implemented.
     LOG(WARNING) << "Invalidate OAuth token because of a sync error: "
                  << sync_service->GetAuthError().ToString();
-    std::string email = user->email();
-    DCHECK(!email.empty());
+    const AccountId& account_id = user->GetAccountId();
+    DCHECK(account_id.is_valid());
     // TODO(nkostyelv): Change observer after active user has changed.
     user_manager::User::OAuthTokenStatus old_status =
         user->oauth_token_status();
     user_manager::UserManager::Get()->SaveUserOAuthStatus(
-        email, user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
-    RecordReauthReason(email, ReauthReason::SYNC_FAILED);
+        account_id, user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
+    RecordReauthReason(account_id, ReauthReason::SYNC_FAILED);
     if (user->GetType() == user_manager::USER_TYPE_SUPERVISED &&
         old_status != user_manager::User::OAUTH2_TOKEN_STATUS_INVALID) {
        // Attempt to restore token from file.
@@ -89,7 +89,7 @@
       LOG(ERROR) <<
           "Got an incorrectly invalidated token case, restoring token status.";
       user_manager::UserManager::Get()->SaveUserOAuthStatus(
-          user->email(), user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
+          user->GetAccountId(), user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
        content::RecordAction(
            base::UserMetricsAction("ManagedUsers_Chromeos_Sync_Recovered"));
     }
diff --git a/chrome/browser/chromeos/login/signin/device_id_browsertest.cc b/chrome/browser/chromeos/login/signin/device_id_browsertest.cc
index e210e9a..ad33d48 100644
--- a/chrome/browser/chromeos/login/signin/device_id_browsertest.cc
+++ b/chrome/browser/chromeos/login/signin/device_id_browsertest.cc
@@ -57,14 +57,14 @@
     OobeBaseTest::TearDownOnMainThread();
   }
 
-  std::string GetDeviceId(const std::string& user_id) {
-    return user_manager::UserManager::Get()->GetKnownUserDeviceId(user_id);
+  std::string GetDeviceId(const AccountId& account_id) {
+    return user_manager::UserManager::Get()->GetKnownUserDeviceId(account_id);
   }
 
-  std::string GetDeviceIdFromSigninClient(const std::string& user_id) {
+  std::string GetDeviceIdFromSigninClient(const AccountId& account_id) {
     return ChromeSigninClientFactory::GetForProfile(
                ProfileHelper::Get()->GetProfileByUser(
-                   user_manager::UserManager::Get()->FindUser(user_id)))
+                   user_manager::UserManager::Get()->FindUser(account_id)))
         ->GetSigninScopedDeviceId();
   }
 
@@ -76,11 +76,11 @@
   // are the same.
   // If |refresh_token| is not empty, checks that device ID associated with the
   // |refresh_token| in GAIA is the same as ID saved on device.
-  void CheckDeviceIDIsConsistent(const std::string& user_id,
+  void CheckDeviceIDIsConsistent(const AccountId& account_id,
                                  const std::string& refresh_token) {
     const std::string device_id_in_signin_client =
-        GetDeviceIdFromSigninClient(user_id);
-    const std::string device_id_in_local_state = GetDeviceId(user_id);
+        GetDeviceIdFromSigninClient(account_id);
+    const std::string device_id_in_local_state = GetDeviceId(account_id);
 
     EXPECT_FALSE(device_id_in_signin_client.empty());
     EXPECT_EQ(device_id_in_signin_client, device_id_in_local_state);
@@ -122,8 +122,8 @@
     WaitForSessionStart();
   }
 
-  void RemoveUser(const std::string& user_id) {
-    user_manager::UserManager::Get()->RemoveUser(user_id, this);
+  void RemoveUser(const AccountId& account_id) {
+    user_manager::UserManager::Get()->RemoveUser(account_id, this);
     user_removal_loop_.Run();
   }
 
@@ -176,34 +176,39 @@
 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_PRE_PRE_NewUsers) {
   SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken1,
                kFakeUserGaiaId);
-  CheckDeviceIDIsConsistent(kFakeUserEmail, kRefreshToken1);
+  CheckDeviceIDIsConsistent(AccountId::FromUserEmail(kFakeUserEmail),
+                            kRefreshToken1);
 }
 
 // Authenticate the first user through GAIA and verify that device ID remains
 // the same.
 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_PRE_NewUsers) {
-  const std::string device_id = GetDeviceId(kFakeUserEmail);
+  const std::string device_id =
+      GetDeviceId(AccountId::FromUserEmail(kFakeUserEmail));
   EXPECT_FALSE(device_id.empty());
   EXPECT_EQ(device_id, GetDeviceIdFromGAIA(kRefreshToken1));
 
   SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken2,
                kFakeUserGaiaId);
-  CheckDeviceIDIsConsistent(kFakeUserEmail, kRefreshToken2);
+  CheckDeviceIDIsConsistent(AccountId::FromUserEmail(kFakeUserEmail),
+                            kRefreshToken2);
 
-  CHECK_EQ(device_id, GetDeviceId(kFakeUserEmail));
+  CHECK_EQ(device_id, GetDeviceId(AccountId::FromUserEmail(kFakeUserEmail)));
 }
 
 // Authenticate the first user offline and verify that device ID remains
 // the same.
 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_NewUsers) {
-  const std::string device_id = GetDeviceId(kFakeUserEmail);
+  const std::string device_id =
+      GetDeviceId(AccountId::FromUserEmail(kFakeUserEmail));
   EXPECT_FALSE(device_id.empty());
 
   SignInOffline(kFakeUserEmail, kFakeUserPassword);
-  CheckDeviceIDIsConsistent(kFakeUserEmail, kRefreshToken2);
+  CheckDeviceIDIsConsistent(AccountId::FromUserEmail(kFakeUserEmail),
+                            kRefreshToken2);
 
   // Verify that device ID remained the same after offline auth.
-  CHECK_EQ(device_id, GetDeviceId(kFakeUserEmail));
+  CHECK_EQ(device_id, GetDeviceId(AccountId::FromUserEmail(kFakeUserEmail)));
 }
 
 // Add the second user.
@@ -212,23 +217,25 @@
   JS().ExecuteAsync("chrome.send('showAddUser')");
   SignInOnline(kSecondUserEmail, kSecondUserPassword, kSecondUserRefreshToken1,
                kSecondUserGaiaId);
-  CheckDeviceIDIsConsistent(kSecondUserEmail, kSecondUserRefreshToken1);
+  CheckDeviceIDIsConsistent(AccountId::FromUserEmail(kSecondUserEmail),
+                            kSecondUserRefreshToken1);
 }
 
 // Remove the second user.
 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_NewUsers) {
   WaitForSigninScreen();
-  RemoveUser(kSecondUserEmail);
+  RemoveUser(AccountId::FromUserEmail(kSecondUserEmail));
 }
 
 // Add the second user back. Verify that device ID has been changed.
 IN_PROC_BROWSER_TEST_F(DeviceIDTest, NewUsers) {
-  EXPECT_TRUE(GetDeviceId(kSecondUserEmail).empty());
+  EXPECT_TRUE(GetDeviceId(AccountId::FromUserEmail(kSecondUserEmail)).empty());
   SignInOnline(kSecondUserEmail, kSecondUserPassword, kSecondUserRefreshToken2,
                kSecondUserGaiaId);
-  CheckDeviceIDIsConsistent(kSecondUserEmail, kSecondUserRefreshToken2);
+  CheckDeviceIDIsConsistent(AccountId::FromUserEmail(kSecondUserEmail),
+                            kSecondUserRefreshToken2);
   EXPECT_NE(GetDeviceIdFromGAIA(kSecondUserRefreshToken1),
-            GetDeviceId(kSecondUserEmail));
+            GetDeviceId(AccountId::FromUserEmail(kSecondUserEmail)));
 }
 
 // Set up a user that has a device ID stored in preference only.
@@ -242,20 +249,21 @@
           ->GetProfileByUser(user_manager::UserManager::Get()->GetActiveUser())
           ->GetPrefs();
   prefs->SetString(prefs::kGoogleServicesSigninScopedDeviceId,
-                   GetDeviceId(kFakeUserEmail));
+                   GetDeviceId(AccountId::FromUserEmail(kFakeUserEmail)));
 
   // Can't use SetKnownUserDeviceId here, because it forbids changing a device
   // ID.
   user_manager::UserManager::Get()->SetKnownUserStringPref(
-      kFakeUserEmail, "device_id", std::string());
+      AccountId::FromUserEmail(kFakeUserEmail), "device_id", std::string());
 }
 
 // Tests that after the first sign in the device ID has been moved to the Local
 // state.
 IN_PROC_BROWSER_TEST_F(DeviceIDTest, Migration) {
-  EXPECT_TRUE(GetDeviceId(kFakeUserEmail).empty());
+  EXPECT_TRUE(GetDeviceId(AccountId::FromUserEmail(kFakeUserEmail)).empty());
   SignInOffline(kFakeUserEmail, kFakeUserPassword);
-  CheckDeviceIDIsConsistent(kFakeUserEmail, kRefreshToken1);
+  CheckDeviceIDIsConsistent(AccountId::FromUserEmail(kFakeUserEmail),
+                            kRefreshToken1);
 }
 
 // Set up a user that doesn't have a device ID.
@@ -273,16 +281,17 @@
   // Can't use SetKnownUserDeviceId here, because it forbids changing a device
   // ID.
   user_manager::UserManager::Get()->SetKnownUserStringPref(
-      kFakeUserEmail, "device_id", std::string());
+      AccountId::FromUserEmail(kFakeUserEmail), "device_id", std::string());
 }
 
 // Tests that device ID has been generated after the first sign in.
 IN_PROC_BROWSER_TEST_F(DeviceIDTest, LegacyUsers) {
-  EXPECT_TRUE(GetDeviceId(kFakeUserEmail).empty());
+  EXPECT_TRUE(GetDeviceId(AccountId::FromUserEmail(kFakeUserEmail)).empty());
   SignInOffline(kFakeUserEmail, kFakeUserPassword);
   // Last param |auth_code| is empty, because we don't pass a device ID to GAIA
   // in this case.
-  CheckDeviceIDIsConsistent(kFakeUserEmail, std::string());
+  CheckDeviceIDIsConsistent(AccountId::FromUserEmail(kFakeUserEmail),
+                            std::string());
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
index b83bb0c..3c224239 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -29,6 +29,7 @@
 #include "chromeos/login/auth/user_context.h"
 #include "components/app_modal/javascript_app_modal_dialog.h"
 #include "components/app_modal/native_app_modal_dialog.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/user_manager/user.h"
@@ -197,7 +198,9 @@
               user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
 
     // Try login.  Primary profile has changed.
-    EXPECT_TRUE(TryToLogin(kTestGaiaId, kTestEmail, kTestAccountPassword));
+    EXPECT_TRUE(
+        TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId),
+                   kTestAccountPassword));
     Profile* profile = ProfileManager::GetPrimaryUserProfile();
 
     // Wait for the session merge to finish.
@@ -212,15 +215,13 @@
               user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
   }
 
-  bool TryToLogin(const std::string& gaia_id,
-                  const std::string& username,
-                  const std::string& password) {
-    if (!AddUserToSession(gaia_id, username, password))
+  bool TryToLogin(const AccountId& account_id, const std::string& password) {
+    if (!AddUserToSession(account_id, password))
       return false;
 
     if (const user_manager::User* active_user =
             user_manager::UserManager::Get()->GetActiveUser()) {
-      return active_user->email() == username;
+      return active_user->GetAccountId() == account_id;
     }
 
     return false;
@@ -251,8 +252,7 @@
     return OobeBaseTest::profile();
   }
 
-  bool AddUserToSession(const std::string& gaia_id,
-                        const std::string& username,
+  bool AddUserToSession(const AccountId& account_id,
                         const std::string& password) {
     ExistingUserController* controller =
         ExistingUserController::current_controller();
@@ -261,8 +261,8 @@
       return false;
     }
 
-    UserContext user_context(username);
-    user_context.SetGaiaID(gaia_id);
+    UserContext user_context(account_id);
+    user_context.SetGaiaID(account_id.GetGaiaId());
     user_context.SetKey(Key(password));
     controller->Login(user_context, SigninSpecifics());
     content::WindowedNotificationObserver(
@@ -273,7 +273,7 @@
     for (user_manager::UserList::const_iterator it = logged_users.begin();
          it != logged_users.end();
          ++it) {
-      if ((*it)->email() == username)
+      if ((*it)->GetAccountId() == account_id)
         return true;
     }
     return false;
@@ -494,7 +494,9 @@
   EXPECT_EQ(GetOAuthStatusFromLocalState(account_id),
             user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
 
-  EXPECT_TRUE(TryToLogin(kTestGaiaId, kTestEmail, kTestAccountPassword));
+  EXPECT_TRUE(
+      TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId),
+                 kTestAccountPassword));
 
   // Wait for the session merge to finish.
   WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_FAILED);
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
index 5e046a4..8b79b2f5 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chromeos/chromeos_switches.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_client.h"
@@ -108,7 +109,8 @@
     // cause user to go through Gaia in next login to obtain a new refresh
     // token.
     user_manager::UserManager::Get()->SaveUserOAuthStatus(
-        primary_account_id, user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN);
+        AccountId::FromUserEmail(primary_account_id),
+        user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN);
 
     token_service->LoadCredentials(primary_account_id);
   }
@@ -129,14 +131,14 @@
 }
 
 void OAuth2LoginManager::OnRefreshTokenAvailable(
-    const std::string& account_id) {
+    const std::string& user_email) {
   VLOG(1) << "OnRefreshTokenAvailable";
 
   if (state_ == SESSION_RESTORE_NOT_STARTED)
     return;
 
   // TODO(fgorski): Once ProfileOAuth2TokenService supports multi-login, make
-  // sure to restore session cookies in the context of the correct account_id.
+  // sure to restore session cookies in the context of the correct user_email.
 
   // Do not validate tokens for supervised users, as they don't actually have
   // oauth2 token.
@@ -145,10 +147,11 @@
     return;
   }
   // Only restore session cookies for the primary account in the profile.
-  if (GetPrimaryAccountId() == account_id) {
+  if (GetPrimaryAccountId() == user_email) {
     // Token is loaded. Undo the flagging before token loading.
     user_manager::UserManager::Get()->SaveUserOAuthStatus(
-        account_id, user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
+        AccountId::FromUserEmail(user_email),
+        user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
     VerifySessionCookies();
   }
 }
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
index 580f3cb..184a2e54 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
@@ -166,7 +166,7 @@
   void OnOAuth2TokensFetchFailed() override;
 
   // OAuth2TokenService::Observer implementation:
-  void OnRefreshTokenAvailable(const std::string& account_id) override;
+  void OnRefreshTokenAvailable(const std::string& user_email) override;
 
   // Signals delegate that authentication is completed, kicks off token fetching
   // process.
diff --git a/chrome/browser/chromeos/login/signin/token_handle_fetcher.cc b/chrome/browser/chromeos/login/signin/token_handle_fetcher.cc
index 3f79988b7..83a287a 100644
--- a/chrome/browser/chromeos/login/signin/token_handle_fetcher.cc
+++ b/chrome/browser/chromeos/login/signin/token_handle_fetcher.cc
@@ -42,15 +42,10 @@
 }  // namespace
 
 TokenHandleFetcher::TokenHandleFetcher(TokenHandleUtil* util,
-                                       const user_manager::UserID& user_id)
+                                       const AccountId& account_id)
     : OAuth2TokenService::Consumer("user_session_manager"),
       token_handle_util_(util),
-      user_id_(user_id),
-      token_service_(nullptr),
-      waiting_for_refresh_token_(false),
-      profile_(nullptr),
-      tokeninfo_response_start_time_(base::TimeTicks()) {
-}
+      account_id_(account_id) {}
 
 TokenHandleFetcher::~TokenHandleFetcher() {
   if (waiting_for_refresh_token_)
@@ -65,9 +60,9 @@
   token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
   SigninManagerBase* signin_manager =
       SigninManagerFactory::GetForProfile(profile);
-  std::string account_id = signin_manager->GetAuthenticatedAccountId();
-  if (!token_service_->RefreshTokenIsAvailable(account_id)) {
-    account_without_token_ = account_id;
+  const std::string user_email = signin_manager->GetAuthenticatedAccountId();
+  if (!token_service_->RefreshTokenIsAvailable(user_email)) {
+    account_without_token_ = user_email;
     profile_shutdown_notification_ =
         ShutdownNotifierFactory::GetInstance()->Get(profile)->Subscribe(
             base::Bind(&TokenHandleFetcher::OnProfileDestroyed,
@@ -77,23 +72,23 @@
     waiting_for_refresh_token_ = true;
     return;
   }
-  RequestAccessToken(account_id);
+  RequestAccessToken(user_email);
 }
 
 void TokenHandleFetcher::OnRefreshTokenAvailable(
-    const std::string& account_id) {
-  if (account_without_token_ != account_id)
+    const std::string& user_email) {
+  if (account_without_token_ != user_email)
     return;
   waiting_for_refresh_token_ = false;
   token_service_->RemoveObserver(this);
-  RequestAccessToken(account_id);
+  RequestAccessToken(user_email);
 }
 
-void TokenHandleFetcher::RequestAccessToken(const std::string& account_id) {
+void TokenHandleFetcher::RequestAccessToken(const std::string& user_email) {
   OAuth2TokenService::ScopeSet scopes;
   scopes.insert(GaiaConstants::kOAuth1LoginScope);
   oauth2_access_token_request_ =
-      token_service_->StartRequest(account_id, scopes, this);
+      token_service_->StartRequest(user_email, scopes, this);
 }
 
 void TokenHandleFetcher::OnGetTokenSuccess(
@@ -110,7 +105,7 @@
   oauth2_access_token_request_.reset();
   LOG(ERROR) << "Could not get access token to backfill token handler"
              << error.ToString();
-  callback_.Run(user_id_, false);
+  callback_.Run(account_id_, false);
 }
 
 void TokenHandleFetcher::FillForNewUser(const std::string& access_token,
@@ -129,11 +124,11 @@
 }
 
 void TokenHandleFetcher::OnOAuthError() {
-  callback_.Run(user_id_, false);
+  callback_.Run(account_id_, false);
 }
 
 void TokenHandleFetcher::OnNetworkError(int response_code) {
-  callback_.Run(user_id_, false);
+  callback_.Run(account_id_, false);
 }
 
 void TokenHandleFetcher::OnGetTokenInfoResponse(
@@ -143,15 +138,15 @@
     std::string handle;
     if (token_info->GetString("token_handle", &handle)) {
       success = true;
-      token_handle_util_->StoreTokenHandle(user_id_, handle);
+      token_handle_util_->StoreTokenHandle(account_id_, handle);
     }
   }
   const base::TimeDelta duration =
       base::TimeTicks::Now() - tokeninfo_response_start_time_;
   UMA_HISTOGRAM_TIMES("Login.TokenObtainResponseTime", duration);
-  callback_.Run(user_id_, success);
+  callback_.Run(account_id_, success);
 }
 
 void TokenHandleFetcher::OnProfileDestroyed() {
-  callback_.Run(user_id_, false);
+  callback_.Run(account_id_, false);
 }
diff --git a/chrome/browser/chromeos/login/signin/token_handle_fetcher.h b/chrome/browser/chromeos/login/signin/token_handle_fetcher.h
index 5c471a438..77ebb8a 100644
--- a/chrome/browser/chromeos/login/signin/token_handle_fetcher.h
+++ b/chrome/browser/chromeos/login/signin/token_handle_fetcher.h
@@ -13,7 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
-#include "components/user_manager/user_id.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "google_apis/gaia/gaia_oauth_client.h"
 #include "google_apis/gaia/oauth2_token_service.h"
 
@@ -29,12 +29,11 @@
                            public OAuth2TokenService::Consumer,
                            public OAuth2TokenService::Observer {
  public:
-  TokenHandleFetcher(TokenHandleUtil* util,
-                     const user_manager::UserID& user_id);
+  TokenHandleFetcher(TokenHandleUtil* util, const AccountId& account_id);
   ~TokenHandleFetcher() override;
 
-  typedef base::Callback<void(const user_manager::UserID&, bool success)>
-      TokenFetchingCallback;
+  using TokenFetchingCallback =
+      base::Callback<void(const AccountId&, bool success)>;
 
   // Get token handle for user who have just signed in via GAIA. This
   // request will be performed using signin profile.
@@ -46,7 +45,7 @@
 
  private:
   // OAuth2TokenService::Observer override:
-  void OnRefreshTokenAvailable(const std::string& account_id) override;
+  void OnRefreshTokenAvailable(const std::string& user_email) override;
 
   // OAuth2TokenService::Consumer overrides:
   void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
@@ -61,20 +60,20 @@
   void OnGetTokenInfoResponse(
       scoped_ptr<base::DictionaryValue> token_info) override;
 
-  void RequestAccessToken(const std::string& account_id);
+  void RequestAccessToken(const std::string& user_email);
   void FillForAccessToken(const std::string& access_token);
 
   // This is called before profile is detroyed.
   void OnProfileDestroyed();
 
-  TokenHandleUtil* token_handle_util_;
-  user_manager::UserID user_id_;
-  OAuth2TokenService* token_service_;
+  TokenHandleUtil* token_handle_util_ = nullptr;
+  AccountId account_id_;
+  OAuth2TokenService* token_service_ = nullptr;
 
-  bool waiting_for_refresh_token_;
+  bool waiting_for_refresh_token_ = false;
   std::string account_without_token_;
-  Profile* profile_;
-  base::TimeTicks tokeninfo_response_start_time_;
+  Profile* profile_ = nullptr;
+  base::TimeTicks tokeninfo_response_start_time_ = base::TimeTicks();
   TokenFetchingCallback callback_;
   scoped_ptr<gaia::GaiaOAuthClient> gaia_client_;
   scoped_ptr<OAuth2TokenService::Request> oauth2_access_token_request_;
diff --git a/chrome/browser/chromeos/login/signin/token_handle_util.cc b/chrome/browser/chromeos/login/signin/token_handle_util.cc
index 4e688a7..5304a94 100644
--- a/chrome/browser/chromeos/login/signin/token_handle_util.cc
+++ b/chrome/browser/chromeos/login/signin/token_handle_util.cc
@@ -9,7 +9,6 @@
 #include "base/values.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
-#include "components/user_manager/user_id.h"
 #include "components/user_manager/user_manager.h"
 #include "google_apis/gaia/gaia_oauth_client.h"
 
@@ -35,20 +34,20 @@
   gaia_client_.reset();
 }
 
-bool TokenHandleUtil::HasToken(const user_manager::UserID& user_id) {
+bool TokenHandleUtil::HasToken(const AccountId& account_id) {
   const base::DictionaryValue* dict = nullptr;
   std::string token;
-  if (!user_manager_->FindKnownUserPrefs(user_id, &dict))
+  if (!user_manager_->FindKnownUserPrefs(account_id, &dict))
     return false;
   if (!dict->GetString(kTokenHandlePref, &token))
     return false;
   return !token.empty();
 }
 
-bool TokenHandleUtil::ShouldObtainHandle(const user_manager::UserID& user_id) {
+bool TokenHandleUtil::ShouldObtainHandle(const AccountId& account_id) {
   const base::DictionaryValue* dict = nullptr;
   std::string token;
-  if (!user_manager_->FindKnownUserPrefs(user_id, &dict))
+  if (!user_manager_->FindKnownUserPrefs(account_id, &dict))
     return true;
   if (!dict->GetString(kTokenHandlePref, &token))
     return true;
@@ -59,32 +58,32 @@
   return kHandleStatusInvalid == status;
 }
 
-void TokenHandleUtil::DeleteHandle(const user_manager::UserID& user_id) {
+void TokenHandleUtil::DeleteHandle(const AccountId& account_id) {
   const base::DictionaryValue* dict = nullptr;
-  if (!user_manager_->FindKnownUserPrefs(user_id, &dict))
+  if (!user_manager_->FindKnownUserPrefs(account_id, &dict))
     return;
   scoped_ptr<base::DictionaryValue> dict_copy(dict->DeepCopy());
   dict_copy->Remove(kTokenHandlePref, nullptr);
   dict_copy->Remove(kTokenHandleStatusPref, nullptr);
-  user_manager_->UpdateKnownUserPrefs(user_id, *dict_copy.get(),
+  user_manager_->UpdateKnownUserPrefs(account_id, *dict_copy.get(),
                                       /* replace values */ true);
 }
 
-void TokenHandleUtil::MarkHandleInvalid(const user_manager::UserID& user_id) {
-  user_manager_->SetKnownUserStringPref(user_id, kTokenHandleStatusPref,
+void TokenHandleUtil::MarkHandleInvalid(const AccountId& account_id) {
+  user_manager_->SetKnownUserStringPref(account_id, kTokenHandleStatusPref,
                                         kHandleStatusInvalid);
 }
 
-void TokenHandleUtil::CheckToken(const user_manager::UserID& user_id,
+void TokenHandleUtil::CheckToken(const AccountId& account_id,
                                  const TokenValidationCallback& callback) {
   const base::DictionaryValue* dict = nullptr;
   std::string token;
-  if (!user_manager_->FindKnownUserPrefs(user_id, &dict)) {
-    callback.Run(user_id, UNKNOWN);
+  if (!user_manager_->FindKnownUserPrefs(account_id, &dict)) {
+    callback.Run(account_id, UNKNOWN);
     return;
   }
   if (!dict->GetString(kTokenHandlePref, &token)) {
-    callback.Run(user_id, UNKNOWN);
+    callback.Run(account_id, UNKNOWN);
     return;
   }
 
@@ -96,15 +95,15 @@
 
   validation_delegates_.set(
       token, scoped_ptr<TokenDelegate>(new TokenDelegate(
-                 weak_factory_.GetWeakPtr(), user_id, token, callback)));
+                 weak_factory_.GetWeakPtr(), account_id, token, callback)));
   gaia_client_->GetTokenHandleInfo(token, kMaxRetries,
                                    validation_delegates_.get(token));
 }
 
-void TokenHandleUtil::StoreTokenHandle(const user_manager::UserID& user_id,
+void TokenHandleUtil::StoreTokenHandle(const AccountId& account_id,
                                        const std::string& handle) {
-  user_manager_->SetKnownUserStringPref(user_id, kTokenHandlePref, handle);
-  user_manager_->SetKnownUserStringPref(user_id, kTokenHandleStatusPref,
+  user_manager_->SetKnownUserStringPref(account_id, kTokenHandlePref, handle);
+  user_manager_->SetKnownUserStringPref(account_id, kTokenHandleStatusPref,
                                         kHandleStatusValid);
 }
 
@@ -112,28 +111,26 @@
   validation_delegates_.erase(token);
 }
 
-void TokenHandleUtil::OnObtainTokenComplete(
-    const user_manager::UserID& user_id) {
-  obtain_delegates_.erase(user_id);
+void TokenHandleUtil::OnObtainTokenComplete(const AccountId& account_id) {
+  obtain_delegates_.erase(account_id);
 }
 
 TokenHandleUtil::TokenDelegate::TokenDelegate(
     const base::WeakPtr<TokenHandleUtil>& owner,
-    const user_manager::UserID& user_id,
+    const AccountId& account_id,
     const std::string& token,
     const TokenValidationCallback& callback)
     : owner_(owner),
-      user_id_(user_id),
+      account_id_(account_id),
       token_(token),
       tokeninfo_response_start_time_(base::TimeTicks::Now()),
-      callback_(callback) {
-}
+      callback_(callback) {}
 
 TokenHandleUtil::TokenDelegate::~TokenDelegate() {
 }
 
 void TokenHandleUtil::TokenDelegate::OnOAuthError() {
-  callback_.Run(user_id_, INVALID);
+  callback_.Run(account_id_, INVALID);
   NotifyDone();
 }
 
@@ -144,7 +141,7 @@
 }
 
 void TokenHandleUtil::TokenDelegate::OnNetworkError(int response_code) {
-  callback_.Run(user_id_, UNKNOWN);
+  callback_.Run(account_id_, UNKNOWN);
   NotifyDone();
 }
 
@@ -160,6 +157,6 @@
   const base::TimeDelta duration =
       base::TimeTicks::Now() - tokeninfo_response_start_time_;
   UMA_HISTOGRAM_TIMES("Login.TokenCheckResponseTime", duration);
-  callback_.Run(user_id_, outcome);
+  callback_.Run(account_id_, outcome);
   NotifyDone();
 }
diff --git a/chrome/browser/chromeos/login/signin/token_handle_util.h b/chrome/browser/chromeos/login/signin/token_handle_util.h
index 572d3345..20ef090 100644
--- a/chrome/browser/chromeos/login/signin/token_handle_util.h
+++ b/chrome/browser/chromeos/login/signin/token_handle_util.h
@@ -12,9 +12,11 @@
 #include "base/containers/scoped_ptr_hash_map.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
-#include "components/user_manager/user_id.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "google_apis/gaia/gaia_oauth_client.h"
 
+class AccountId;
+
 namespace base {
 class DictionaryValue;
 }
@@ -34,37 +36,36 @@
 
   enum TokenHandleStatus { VALID, INVALID, UNKNOWN };
 
-  typedef base::Callback<void(const user_manager::UserID&, TokenHandleStatus)>
-      TokenValidationCallback;
+  using TokenValidationCallback =
+      base::Callback<void(const AccountId&, TokenHandleStatus)>;
 
-  // Returns true if UserManager has token handle associated with |user_id|.
-  bool HasToken(const user_manager::UserID& user_id);
+  // Returns true if UserManager has token handle associated with |account_id|.
+  bool HasToken(const AccountId& account_id);
 
-  // Removes token handle for |user_id| from UserManager storage.
-  void DeleteHandle(const user_manager::UserID& user_id);
+  // Removes token handle for |account_id| from UserManager storage.
+  void DeleteHandle(const AccountId& account_id);
 
   // Marks current handle as invalid, new one should be obtained at next sign
   // in.
-  void MarkHandleInvalid(const user_manager::UserID& user_id);
+  void MarkHandleInvalid(const AccountId& account_id);
 
-  // Indicates if token handle for |user_id| is missing or marked as invalid.
-  bool ShouldObtainHandle(const user_manager::UserID& user_id);
+  // Indicates if token handle for |account_id| is missing or marked as invalid.
+  bool ShouldObtainHandle(const AccountId& account_id);
 
-  // Performs token handle check for |user_id|. Will call |callback| with
+  // Performs token handle check for |account_id|. Will call |callback| with
   // corresponding result.
-  void CheckToken(const user_manager::UserID& user_id,
+  void CheckToken(const AccountId& account_id,
                   const TokenValidationCallback& callback);
 
-  // Given the token |handle| store it for |user_id|.
-  void StoreTokenHandle(const user_manager::UserID& user_id,
-                        const std::string& handle);
+  // Given the token |handle| store it for |account_id|.
+  void StoreTokenHandle(const AccountId& account_id, const std::string& handle);
 
  private:
   // Associates GaiaOAuthClient::Delegate with User ID and Token.
   class TokenDelegate : public gaia::GaiaOAuthClient::Delegate {
    public:
     TokenDelegate(const base::WeakPtr<TokenHandleUtil>& owner,
-                  const user_manager::UserID& user_id,
+                  const AccountId& account_id,
                   const std::string& token,
                   const TokenValidationCallback& callback);
     ~TokenDelegate() override;
@@ -76,7 +77,7 @@
 
    private:
     base::WeakPtr<TokenHandleUtil> owner_;
-    user_manager::UserID user_id_;
+    AccountId account_id_;
     std::string token_;
     base::TimeTicks tokeninfo_response_start_time_;
     TokenValidationCallback callback_;
@@ -85,7 +86,7 @@
   };
 
   void OnValidationComplete(const std::string& token);
-  void OnObtainTokenComplete(const user_manager::UserID& id);
+  void OnObtainTokenComplete(const AccountId& account_id);
 
   // UserManager that stores corresponding user data.
   user_manager::UserManager* user_manager_;
@@ -95,7 +96,7 @@
       validation_delegates_;
 
   // Map of pending obtain operations.
-  base::ScopedPtrHashMap<user_manager::UserID, scoped_ptr<TokenDelegate>>
+  base::ScopedPtrHashMap<AccountId, scoped_ptr<TokenDelegate>>
       obtain_delegates_;
 
   // Instance of GAIA Client.
diff --git a/chrome/browser/chromeos/login/signin_screen_controller.cc b/chrome/browser/chromeos/login/signin_screen_controller.cc
index 06e683d..fdcfd5a 100644
--- a/chrome/browser/chromeos/login/signin_screen_controller.cc
+++ b/chrome/browser/chromeos/login/signin_screen_controller.cc
@@ -59,7 +59,8 @@
 }
 
 void SignInScreenController::RemoveUser(const std::string& user_id) {
-  user_manager::UserManager::Get()->RemoveUser(user_id, this);
+  user_manager::UserManager::Get()->RemoveUser(
+      AccountId::FromUserEmail(user_id), this);
 }
 
 void SignInScreenController::OnBeforeUserRemoved(const std::string& username) {
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_authentication.cc b/chrome/browser/chromeos/login/supervised/supervised_user_authentication.cc
index 7485604..7fcd6e8 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_authentication.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_authentication.cc
@@ -104,14 +104,15 @@
 UserContext SupervisedUserAuthentication::TransformKey(
     const UserContext& context) {
   UserContext result = context;
-  int user_schema = GetPasswordSchema(context.GetUserID());
+  int user_schema = GetPasswordSchema(context.GetAccountId().GetUserEmail());
   if (user_schema == SCHEMA_PLAIN)
     return result;
 
   if (user_schema == SCHEMA_SALT_HASHED) {
     base::DictionaryValue holder;
     std::string salt;
-    owner_->GetPasswordInformation(context.GetUserID(), &holder);
+    owner_->GetPasswordInformation(context.GetAccountId().GetUserEmail(),
+                                   &holder);
     holder.GetStringWithoutPathExpansion(kSalt, &salt);
     DCHECK(!salt.empty());
     Key* const key = result.GetKey();
@@ -120,7 +121,8 @@
     result.SetIsUsingOAuth(false);
     return result;
   }
-  NOTREACHED() << "Unknown password schema for " << context.GetUserID();
+  NOTREACHED() << "Unknown password schema for "
+               << context.GetAccountId().GetUserEmail();
   return context;
 }
 
@@ -223,8 +225,8 @@
 void SupervisedUserAuthentication::ScheduleSupervisedPasswordChange(
     const std::string& supervised_user_id,
     const base::DictionaryValue* password_data) {
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(supervised_user_id);
+  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+      AccountId::FromUserEmail(supervised_user_id));
   base::FilePath profile_path = ProfileHelper::GetProfilePathByUserIdHash(
       user->username_hash());
   JSONFileValueSerializer serializer(profile_path.Append(kPasswordUpdateFile));
@@ -281,8 +283,8 @@
     const std::string& user_id,
     const PasswordDataCallback& success_callback,
     const base::Closure& failure_callback) {
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id);
+  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+      AccountId::FromUserEmail(user_id));
   base::FilePath profile_path =
       ProfileHelper::GetProfilePathByUserIdHash(user->username_hash());
   PostTaskAndReplyWithResult(
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_creation_controller_new.cc b/chrome/browser/chromeos/login/supervised/supervised_user_creation_controller_new.cc
index 0e512ff..1ad658c 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_controller_new.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_controller_new.cc
@@ -27,6 +27,7 @@
 #include "chromeos/dbus/session_manager_client.h"
 #include "chromeos/login/auth/key.h"
 #include "chromeos/login/auth/user_context.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_thread.h"
@@ -287,7 +288,8 @@
           std::string(),  // The salt is stored elsewhere.
           creation_context_->salted_master_key);
   key.SetLabel(kCryptohomeMasterKeyLabel);
-  UserContext context(creation_context_->local_user_id);
+  UserContext context(
+      AccountId::FromUserEmail(creation_context_->local_user_id));
   context.SetKey(key);
   context.SetIsUsingOAuth(false);
 
@@ -381,7 +383,7 @@
   // Assume that new token is valid. It will be automatically invalidated if
   // sync service fails to use it.
   user_manager::UserManager::Get()->SaveUserOAuthStatus(
-      creation_context_->local_user_id,
+      AccountId::FromUserEmail(creation_context_->local_user_id),
       user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
 
   stage_ = TOKEN_WRITTEN;
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc b/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc
index 2648f7f..99ef7a4f 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc
@@ -223,14 +223,15 @@
   manager_signin_in_progress_ = true;
 
   UserFlow* flow = new SupervisedUserCreationFlow(manager_id);
-  ChromeUserManager::Get()->SetUserFlow(manager_id, flow);
+  ChromeUserManager::Get()->SetUserFlow(AccountId::FromUserEmail(manager_id),
+                                        flow);
 
   // Make sure no two controllers exist at the same time.
   controller_.reset();
 
   controller_.reset(new SupervisedUserCreationControllerNew(this, manager_id));
 
-  UserContext user_context(manager_id);
+  UserContext user_context(AccountId::FromUserEmail(manager_id));
   user_context.SetKey(Key(manager_password));
   ExistingUserController::current_controller()->Login(user_context,
                                                       SigninSpecifics());
@@ -484,7 +485,8 @@
 void SupervisedUserCreationScreen::ApplyPicture() {
   std::string user_id = controller_->GetSupervisedUserId();
   UserImageManager* image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(user_id);
+      ChromeUserManager::Get()->GetUserImageManager(
+          AccountId::FromUserEmail(user_id));
   switch (selected_image_) {
     case user_manager::User::USER_IMAGE_EXTERNAL:
       // Photo decoding may not have been finished yet.
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc b/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc
index 39fca9f..ab41788 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc
@@ -294,7 +294,7 @@
 
   // Next button is now enabled.
   JSExpect("!$('supervised-user-creation-next-button').disabled");
-  UserContext user_context(kTestManager);
+  UserContext user_context(AccountId::FromUserEmail(kTestManager));
   user_context.SetGaiaID(GetGaiaIDForUserID(kTestManager));
   user_context.SetKey(Key(kTestManagerPassword));
   SetExpectedCredentials(user_context);
@@ -308,7 +308,8 @@
 
   // OAuth token is valid.
   user_manager::UserManager::Get()->SaveUserOAuthStatus(
-      kTestManager, user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
+      AccountId::FromUserEmail(kTestManager),
+      user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
   base::RunLoop().RunUntilIdle();
 
   // Check the page have changed.
diff --git a/chrome/browser/chromeos/login/user_flow.cc b/chrome/browser/chromeos/login/user_flow.cc
index 7f48e1b..74e37c3 100644
--- a/chrome/browser/chromeos/login/user_flow.cc
+++ b/chrome/browser/chromeos/login/user_flow.cc
@@ -6,13 +6,14 @@
 #include "base/message_loop/message_loop.h"
 #include "chrome/browser/chromeos/login/user_flow.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
+#include "components/signin/core/account_id/account_id.h"
 
 namespace chromeos {
 
 namespace {
 
 void UnregisterFlow(const std::string& user_id) {
-  ChromeUserManager::Get()->ResetUserFlow(user_id);
+  ChromeUserManager::Get()->ResetUserFlow(AccountId::FromUserEmail(user_id));
 }
 
 } // namespace
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_browsertest.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_browsertest.cc
index b3ceb6882..df168436 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_browsertest.cc
@@ -103,8 +103,9 @@
 class UserImageManagerTest : public LoginManagerTest,
                              public user_manager::UserManager::Observer {
  protected:
-  UserImageManagerTest() : LoginManagerTest(true) {
-  }
+  UserImageManagerTest()
+      : LoginManagerTest(true),
+        enterprise_account_id_(AccountId::FromUserEmail(kEnterpriseUser1)) {}
 
   // LoginManagerTest overrides:
   void SetUpInProcessBrowserTestFixture() override {
@@ -131,32 +132,35 @@
       run_loop_->Quit();
   }
 
-  // Logs in |username|.
-  void LogIn(const std::string& username) {
-    user_manager::UserManager::Get()->UserLoggedIn(username, username, false);
+  // Logs in |account_id|.
+  void LogIn(const AccountId& account_id) {
+    user_manager::UserManager::Get()->UserLoggedIn(
+        account_id, account_id.GetUserEmail(), false);
   }
 
   // Stores old (pre-migration) user image info.
-  void SetOldUserImageInfo(const std::string& username,
+  void SetOldUserImageInfo(const AccountId& account_id,
                            int image_index,
                            const base::FilePath& image_path) {
-    RegisterUser(username);
+    RegisterUser(account_id.GetUserEmail());
     DictionaryPrefUpdate images_pref(local_state_, "UserImages");
     base::DictionaryValue* image_properties = new base::DictionaryValue();
     image_properties->Set("index", new base::FundamentalValue(image_index));
     image_properties->Set(
         "path" , new base::StringValue(image_path.value()));
-    images_pref->SetWithoutPathExpansion(username, image_properties);
+    images_pref->SetWithoutPathExpansion(account_id.GetUserEmail(),
+                                         image_properties);
   }
 
   // Verifies user image info in |images_pref| dictionary.
   void ExpectUserImageInfo(const base::DictionaryValue* images_pref,
-                           const std::string& username,
+                           const AccountId& account_id,
                            int image_index,
                            const base::FilePath& image_path) {
     ASSERT_TRUE(images_pref);
     const base::DictionaryValue* image_properties = NULL;
-    images_pref->GetDictionaryWithoutPathExpansion(username, &image_properties);
+    images_pref->GetDictionaryWithoutPathExpansion(account_id.GetUserEmail(),
+                                                   &image_properties);
     ASSERT_TRUE(image_properties);
     int actual_image_index;
     std::string actual_image_path;
@@ -166,42 +170,42 @@
     EXPECT_EQ(image_path.value(), actual_image_path);
   }
 
-  // Verifies that there is no image info for |username| in dictionary
+  // Verifies that there is no image info for |account_id| in dictionary
   // |images_pref|.
   void ExpectNoUserImageInfo(const base::DictionaryValue* images_pref,
-                             const std::string& username) {
+                             const AccountId& account_id) {
     ASSERT_TRUE(images_pref);
     const base::DictionaryValue* image_properties = NULL;
-    images_pref->GetDictionaryWithoutPathExpansion(username, &image_properties);
+    images_pref->GetDictionaryWithoutPathExpansion(account_id.GetUserEmail(),
+                                                   &image_properties);
     ASSERT_FALSE(image_properties);
   }
 
   // Verifies that old user image info matches |image_index| and |image_path|
   // and that new user image info does not exist.
-  void ExpectOldUserImageInfo(const std::string& username,
+  void ExpectOldUserImageInfo(const AccountId& account_id,
                               int image_index,
                               const base::FilePath& image_path) {
-    ExpectUserImageInfo(local_state_->GetDictionary("UserImages"),
-                        username, image_index, image_path);
+    ExpectUserImageInfo(local_state_->GetDictionary("UserImages"), account_id,
+                        image_index, image_path);
     ExpectNoUserImageInfo(local_state_->GetDictionary("user_image_info"),
-                          username);
+                          account_id);
   }
 
   // Verifies that new user image info matches |image_index| and |image_path|
   // and that old user image info does not exist.
-  void ExpectNewUserImageInfo(const std::string& username,
+  void ExpectNewUserImageInfo(const AccountId& account_id,
                               int image_index,
                               const base::FilePath& image_path) {
     ExpectUserImageInfo(local_state_->GetDictionary("user_image_info"),
-                        username, image_index, image_path);
+                        account_id, image_index, image_path);
     ExpectNoUserImageInfo(local_state_->GetDictionary("UserImages"),
-                          username);
+                          account_id);
   }
 
-  // Sets bitmap |resource_id| as image for |username| and saves it to disk.
-  void SaveUserImagePNG(const std::string& username,
-                        int resource_id) {
-    base::FilePath image_path = GetUserImagePath(username, "png");
+  // Sets bitmap |resource_id| as image for |account_id| and saves it to disk.
+  void SaveUserImagePNG(const AccountId& account_id, int resource_id) {
+    base::FilePath image_path = GetUserImagePath(account_id, "png");
     scoped_refptr<base::RefCountedStaticMemory> image_data(
         ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
             resource_id, ui::SCALE_FACTOR_100P));
@@ -210,28 +214,29 @@
         reinterpret_cast<const char*>(image_data->front()),
         image_data->size());
     EXPECT_EQ(static_cast<int>(image_data->size()), written);
-    SetOldUserImageInfo(
-        username, user_manager::User::USER_IMAGE_EXTERNAL, image_path);
+    SetOldUserImageInfo(account_id, user_manager::User::USER_IMAGE_EXTERNAL,
+                        image_path);
   }
 
-  // Returns the image path for user |username| with specified |extension|.
-  base::FilePath GetUserImagePath(const std::string& username,
+  // Returns the image path for user |account_id| with specified |extension|.
+  base::FilePath GetUserImagePath(const AccountId& account_id,
                                   const std::string& extension) {
-    return user_data_dir_.Append(username).AddExtension(extension);
+    return user_data_dir_.Append(account_id.GetUserEmail())
+        .AddExtension(extension);
   }
 
   // Seeds the AccountTrackerService with test data so the ProfileDownloader can
   // retrieve the picture URL and fetch the image.
-  void SeedAccountTrackerService(const std::string& username,
+  void SeedAccountTrackerService(const AccountId& account_id,
                                  Profile* profile) {
     AccountInfo info;
     info.account_id = std::string();
-    info.gaia = username;
-    info.email = username;
-    info.full_name = username;
-    info.given_name = username;
+    info.gaia = account_id.GetUserEmail();
+    info.email = account_id.GetUserEmail();
+    info.full_name = account_id.GetUserEmail();
+    info.given_name = account_id.GetUserEmail();
     info.hosted_domain = std::string();
-    info.locale = username;
+    info.locale = account_id.GetUserEmail();
     info.picture_url = "http://localhost/avatar.jpg";
     info.is_child_account = false;
 
@@ -239,16 +244,16 @@
   }
 
   // Completes the download of all non-image profile data for the user
-  // |username|.  This method must only be called after a profile data
+  // |account_id|.  This method must only be called after a profile data
   // download has been started.  |url_fetcher_factory| will capture
   // the net::TestURLFetcher created by the ProfileDownloader to
   // download the profile image.
   void CompleteProfileMetadataDownload(
-      const std::string& username,
+      const AccountId& account_id,
       net::TestURLFetcherFactory* url_fetcher_factory) {
     ProfileDownloader* profile_downloader =
         reinterpret_cast<UserImageManagerImpl*>(
-            ChromeUserManager::Get()->GetUserImageManager(username))
+            ChromeUserManager::Get()->GetUserImageManager(account_id))
             ->profile_downloader_.get();
     ASSERT_TRUE(profile_downloader);
 
@@ -290,7 +295,7 @@
         user_manager::UserManager::Get()->GetLoggedInUser();
     ASSERT_TRUE(user);
     UserImageManagerImpl* uim = reinterpret_cast<UserImageManagerImpl*>(
-        ChromeUserManager::Get()->GetUserImageManager(user->email()));
+        ChromeUserManager::Get()->GetUserImageManager(user->GetAccountId()));
     if (uim->job_.get()) {
       run_loop_.reset(new base::RunLoop);
       run_loop_->Run();
@@ -306,6 +311,10 @@
 
   scoped_ptr<base::RunLoop> run_loop_;
 
+  const AccountId test_account_id1_ = AccountId::FromUserEmail(kTestUser1);
+  const AccountId test_account_id2_ = AccountId::FromUserEmail(kTestUser2);
+  const AccountId enterprise_account_id_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(UserImageManagerTest);
 };
@@ -313,49 +322,56 @@
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_DefaultUserImagePreserved) {
   // Setup an old default (stock) user image.
   ScopedUserManagerEnabler(new MockUserManager);
-  SetOldUserImageInfo(
-      kTestUser1, user_manager::kFirstDefaultImageIndex, base::FilePath());
+  SetOldUserImageInfo(test_account_id1_, user_manager::kFirstDefaultImageIndex,
+                      base::FilePath());
 }
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, DefaultUserImagePreserved) {
   user_manager::UserManager::Get()->GetUsers();  // Load users.
   // Old info preserved.
-  ExpectOldUserImageInfo(
-      kTestUser1, user_manager::kFirstDefaultImageIndex, base::FilePath());
-  LogIn(kTestUser1);
+  ExpectOldUserImageInfo(test_account_id1_,
+                         user_manager::kFirstDefaultImageIndex,
+                         base::FilePath());
+  LogIn(test_account_id1_);
   // Image info is migrated now.
-  ExpectNewUserImageInfo(
-      kTestUser1, user_manager::kFirstDefaultImageIndex, base::FilePath());
+  ExpectNewUserImageInfo(test_account_id1_,
+                         user_manager::kFirstDefaultImageIndex,
+                         base::FilePath());
 }
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_OtherUsersUnaffected) {
   // Setup two users with stock images.
   ScopedUserManagerEnabler(new MockUserManager);
-  SetOldUserImageInfo(
-      kTestUser1, user_manager::kFirstDefaultImageIndex, base::FilePath());
-  SetOldUserImageInfo(
-      kTestUser2, user_manager::kFirstDefaultImageIndex + 1, base::FilePath());
+  SetOldUserImageInfo(test_account_id1_, user_manager::kFirstDefaultImageIndex,
+                      base::FilePath());
+  SetOldUserImageInfo(test_account_id2_,
+                      user_manager::kFirstDefaultImageIndex + 1,
+                      base::FilePath());
 }
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, OtherUsersUnaffected) {
   user_manager::UserManager::Get()->GetUsers();  // Load users.
   // Old info preserved.
-  ExpectOldUserImageInfo(
-      kTestUser1, user_manager::kFirstDefaultImageIndex, base::FilePath());
-  ExpectOldUserImageInfo(
-      kTestUser2, user_manager::kFirstDefaultImageIndex + 1, base::FilePath());
-  LogIn(kTestUser1);
+  ExpectOldUserImageInfo(test_account_id1_,
+                         user_manager::kFirstDefaultImageIndex,
+                         base::FilePath());
+  ExpectOldUserImageInfo(test_account_id2_,
+                         user_manager::kFirstDefaultImageIndex + 1,
+                         base::FilePath());
+  LogIn(test_account_id1_);
   // Image info is migrated for the first user and unaffected for the rest.
-  ExpectNewUserImageInfo(
-      kTestUser1, user_manager::kFirstDefaultImageIndex, base::FilePath());
-  ExpectOldUserImageInfo(
-      kTestUser2, user_manager::kFirstDefaultImageIndex + 1, base::FilePath());
+  ExpectNewUserImageInfo(test_account_id1_,
+                         user_manager::kFirstDefaultImageIndex,
+                         base::FilePath());
+  ExpectOldUserImageInfo(test_account_id2_,
+                         user_manager::kFirstDefaultImageIndex + 1,
+                         base::FilePath());
 }
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_PRE_NonJPEGImageFromFile) {
   // Setup a user with non-JPEG image.
   ScopedUserManagerEnabler(new MockUserManager);
-  SaveUserImagePNG(kTestUser1,
+  SaveUserImagePNG(test_account_id1_,
                    user_manager::kDefaultImageResourceIDs
                        [user_manager::kFirstDefaultImageIndex]);
 }
@@ -363,26 +379,26 @@
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_NonJPEGImageFromFile) {
   user_manager::UserManager::Get()->GetUsers();  // Load users.
   // Old info preserved.
-  ExpectOldUserImageInfo(kTestUser1,
+  ExpectOldUserImageInfo(test_account_id1_,
                          user_manager::User::USER_IMAGE_EXTERNAL,
-                         GetUserImagePath(kTestUser1, "png"));
+                         GetUserImagePath(test_account_id1_, "png"));
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kTestUser1);
+      user_manager::UserManager::Get()->FindUser(test_account_id1_);
   EXPECT_TRUE(user->image_is_stub());
 
   base::RunLoop run_loop;
   PrefChangeRegistrar pref_change_registrar_;
   pref_change_registrar_.Init(local_state_);
   pref_change_registrar_.Add("UserImages", run_loop.QuitClosure());
-  LogIn(kTestUser1);
+  LogIn(test_account_id1_);
 
   // Wait for migration.
   run_loop.Run();
 
   // Image info is migrated and the image is converted to JPG.
-  ExpectNewUserImageInfo(kTestUser1,
+  ExpectNewUserImageInfo(test_account_id1_,
                          user_manager::User::USER_IMAGE_EXTERNAL,
-                         GetUserImagePath(kTestUser1, "jpg"));
+                         GetUserImagePath(test_account_id1_, "jpg"));
   user = user_manager::UserManager::Get()->GetLoggedInUser();
   ASSERT_TRUE(user);
   EXPECT_FALSE(user->image_is_safe_format());
@@ -396,7 +412,7 @@
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, NonJPEGImageFromFile) {
   user_manager::UserManager::Get()->GetUsers();  // Load users.
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kTestUser1);
+      user_manager::UserManager::Get()->FindUser(test_account_id1_);
   ASSERT_TRUE(user);
   // Wait for image load.
   if (user->image_index() == user_manager::User::USER_IMAGE_INVALID) {
@@ -414,40 +430,41 @@
 }
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserDefaultImageIndex) {
-  RegisterUser(kTestUser1);
+  RegisterUser(test_account_id1_.GetUserEmail());
 }
 
 // Verifies that SaveUserDefaultImageIndex() correctly sets and persists the
 // chosen user image.
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserDefaultImageIndex) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kTestUser1);
+      user_manager::UserManager::Get()->FindUser(test_account_id1_);
   ASSERT_TRUE(user);
 
   const gfx::ImageSkia& default_image =
       user_manager::GetDefaultImage(user_manager::kFirstDefaultImageIndex);
 
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(kTestUser1);
+      ChromeUserManager::Get()->GetUserImageManager(test_account_id1_);
   user_image_manager->SaveUserDefaultImageIndex(
       user_manager::kFirstDefaultImageIndex);
 
   EXPECT_TRUE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::kFirstDefaultImageIndex, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
-  ExpectNewUserImageInfo(
-      kTestUser1, user_manager::kFirstDefaultImageIndex, base::FilePath());
+  ExpectNewUserImageInfo(test_account_id1_,
+                         user_manager::kFirstDefaultImageIndex,
+                         base::FilePath());
 }
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImage) {
-  RegisterUser(kTestUser1);
+  RegisterUser(test_account_id1_.GetUserEmail());
 }
 
 // Verifies that SaveUserImage() correctly sets and persists the chosen user
 // image.
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImage) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kTestUser1);
+      user_manager::UserManager::Get()->FindUser(test_account_id1_);
   ASSERT_TRUE(user);
 
   SkBitmap custom_image_bitmap;
@@ -459,7 +476,7 @@
 
   run_loop_.reset(new base::RunLoop);
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(kTestUser1);
+      ChromeUserManager::Get()->GetUserImageManager(test_account_id1_);
   user_image_manager->SaveUserImage(
       user_manager::UserImage::CreateAndEncode(custom_image));
   run_loop_->Run();
@@ -467,12 +484,12 @@
   EXPECT_FALSE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(custom_image, user->GetImage()));
-  ExpectNewUserImageInfo(kTestUser1,
+  ExpectNewUserImageInfo(test_account_id1_,
                          user_manager::User::USER_IMAGE_EXTERNAL,
-                         GetUserImagePath(kTestUser1, "jpg"));
+                         GetUserImagePath(test_account_id1_, "jpg"));
 
   const scoped_ptr<gfx::ImageSkia> saved_image =
-      test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
+      test::ImageLoader(GetUserImagePath(test_account_id1_, "jpg")).Load();
   ASSERT_TRUE(saved_image);
 
   // Check image dimensions. Images can't be compared since JPEG is lossy.
@@ -481,14 +498,14 @@
 }
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImageFromFile) {
-  RegisterUser(kTestUser1);
+  RegisterUser(test_account_id1_.GetUserEmail());
 }
 
 // Verifies that SaveUserImageFromFile() correctly sets and persists the chosen
 // user image.
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromFile) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kTestUser1);
+      user_manager::UserManager::Get()->FindUser(test_account_id1_);
   ASSERT_TRUE(user);
 
   const base::FilePath custom_image_path =
@@ -499,19 +516,19 @@
 
   run_loop_.reset(new base::RunLoop);
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(kTestUser1);
+      ChromeUserManager::Get()->GetUserImageManager(test_account_id1_);
   user_image_manager->SaveUserImageFromFile(custom_image_path);
   run_loop_->Run();
 
   EXPECT_FALSE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(*custom_image, user->GetImage()));
-  ExpectNewUserImageInfo(kTestUser1,
+  ExpectNewUserImageInfo(test_account_id1_,
                          user_manager::User::USER_IMAGE_EXTERNAL,
-                         GetUserImagePath(kTestUser1, "jpg"));
+                         GetUserImagePath(test_account_id1_, "jpg"));
 
   const scoped_ptr<gfx::ImageSkia> saved_image =
-      test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
+      test::ImageLoader(GetUserImagePath(test_account_id1_, "jpg")).Load();
   ASSERT_TRUE(saved_image);
 
   // Check image dimensions. Images can't be compared since JPEG is lossy.
@@ -521,7 +538,7 @@
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
                        PRE_SaveUserImageFromProfileImage) {
-  RegisterUser(kTestUser1);
+  RegisterUser(test_account_id1_.GetUserEmail());
   chromeos::StartupUtils::MarkOobeCompleted();
 }
 
@@ -529,22 +546,22 @@
 // persists the chosen user image.
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromProfileImage) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kTestUser1);
+      user_manager::UserManager::Get()->FindUser(test_account_id1_);
   ASSERT_TRUE(user);
 
   UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting();
-  LoginUser(kTestUser1);
+  LoginUser(test_account_id1_.GetUserEmail());
   Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
-  SeedAccountTrackerService(kTestUser1, profile);
+  SeedAccountTrackerService(test_account_id1_, profile);
 
   run_loop_.reset(new base::RunLoop);
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(kTestUser1);
+      ChromeUserManager::Get()->GetUserImageManager(test_account_id1_);
   user_image_manager->SaveUserImageFromProfileImage();
   run_loop_->Run();
 
   net::TestURLFetcherFactory url_fetcher_factory;
-  CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory);
+  CompleteProfileMetadataDownload(test_account_id1_, &url_fetcher_factory);
   CompleteProfileImageDownload(&url_fetcher_factory);
 
   const gfx::ImageSkia& profile_image =
@@ -553,12 +570,12 @@
   EXPECT_FALSE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::User::USER_IMAGE_PROFILE, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(profile_image, user->GetImage()));
-  ExpectNewUserImageInfo(kTestUser1,
+  ExpectNewUserImageInfo(test_account_id1_,
                          user_manager::User::USER_IMAGE_PROFILE,
-                         GetUserImagePath(kTestUser1, "jpg"));
+                         GetUserImagePath(test_account_id1_, "jpg"));
 
   const scoped_ptr<gfx::ImageSkia> saved_image =
-      test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
+      test::ImageLoader(GetUserImagePath(test_account_id1_, "jpg")).Load();
   ASSERT_TRUE(saved_image);
 
   // Check image dimensions. Images can't be compared since JPEG is lossy.
@@ -568,7 +585,7 @@
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
                        PRE_ProfileImageDownloadDoesNotClobber) {
-  RegisterUser(kTestUser1);
+  RegisterUser(test_account_id1_.GetUserEmail());
   chromeos::StartupUtils::MarkOobeCompleted();
 }
 
@@ -579,25 +596,25 @@
 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
                        ProfileImageDownloadDoesNotClobber) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kTestUser1);
+      user_manager::UserManager::Get()->FindUser(test_account_id1_);
   ASSERT_TRUE(user);
 
   const gfx::ImageSkia& default_image =
       user_manager::GetDefaultImage(user_manager::kFirstDefaultImageIndex);
 
   UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting();
-  LoginUser(kTestUser1);
+  LoginUser(test_account_id1_.GetUserEmail());
   Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
-  SeedAccountTrackerService(kTestUser1, profile);
+  SeedAccountTrackerService(test_account_id1_, profile);
 
   run_loop_.reset(new base::RunLoop);
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(kTestUser1);
+      ChromeUserManager::Get()->GetUserImageManager(test_account_id1_);
   user_image_manager->SaveUserImageFromProfileImage();
   run_loop_->Run();
 
   net::TestURLFetcherFactory url_fetcher_factory;
-  CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory);
+  CompleteProfileMetadataDownload(test_account_id1_, &url_fetcher_factory);
 
   user_image_manager->SaveUserDefaultImageIndex(
       user_manager::kFirstDefaultImageIndex);
@@ -607,8 +624,9 @@
   EXPECT_TRUE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::kFirstDefaultImageIndex, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
-  ExpectNewUserImageInfo(
-      kTestUser1, user_manager::kFirstDefaultImageIndex, base::FilePath());
+  ExpectNewUserImageInfo(test_account_id1_,
+                         user_manager::kFirstDefaultImageIndex,
+                         base::FilePath());
 }
 
 class UserImageManagerPolicyTest : public UserImageManagerTest,
@@ -632,7 +650,8 @@
     ASSERT_TRUE(PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
                                  &user_keys_dir));
     const std::string sanitized_username =
-        chromeos::CryptohomeClient::GetStubSanitizedUsername(kEnterpriseUser1);
+        chromeos::CryptohomeClient::GetStubSanitizedUsername(
+            enterprise_account_id_.GetUserEmail());
     const base::FilePath user_key_file =
         user_keys_dir.AppendASCII(sanitized_username)
                      .AppendASCII("policy.pub");
@@ -644,7 +663,8 @@
                   reinterpret_cast<const char*>(user_key_bits.data()),
                   user_key_bits.size()),
               static_cast<int>(user_key_bits.size()));
-    user_policy_.policy_data().set_username(kEnterpriseUser1);
+    user_policy_.policy_data().set_username(
+        enterprise_account_id_.GetUserEmail());
 
     policy_image_ = test::ImageLoader(test_data_dir_.Append(
         test::kUserAvatarImage2RelativePath)).Load();
@@ -688,7 +708,7 @@
 };
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_SetAndClear) {
-  RegisterUser(kEnterpriseUser1);
+  RegisterUser(enterprise_account_id_.GetUserEmail());
   chromeos::StartupUtils::MarkOobeCompleted();
 }
 
@@ -698,10 +718,10 @@
 // http://crbug.com/396352
 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, DISABLED_SetAndClear) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kEnterpriseUser1);
+      user_manager::UserManager::Get()->FindUser(enterprise_account_id_);
   ASSERT_TRUE(user);
 
-  LoginUser(kEnterpriseUser1);
+  LoginUser(enterprise_account_id_.GetUserEmail());
   base::RunLoop().RunUntilIdle();
 
   policy::CloudPolicyStore* store = GetStoreForUser(user);
@@ -712,8 +732,8 @@
   user_policy_.payload().mutable_useravatarimage()->set_value(
       ConstructPolicy(test::kUserAvatarImage2RelativePath));
   user_policy_.Build();
-  fake_session_manager_client_->set_user_policy(kEnterpriseUser1,
-                                                user_policy_.GetBlob());
+  fake_session_manager_client_->set_user_policy(
+      enterprise_account_id_.GetUserEmail(), user_policy_.GetBlob());
   run_loop_.reset(new base::RunLoop);
   store->Load();
   run_loop_->Run();
@@ -721,12 +741,12 @@
   EXPECT_FALSE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
-  ExpectNewUserImageInfo(kEnterpriseUser1,
+  ExpectNewUserImageInfo(enterprise_account_id_,
                          user_manager::User::USER_IMAGE_EXTERNAL,
-                         GetUserImagePath(kEnterpriseUser1, "jpg"));
+                         GetUserImagePath(enterprise_account_id_, "jpg"));
 
   scoped_ptr<gfx::ImageSkia> saved_image =
-      test::ImageLoader(GetUserImagePath(kEnterpriseUser1, "jpg")).Load();
+      test::ImageLoader(GetUserImagePath(enterprise_account_id_, "jpg")).Load();
   ASSERT_TRUE(saved_image);
 
   // Check image dimensions. Images can't be compared since JPEG is lossy.
@@ -737,8 +757,8 @@
   // image.
   user_policy_.payload().Clear();
   user_policy_.Build();
-  fake_session_manager_client_->set_user_policy(kEnterpriseUser1,
-                                                user_policy_.GetBlob());
+  fake_session_manager_client_->set_user_policy(
+      enterprise_account_id_.GetUserEmail(), user_policy_.GetBlob());
   run_loop_.reset(new base::RunLoop);
   store->AddObserver(this);
   store->Load();
@@ -755,7 +775,7 @@
   const gfx::ImageSkia& default_image =
       user_manager::GetDefaultImage(default_image_index);
   EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
-  ExpectNewUserImageInfo(kEnterpriseUser1, default_image_index,
+  ExpectNewUserImageInfo(enterprise_account_id_, default_image_index,
                          base::FilePath());
 
   // Choose a different user image. Verify that the chosen user image is set and
@@ -768,17 +788,18 @@
       user_manager::GetDefaultImage(user_image_index);
 
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(kEnterpriseUser1);
+      ChromeUserManager::Get()->GetUserImageManager(enterprise_account_id_);
   user_image_manager->SaveUserDefaultImageIndex(user_image_index);
 
   EXPECT_TRUE(user->HasDefaultImage());
   EXPECT_EQ(user_image_index, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(user_image, user->GetImage()));
-  ExpectNewUserImageInfo(kEnterpriseUser1, user_image_index, base::FilePath());
+  ExpectNewUserImageInfo(enterprise_account_id_, user_image_index,
+                         base::FilePath());
 }
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_PolicyOverridesUser) {
-  RegisterUser(kEnterpriseUser1);
+  RegisterUser(enterprise_account_id_.GetUserEmail());
   chromeos::StartupUtils::MarkOobeCompleted();
 }
 
@@ -787,10 +808,10 @@
 // previously chosen image.
 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PolicyOverridesUser) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kEnterpriseUser1);
+      user_manager::UserManager::Get()->FindUser(enterprise_account_id_);
   ASSERT_TRUE(user);
 
-  LoginUser(kEnterpriseUser1);
+  LoginUser(enterprise_account_id_.GetUserEmail());
   base::RunLoop().RunUntilIdle();
 
   policy::CloudPolicyStore* store = GetStoreForUser(user);
@@ -802,14 +823,14 @@
       user_manager::GetDefaultImage(user_manager::kFirstDefaultImageIndex);
 
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(kEnterpriseUser1);
+      ChromeUserManager::Get()->GetUserImageManager(enterprise_account_id_);
   user_image_manager->SaveUserDefaultImageIndex(
       user_manager::kFirstDefaultImageIndex);
 
   EXPECT_TRUE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::kFirstDefaultImageIndex, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
-  ExpectNewUserImageInfo(kEnterpriseUser1,
+  ExpectNewUserImageInfo(enterprise_account_id_,
                          user_manager::kFirstDefaultImageIndex,
                          base::FilePath());
 
@@ -818,8 +839,8 @@
   user_policy_.payload().mutable_useravatarimage()->set_value(
       ConstructPolicy(test::kUserAvatarImage2RelativePath));
   user_policy_.Build();
-  fake_session_manager_client_->set_user_policy(kEnterpriseUser1,
-                                                user_policy_.GetBlob());
+  fake_session_manager_client_->set_user_policy(
+      enterprise_account_id_.GetUserEmail(), user_policy_.GetBlob());
   run_loop_.reset(new base::RunLoop);
   store->Load();
   run_loop_->Run();
@@ -827,12 +848,12 @@
   EXPECT_FALSE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
-  ExpectNewUserImageInfo(kEnterpriseUser1,
+  ExpectNewUserImageInfo(enterprise_account_id_,
                          user_manager::User::USER_IMAGE_EXTERNAL,
-                         GetUserImagePath(kEnterpriseUser1, "jpg"));
+                         GetUserImagePath(enterprise_account_id_, "jpg"));
 
   scoped_ptr<gfx::ImageSkia> saved_image =
-      test::ImageLoader(GetUserImagePath(kEnterpriseUser1, "jpg")).Load();
+      test::ImageLoader(GetUserImagePath(enterprise_account_id_, "jpg")).Load();
   ASSERT_TRUE(saved_image);
 
   // Check image dimensions. Images can't be compared since JPEG is lossy.
@@ -842,7 +863,7 @@
 
 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest,
                        PRE_UserDoesNotOverridePolicy) {
-  RegisterUser(kEnterpriseUser1);
+  RegisterUser(enterprise_account_id_.GetUserEmail());
   chromeos::StartupUtils::MarkOobeCompleted();
 }
 
@@ -851,10 +872,10 @@
 // from overriding the previously chosen image.
 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, UserDoesNotOverridePolicy) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(kEnterpriseUser1);
+      user_manager::UserManager::Get()->FindUser(enterprise_account_id_);
   ASSERT_TRUE(user);
 
-  LoginUser(kEnterpriseUser1);
+  LoginUser(enterprise_account_id_.GetUserEmail());
   base::RunLoop().RunUntilIdle();
 
   policy::CloudPolicyStore* store = GetStoreForUser(user);
@@ -865,8 +886,8 @@
   user_policy_.payload().mutable_useravatarimage()->set_value(
       ConstructPolicy(test::kUserAvatarImage2RelativePath));
   user_policy_.Build();
-  fake_session_manager_client_->set_user_policy(kEnterpriseUser1,
-                                                user_policy_.GetBlob());
+  fake_session_manager_client_->set_user_policy(
+      enterprise_account_id_.GetUserEmail(), user_policy_.GetBlob());
   run_loop_.reset(new base::RunLoop);
   store->Load();
   run_loop_->Run();
@@ -874,12 +895,12 @@
   EXPECT_FALSE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
-  ExpectNewUserImageInfo(kEnterpriseUser1,
+  ExpectNewUserImageInfo(enterprise_account_id_,
                          user_manager::User::USER_IMAGE_EXTERNAL,
-                         GetUserImagePath(kEnterpriseUser1, "jpg"));
+                         GetUserImagePath(enterprise_account_id_, "jpg"));
 
   scoped_ptr<gfx::ImageSkia> saved_image =
-      test::ImageLoader(GetUserImagePath(kEnterpriseUser1, "jpg")).Load();
+      test::ImageLoader(GetUserImagePath(enterprise_account_id_, "jpg")).Load();
   ASSERT_TRUE(saved_image);
 
   // Check image dimensions. Images can't be compared since JPEG is lossy.
@@ -889,19 +910,19 @@
   // Choose a different user image. Verify that the user image does not change
   // as policy takes precedence.
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(kEnterpriseUser1);
+      ChromeUserManager::Get()->GetUserImageManager(enterprise_account_id_);
   user_image_manager->SaveUserDefaultImageIndex(
       user_manager::kFirstDefaultImageIndex);
 
   EXPECT_FALSE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, user->image_index());
   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
-  ExpectNewUserImageInfo(kEnterpriseUser1,
+  ExpectNewUserImageInfo(enterprise_account_id_,
                          user_manager::User::USER_IMAGE_EXTERNAL,
-                         GetUserImagePath(kEnterpriseUser1, "jpg"));
+                         GetUserImagePath(enterprise_account_id_, "jpg"));
 
   saved_image =
-      test::ImageLoader(GetUserImagePath(kEnterpriseUser1, "jpg")).Load();
+      test::ImageLoader(GetUserImagePath(enterprise_account_id_, "jpg")).Load();
   ASSERT_TRUE(saved_image);
 
   // Check image dimensions. Images can't be compared since JPEG is lossy.
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
index f9f4a49..df6d304 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
@@ -410,8 +410,7 @@
 }
 
 void UserImageManagerImpl::Job::UpdateUser() {
-  user_manager::User* user =
-      parent_->user_manager_->FindUserAndModify(user_id());
+  user_manager::User* user = parent_->GetUserAndModify();
   if (!user)
     return;
 
@@ -451,7 +450,8 @@
 void UserImageManagerImpl::Job::UpdateLocalState() {
   // Ignore if data stored or cached outside the user's cryptohome is to be
   // treated as ephemeral.
-  if (parent_->user_manager_->IsUserNonCryptohomeDataEphemeral(user_id()))
+  if (parent_->user_manager_->IsUserNonCryptohomeDataEphemeral(
+          AccountId::FromUserEmail(user_id())))
     return;
 
   scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
@@ -769,10 +769,9 @@
   DCHECK_EQ(downloader, profile_downloader.get());
 
   user_manager_->UpdateUserAccountData(
-      user_id(),
+      AccountId::FromUserEmail(user_id()),
       user_manager::UserManager::UserAccountData(
-          downloader->GetProfileFullName(),
-          downloader->GetProfileGivenName(),
+          downloader->GetProfileFullName(), downloader->GetProfileGivenName(),
           downloader->GetProfileLocale()));
   if (!downloading_profile_image_)
     return;
@@ -1017,11 +1016,11 @@
 }
 
 const user_manager::User* UserImageManagerImpl::GetUser() const {
-  return user_manager_->FindUser(user_id());
+  return user_manager_->FindUser(AccountId::FromUserEmail(user_id()));
 }
 
 user_manager::User* UserImageManagerImpl::GetUserAndModify() const {
-  return user_manager_->FindUserAndModify(user_id());
+  return user_manager_->FindUserAndModify(AccountId::FromUserEmail(user_id()));
 }
 
 bool UserImageManagerImpl::IsUserLoggedInAndHasGaiaAccount() const {
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.cc b/chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.cc
index bf501d1..47a774d 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.cc
@@ -171,7 +171,7 @@
   if ((synced_index == local_index) || !IsIndexSupported(synced_index))
     return;
   UserImageManager* image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(user_->email());
+      ChromeUserManager::Get()->GetUserImageManager(user_->GetAccountId());
   if (synced_index == user_manager::User::USER_IMAGE_PROFILE) {
     image_manager->SaveUserImageFromProfileImage();
   } else {
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
index a846b7ac..40e4a0ee 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -206,12 +206,13 @@
 }
 
 UserImageManager* ChromeUserManagerImpl::GetUserImageManager(
-    const std::string& user_id) {
-  UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
+    const AccountId& account_id) {
+  UserImageManagerMap::iterator ui = user_image_managers_.find(account_id);
   if (ui != user_image_managers_.end())
     return ui->second.get();
-  linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
-  user_image_managers_[user_id] = mgr;
+  linked_ptr<UserImageManagerImpl> mgr(
+      new UserImageManagerImpl(account_id.GetUserEmail(), this));
+  user_image_managers_[account_id] = mgr;
   return mgr.get();
 }
 
@@ -316,15 +317,13 @@
 }
 
 void ChromeUserManagerImpl::RemoveUserInternal(
-    const std::string& user_email,
+    const AccountId& account_id,
     user_manager::RemoveUserDelegate* delegate) {
   CrosSettings* cros_settings = CrosSettings::Get();
 
   const base::Closure& callback =
       base::Bind(&ChromeUserManagerImpl::RemoveUserInternal,
-                 weak_factory_.GetWeakPtr(),
-                 user_email,
-                 delegate);
+                 weak_factory_.GetWeakPtr(), account_id, delegate);
 
   // Ensure the value of owner email has been fetched.
   if (CrosSettingsProvider::TRUSTED !=
@@ -335,32 +334,34 @@
   }
   std::string owner;
   cros_settings->GetString(kDeviceOwner, &owner);
-  if (user_email == owner) {
+  if (account_id == AccountId::FromUserEmail(owner)) {
     // Owner is not allowed to be removed from the device.
     return;
   }
-  RemoveNonOwnerUserInternal(user_email, delegate);
+  RemoveNonOwnerUserInternal(account_id, delegate);
 }
 
 void ChromeUserManagerImpl::SaveUserOAuthStatus(
-    const std::string& user_id,
+    const AccountId& account_id,
     user_manager::User::OAuthTokenStatus oauth_token_status) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  ChromeUserManager::SaveUserOAuthStatus(user_id, oauth_token_status);
+  ChromeUserManager::SaveUserOAuthStatus(account_id, oauth_token_status);
 
-  GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
+  GetUserFlow(account_id)->HandleOAuthTokenStatusChange(oauth_token_status);
 }
 
 void ChromeUserManagerImpl::SaveUserDisplayName(
-    const std::string& user_id,
+    const AccountId& account_id,
     const base::string16& display_name) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  ChromeUserManager::SaveUserDisplayName(user_id, display_name);
+  ChromeUserManager::SaveUserDisplayName(account_id, display_name);
 
   // Do not update local state if data stored or cached outside the user's
   // cryptohome is to be treated as ephemeral.
-  if (!IsUserNonCryptohomeDataEphemeral(user_id))
-    supervised_user_manager_->UpdateManagerName(user_id, display_name);
+  if (!IsUserNonCryptohomeDataEphemeral(account_id)) {
+    supervised_user_manager_->UpdateManagerName(account_id.GetUserEmail(),
+                                                display_name);
+  }
 }
 
 void ChromeUserManagerImpl::StopPolicyObserverForTesting() {
@@ -411,14 +412,12 @@
       if (user != NULL) {
         user->set_profile_is_created();
 
-        if (user->HasGaiaAccount()) {
-          UserImageManager* image_manager = GetUserImageManager(user->email());
-          image_manager->UserProfileCreated();
-        }
+        if (user->HasGaiaAccount())
+          GetUserImageManager(user->GetAccountId())->UserProfileCreated();
       }
 
       // If there is pending user switch, do it now.
-      if (!GetPendingUserSwitchID().empty()) {
+      if (GetPendingUserSwitchID().is_valid()) {
         // Call SwitchActiveUser async because otherwise it may cause
         // ProfileManager::GetProfile before the profile gets registered
         // in ProfileManager. It happens in case of sync profile load when
@@ -428,7 +427,7 @@
             base::Bind(&ChromeUserManagerImpl::SwitchActiveUser,
                        weak_factory_.GetWeakPtr(),
                        GetPendingUserSwitchID()));
-        SetPendingUserSwitchID(std::string());
+        SetPendingUserSwitchId(EmptyAccountId());
       }
       break;
     }
@@ -440,7 +439,8 @@
 void ChromeUserManagerImpl::OnExternalDataSet(const std::string& policy,
                                               const std::string& user_id) {
   if (policy == policy::key::kUserAvatarImage)
-    GetUserImageManager(user_id)->OnExternalDataSet(policy);
+    GetUserImageManager(AccountId::FromUserEmail(user_id))
+        ->OnExternalDataSet(policy);
   else if (policy == policy::key::kWallpaperImage)
     WallpaperManager::Get()->OnPolicySet(policy, user_id);
   else
@@ -450,7 +450,8 @@
 void ChromeUserManagerImpl::OnExternalDataCleared(const std::string& policy,
                                                   const std::string& user_id) {
   if (policy == policy::key::kUserAvatarImage)
-    GetUserImageManager(user_id)->OnExternalDataCleared(policy);
+    GetUserImageManager(AccountId::FromUserEmail(user_id))
+        ->OnExternalDataCleared(policy);
   else if (policy == policy::key::kWallpaperImage)
     WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
   else
@@ -462,7 +463,8 @@
     const std::string& user_id,
     scoped_ptr<std::string> data) {
   if (policy == policy::key::kUserAvatarImage)
-    GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
+    GetUserImageManager(AccountId::FromUserEmail(user_id))
+        ->OnExternalDataFetched(policy, data.Pass());
   else if (policy == policy::key::kWallpaperImage)
     WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
   else
@@ -470,7 +472,7 @@
 }
 
 void ChromeUserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
-  const user_manager::User* user = FindUser(user_id);
+  const user_manager::User* user = FindUser(AccountId::FromUserEmail(user_id));
   if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
     return;
   UpdatePublicAccountDisplayName(user_id);
@@ -487,24 +489,24 @@
 }
 
 bool ChromeUserManagerImpl::IsUserNonCryptohomeDataEphemeral(
-    const std::string& user_id) const {
+    const AccountId& account_id) const {
   // Data belonging to the obsolete public accounts whose data has not been
   // removed yet is not ephemeral.
-  bool is_obsolete_public_account = IsPublicAccountMarkedForRemoval(user_id);
+  bool is_obsolete_public_account = IsPublicAccountMarkedForRemoval(account_id);
 
   return !is_obsolete_public_account &&
-         ChromeUserManager::IsUserNonCryptohomeDataEphemeral(user_id);
+         ChromeUserManager::IsUserNonCryptohomeDataEphemeral(account_id);
 }
 
 bool ChromeUserManagerImpl::AreEphemeralUsersEnabled() const {
   policy::BrowserPolicyConnectorChromeOS* connector =
       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   return GetEphemeralUsersEnabled() &&
-         (connector->IsEnterpriseManaged() || !GetOwnerEmail().empty());
+         (connector->IsEnterpriseManaged() || GetOwnerAccountId().is_valid());
 }
 
-void ChromeUserManagerImpl::OnUserRemoved(const std::string& user_id) {
-  RemoveReportingUser(FullyCanonicalize(user_id));
+void ChromeUserManagerImpl::OnUserRemoved(const AccountId& account_id) {
+  RemoveReportingUser(FullyCanonicalize(account_id.GetUserEmail()));
 }
 
 const std::string& ChromeUserManagerImpl::GetApplicationLocale() const {
@@ -516,9 +518,9 @@
 }
 
 void ChromeUserManagerImpl::HandleUserOAuthTokenStatusChange(
-    const std::string& user_id,
+    const AccountId& account_id,
     user_manager::User::OAuthTokenStatus status) const {
-  GetUserFlow(user_id)->HandleOAuthTokenStatusChange(status);
+  GetUserFlow(account_id)->HandleOAuthTokenStatusChange(status);
 }
 
 bool ChromeUserManagerImpl::IsEnterpriseManaged() const {
@@ -528,19 +530,15 @@
 }
 
 void ChromeUserManagerImpl::LoadPublicAccounts(
-    std::set<std::string>* public_sessions_set) {
+    std::set<AccountId>* public_sessions_set) {
   const base::ListValue* prefs_public_sessions =
       GetLocalState()->GetList(kPublicAccounts);
-  std::vector<std::string> public_sessions;
-  ParseUserList(*prefs_public_sessions,
-                std::set<std::string>(),
-                &public_sessions,
+  std::vector<AccountId> public_sessions;
+  ParseUserList(*prefs_public_sessions, std::set<AccountId>(), &public_sessions,
                 public_sessions_set);
-  for (std::vector<std::string>::const_iterator it = public_sessions.begin();
-       it != public_sessions.end();
-       ++it) {
-    users_.push_back(user_manager::User::CreatePublicAccountUser(*it));
-    UpdatePublicAccountDisplayName(*it);
+  for (const AccountId& account_id : public_sessions) {
+    users_.push_back(user_manager::User::CreatePublicAccountUser(account_id));
+    UpdatePublicAccountDisplayName(account_id.GetUserEmail());
   }
 }
 
@@ -559,7 +557,7 @@
   for (user_manager::UserList::iterator ui = users_.begin(), ue = users_.end();
        ui != ue;
        ++ui) {
-    GetUserImageManager((*ui)->email())->LoadUserImage();
+    GetUserImageManager((*ui)->GetAccountId())->LoadUserImage();
   }
 }
 
@@ -571,22 +569,22 @@
       new SessionLengthLimiter(NULL, browser_restart));
 }
 
-bool ChromeUserManagerImpl::IsDemoApp(const std::string& user_id) const {
-  return DemoAppLauncher::IsDemoAppSession(user_id);
+bool ChromeUserManagerImpl::IsDemoApp(const AccountId& account_id) const {
+  return DemoAppLauncher::IsDemoAppSession(account_id.GetUserEmail());
 }
 
-bool ChromeUserManagerImpl::IsKioskApp(const std::string& user_id) const {
+bool ChromeUserManagerImpl::IsKioskApp(const AccountId& account_id) const {
   policy::DeviceLocalAccount::Type device_local_account_type;
-  return policy::IsDeviceLocalAccountUser(user_id,
+  return policy::IsDeviceLocalAccountUser(account_id.GetUserEmail(),
                                           &device_local_account_type) &&
          device_local_account_type ==
              policy::DeviceLocalAccount::TYPE_KIOSK_APP;
 }
 
 bool ChromeUserManagerImpl::IsPublicAccountMarkedForRemoval(
-    const std::string& user_id) const {
-  return user_id ==
-         GetLocalState()->GetString(kPublicAccountPendingDataRemoval);
+    const AccountId& account_id) const {
+  return account_id == AccountId::FromUserEmail(GetLocalState()->GetString(
+                           kPublicAccountPendingDataRemoval));
 }
 
 void ChromeUserManagerImpl::RetrieveTrustedDevicePolicies() {
@@ -595,7 +593,7 @@
     return;
 
   SetEphemeralUsersEnabled(false);
-  SetOwnerEmail(std::string());
+  SetOwnerId(EmptyAccountId());
 
   // Schedule a callback if device policy has not yet been verified.
   if (CrosSettingsProvider::TRUSTED !=
@@ -612,7 +610,7 @@
 
   std::string owner_email;
   cros_settings_->GetString(kDeviceOwner, &owner_email);
-  SetOwnerEmail(owner_email);
+  SetOwnerId(AccountId::FromUserEmail(owner_email));
 
   EnsureUsersLoaded();
 
@@ -626,15 +624,16 @@
     prefs_users_update->Clear();
     for (user_manager::UserList::iterator it = users_.begin();
          it != users_.end();) {
-      const std::string user_email = (*it)->email();
-      if ((*it)->HasGaiaAccount() && user_email != GetOwnerEmail()) {
-        RemoveNonCryptohomeData(user_email);
+      const AccountId account_id = (*it)->GetAccountId();
+      if ((*it)->HasGaiaAccount() && account_id != GetOwnerAccountId()) {
+        RemoveNonCryptohomeData(account_id);
         DeleteUser(*it);
         it = users_.erase(it);
         changed = true;
       } else {
         if ((*it)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
-          prefs_users_update->Append(new base::StringValue(user_email));
+          prefs_users_update->Append(
+              new base::StringValue(account_id.GetUserEmail()));
         ++it;
       }
     }
@@ -663,20 +662,21 @@
       login::GuestAccountId().GetUserEmail());
 }
 
-void ChromeUserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
-  ChromeUserManager::RegularUserLoggedIn(user_id);
+void ChromeUserManagerImpl::RegularUserLoggedIn(const AccountId& account_id) {
+  ChromeUserManager::RegularUserLoggedIn(account_id);
 
   if (FakeOwnership()) {
-    std::string owner_email = GetActiveUser()->email();
-    VLOG(1) << "Set device owner to: " << owner_email;
-    CrosSettings::Get()->SetString(kDeviceOwner, owner_email);
-    SetOwnerEmail(owner_email);
+    const AccountId owner_account_id = GetActiveUser()->GetAccountId();
+    VLOG(1) << "Set device owner to: " << owner_account_id.GetUserEmail();
+    CrosSettings::Get()->SetString(kDeviceOwner,
+                                   owner_account_id.GetUserEmail());
+    SetOwnerId(owner_account_id);
   }
 
   if (IsCurrentUserNew())
-    WallpaperManager::Get()->SetUserWallpaperNow(user_id);
+    WallpaperManager::Get()->SetUserWallpaperNow(account_id.GetUserEmail());
 
-  GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
+  GetUserImageManager(account_id)->UserLoggedIn(IsCurrentUserNew(), false);
 
   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
 
@@ -685,30 +685,31 @@
 }
 
 void ChromeUserManagerImpl::RegularUserLoggedInAsEphemeral(
-    const std::string& user_id) {
+    const AccountId& account_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  ChromeUserManager::RegularUserLoggedInAsEphemeral(user_id);
+  ChromeUserManager::RegularUserLoggedInAsEphemeral(account_id);
 
-  GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
-  WallpaperManager::Get()->SetUserWallpaperNow(user_id);
+  GetUserImageManager(account_id)->UserLoggedIn(IsCurrentUserNew(), false);
+  WallpaperManager::Get()->SetUserWallpaperNow(account_id.GetUserEmail());
 }
 
-void ChromeUserManagerImpl::SupervisedUserLoggedIn(const std::string& user_id) {
+void ChromeUserManagerImpl::SupervisedUserLoggedIn(
+    const AccountId& account_id) {
   // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
 
   // Remove the user from the user list.
-  active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
+  active_user_ = RemoveRegularOrSupervisedUserFromList(account_id);
 
   // If the user was not found on the user list, create a new user.
   if (!GetActiveUser()) {
     SetIsCurrentUserNew(true);
-    active_user_ = user_manager::User::CreateSupervisedUser(user_id);
+    active_user_ = user_manager::User::CreateSupervisedUser(account_id);
     // Leaving OAuth token status at the default state = unknown.
-    WallpaperManager::Get()->SetUserWallpaperNow(user_id);
+    WallpaperManager::Get()->SetUserWallpaperNow(account_id.GetUserEmail());
   } else {
-    if (supervised_user_manager_->CheckForFirstRun(user_id)) {
+    if (supervised_user_manager_->CheckForFirstRun(account_id.GetUserEmail())) {
       SetIsCurrentUserNew(true);
-      WallpaperManager::Get()->SetUserWallpaperNow(user_id);
+      WallpaperManager::Get()->SetUserWallpaperNow(account_id.GetUserEmail());
     } else {
       SetIsCurrentUserNew(false);
     }
@@ -716,16 +717,17 @@
 
   // Add the user to the front of the user list.
   ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
-  prefs_users_update->Insert(0, new base::StringValue(user_id));
+  prefs_users_update->Insert(0,
+                             new base::StringValue(account_id.GetUserEmail()));
   users_.insert(users_.begin(), active_user_);
 
   // Now that user is in the list, save display name.
   if (IsCurrentUserNew()) {
-    SaveUserDisplayName(GetActiveUser()->email(),
+    SaveUserDisplayName(GetActiveUser()->GetAccountId(),
                         GetActiveUser()->GetDisplayName());
   }
 
-  GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), true);
+  GetUserImageManager(account_id)->UserLoggedIn(IsCurrentUserNew(), true);
   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
 
   // Make sure that new data is persisted to Local State.
@@ -733,8 +735,8 @@
 }
 
 bool ChromeUserManagerImpl::HasPendingBootstrap(
-    const std::string& user_id) const {
-  return bootstrap_manager_->HasPendingBootstrap(user_id);
+    const AccountId& account_id) const {
+  return bootstrap_manager_->HasPendingBootstrap(account_id.GetUserEmail());
 }
 
 void ChromeUserManagerImpl::PublicAccountUserLoggedIn(
@@ -745,18 +747,20 @@
   // The UserImageManager chooses a random avatar picture when a user logs in
   // for the first time. Tell the UserImageManager that this user is not new to
   // prevent the avatar from getting changed.
-  GetUserImageManager(user->email())->UserLoggedIn(false, true);
+  GetUserImageManager(user->GetAccountId())->UserLoggedIn(false, true);
   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
 }
 
-void ChromeUserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
+void ChromeUserManagerImpl::KioskAppLoggedIn(
+    const AccountId& kiosk_app_account_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   policy::DeviceLocalAccount::Type device_local_account_type;
-  DCHECK(policy::IsDeviceLocalAccountUser(app_id, &device_local_account_type));
+  DCHECK(policy::IsDeviceLocalAccountUser(kiosk_app_account_id.GetUserEmail(),
+                                          &device_local_account_type));
   DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
             device_local_account_type);
 
-  active_user_ = user_manager::User::CreateKioskAppUser(app_id);
+  active_user_ = user_manager::User::CreateKioskAppUser(kiosk_app_account_id);
   active_user_->SetStubImage(
       user_manager::UserImage(
           *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
@@ -764,7 +768,8 @@
       user_manager::User::USER_IMAGE_INVALID,
       false);
 
-  WallpaperManager::Get()->SetUserWallpaperNow(app_id);
+  WallpaperManager::Get()->SetUserWallpaperNow(
+      kiosk_app_account_id.GetUserEmail());
 
   // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
   // the kiosk_app_id in these objects, removing the need to re-parse the
@@ -776,22 +781,23 @@
            device_local_accounts.begin();
        it != device_local_accounts.end();
        ++it) {
-    if (it->user_id == app_id) {
+    if (it->user_id == kiosk_app_account_id.GetUserEmail()) {
       account = &*it;
       break;
     }
   }
-  std::string kiosk_app_id;
+  std::string kiosk_app_name;
   if (account) {
-    kiosk_app_id = account->kiosk_app_id;
+    kiosk_app_name = account->kiosk_app_id;
   } else {
-    LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
+    LOG(ERROR) << "Logged into nonexistent kiosk-app account: "
+               << kiosk_app_account_id.GetUserEmail();
     NOTREACHED();
   }
 
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   command_line->AppendSwitch(::switches::kForceAppMode);
-  command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
+  command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_name);
 
   // Disable window animation since kiosk app runs in a single full screen
   // window and window animation causes start-up janks.
@@ -800,8 +806,7 @@
 
 void ChromeUserManagerImpl::DemoAccountLoggedIn() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  active_user_ = user_manager::User::CreateKioskAppUser(
-      login::DemoAccountId().GetUserEmail());
+  active_user_ = user_manager::User::CreateKioskAppUser(login::DemoAccountId());
   active_user_->SetStubImage(
       user_manager::UserImage(
           *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
@@ -849,17 +854,17 @@
 }
 
 void ChromeUserManagerImpl::RemoveNonCryptohomeData(
-    const std::string& user_id) {
-  ChromeUserManager::RemoveNonCryptohomeData(user_id);
+    const AccountId& account_id) {
+  ChromeUserManager::RemoveNonCryptohomeData(account_id);
 
-  WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
-  GetUserImageManager(user_id)->DeleteUserImage();
+  WallpaperManager::Get()->RemoveUserWallpaperInfo(account_id.GetUserEmail());
+  GetUserImageManager(account_id)->DeleteUserImage();
 
-  supervised_user_manager_->RemoveNonCryptohomeData(user_id);
+  supervised_user_manager_->RemoveNonCryptohomeData(account_id.GetUserEmail());
 
-  multi_profile_user_controller_->RemoveCachedValues(user_id);
+  multi_profile_user_controller_->RemoveCachedValues(account_id.GetUserEmail());
 
-  EasyUnlockService::ResetLocalStateForUser(user_id);
+  EasyUnlockService::ResetLocalStateForUser(account_id.GetUserEmail());
 }
 
 void
@@ -873,7 +878,8 @@
     return;
   }
 
-  RemoveNonCryptohomeData(public_account_pending_data_removal);
+  RemoveNonCryptohomeData(
+      AccountId::FromUserEmail(public_account_pending_data_removal));
   local_state->ClearPref(kPublicAccountPendingDataRemoval);
 }
 
@@ -903,7 +909,7 @@
        it != old_public_accounts.end();
        ++it) {
     if (users.find(*it) == users.end())
-      RemoveNonCryptohomeData(*it);
+      RemoveNonCryptohomeData(AccountId::FromUserEmail(*it));
   }
 }
 
@@ -976,8 +982,8 @@
     if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
       users_.insert(users_.begin(), GetLoggedInUser());
     else
-      users_.insert(users_.begin(),
-                    user_manager::User::CreatePublicAccountUser(*it));
+      users_.insert(users_.begin(), user_manager::User::CreatePublicAccountUser(
+                                        AccountId::FromUserEmail(*it)));
     UpdatePublicAccountDisplayName(*it);
   }
 
@@ -986,7 +992,7 @@
            ue = users_.begin() + new_public_accounts.size();
        ui != ue;
        ++ui) {
-    GetUserImageManager((*ui)->email())->LoadUserImage();
+    GetUserImageManager((*ui)->GetAccountId())->LoadUserImage();
   }
 
   // Remove data belonging to public accounts that are no longer found on the
@@ -1008,34 +1014,36 @@
   }
 
   // Set or clear the display name.
-  SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
+  SaveUserDisplayName(AccountId::FromUserEmail(user_id),
+                      base::UTF8ToUTF16(display_name));
 }
 
 UserFlow* ChromeUserManagerImpl::GetCurrentUserFlow() const {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (!IsUserLoggedIn())
     return GetDefaultUserFlow();
-  return GetUserFlow(GetLoggedInUser()->email());
+  return GetUserFlow(GetLoggedInUser()->GetAccountId());
 }
 
-UserFlow* ChromeUserManagerImpl::GetUserFlow(const std::string& user_id) const {
+UserFlow* ChromeUserManagerImpl::GetUserFlow(
+    const AccountId& account_id) const {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  FlowMap::const_iterator it = specific_flows_.find(user_id);
+  FlowMap::const_iterator it = specific_flows_.find(account_id);
   if (it != specific_flows_.end())
     return it->second;
   return GetDefaultUserFlow();
 }
 
-void ChromeUserManagerImpl::SetUserFlow(const std::string& user_id,
+void ChromeUserManagerImpl::SetUserFlow(const AccountId& account_id,
                                         UserFlow* flow) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  ResetUserFlow(user_id);
-  specific_flows_[user_id] = flow;
+  ResetUserFlow(account_id);
+  specific_flows_[account_id] = flow;
 }
 
-void ChromeUserManagerImpl::ResetUserFlow(const std::string& user_id) {
+void ChromeUserManagerImpl::ResetUserFlow(const AccountId& account_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  FlowMap::iterator it = specific_flows_.find(user_id);
+  FlowMap::iterator it = specific_flows_.find(account_id);
   if (it != specific_flows_.end()) {
     delete it->second;
     specific_flows_.erase(it);
@@ -1072,7 +1080,7 @@
   // before the crash.
   if (user_switch_pending &&
       !UserSessionManager::GetInstance()->UserSessionsRestoreInProgress()) {
-    SetPendingUserSwitchID(added_user->email());
+    SetPendingUserSwitchId(added_user->GetAccountId());
   }
 
   UpdateNumberOfUsers();
@@ -1087,8 +1095,9 @@
 
 void ChromeUserManagerImpl::RemovePendingBootstrapUser(
     const std::string& user_id) {
-  DCHECK(HasPendingBootstrap(user_id));
-  RemoveNonOwnerUserInternal(user_id, NULL);
+  const AccountId account_id(AccountId::FromUserEmail(user_id));
+  DCHECK(HasPendingBootstrap(account_id));
+  RemoveNonOwnerUserInternal(account_id, nullptr);
 }
 
 void ChromeUserManagerImpl::UpdateNumberOfUsers() {
@@ -1142,7 +1151,8 @@
     const std::string& user_email,
     const AffiliationIDSet& user_affiliation_ids) {
   std::string canonicalized_email = FullyCanonicalize(user_email);
-  user_manager::User* user = FindUserAndModify(canonicalized_email);
+  user_manager::User* user =
+      FindUserAndModify(AccountId::FromUserEmail(canonicalized_email));
 
   if (user) {
     policy::BrowserPolicyConnectorChromeOS const* const connector =
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h
index dbbf3f5..20cbdba 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h
@@ -27,6 +27,7 @@
 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -69,12 +70,12 @@
   // UserManagerInterface implementation:
   BootstrapManager* GetBootstrapManager() override;
   MultiProfileUserController* GetMultiProfileUserController() override;
-  UserImageManager* GetUserImageManager(const std::string& user_id) override;
+  UserImageManager* GetUserImageManager(const AccountId& account_id) override;
   SupervisedUserManager* GetSupervisedUserManager() override;
   UserFlow* GetCurrentUserFlow() const override;
-  UserFlow* GetUserFlow(const std::string& user_id) const override;
-  void SetUserFlow(const std::string& user_id, UserFlow* flow) override;
-  void ResetUserFlow(const std::string& user_id) override;
+  UserFlow* GetUserFlow(const AccountId& account_id) const override;
+  void SetUserFlow(const AccountId& account_id, UserFlow* flow) override;
+  void ResetUserFlow(const AccountId& account_id) override;
 
   // UserManager implementation:
   void Shutdown() override;
@@ -84,13 +85,13 @@
   user_manager::UserList GetUnlockUsers() const override;
   void SessionStarted() override;
   void SaveUserOAuthStatus(
-      const std::string& user_id,
+      const AccountId& account_id,
       user_manager::User::OAuthTokenStatus oauth_token_status) override;
-  void SaveUserDisplayName(const std::string& user_id,
+  void SaveUserDisplayName(const AccountId& account_id,
                            const base::string16& display_name) override;
   bool CanCurrentUserLock() const override;
   bool IsUserNonCryptohomeDataEphemeral(
-      const std::string& user_id) const override;
+      const AccountId& account_id) const override;
   bool AreSupervisedUsersAllowed() const override;
 
   // content::NotificationObserver implementation.
@@ -115,7 +116,7 @@
 
   // UserManagerBase implementation:
   bool AreEphemeralUsersEnabled() const override;
-  void OnUserRemoved(const std::string& user_id) override;
+  void OnUserRemoved(const AccountId& account_id) override;
 
   // ChromeUserManager implementation:
   bool ShouldReportUser(const std::string& user_id) const override;
@@ -127,31 +128,31 @@
   const std::string& GetApplicationLocale() const override;
   PrefService* GetLocalState() const override;
   void HandleUserOAuthTokenStatusChange(
-      const std::string& user_id,
+      const AccountId& account_id,
       user_manager::User::OAuthTokenStatus status) const override;
   bool IsEnterpriseManaged() const override;
-  void LoadPublicAccounts(std::set<std::string>* users_set) override;
+  void LoadPublicAccounts(std::set<AccountId>* users_set) override;
   void NotifyOnLogin() override;
   void NotifyUserAddedToSession(const user_manager::User* added_user,
                                 bool user_switch_pending) override;
   void PerformPreUserListLoadingActions() override;
   void PerformPostUserListLoadingActions() override;
   void PerformPostUserLoggedInActions(bool browser_restart) override;
-  void RemoveNonCryptohomeData(const std::string& user_id) override;
-  void RemoveUserInternal(const std::string& user_email,
+  void RemoveNonCryptohomeData(const AccountId& account_id) override;
+  void RemoveUserInternal(const AccountId& account_id,
                           user_manager::RemoveUserDelegate* delegate) override;
-  bool IsDemoApp(const std::string& user_id) const override;
-  bool IsKioskApp(const std::string& user_id) const override;
+  bool IsDemoApp(const AccountId& account_id) const override;
+  bool IsKioskApp(const AccountId& account_id) const override;
   bool IsPublicAccountMarkedForRemoval(
-      const std::string& user_id) const override;
+      const AccountId& account_id) const override;
   void DemoAccountLoggedIn() override;
   void GuestUserLoggedIn() override;
-  void KioskAppLoggedIn(const std::string& app_id) override;
+  void KioskAppLoggedIn(const AccountId& kiosk_app_account_id) override;
   void PublicAccountUserLoggedIn(user_manager::User* user) override;
-  void RegularUserLoggedIn(const std::string& user_id) override;
-  void RegularUserLoggedInAsEphemeral(const std::string& user_id) override;
-  void SupervisedUserLoggedIn(const std::string& user_id) override;
-  bool HasPendingBootstrap(const std::string& user_id) const override;
+  void RegularUserLoggedIn(const AccountId& account_id) override;
+  void RegularUserLoggedInAsEphemeral(const AccountId& account_id) override;
+  void SupervisedUserLoggedIn(const AccountId& account_id) override;
+  bool HasPendingBootstrap(const AccountId& account_id) const override;
 
  private:
   friend class SupervisedUserManagerImpl;
@@ -159,8 +160,8 @@
   friend class WallpaperManager;
   friend class WallpaperManagerTest;
 
-  typedef base::hash_map<std::string, linked_ptr<UserImageManager> >
-      UserImageManagerMap;
+  using UserImageManagerMap =
+      base::hash_map<AccountId, linked_ptr<UserImageManager> >;
 
   ChromeUserManagerImpl();
 
@@ -237,7 +238,7 @@
   // Session length limiter.
   scoped_ptr<SessionLengthLimiter> session_length_limiter_;
 
-  typedef std::map<std::string, UserFlow*> FlowMap;
+  using FlowMap = std::map<AccountId, UserFlow*>;
 
   // Lazy-initialized default flow.
   mutable scoped_ptr<UserFlow> default_flow_;
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
index 7191f0c..88fec2c9 100644
--- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
+++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -20,24 +20,23 @@
 FakeChromeUserManager::FakeChromeUserManager()
     : supervised_user_manager_(new FakeSupervisedUserManager),
       bootstrap_manager_(NULL),
-      multi_profile_user_controller_(NULL) {
-}
+      multi_profile_user_controller_(NULL) {}
 
 FakeChromeUserManager::~FakeChromeUserManager() {
 }
 
 const user_manager::User* FakeChromeUserManager::AddUser(
-    const std::string& email) {
-  return AddUserWithAffiliation(email, false);
+    const AccountId& account_id) {
+  return AddUserWithAffiliation(account_id, false);
 }
 
 const user_manager::User* FakeChromeUserManager::AddUserWithAffiliation(
-    const std::string& email,
+    const AccountId& account_id,
     bool is_affiliated) {
-  user_manager::User* user = user_manager::User::CreateRegularUser(email);
+  user_manager::User* user = user_manager::User::CreateRegularUser(account_id);
   user->set_affiliation(is_affiliated);
-  user->set_username_hash(
-      ProfileHelper::GetUserIdHashByUserIdForTesting(email));
+  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
+      account_id.GetUserEmail()));
   user->SetStubImage(user_manager::UserImage(
                          *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
                              IDR_PROFILE_PICTURE_LOADING)),
@@ -47,10 +46,11 @@
 }
 
 const user_manager::User* FakeChromeUserManager::AddPublicAccountUser(
-    const std::string& email) {
-  user_manager::User* user = user_manager::User::CreatePublicAccountUser(email);
-  user->set_username_hash(
-      ProfileHelper::GetUserIdHashByUserIdForTesting(email));
+    const AccountId& account_id) {
+  user_manager::User* user =
+      user_manager::User::CreatePublicAccountUser(account_id);
+  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
+      account_id.GetUserEmail()));
   user->SetStubImage(user_manager::UserImage(
                          *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
                              IDR_PROFILE_PICTURE_LOADING)),
@@ -60,16 +60,17 @@
 }
 
 void FakeChromeUserManager::AddKioskAppUser(
-    const std::string& kiosk_app_username) {
+    const AccountId& kiosk_app_account_id) {
   user_manager::User* user =
-      user_manager::User::CreateKioskAppUser(kiosk_app_username);
-  user->set_username_hash(
-      ProfileHelper::GetUserIdHashByUserIdForTesting(kiosk_app_username));
+      user_manager::User::CreateKioskAppUser(kiosk_app_account_id);
+  user->set_username_hash(ProfileHelper::GetUserIdHashByUserIdForTesting(
+      kiosk_app_account_id.GetUserEmail()));
   users_.push_back(user);
 }
 
-void FakeChromeUserManager::LoginUser(const std::string& email) {
-  UserLoggedIn(email, ProfileHelper::GetUserIdHashByUserIdForTesting(email),
+void FakeChromeUserManager::LoginUser(const AccountId& account_id) {
+  UserLoggedIn(account_id, ProfileHelper::GetUserIdHashByUserIdForTesting(
+                               account_id.GetUserEmail()),
                false /* browser_restart */);
 }
 
@@ -87,58 +88,59 @@
 }
 
 UserImageManager* FakeChromeUserManager::GetUserImageManager(
-    const std::string& /* user_id */) {
+    const AccountId& /* account_id */) {
   return nullptr;
 }
 
-void FakeChromeUserManager::SetUserFlow(const std::string& email,
+void FakeChromeUserManager::SetUserFlow(const AccountId& account_id,
                                         UserFlow* flow) {
-  ResetUserFlow(email);
-  specific_flows_[email] = flow;
+  ResetUserFlow(account_id);
+  specific_flows_[account_id] = flow;
 }
 
 UserFlow* FakeChromeUserManager::GetCurrentUserFlow() const {
   if (!IsUserLoggedIn())
     return GetDefaultUserFlow();
-  return GetUserFlow(GetLoggedInUser()->email());
+  return GetUserFlow(GetLoggedInUser()->GetAccountId());
 }
 
-UserFlow* FakeChromeUserManager::GetUserFlow(const std::string& email) const {
-  FlowMap::const_iterator it = specific_flows_.find(email);
+UserFlow* FakeChromeUserManager::GetUserFlow(
+    const AccountId& account_id) const {
+  FlowMap::const_iterator it = specific_flows_.find(account_id);
   if (it != specific_flows_.end())
     return it->second;
   return GetDefaultUserFlow();
 }
 
-void FakeChromeUserManager::ResetUserFlow(const std::string& email) {
-  FlowMap::iterator it = specific_flows_.find(email);
+void FakeChromeUserManager::ResetUserFlow(const AccountId& account_id) {
+  FlowMap::iterator it = specific_flows_.find(account_id);
   if (it != specific_flows_.end()) {
     delete it->second;
     specific_flows_.erase(it);
   }
 }
 
-void FakeChromeUserManager::SwitchActiveUser(const std::string& email) {
-  active_user_id_ = email;
+void FakeChromeUserManager::SwitchActiveUser(const AccountId& account_id) {
+  active_account_id_ = account_id;
   ProfileHelper::Get()->ActiveUserHashChanged(
-      ProfileHelper::GetUserIdHashByUserIdForTesting(email));
-  if (!users_.empty() && !active_user_id_.empty()) {
+      ProfileHelper::GetUserIdHashByUserIdForTesting(
+          account_id.GetUserEmail()));
+  if (!users_.empty() && active_account_id_.is_valid()) {
     for (user_manager::User* user : users_)
-      user->set_is_active(user->email() == active_user_id_);
+      user->set_is_active(user->GetAccountId() == active_account_id_);
   }
 }
 
-const std::string& FakeChromeUserManager::GetOwnerEmail() const {
-  return owner_email_;
+const AccountId& FakeChromeUserManager::GetOwnerAccountId() const {
+  return owner_account_id_;
 }
 
 void FakeChromeUserManager::SessionStarted() {
 }
 
 void FakeChromeUserManager::RemoveUser(
-    const std::string& email,
-    user_manager::RemoveUserDelegate* delegate) {
-}
+    const AccountId& account_id,
+    user_manager::RemoveUserDelegate* delegate) {}
 
 user_manager::UserList
 FakeChromeUserManager::GetUsersAllowedForSupervisedUsersCreation() const {
@@ -181,15 +183,14 @@
 }
 
 bool FakeChromeUserManager::FindKnownUserPrefs(
-    const user_manager::UserID& user_id,
+    const AccountId& account_id,
     const base::DictionaryValue** out_value) {
   return false;
 }
 
 void FakeChromeUserManager::UpdateKnownUserPrefs(
-    const user_manager::UserID& user_id,
+    const AccountId& account_id,
     const base::DictionaryValue& values,
-    bool clear) {
-}
+    bool clear) {}
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
index d5c90fcc..6c4d975 100644
--- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
+++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
@@ -29,46 +29,46 @@
   ~FakeChromeUserManager() override;
 
   // Create and add a kiosk app user.
-  void AddKioskAppUser(const std::string& kiosk_app_username);
+  void AddKioskAppUser(const AccountId& kiosk_app_account_id);
 
   // Create and add a public account user.
-  const user_manager::User* AddPublicAccountUser(const std::string& email);
+  const user_manager::User* AddPublicAccountUser(const AccountId& account_id);
 
   // Calculates the user name hash and calls UserLoggedIn to login a user.
-  void LoginUser(const std::string& email);
+  void LoginUser(const AccountId& account_id);
 
   // UserManager overrides.
   user_manager::UserList GetUsersAllowedForMultiProfile() const override;
 
   // user_manager::FakeUserManager override.
-  const user_manager::User* AddUser(const std::string& email) override;
-  const user_manager::User* AddUserWithAffiliation(const std::string& email,
+  const user_manager::User* AddUser(const AccountId& account_id) override;
+  const user_manager::User* AddUserWithAffiliation(const AccountId& account_id,
                                                    bool is_affiliated) override;
 
   // UserManagerInterface implementation.
   BootstrapManager* GetBootstrapManager() override;
   MultiProfileUserController* GetMultiProfileUserController() override;
-  UserImageManager* GetUserImageManager(const std::string& user_id) override;
+  UserImageManager* GetUserImageManager(const AccountId& account_id) override;
   SupervisedUserManager* GetSupervisedUserManager() override;
-  void SetUserFlow(const std::string& email, UserFlow* flow) override;
+  void SetUserFlow(const AccountId& account_id, UserFlow* flow) override;
   UserFlow* GetCurrentUserFlow() const override;
-  UserFlow* GetUserFlow(const std::string& email) const override;
-  void ResetUserFlow(const std::string& email) override;
+  UserFlow* GetUserFlow(const AccountId& account_id) const override;
+  void ResetUserFlow(const AccountId& account_id) override;
   user_manager::UserList GetUsersAllowedForSupervisedUsersCreation()
       const override;
-  void SwitchActiveUser(const std::string& email) override;
-  const std::string& GetOwnerEmail() const override;
+  void SwitchActiveUser(const AccountId& account_id) override;
+  const AccountId& GetOwnerAccountId() const override;
   void SessionStarted() override;
-  void RemoveUser(const std::string& email,
+  void RemoveUser(const AccountId& account_id,
                   user_manager::RemoveUserDelegate* delegate) override;
-  bool FindKnownUserPrefs(const user_manager::UserID& user_id,
+  bool FindKnownUserPrefs(const AccountId& account_id,
                           const base::DictionaryValue** out_value) override;
-  void UpdateKnownUserPrefs(const user_manager::UserID& user_id,
+  void UpdateKnownUserPrefs(const AccountId& account_id,
                             const base::DictionaryValue& values,
                             bool clear) override;
 
-  void set_owner_email(const std::string& owner_email) {
-    owner_email_ = owner_email;
+  void set_owner_id(const AccountId& owner_account_id) {
+    owner_account_id_ = owner_account_id;
   }
 
   void set_bootstrap_manager(BootstrapManager* bootstrap_manager) {
@@ -85,16 +85,16 @@
   UserFlow* GetDefaultUserFlow() const;
 
   scoped_ptr<FakeSupervisedUserManager> supervised_user_manager_;
-  std::string owner_email_;
+  AccountId owner_account_id_ = EmptyAccountId();
 
   BootstrapManager* bootstrap_manager_;
   MultiProfileUserController* multi_profile_user_controller_;
 
-  typedef std::map<std::string, UserFlow*> FlowMap;
-
   // Lazy-initialized default flow.
   mutable scoped_ptr<UserFlow> default_flow_;
 
+  using FlowMap = std::map<AccountId, UserFlow*>;
+
   // Specific flows by user e-mail.
   // Keys should be canonicalized before access.
   FlowMap specific_flows_;
diff --git a/chrome/browser/chromeos/login/users/mock_user_manager.cc b/chrome/browser/chromeos/login/users/mock_user_manager.cc
index 0e79f65..20be180 100644
--- a/chrome/browser/chromeos/login/users/mock_user_manager.cc
+++ b/chrome/browser/chromeos/login/users/mock_user_manager.cc
@@ -56,8 +56,9 @@
   return user_list_;
 }
 
-const std::string& MockUserManager::GetOwnerEmail() const {
-  return GetLoggedInUser()->email();
+const AccountId& MockUserManager::GetOwnerAccountId() const {
+  temporary_owner_account_id_ = GetLoggedInUser()->GetAccountId();
+  return temporary_owner_account_id_;
 }
 
 const user_manager::User* MockUserManager::GetActiveUser() const {
@@ -81,7 +82,7 @@
 }
 
 UserImageManager* MockUserManager::GetUserImageManager(
-    const std::string& user_id) {
+    const AccountId& account_id) {
   return NULL;
 }
 
@@ -90,43 +91,44 @@
 }
 
 // Creates a new User instance.
-void MockUserManager::SetActiveUser(const std::string& email) {
+void MockUserManager::SetActiveUser(const AccountId& account_id) {
   ClearUserList();
-  AddUser(email);
+  AddUser(account_id);
 }
 
 UserFlow* MockUserManager::GetCurrentUserFlow() const {
   return user_flow_.get();
 }
 
-UserFlow* MockUserManager::GetUserFlow(const std::string&) const {
+UserFlow* MockUserManager::GetUserFlow(const AccountId&) const {
   return user_flow_.get();
 }
 
 user_manager::User* MockUserManager::CreatePublicAccountUser(
-    const std::string& email) {
+    const AccountId& account_id) {
   ClearUserList();
-  user_manager::User* user = user_manager::User::CreatePublicAccountUser(email);
+  user_manager::User* user =
+      user_manager::User::CreatePublicAccountUser(account_id);
   user_list_.push_back(user);
   ProfileHelper::Get()->SetProfileToUserMappingForTesting(user);
   return user_list_.back();
 }
 
 user_manager::User* MockUserManager::CreateKioskAppUser(
-    const std::string& email) {
+    const AccountId& account_id) {
   ClearUserList();
-  user_list_.push_back(user_manager::User::CreateKioskAppUser(email));
+  user_list_.push_back(user_manager::User::CreateKioskAppUser(account_id));
   ProfileHelper::Get()->SetProfileToUserMappingForTesting(user_list_.back());
   return user_list_.back();
 }
 
-void MockUserManager::AddUser(const std::string& email) {
-  AddUserWithAffiliation(email, false);
+void MockUserManager::AddUser(const AccountId& account_id) {
+  AddUserWithAffiliation(account_id, false);
 }
 
-void MockUserManager::AddUserWithAffiliation(const std::string& email,
+void MockUserManager::AddUserWithAffiliation(const AccountId& account_id,
                                              bool is_affiliated) {
-  user_manager::User* user = user_manager::User::CreateRegularUser(email);
+  user_manager::User* user = user_manager::User::CreateRegularUser(account_id);
   user->set_affiliation(is_affiliated);
   user_list_.push_back(user);
   ProfileHelper::Get()->SetProfileToUserMappingForTesting(user);
@@ -134,17 +136,16 @@
 
 void MockUserManager::ClearUserList() {
   // Can't use STLDeleteElements because of the protected destructor of User.
-  user_manager::UserList::iterator user;
-  for (user = user_list_.begin(); user != user_list_.end(); ++user)
+  for (user_manager::UserList::iterator user = user_list_.begin();
+       user != user_list_.end(); ++user)
     delete *user;
   user_list_.clear();
 }
 
 bool MockUserManager::ShouldReportUser(const std::string& user_id) const {
   for (const auto& user : user_list_) {
-    if (user->GetUserID() == user_id) {
+    if (user->email() == user_id)
       return user->is_affiliated();
-    }
   }
   NOTREACHED();
   return false;
diff --git a/chrome/browser/chromeos/login/users/mock_user_manager.h b/chrome/browser/chromeos/login/users/mock_user_manager.h
index bc05a8f..77a25ad 100644
--- a/chrome/browser/chromeos/login/users/mock_user_manager.h
+++ b/chrome/browser/chromeos/login/users/mock_user_manager.h
@@ -13,6 +13,7 @@
 #include "chrome/browser/chromeos/login/users/affiliation.h"
 #include "chrome/browser/chromeos/login/users/avatar/mock_user_image_manager.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_image/user_image.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -33,27 +34,26 @@
                      user_manager::UserList(void));
   MOCK_CONST_METHOD0(GetLoggedInUsers, const user_manager::UserList&(void));
   MOCK_CONST_METHOD0(GetLRULoggedInUsers, const user_manager::UserList&(void));
-  MOCK_METHOD3(UserLoggedIn, void(
-      const std::string&, const std::string&, bool));
-  MOCK_METHOD1(SwitchActiveUser, void(const std::string& email));
+  MOCK_METHOD3(UserLoggedIn, void(const AccountId&, const std::string&, bool));
+  MOCK_METHOD1(SwitchActiveUser, void(const AccountId& account_id));
   MOCK_METHOD0(SessionStarted, void(void));
   MOCK_METHOD2(RemoveUser,
-               void(const std::string&, user_manager::RemoveUserDelegate*));
-  MOCK_METHOD1(RemoveUserFromList, void(const std::string&));
-  MOCK_CONST_METHOD1(IsKnownUser, bool(const std::string&));
-  MOCK_CONST_METHOD1(FindUser, const user_manager::User*(const std::string&));
-  MOCK_METHOD1(FindUserAndModify, user_manager::User*(const std::string&));
+               void(const AccountId&, user_manager::RemoveUserDelegate*));
+  MOCK_METHOD1(RemoveUserFromList, void(const AccountId&));
+  MOCK_CONST_METHOD1(IsKnownUser, bool(const AccountId&));
+  MOCK_CONST_METHOD1(FindUser, const user_manager::User*(const AccountId&));
+  MOCK_METHOD1(FindUserAndModify, user_manager::User*(const AccountId&));
   MOCK_METHOD2(SaveUserOAuthStatus,
-               void(const std::string&, user_manager::User::OAuthTokenStatus));
-  MOCK_METHOD2(SaveForceOnlineSignin, void(const std::string&, bool));
-  MOCK_METHOD2(SaveUserDisplayName, void(const std::string&,
-                                         const base::string16&));
+               void(const AccountId&, user_manager::User::OAuthTokenStatus));
+  MOCK_METHOD2(SaveForceOnlineSignin, void(const AccountId&, bool));
+  MOCK_METHOD2(SaveUserDisplayName,
+               void(const AccountId&, const base::string16&));
   MOCK_METHOD2(UpdateUserAccountData,
-               void(const std::string&, const UserAccountData&));
-  MOCK_CONST_METHOD1(GetUserDisplayName, base::string16(const std::string&));
-  MOCK_METHOD2(SaveUserDisplayEmail, void(const std::string&,
-                                          const std::string&));
-  MOCK_CONST_METHOD1(GetUserDisplayEmail, std::string(const std::string&));
+               void(const AccountId&, const UserAccountData&));
+  MOCK_CONST_METHOD1(GetUserDisplayName, base::string16(const AccountId&));
+  MOCK_METHOD2(SaveUserDisplayEmail,
+               void(const AccountId&, const std::string&));
+  MOCK_CONST_METHOD1(GetUserDisplayEmail, std::string(const AccountId&));
   MOCK_CONST_METHOD0(IsCurrentUserOwner, bool(void));
   MOCK_CONST_METHOD0(IsCurrentUserNew, bool(void));
   MOCK_CONST_METHOD0(IsCurrentUserNonCryptohomeDataEphemeral, bool(void));
@@ -66,8 +66,7 @@
   MOCK_CONST_METHOD0(IsLoggedInAsKioskApp, bool(void));
   MOCK_CONST_METHOD0(IsLoggedInAsStub, bool(void));
   MOCK_CONST_METHOD0(IsSessionStarted, bool(void));
-  MOCK_CONST_METHOD1(IsUserNonCryptohomeDataEphemeral,
-                     bool(const std::string&));
+  MOCK_CONST_METHOD1(IsUserNonCryptohomeDataEphemeral, bool(const AccountId&));
   MOCK_METHOD1(AddObserver, void(UserManager::Observer*));
   MOCK_METHOD1(RemoveObserver, void(UserManager::Observer*));
   MOCK_METHOD1(AddSessionStateObserver,
@@ -82,31 +81,28 @@
   MOCK_CONST_METHOD0(GetApplicationLocale, const std::string&(void));
   MOCK_CONST_METHOD0(GetLocalState, PrefService*(void));
   MOCK_CONST_METHOD2(HandleUserOAuthTokenStatusChange,
-                     void(const std::string&,
+                     void(const AccountId&,
                           user_manager::User::OAuthTokenStatus status));
   MOCK_CONST_METHOD0(IsEnterpriseManaged, bool(void));
-  MOCK_METHOD1(LoadPublicAccounts, void(std::set<std::string>*));
+  MOCK_METHOD1(LoadPublicAccounts, void(std::set<AccountId>*));
   MOCK_METHOD0(PerformPreUserListLoadingActions, void(void));
   MOCK_METHOD0(PerformPostUserListLoadingActions, void(void));
   MOCK_METHOD1(PerformPostUserLoggedInActions, void(bool));
-  MOCK_CONST_METHOD1(IsDemoApp, bool(const std::string&));
-  MOCK_CONST_METHOD1(IsKioskApp, bool(const std::string&));
-  MOCK_CONST_METHOD1(IsPublicAccountMarkedForRemoval, bool(const std::string&));
+  MOCK_CONST_METHOD1(IsDemoApp, bool(const AccountId&));
+  MOCK_CONST_METHOD1(IsKioskApp, bool(const AccountId&));
+  MOCK_CONST_METHOD1(IsPublicAccountMarkedForRemoval, bool(const AccountId&));
   MOCK_METHOD0(DemoAccountLoggedIn, void(void));
-  MOCK_METHOD1(KioskAppLoggedIn, void(const std::string&));
+  MOCK_METHOD1(KioskAppLoggedIn, void(const AccountId&));
   MOCK_METHOD1(PublicAccountUserLoggedIn, void(user_manager::User*));
-  MOCK_METHOD1(SupervisedUserLoggedIn, void(const std::string&));
-  MOCK_METHOD1(OnUserRemoved, void(const std::string&));
-  MOCK_METHOD2(SetUserAffiliation,
-               void(const std::string& user_id,
-                    const chromeos::AffiliationIDSet& user_affiliation_ids));
+  MOCK_METHOD1(SupervisedUserLoggedIn, void(const AccountId&));
+  MOCK_METHOD1(OnUserRemoved, void(const AccountId&));
 
   // You can't mock these functions easily because nobody can create
   // User objects but the ChromeUserManager and us.
   const user_manager::UserList& GetUsers() const override;
   const user_manager::User* GetLoggedInUser() const override;
   user_manager::UserList GetUnlockUsers() const override;
-  const std::string& GetOwnerEmail() const override;
+  const AccountId& GetOwnerAccountId() const override;
   user_manager::User* GetLoggedInUser() override;
   const user_manager::User* GetActiveUser() const override;
   user_manager::User* GetActiveUser() override;
@@ -115,35 +111,38 @@
   // ChromeUserManager overrides:
   BootstrapManager* GetBootstrapManager() override;
   MultiProfileUserController* GetMultiProfileUserController() override;
-  UserImageManager* GetUserImageManager(const std::string& user_id) override;
+  UserImageManager* GetUserImageManager(const AccountId& account_id) override;
   SupervisedUserManager* GetSupervisedUserManager() override;
-  MOCK_METHOD2(SetUserFlow, void(const std::string&, UserFlow*));
-  MOCK_METHOD1(ResetUserFlow, void(const std::string&));
+  MOCK_METHOD2(SetUserFlow, void(const AccountId&, UserFlow*));
+  MOCK_METHOD1(ResetUserFlow, void(const AccountId&));
   UserFlow* GetCurrentUserFlow() const override;
-  UserFlow* GetUserFlow(const std::string&) const override;
+  UserFlow* GetUserFlow(const AccountId&) const override;
+  MOCK_METHOD2(SetUserAffiliation,
+               void(const std::string& user_id,
+                    const chromeos::AffiliationIDSet& user_affiliation_ids));
 
   bool ShouldReportUser(const std::string& user_id) const override;
 
   // Sets a new User instance. Users previously created by this MockUserManager
   // become invalid.
-  void SetActiveUser(const std::string& email);
+  void SetActiveUser(const AccountId& account_id);
 
   // Creates a new public session user. Users previously created by this
   // MockUserManager become invalid.
-  user_manager::User* CreatePublicAccountUser(const std::string& email);
+  user_manager::User* CreatePublicAccountUser(const AccountId& account_id);
 
   // Creates a new kiosk app user. Users previously created by this
   // MockUserManager become invalid.
-  user_manager::User* CreateKioskAppUser(const std::string& user_id);
+  user_manager::User* CreateKioskAppUser(const AccountId& account_id);
 
   // Adds a new User instance to the back of the user list. Users previously
   // created by this MockUserManager remain valid. The added User is not
   // affiliated with the domain, that owns the device.
-  void AddUser(const std::string& email);
+  void AddUser(const AccountId& account_id);
 
   // The same as AddUser, but allows specifying affiliation with the domain,
   // that owns the device.
-  void AddUserWithAffiliation(const std::string& email, bool is_affiliated);
+  void AddUserWithAffiliation(const AccountId& account_id, bool is_affiliated);
 
   // Clears the user list and the active user. Users previously created by this
   // MockUserManager become invalid.
@@ -153,6 +152,10 @@
   scoped_ptr<MockUserImageManager> user_image_manager_;
   scoped_ptr<FakeSupervisedUserManager> supervised_user_manager_;
   user_manager::UserList user_list_;
+  // TODO (alemate): remove temporary_owner_account_id_ as soon as
+  // User::GetAccountId will
+  // return constant reference. crbug.com/546863
+  mutable AccountId temporary_owner_account_id_ = EmptyAccountId();
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc b/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc
index 04c945e..68cceed 100644
--- a/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc
+++ b/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc
@@ -116,7 +116,12 @@
   MultiProfileUserControllerTest()
       : fake_user_manager_(new FakeChromeUserManager),
         user_manager_enabler_(fake_user_manager_),
-        user_not_allowed_count_(0) {}
+        user_not_allowed_count_(0) {
+    for (size_t i = 0; i < arraysize(kUsers); ++i) {
+      test_users_.push_back(AccountId::FromUserEmail(kUsers[i]));
+    }
+  }
+
   ~MultiProfileUserControllerTest() override {}
 
   void SetUp() override {
@@ -126,14 +131,15 @@
     controller_.reset(new MultiProfileUserController(
         this, TestingBrowserProcess::GetGlobal()->local_state()));
 
-    for (size_t i = 0; i < arraysize(kUsers); ++i) {
-      const std::string user_email(kUsers[i]);
-      const user_manager::User* user = fake_user_manager_->AddUser(user_email);
+    for (size_t i = 0; i < test_users_.size(); ++i) {
+      const AccountId account_id(test_users_[i]);
+      const user_manager::User* user =
+          fake_user_manager_->AddUser(test_users_[i]);
 
       // Note that user profiles are created after user login in reality.
       TestingProfile* user_profile =
-          profile_manager_->CreateTestingProfile(user_email);
-      user_profile->set_profile_name(user_email);
+          profile_manager_->CreateTestingProfile(account_id.GetUserEmail());
+      user_profile->set_profile_name(account_id.GetUserEmail());
       user_profiles_.push_back(user_profile);
 
       ProfileHelper::Get()->SetUserToProfileMappingForTesting(user,
@@ -157,13 +163,13 @@
   }
 
   void LoginUser(size_t user_index) {
-    ASSERT_LT(user_index, arraysize(kUsers));
-    fake_user_manager_->LoginUser(kUsers[user_index]);
+    ASSERT_LT(user_index, test_users_.size());
+    fake_user_manager_->LoginUser(test_users_[user_index]);
     controller_->StartObserving(user_profiles_[user_index]);
   }
 
   void SetOwner(size_t user_index) {
-    fake_user_manager_->set_owner_email(kUsers[user_index]);
+    fake_user_manager_->set_owner_id(test_users_[user_index]);
   }
 
   PrefService* GetUserPrefs(size_t user_index) {
@@ -176,12 +182,13 @@
   }
 
   std::string GetCachedBehavior(size_t user_index) {
-    return controller_->GetCachedValue(kUsers[user_index]);
+    return controller_->GetCachedValue(test_users_[user_index].GetUserEmail());
   }
 
   void SetCachedBehavior(size_t user_index,
                          const std::string& behavior) {
-    controller_->SetCachedValue(kUsers[user_index], behavior);
+    controller_->SetCachedValue(test_users_[user_index].GetUserEmail(),
+                                behavior);
   }
 
   void ResetCounts() {
@@ -212,6 +219,8 @@
 
   int user_not_allowed_count_;
 
+  std::vector<AccountId> test_users_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(MultiProfileUserControllerTest);
 };
@@ -226,7 +235,8 @@
   for (size_t i = 0; i < arraysize(kTestCases); ++i) {
     SetCachedBehavior(0, kTestCases[i]);
     MultiProfileUserController::UserAllowedInSessionReason reason;
-    EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0], &reason))
+    EXPECT_TRUE(controller()->IsUserAllowedInSession(
+        test_users_[0].GetUserEmail(), &reason))
         << "Case " << i;
     EXPECT_EQ(MultiProfileUserController::ALLOWED, reason) << "Case " << i;
     EXPECT_EQ(MultiProfileUserController::ALLOWED,
@@ -292,7 +302,8 @@
               MultiProfileUserController::GetPrimaryUserPolicy())
         << "Case " << i;
     MultiProfileUserController::UserAllowedInSessionReason reason;
-    controller()->IsUserAllowedInSession(kUsers[1], &reason);
+    controller()->IsUserAllowedInSession(test_users_[1].GetUserEmail(),
+                                         &reason);
     EXPECT_EQ(kBehaviorTestCases[i].expected_secondary_allowed, reason)
         << "Case " << i;
   }
@@ -326,11 +337,14 @@
        UsedPolicyCertificatesAllowedForPrimary) {
   // Verifies that any user can sign-in as the primary user, regardless of the
   // tainted state.
-  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
+  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
+      test_users_[0].GetUserEmail());
   MultiProfileUserController::UserAllowedInSessionReason reason;
-  EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0], &reason));
+  EXPECT_TRUE(controller()->IsUserAllowedInSession(
+      test_users_[0].GetUserEmail(), &reason));
   EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
-  EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
+  EXPECT_TRUE(controller()->IsUserAllowedInSession(
+      test_users_[1].GetUserEmail(), &reason));
   EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
   EXPECT_EQ(MultiProfileUserController::ALLOWED,
             MultiProfileUserController::GetPrimaryUserPolicy());
@@ -347,11 +361,14 @@
   SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted);
 
   MultiProfileUserController::UserAllowedInSessionReason reason;
-  EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0], &reason));
+  EXPECT_TRUE(controller()->IsUserAllowedInSession(
+      test_users_[0].GetUserEmail(), &reason));
   EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
 
-  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
-  EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[0], &reason));
+  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
+      test_users_[0].GetUserEmail());
+  EXPECT_FALSE(controller()->IsUserAllowedInSession(
+      test_users_[0].GetUserEmail(), &reason));
   EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED,
             reason);
 }
@@ -360,7 +377,8 @@
        UsedPolicyCertificatesDisallowsSecondaries) {
   // Verifies that if a tainted user is signed-in then no other users can
   // be added.
-  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
+  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
+      test_users_[0].GetUserEmail());
   LoginUser(0);
 
   cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure()));
@@ -370,13 +388,16 @@
           profile(0), TestPolicyCertServiceFactory));
 
   MultiProfileUserController::UserAllowedInSessionReason reason;
-  EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
+  EXPECT_FALSE(controller()->IsUserAllowedInSession(
+      test_users_[1].GetUserEmail(), &reason));
   EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
             reason);
   EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
             MultiProfileUserController::GetPrimaryUserPolicy());
-  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[1]);
-  EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
+  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
+      test_users_[1].GetUserEmail());
+  EXPECT_FALSE(controller()->IsUserAllowedInSession(
+      test_users_[1].GetUserEmail(), &reason));
   EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED,
             reason);
   EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
@@ -407,7 +428,8 @@
 
   EXPECT_FALSE(service->has_policy_certificates());
   MultiProfileUserController::UserAllowedInSessionReason reason;
-  EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
+  EXPECT_TRUE(controller()->IsUserAllowedInSession(
+      test_users_[1].GetUserEmail(), &reason));
   EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
   EXPECT_EQ(MultiProfileUserController::ALLOWED,
             MultiProfileUserController::GetPrimaryUserPolicy());
@@ -417,7 +439,8 @@
       "subject", "issuer", base::Time(), base::Time()));
   service->OnTrustAnchorsChanged(certificates);
   EXPECT_TRUE(service->has_policy_certificates());
-  EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
+  EXPECT_FALSE(controller()->IsUserAllowedInSession(
+      test_users_[1].GetUserEmail(), &reason));
   EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
             reason);
   EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
diff --git a/chrome/browser/chromeos/login/users/supervised_user_manager_impl.cc b/chrome/browser/chromeos/login/users/supervised_user_manager_impl.cc
index 0668465..c54efe2c 100644
--- a/chrome/browser/chromeos/login/users/supervised_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/supervised_user_manager_impl.cc
@@ -149,7 +149,7 @@
     id = base::StringPrintf(
         "%d@%s", counter, chromeos::login::kSupervisedUserDomain);
     counter++;
-    user_exists = (NULL != owner_->FindUser(id));
+    user_exists = (nullptr != owner_->FindUser(AccountId::FromUserEmail(id)));
     DCHECK(!user_exists);
     if (user_exists) {
       LOG(ERROR) << "Supervised user with id " << id << " already exists.";
@@ -186,13 +186,14 @@
   DCHECK(!user);
   if (user)
     return user;
-  const user_manager::User* manager = owner_->FindUser(manager_id);
+  const user_manager::User* manager =
+      owner_->FindUser(AccountId::FromUserEmail(manager_id));
   CHECK(manager);
 
   PrefService* local_state = g_browser_process->local_state();
 
-  user_manager::User* new_user =
-      user_manager::User::CreateSupervisedUser(local_user_id);
+  user_manager::User* new_user = user_manager::User::CreateSupervisedUser(
+      AccountId::FromUserEmail(local_user_id));
 
   owner_->AddUserRecord(new_user);
 
@@ -217,7 +218,8 @@
   manager_email_update->SetWithoutPathExpansion(local_user_id,
       new base::StringValue(manager->display_email()));
 
-  owner_->SaveUserDisplayName(local_user_id, display_name);
+  owner_->SaveUserDisplayName(AccountId::FromUserEmail(local_user_id),
+                              display_name);
 
   g_browser_process->local_state()->CommitPendingWrite();
   return new_user;
@@ -442,7 +444,8 @@
     prefs->CommitPendingWrite();
     return;
   }
-  owner_->RemoveNonOwnerUserInternal(user_id, NULL);
+  owner_->RemoveNonOwnerUserInternal(AccountId::FromUserEmail(user_id),
+                                     nullptr);
 
   prefs->ClearPref(kSupervisedUserCreationTransactionDisplayName);
   prefs->ClearPref(kSupervisedUserCreationTransactionUserId);
diff --git a/chrome/browser/chromeos/login/users/user_manager_interface.h b/chrome/browser/chromeos/login/users/user_manager_interface.h
index 4ca26eb..c6bf205 100644
--- a/chrome/browser/chromeos/login/users/user_manager_interface.h
+++ b/chrome/browser/chromeos/login/users/user_manager_interface.h
@@ -9,6 +9,8 @@
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_type.h"
 
+class AccountId;
+
 namespace chromeos {
 
 class BootstrapManager;
@@ -17,7 +19,7 @@
 class UserFlow;
 class UserImageManager;
 
-// Chrome specific add-ons interface for the UserManager.
+// ChromeOS specific add-ons interface for the UserManager.
 class UserManagerInterface {
  public:
   UserManagerInterface() {}
@@ -25,27 +27,28 @@
 
   virtual BootstrapManager* GetBootstrapManager() = 0;
   virtual MultiProfileUserController* GetMultiProfileUserController() = 0;
-  virtual UserImageManager* GetUserImageManager(const std::string& user_id) = 0;
+  virtual UserImageManager* GetUserImageManager(
+      const AccountId& account_id) = 0;
   virtual SupervisedUserManager* GetSupervisedUserManager() = 0;
 
-  // Method that allows to set |flow| for user identified by |user_id|.
+  // Method that allows to set |flow| for user identified by |account_id|.
   // Flow should be set before login attempt.
   // Takes ownership of the |flow|, |flow| will be deleted in case of login
   // failure.
-  virtual void SetUserFlow(const std::string& user_id, UserFlow* flow) = 0;
+  virtual void SetUserFlow(const AccountId& account_id, UserFlow* flow) = 0;
 
   // Return user flow for current user. Returns instance of DefaultUserFlow if
   // no flow was defined for current user, or user is not logged in.
   // Returned value should not be cached.
   virtual UserFlow* GetCurrentUserFlow() const = 0;
 
-  // Return user flow for user identified by |user_id|. Returns instance of
+  // Return user flow for user identified by |account_id|. Returns instance of
   // DefaultUserFlow if no flow was defined for user.
   // Returned value should not be cached.
-  virtual UserFlow* GetUserFlow(const std::string& user_id) const = 0;
+  virtual UserFlow* GetUserFlow(const AccountId& account_id) const = 0;
 
-  // Resets user flow for user identified by |user_id|.
-  virtual void ResetUserFlow(const std::string& user_id) = 0;
+  // Resets user flow for user identified by |account_id|.
+  virtual void ResetUserFlow(const AccountId& account_id) = 0;
 
   // Returns list of users allowed for supervised user creation.
   // Returns an empty list in cases when supervised user creation or adding new
diff --git a/chrome/browser/chromeos/login/users/user_manager_unittest.cc b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
index b2e6368..db5a69a 100644
--- a/chrome/browser/chromeos/login/users/user_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
@@ -47,6 +47,9 @@
 };
 
 class UserManagerTest : public testing::Test {
+ public:
+  UserManagerTest() {}
+
  protected:
   void SetUp() override {
     base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
@@ -99,12 +102,12 @@
     GetChromeUserManager()->SetEphemeralUsersEnabled(ephemeral_users_enabled);
   }
 
-  const std::string& GetUserManagerOwnerEmail() const {
-    return GetChromeUserManager()->GetOwnerEmail();
+  AccountId GetUserManagerOwnerId() const {
+    return GetChromeUserManager()->GetOwnerAccountId();
   }
 
-  void SetUserManagerOwnerEmail(const std::string& owner_email) {
-    GetChromeUserManager()->SetOwnerEmail(owner_email);
+  void SetUserManagerOwnerId(const AccountId& owner_account_id) {
+    GetChromeUserManager()->SetOwnerId(owner_account_id);
   }
 
   void ResetUserManager() {
@@ -133,6 +136,13 @@
     GetChromeUserManager()->RetrieveTrustedDevicePolicies();
   }
 
+  const AccountId owner_account_id_at_invalid_domain_ =
+      AccountId::FromUserEmail("owner@invalid.domain");
+  const AccountId account_id0_at_invalid_domain_ =
+      AccountId::FromUserEmail("user0@invalid.domain");
+  const AccountId account_id1_at_invalid_domain_ =
+      AccountId::FromUserEmail("user1@invalid.domain");
+
  protected:
   content::TestBrowserThreadBundle thread_bundle_;
 
@@ -145,56 +155,64 @@
 
 TEST_F(UserManagerTest, RetrieveTrustedDevicePolicies) {
   SetUserManagerEphemeralUsersEnabled(true);
-  SetUserManagerOwnerEmail("");
+  SetUserManagerOwnerId(EmptyAccountId());
 
-  SetDeviceSettings(false, "owner@invalid.domain", false);
+  SetDeviceSettings(false, owner_account_id_at_invalid_domain_.GetUserEmail(),
+                    false);
   RetrieveTrustedDevicePolicies();
 
   EXPECT_FALSE(GetUserManagerEphemeralUsersEnabled());
-  EXPECT_EQ(GetUserManagerOwnerEmail(), "owner@invalid.domain");
+  EXPECT_EQ(GetUserManagerOwnerId(), owner_account_id_at_invalid_domain_);
 }
 
 TEST_F(UserManagerTest, RemoveAllExceptOwnerFromList) {
   user_manager::UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", false);
+      owner_account_id_at_invalid_domain_,
+      owner_account_id_at_invalid_domain_.GetUserEmail(), false);
   ResetUserManager();
   user_manager::UserManager::Get()->UserLoggedIn(
-      "user0@invalid.domain", "owner@invalid.domain", false);
+      account_id0_at_invalid_domain_,
+      owner_account_id_at_invalid_domain_.GetUserEmail(), false);
   ResetUserManager();
   user_manager::UserManager::Get()->UserLoggedIn(
-      "user1@invalid.domain", "owner@invalid.domain", false);
+      account_id1_at_invalid_domain_,
+      owner_account_id_at_invalid_domain_.GetUserEmail(), false);
   ResetUserManager();
 
   const user_manager::UserList* users =
       &user_manager::UserManager::Get()->GetUsers();
   ASSERT_EQ(3U, users->size());
-  EXPECT_EQ((*users)[0]->email(), "user1@invalid.domain");
-  EXPECT_EQ((*users)[1]->email(), "user0@invalid.domain");
-  EXPECT_EQ((*users)[2]->email(), "owner@invalid.domain");
+  EXPECT_EQ((*users)[0]->GetAccountId(), account_id1_at_invalid_domain_);
+  EXPECT_EQ((*users)[1]->GetAccountId(), account_id0_at_invalid_domain_);
+  EXPECT_EQ((*users)[2]->GetAccountId(), owner_account_id_at_invalid_domain_);
 
-  SetDeviceSettings(true, "owner@invalid.domain", false);
+  SetDeviceSettings(true, owner_account_id_at_invalid_domain_.GetUserEmail(),
+                    false);
   RetrieveTrustedDevicePolicies();
 
   users = &user_manager::UserManager::Get()->GetUsers();
   EXPECT_EQ(1U, users->size());
-  EXPECT_EQ((*users)[0]->email(), "owner@invalid.domain");
+  EXPECT_EQ((*users)[0]->GetAccountId(), owner_account_id_at_invalid_domain_);
 }
 
 TEST_F(UserManagerTest, RegularUserLoggedInAsEphemeral) {
-  SetDeviceSettings(true, "owner@invalid.domain", false);
+  SetDeviceSettings(true, owner_account_id_at_invalid_domain_.GetUserEmail(),
+                    false);
   RetrieveTrustedDevicePolicies();
 
   user_manager::UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "user0@invalid.domain", false);
+      owner_account_id_at_invalid_domain_,
+      account_id0_at_invalid_domain_.GetUserEmail(), false);
   ResetUserManager();
   user_manager::UserManager::Get()->UserLoggedIn(
-      "user0@invalid.domain", "user0@invalid.domain", false);
+      account_id0_at_invalid_domain_,
+      account_id0_at_invalid_domain_.GetUserEmail(), false);
   ResetUserManager();
 
   const user_manager::UserList* users =
       &user_manager::UserManager::Get()->GetUsers();
   EXPECT_EQ(1U, users->size());
-  EXPECT_EQ((*users)[0]->email(), "owner@invalid.domain");
+  EXPECT_EQ((*users)[0]->GetAccountId(), owner_account_id_at_invalid_domain_);
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
index cf3d3af..4b8f6c8 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -478,12 +478,12 @@
     return;
   }
 
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id);
+  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+      AccountId::FromUserEmail(user_id));
   CHECK(user);
-  bool is_persistent =
+  const bool is_persistent =
       !user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
-          user_id) ||
+          AccountId::FromUserEmail(user_id)) ||
       (type == user_manager::User::POLICY &&
        user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT);
 
@@ -556,8 +556,8 @@
 
   const base::FilePath* file = NULL;
 
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id);
+  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+      AccountId::FromUserEmail(user_id));
 
   if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) {
     file =
@@ -624,8 +624,9 @@
     return;
   }
 
+  const AccountId account_id = AccountId::FromUserEmail(user_id);
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id);
+      user_manager::UserManager::Get()->FindUser(account_id);
 
   // User is unknown or there is no visible background in kiosk mode.
   if (!user || user->GetType() == user_manager::USER_TYPE_KIOSK_APP)
@@ -633,7 +634,7 @@
 
   // Guest user or regular user in ephemeral mode.
   if ((user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
-           user_id) &&
+           account_id) &&
        user->HasGaiaAccount()) ||
       user->GetType() == user_manager::USER_TYPE_GUEST) {
     InitInitialUserWallpaper(user_id, false);
@@ -810,7 +811,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
-          user_id)) {
+          AccountId::FromUserEmail(user_id))) {
     // Default to the values cached in memory.
     *info = current_user_wallpaper_info_;
 
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
index b61138f..f3fb513a 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
@@ -111,20 +111,20 @@
     return wallpaper_path;
   }
 
-  // Logs in |username|.
-  void LogIn(const std::string& username, const std::string& username_hash) {
-    user_manager::UserManager::Get()->UserLoggedIn(
-        username, username_hash, false);
+  // Logs in |account_id|.
+  void LogIn(const AccountId& account_id, const std::string& user_id_hash) {
+    user_manager::UserManager::Get()->UserLoggedIn(account_id, user_id_hash,
+                                                   false);
     WaitAsyncWallpaperLoadStarted();
   }
 
-  // Logs in |username| and sets it as child account.
-  void LogInAsChild(
-      const std::string& username, const std::string& username_hash) {
-    user_manager::UserManager::Get()->UserLoggedIn(
-        username, username_hash, false);
+  // Logs in |account_id| and sets it as child account.
+  void LogInAsChild(const AccountId& account_id,
+                    const std::string& user_id_hash) {
+    user_manager::UserManager::Get()->UserLoggedIn(account_id, user_id_hash,
+                                                   false);
     user_manager::User* user =
-        user_manager::UserManager::Get()->FindUserAndModify(username);
+        user_manager::UserManager::Get()->FindUserAndModify(account_id);
     user_manager::UserManager::Get()->ChangeUserChildStatus(
         user, true /* is_child */);
   }
@@ -169,7 +169,7 @@
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
                        LoadCustomLargeWallpaperForLargeExternalScreen) {
   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
   base::FilePath small_wallpaper_path = GetCustomWallpaperPath(
       wallpaper::kSmallWallpaperSubDir, kTestUser1Hash, id);
@@ -245,7 +245,7 @@
                        PreventReloadingSameWallpaper) {
   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
   // New user log in, a default wallpaper is loaded.
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   EXPECT_EQ(1, LoadedWallpapers());
   // Loads the same wallpaper before the initial one finished. It should be
   // prevented.
@@ -296,7 +296,7 @@
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
                        PRE_UseMigratedWallpaperInfo) {
   // New user log in, a default wallpaper is loaded.
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   // Old wallpaper migration code doesn't exist in codebase anymore. Modify user
   // wallpaper info directly to simulate the wallpaper migration. See
   // crosbug.com/38429 for details about why we modify wallpaper info this way.
@@ -315,7 +315,7 @@
 
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
                        UseMigratedWallpaperInfo) {
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   // This test should finish normally. If timeout, it is probably because
   // migrated wallpaper is somehow not loaded. Bad things can happen if
@@ -327,7 +327,7 @@
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
                        PRE_UsePreMigrationWallpaperInfo) {
   // New user log in, a default wallpaper is loaded.
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   // Old wallpaper migration code doesn't exist in codebase anymore. So if
   // user's profile is not migrated, it is the same as no wallpaper info. To
   // simulate this, we remove user's wallpaper info here.
@@ -336,7 +336,7 @@
 
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
                        UsePreMigrationWallpaperInfo) {
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   // This test should finish normally. If timeout, it is probably because chrome
   // can not handle pre migrated user profile (M21 profile or older).
@@ -374,7 +374,7 @@
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
                        PRE_UseMigratedWallpaperInfo) {
   // New user log in, a default wallpaper is loaded.
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   // Old wallpaper migration code doesn't exist in codebase anymore. Modify user
   // wallpaper info directly to simulate the wallpaper migration. See
   // crosbug.com/38429 for details about why we modify wallpaper info this way.
@@ -393,7 +393,7 @@
 
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
                        UseMigratedWallpaperInfo) {
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   // This test should finish normally. If timeout, it is probably because
   // migrated wallpaper is somehow not loaded. Bad things can happen if
@@ -405,7 +405,7 @@
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
                        PRE_UsePreMigrationWallpaperInfo) {
   // New user log in, a default wallpaper is loaded.
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   // Old wallpaper migration code doesn't exist in codebase anymore. So if
   // user's profile is not migrated, it is the same as no wallpaper info. To
@@ -415,7 +415,7 @@
 
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestNoAnimation,
                        UsePreMigrationWallpaperInfo) {
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   // This test should finish normally. If timeout, it is probably because chrome
   // can not handle pre migrated user profile (M21 profile or older).
@@ -434,7 +434,7 @@
 
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCrashRestore,
                        PRE_RestoreWallpaper) {
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
 }
 
@@ -469,7 +469,7 @@
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCacheUpdate,
                        PRE_VerifyWallpaperCache) {
   // Add kTestUser1 to user list. kTestUser1 is the default login profile.
-  LogIn(kTestUser1, kTestUser1Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
 
   std::string id = base::Int64ToString(base::Time::Now().ToInternalValue());
   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
@@ -535,7 +535,7 @@
   EXPECT_TRUE(test_api->GetPathFromCache(kTestUser1, &original_path));
   EXPECT_FALSE(original_path.empty());
 
-  LogIn(kTestUser2, kTestUser2Hash);
+  LogIn(AccountId::FromUserEmail(kTestUser2), kTestUser2Hash);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   // Login another user should not delete logged in user's wallpaper cache.
   // Note active user is still kTestUser1.
@@ -756,7 +756,8 @@
     return;
   CreateCmdlineWallpapers();
   user_manager::UserManager::Get()->UserLoggedIn(
-      chromeos::login::kGuestUserName, chromeos::login::kGuestUserName, false);
+      chromeos::login::GuestAccountId(), chromeos::login::kGuestUserName,
+      false);
   UpdateDisplay("800x600");
   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
@@ -771,7 +772,8 @@
 
   CreateCmdlineWallpapers();
   user_manager::UserManager::Get()->UserLoggedIn(
-      chromeos::login::kGuestUserName, chromeos::login::kGuestUserName, false);
+      chromeos::login::GuestAccountId(), chromeos::login::kGuestUserName,
+      false);
   UpdateDisplay("1600x1200");
   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
@@ -784,7 +786,7 @@
   if (!ash::test::AshTestHelper::SupportsMultipleDisplays())
     return;
   CreateCmdlineWallpapers();
-  LogInAsChild(kTestUser1, kTestUser1Hash);
+  LogInAsChild(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   UpdateDisplay("800x600");
   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
@@ -798,7 +800,7 @@
     return;
 
   CreateCmdlineWallpapers();
-  LogInAsChild(kTestUser1, kTestUser1Hash);
+  LogInAsChild(AccountId::FromUserEmail(kTestUser1), kTestUser1Hash);
   UpdateDisplay("1600x1200");
   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
@@ -813,7 +815,7 @@
   UpdateDisplay("640x480");
   CreateCmdlineWallpapers();
   user_manager::UserManager::Get()->UserLoggedIn(
-      chromeos::login::kStubUser, "test_hash", false);
+      chromeos::login::StubAccountId(), "test_hash", false);
 
   WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
 
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc
index ca7ff24..11876de 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc
@@ -244,8 +244,8 @@
     }
     builder->Build();
     fake_session_manager_client_->set_user_policy(user_id, builder->GetBlob());
-    const user_manager::User* user =
-        user_manager::UserManager::Get()->FindUser(user_id);
+    const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+        AccountId::FromUserEmail(user_id));
     ASSERT_TRUE(user);
     policy::CloudPolicyStore* store = GetStoreForUser(user);
     ASSERT_TRUE(store);
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc
index 9c9f6154..ac00c1d 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc
@@ -72,19 +72,22 @@
 
 TEST_F(WallpaperManagerCacheTest, VerifyWallpaperCache) {
   // Add three users to known users.
-  std::string test_user_1 = "test1@example.com";
-  std::string test_user_2 = "test2@example.com";
-  std::string test_user_3 = "test3@example.com";
+  const AccountId test_account_id_1 =
+      AccountId::FromUserEmail("test1@example.com");
+  const AccountId test_account_id_2 =
+      AccountId::FromUserEmail("test2@example.com");
+  const AccountId test_account_id_3 =
+      AccountId::FromUserEmail("test3@example.com");
   base::FilePath path1("path1");
   base::FilePath path2("path2");
   base::FilePath path3("path3");
-  fake_user_manager()->AddUser(test_user_1);
-  fake_user_manager()->AddUser(test_user_2);
-  fake_user_manager()->AddUser(test_user_3);
+  fake_user_manager()->AddUser(test_account_id_1);
+  fake_user_manager()->AddUser(test_account_id_2);
+  fake_user_manager()->AddUser(test_account_id_3);
 
   // Login two users.
-  fake_user_manager()->LoginUser(test_user_1);
-  fake_user_manager()->LoginUser(test_user_2);
+  fake_user_manager()->LoginUser(test_account_id_1);
+  fake_user_manager()->LoginUser(test_account_id_2);
 
   scoped_ptr<WallpaperManager::TestApi> test_api;
   test_api.reset(new WallpaperManager::TestApi(WallpaperManager::Get()));
@@ -92,27 +95,36 @@
   gfx::ImageSkia test_user_1_wallpaper = CreateTestImage(SK_ColorRED);
   gfx::ImageSkia test_user_2_wallpaper = CreateTestImage(SK_ColorGREEN);
   gfx::ImageSkia test_user_3_wallpaper = CreateTestImage(SK_ColorWHITE);
-  test_api->SetWallpaperCache(test_user_1, path1, test_user_1_wallpaper);
-  test_api->SetWallpaperCache(test_user_2, path2, test_user_2_wallpaper);
-  test_api->SetWallpaperCache(test_user_3, path3, test_user_3_wallpaper);
+  test_api->SetWallpaperCache(test_account_id_1.GetUserEmail(), path1,
+                              test_user_1_wallpaper);
+  test_api->SetWallpaperCache(test_account_id_2.GetUserEmail(), path2,
+                              test_user_2_wallpaper);
+  test_api->SetWallpaperCache(test_account_id_3.GetUserEmail(), path3,
+                              test_user_3_wallpaper);
 
   test_api->ClearDisposableWallpaperCache();
 
   gfx::ImageSkia cached_wallpaper;
-  EXPECT_TRUE(test_api->GetWallpaperFromCache(test_user_1, &cached_wallpaper));
+  EXPECT_TRUE(test_api->GetWallpaperFromCache(test_account_id_1.GetUserEmail(),
+                                              &cached_wallpaper));
   base::FilePath path;
-  EXPECT_TRUE(test_api->GetPathFromCache(test_user_1, &path));
+  EXPECT_TRUE(
+      test_api->GetPathFromCache(test_account_id_1.GetUserEmail(), &path));
   // Logged in users' wallpaper cache should be kept.
   EXPECT_TRUE(cached_wallpaper.BackedBySameObjectAs(test_user_1_wallpaper));
   EXPECT_EQ(path, path1);
-  EXPECT_TRUE(test_api->GetWallpaperFromCache(test_user_2, &cached_wallpaper));
-  EXPECT_TRUE(test_api->GetPathFromCache(test_user_2, &path));
+  EXPECT_TRUE(test_api->GetWallpaperFromCache(test_account_id_2.GetUserEmail(),
+                                              &cached_wallpaper));
+  EXPECT_TRUE(
+      test_api->GetPathFromCache(test_account_id_2.GetUserEmail(), &path));
   EXPECT_TRUE(cached_wallpaper.BackedBySameObjectAs(test_user_2_wallpaper));
   EXPECT_EQ(path, path2);
 
   // Not logged in user's wallpaper cache should be cleared.
-  EXPECT_FALSE(test_api->GetWallpaperFromCache(test_user_3, &cached_wallpaper));
-  EXPECT_FALSE(test_api->GetPathFromCache(test_user_3, &path));
+  EXPECT_FALSE(test_api->GetWallpaperFromCache(test_account_id_3.GetUserEmail(),
+                                               &cached_wallpaper));
+  EXPECT_FALSE(
+      test_api->GetPathFromCache(test_account_id_3.GetUserEmail(), &path));
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
index 75b5b9a..e3760aa 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
@@ -89,12 +89,14 @@
     ASSERT_TRUE(test_profile_manager_.SetUp());
 
     // Add a user.
-    const char kTestUserName[] = "test-user@example.com";
-    user_manager->AddUser(kTestUserName);
-    user_manager->LoginUser(kTestUserName);
+    const AccountId test_account_id(
+        AccountId::FromUserEmail("test-user@example.com"));
+    user_manager->AddUser(test_account_id);
+    user_manager->LoginUser(test_account_id);
 
     // Create a profile for the user.
-    profile_ = test_profile_manager_.CreateTestingProfile(kTestUserName);
+    profile_ = test_profile_manager_.CreateTestingProfile(
+        test_account_id.GetUserEmail());
     test_profile_manager_.SetLoggedIn(true);
     EXPECT_TRUE(user_manager::UserManager::Get()->GetPrimaryUser());
 
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
index 6a4ba6d3..a6c5d91c7 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
@@ -721,7 +721,7 @@
 
   const user_manager::User* user =
       ProfileHelper::Get()->GetUserByProfile(profile_);
-  user_id_ = user ? user->GetUserID() : std::string();
+  user_id_ = user ? user->GetAccountId().GetUserEmail() : std::string();
 
   const bool is_owner = IsOwner() || IsOwnerInTests(user_id_);
   if (is_owner && device_settings_service_)
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
index aa4d68909..1a36696 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
@@ -100,7 +100,8 @@
     provider_.reset(new DeviceSettingsProvider(base::Bind(&OnPrefChanged),
                                                &device_settings_service_));
     owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
-    InitOwner(device_policy_.policy_data().username(), true);
+    InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+              true);
     FlushDeviceSettings();
 
     service_ = OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(
@@ -342,7 +343,8 @@
   EXPECT_FALSE(FindInListValue(device_policy_.policy_data().username(),
                                provider_->Get(kAccountsPrefUsers)));
   owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   ReloadDeviceSettings();
   ASSERT_TRUE(service_->IsOwner());
 
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
index 143a37e1..9009677 100644
--- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
@@ -222,7 +222,7 @@
 
 Profile* AffiliatedInvalidationServiceProviderImplTest::LogInAndReturnProfile(
     const std::string& user_id) {
-  fake_user_manager_->AddUser(user_id);
+  fake_user_manager_->AddUser(AccountId::FromUserEmail(user_id));
   Profile* profile = profile_manager_.CreateTestingProfile(user_id);
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
diff --git a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
index 768bb466..f3ce1e1 100644
--- a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
+++ b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
@@ -246,7 +246,8 @@
     EXPECT_EQ(policy::USER_AFFILIATION_MANAGED,
               browser_policy_connector()->GetUserAffiliation(kUsername));
     RunUntilIdle();
-    EXPECT_FALSE(user_manager->IsKnownUser(kUsername));
+    EXPECT_FALSE(
+        user_manager->IsKnownUser(AccountId::FromUserEmail(kUsername)));
   }
 
   // Skip the OOBE, go to the sign-in screen, and wait for the login screen to
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc b/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc
index 95982a3..e963d02 100644
--- a/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc
+++ b/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc
@@ -123,7 +123,7 @@
 
   void RefreshDeviceLocalAccountPolicy(DeviceLocalAccountPolicyBroker* broker);
 
-  void LogInAsDeviceLocalAccount(const std::string& user_id);
+  void LogInAsDeviceLocalAccount(const AccountId& account_id);
 
   void SetRegularUserAvatarPolicy(const std::string& value);
 
@@ -320,13 +320,12 @@
 }
 
 void CloudExternalDataPolicyObserverTest::LogInAsDeviceLocalAccount(
-    const std::string& user_id) {
-  user_manager_->AddUser(user_id);
+    const AccountId& account_id) {
+  user_manager_->AddUser(account_id);
 
   device_local_account_policy_provider_.reset(
       new DeviceLocalAccountPolicyProvider(
-          user_id,
-          device_local_account_policy_service_.get(),
+          account_id.GetUserEmail(), device_local_account_policy_service_.get(),
           scoped_ptr<PolicyMap>()));
 
   PolicyServiceImpl::Providers providers;
@@ -335,10 +334,11 @@
   builder.SetPolicyService(
       scoped_ptr<PolicyService>(new PolicyServiceImpl(providers)));
   builder.SetPath(chromeos::ProfileHelper::Get()->GetProfilePathByUserIdHash(
-      chromeos::ProfileHelper::GetUserIdHashByUserIdForTesting(user_id)));
+      chromeos::ProfileHelper::GetUserIdHashByUserIdForTesting(
+          account_id.GetUserEmail())));
 
   profile_ = builder.Build();
-  profile_->set_profile_name(user_id);
+  profile_->set_profile_name(account_id.GetUserEmail());
 
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
@@ -363,7 +363,7 @@
 }
 
 void CloudExternalDataPolicyObserverTest::LogInAsRegularUser() {
-  user_manager_->AddUser(kRegularUserID);
+  user_manager_->AddUser(AccountId::FromUserEmail(kRegularUserID));
 
   PolicyServiceImpl::Providers providers;
   providers.push_back(&user_policy_provider_);
@@ -661,7 +661,7 @@
 
   CreateObserver();
 
-  LogInAsDeviceLocalAccount(kDeviceLocalAccount);
+  LogInAsDeviceLocalAccount(AccountId::FromUserEmail(kDeviceLocalAccount));
 
   EXPECT_TRUE(set_calls_.empty());
   EXPECT_TRUE(cleared_calls_.empty());
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc b/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc
index b1c209d..c0f2c93f 100644
--- a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc
+++ b/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc
@@ -44,9 +44,9 @@
         make_scoped_ptr(fake_service_));
 
     // Set up FakeChromeUserManager.
-    fake_user_manager_->AddUser(kTestOwner);
-    fake_user_manager_->AddUser(kTestUser);
-    fake_user_manager_->set_owner_email(kTestOwner);
+    fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestOwner));
+    fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestUser));
+    fake_user_manager_->set_owner_id(AccountId::FromUserEmail(kTestOwner));
   }
 
   void SetUp() override {
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc b/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc
index 7116c61..74e806f 100644
--- a/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc
+++ b/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc
@@ -62,9 +62,9 @@
         make_scoped_ptr(fake_initializer_));
 
     // Set up FakeChromeUserManager.
-    fake_user_manager_->AddUser(kTestOwner);
-    fake_user_manager_->AddUser(kTestUser);
-    fake_user_manager_->set_owner_email(kTestOwner);
+    fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestOwner));
+    fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestUser));
+    fake_user_manager_->set_owner_id(AccountId::FromUserEmail(kTestOwner));
   }
 
   void SetUp() override {
diff --git a/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc b/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc
index 5963c82..23df640 100644
--- a/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc
+++ b/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc
@@ -44,9 +44,9 @@
         make_scoped_ptr(fake_service_));
 
     // Set up FakeChromeUserManager.
-    fake_user_manager_->AddUser(kTestOwner);
-    fake_user_manager_->AddUser(kTestUser);
-    fake_user_manager_->set_owner_email(kTestOwner);
+    fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestOwner));
+    fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestUser));
+    fake_user_manager_->set_owner_id(AccountId::FromUserEmail(kTestOwner));
   }
 
   void SetUp() override {
diff --git a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc b/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc
index 1a9ba8b..c9717879 100644
--- a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc
+++ b/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc
@@ -44,7 +44,8 @@
 
     // Set up the ownership, so that we can modify device settings.
     owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
-    InitOwner(device_policy_.policy_data().username(), true);
+    InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+              true);
     FlushDeviceSettings();
 
 
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
index 7bc9ec7..3795901 100644
--- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -682,7 +682,8 @@
        SuccessfulConsumerManagementEnrollment) {
   management_mode_ = MANAGEMENT_MODE_CONSUMER_MANAGED;
   owner_key_util_->SetPrivateKey(device_policy_.GetNewSigningKey());
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   FlushDeviceSettings();
 
   device_policy_.policy_data().set_management_mode(em::PolicyData::LOCAL_OWNER);
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index 53cbbdc9..f7f4019 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -419,13 +419,9 @@
                                public extensions::AppWindowRegistry::Observer {
  protected:
   DeviceLocalAccountTest()
-      : user_id_1_(GenerateDeviceLocalAccountUserId(
-            kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
-        user_id_2_(GenerateDeviceLocalAccountUserId(
-            kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
-        public_session_input_method_id_(base::StringPrintf(
-            kPublicSessionInputMethodIDTemplate,
-            chromeos::extension_ime_util::kXkbExtensionId)),
+      : public_session_input_method_id_(
+            base::StringPrintf(kPublicSessionInputMethodIDTemplate,
+                               chromeos::extension_ime_util::kXkbExtensionId)),
         contents_(NULL) {
     set_exit_when_last_browser_closes(false);
   }
@@ -634,11 +630,11 @@
                                           proto.SerializeAsString()));
   }
 
-  void CheckPublicSessionPresent(const std::string& id) {
+  void CheckPublicSessionPresent(const AccountId& account_id) {
     const user_manager::User* user =
-        user_manager::UserManager::Get()->FindUser(id);
+        user_manager::UserManager::Get()->FindUser(account_id);
     ASSERT_TRUE(user);
-    EXPECT_EQ(id, user->email());
+    EXPECT_EQ(account_id, user->GetAccountId());
     EXPECT_EQ(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user->GetType());
   }
 
@@ -684,7 +680,7 @@
     // Wait for the display name becoming available as that indicates
     // device-local account policy is fully loaded, which is a prerequisite for
     // successful login.
-    WaitForDisplayName(user_id_1_, kDisplayName1);
+    WaitForDisplayName(account_id_1_.GetUserEmail(), kDisplayName1);
   }
 
   void ExpandPublicSessionPod(bool expect_advanced) {
@@ -697,7 +693,7 @@
             "    document.getElementById('pod-row').getPodWithUsername_('%s');"
             "pod.click();"
             "domAutomationController.send(pod.classList.contains('advanced'));",
-            user_id_1_.c_str()),
+            account_id_1_.GetUserEmail().c_str()),
         &advanced));
     // Verify that the pod expanded to its basic/advanced form, as expected.
     EXPECT_EQ(expect_advanced, advanced);
@@ -741,7 +737,7 @@
     ASSERT_TRUE(controller);
 
     chromeos::UserContext user_context(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
-                                       user_id_1_);
+                                       account_id_1_.GetUserEmail());
     user_context.SetPublicSessionLocale(locale);
     user_context.SetPublicSessionInputMethod(input_method);
     controller->Login(user_context, chromeos::SigninSpecifics());
@@ -787,8 +783,14 @@
     VerifyKeyboardLayoutMatchesLocale();
   }
 
-  const std::string user_id_1_;
-  const std::string user_id_2_;
+  const AccountId account_id_1_ =
+      AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId(
+          kAccountId1,
+          DeviceLocalAccount::TYPE_PUBLIC_SESSION));
+  const AccountId account_id_2_ =
+      AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId(
+          kAccountId2,
+          DeviceLocalAccount::TYPE_PUBLIC_SESSION));
   const std::string public_session_input_method_id_;
 
   std::string initial_locale_;
@@ -805,7 +807,7 @@
   DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest);
 };
 
-static bool IsKnownUser(const std::string& account_id) {
+static bool IsKnownUser(const AccountId& account_id) {
   return user_manager::UserManager::Get()->IsKnownUser(account_id);
 }
 
@@ -814,12 +816,12 @@
   AddPublicSessionToDevicePolicy(kAccountId2);
 
   content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED,
-                                        base::Bind(&IsKnownUser, user_id_1_))
+                                        base::Bind(&IsKnownUser, account_id_1_))
       .Wait();
-  EXPECT_TRUE(IsKnownUser(user_id_2_));
+  EXPECT_TRUE(IsKnownUser(account_id_2_));
 
-  CheckPublicSessionPresent(user_id_1_);
-  CheckPublicSessionPresent(user_id_2_);
+  CheckPublicSessionPresent(account_id_1_);
+  CheckPublicSessionPresent(account_id_2_);
 }
 
 // Flaky: http://crbug.com/512670.
@@ -833,7 +835,7 @@
   const std::string get_compact_pod_display_name = base::StringPrintf(
       "domAutomationController.send(document.getElementById('pod-row')"
       "    .getPodWithUsername_('%s').nameElement.textContent);",
-      user_id_1_.c_str());
+      account_id_1_.GetUserEmail().c_str());
   std::string display_name;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
       contents_,
@@ -844,7 +846,7 @@
       "domAutomationController.send(document.getElementById('pod-row')"
       "    .getPodWithUsername_('%s').querySelector('.expanded-pane-name')"
       "        .textContent);",
-      user_id_1_.c_str());
+      account_id_1_.GetUserEmail().c_str());
   display_name.clear();
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
       contents_,
@@ -858,7 +860,7 @@
       base::StringPrintf(
           "document.getElementById('pod-row').getPodWithUsername_('%s')"
           "    .click();",
-      user_id_1_.c_str())));
+          account_id_1_.GetUserEmail().c_str())));
 
   // Change the display name.
   device_local_account_policy_.payload().mutable_userdisplayname()->set_value(
@@ -868,10 +870,10 @@
       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   DeviceLocalAccountPolicyBroker* broker =
       connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
-          user_id_1_);
+          account_id_1_.GetUserEmail());
   ASSERT_TRUE(broker);
   broker->core()->store()->Load();
-  WaitForDisplayName(user_id_1_, kDisplayName2);
+  WaitForDisplayName(account_id_1_.GetUserEmail(), kDisplayName2);
 
   // Verify that the new display name is shown in the UI.
   display_name.clear();
@@ -895,7 +897,7 @@
       base::StringPrintf(
           "domAutomationController.send(document.getElementById('pod-row')"
           "    .getPodWithUsername_('%s').expanded);",
-          user_id_1_.c_str()),
+          account_id_1_.GetUserEmail().c_str()),
       &expanded));
   EXPECT_TRUE(expanded);
 }
@@ -911,7 +913,7 @@
       kAccountId1).empty());
 }
 
-static bool IsNotKnownUser(const std::string& account_id) {
+static bool IsNotKnownUser(const AccountId& account_id) {
   return !IsKnownUser(account_id);
 }
 
@@ -920,9 +922,9 @@
   AddPublicSessionToDevicePolicy(kAccountId2);
 
   content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED,
-                                        base::Bind(&IsKnownUser, user_id_1_))
+                                        base::Bind(&IsKnownUser, account_id_1_))
       .Wait();
-  EXPECT_TRUE(IsKnownUser(user_id_2_));
+  EXPECT_TRUE(IsKnownUser(account_id_2_));
 
   // Update policy to remove kAccountId2.
   em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
@@ -942,8 +944,9 @@
   g_browser_process->policy_service()->RefreshPolicies(base::Closure());
 
   // Make sure the second device-local account disappears.
-  content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED,
-                                        base::Bind(&IsNotKnownUser, user_id_2_))
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_USER_LIST_CHANGED,
+      base::Bind(&IsNotKnownUser, account_id_2_))
       .Wait();
 }
 
@@ -1078,8 +1081,10 @@
   // Verify that the extension was removed from the account's extension cache
   // after the installation failure.
   DeviceLocalAccountPolicyBroker* broker =
-      g_browser_process->platform_part()->browser_policy_connector_chromeos()->
-          GetDeviceLocalAccountPolicyService()->GetBrokerForUser(user_id_1_);
+      g_browser_process->platform_part()
+          ->browser_policy_connector_chromeos()
+          ->GetDeviceLocalAccountPolicyService()
+          ->GetBrokerForUser(account_id_1_.GetUserEmail());
   ASSERT_TRUE(broker);
   chromeos::ExternalCache* cache =
       broker->extension_loader()->GetExternalCacheForTesting();
@@ -1151,8 +1156,10 @@
 
   // Verify that the extension was removed from the account's extension cache.
   DeviceLocalAccountPolicyBroker* broker =
-      g_browser_process->platform_part()->browser_policy_connector_chromeos()->
-          GetDeviceLocalAccountPolicyService()->GetBrokerForUser(user_id_1_);
+      g_browser_process->platform_part()
+          ->browser_policy_connector_chromeos()
+          ->GetDeviceLocalAccountPolicyService()
+          ->GetBrokerForUser(account_id_1_.GetUserEmail());
   ASSERT_TRUE(broker);
   chromeos::ExternalCache* cache =
       broker->extension_loader()->GetExternalCacheForTesting();
@@ -1311,7 +1318,7 @@
       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   DeviceLocalAccountPolicyBroker* broker =
       connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
-          user_id_1_);
+          account_id_1_.GetUserEmail());
   ASSERT_TRUE(broker);
   broker->core()->store()->Load();
 
@@ -1401,7 +1408,7 @@
       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   DeviceLocalAccountPolicyBroker* broker =
       connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
-          user_id_1_);
+          account_id_1_.GetUserEmail());
   ASSERT_TRUE(broker);
 
   run_loop_.reset(new base::RunLoop);
@@ -1415,13 +1422,13 @@
   ASSERT_TRUE(policy_image);
 
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id_1_);
+      user_manager::UserManager::Get()->FindUser(account_id_1_);
   ASSERT_TRUE(user);
 
   base::FilePath user_data_dir;
   ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
   const base::FilePath saved_image_path =
-      user_data_dir.Append(user_id_1_).AddExtension("jpg");
+      user_data_dir.Append(account_id_1_.GetUserEmail()).AddExtension("jpg");
 
   EXPECT_FALSE(user->HasDefaultImage());
   EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, user->image_index());
@@ -1431,8 +1438,7 @@
   ASSERT_TRUE(images_pref);
   const base::DictionaryValue* image_properties;
   ASSERT_TRUE(images_pref->GetDictionaryWithoutPathExpansion(
-      user_id_1_,
-      &image_properties));
+      account_id_1_.GetUserEmail(), &image_properties));
   int image_index;
   std::string image_path;
   ASSERT_TRUE(image_properties->GetInteger("index", &image_index));
@@ -1618,7 +1624,7 @@
       base::StringPrintf(
           "document.getElementById('pod-row').getPodWithUsername_('%s')"
           "    .querySelector('.enter-button').click();",
-          user_id_1_.c_str())));
+          account_id_1_.GetUserEmail().c_str())));
 
   WaitForSessionStart();
 
@@ -1647,7 +1653,7 @@
           "    document.getElementById('pod-row').getPodWithUsername_('%s');"
           "pod.querySelector('.language-and-input').click();"
           "domAutomationController.send(pod.classList.contains('advanced'));",
-          user_id_1_.c_str()),
+          account_id_1_.GetUserEmail().c_str()),
       &advanced));
   EXPECT_FALSE(advanced);
 
@@ -1661,8 +1667,7 @@
           "var event = document.createEvent('HTMLEvents');"
           "event.initEvent('change', false, true);"
           "languageSelect.dispatchEvent(event);",
-          user_id_1_.c_str(),
-          kPublicSessionLocale)));
+          account_id_1_.GetUserEmail().c_str(), kPublicSessionLocale)));
 
   // The UI will have requested an updated list of keyboard layouts at this
   // point. Wait for the constructions of this list to finish.
@@ -1677,7 +1682,7 @@
           "    document.getElementById('pod-row').getPodWithUsername_('%s');"
           "pod.querySelector('.keyboard-select').value = '%s';"
           "pod.querySelector('.enter-button').click();",
-          user_id_1_.c_str(),
+          account_id_1_.GetUserEmail().c_str(),
           public_session_input_method_id_.c_str())));
 
   WaitForSessionStart();
@@ -1710,7 +1715,7 @@
       base::StringPrintf(
           "document.getElementById('pod-row').getPodWithUsername_('%s')"
           "    .querySelector('.enter-button').click();",
-          user_id_1_.c_str())));
+          account_id_1_.GetUserEmail().c_str())));
 
   WaitForSessionStart();
 
@@ -1743,7 +1748,7 @@
       "for (var i = 0; i < languageSelect.length; ++i)"
       "  locales.push(languageSelect.options[i].value);"
       "domAutomationController.send(JSON.stringify(locales));",
-      user_id_1_.c_str());
+      account_id_1_.GetUserEmail().c_str());
   std::string json;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
                                                      get_locale_list,
@@ -1774,12 +1779,11 @@
   }
 
   // Verify that the first recommended locale is selected.
-  const std::string get_selected_locale =
-      base::StringPrintf(
-          "domAutomationController.send(document.getElementById('pod-row')"
-          "    .getPodWithUsername_('%s').querySelector('.language-select')"
-          "        .value);",
-          user_id_1_.c_str());
+  const std::string get_selected_locale = base::StringPrintf(
+      "domAutomationController.send(document.getElementById('pod-row')"
+      "    .getPodWithUsername_('%s').querySelector('.language-select')"
+      "        .value);",
+      account_id_1_.GetUserEmail().c_str());
   std::string selected_locale;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
                                                      get_selected_locale,
@@ -1798,10 +1802,10 @@
       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   DeviceLocalAccountPolicyBroker* broker =
       connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
-          user_id_1_);
+          account_id_1_.GetUserEmail());
   ASSERT_TRUE(broker);
   broker->core()->store()->Load();
-  WaitForDisplayName(user_id_1_, kDisplayName2);
+  WaitForDisplayName(account_id_1_.GetUserEmail(), kDisplayName2);
 
   // Verify that the new list of locales is shown in the UI.
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
@@ -1834,8 +1838,7 @@
           "var event = document.createEvent('HTMLEvents');"
           "event.initEvent('change', false, true);"
           "languageSelect.dispatchEvent(event);",
-          user_id_1_.c_str(),
-          kPublicSessionLocale)));
+          account_id_1_.GetUserEmail().c_str(), kPublicSessionLocale)));
 
   // Change the list of recommended locales.
   SetRecommendedLocales(kRecommendedLocales2, arraysize(kRecommendedLocales2));
@@ -1843,7 +1846,7 @@
       kDisplayName1);
   UploadAndInstallDeviceLocalAccountPolicy();
   broker->core()->store()->Load();
-  WaitForDisplayName(user_id_1_, kDisplayName1);
+  WaitForDisplayName(account_id_1_.GetUserEmail(), kDisplayName1);
 
   // Verify that the manually selected locale is still selected.
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
@@ -1861,7 +1864,7 @@
       base::StringPrintf(
           "document.getElementById('pod-row').getPodWithUsername_('%s')"
           "    .querySelector('.keyboard-select').value = '%s';",
-          user_id_1_.c_str(),
+          account_id_1_.GetUserEmail().c_str(),
           public_session_input_method_id_.c_str())));
 
   // Click on a different pod, causing focus to shift away and the pod to
@@ -1871,7 +1874,7 @@
       base::StringPrintf(
           "document.getElementById('pod-row').getPodWithUsername_('%s')"
           "    .click();",
-          user_id_2_.c_str())));
+          account_id_2_.GetUserEmail().c_str())));
 
   // Click on the pod again, causing it to expand again. Verify that the pod has
   // kept all its state (the advanced form is being shown, the manually selected
@@ -1888,7 +1891,7 @@
           "state.keyboardLayout = pod.querySelector('.keyboard-select').value;"
           "console.log(JSON.stringify(state));"
           "domAutomationController.send(JSON.stringify(state));",
-          user_id_1_.c_str()),
+          account_id_1_.GetUserEmail().c_str()),
       &json));
   LOG(ERROR) << json;
   value_ptr = base::JSONReader::Read(json);
@@ -1910,7 +1913,7 @@
       base::StringPrintf(
           "document.getElementById('pod-row').getPodWithUsername_('%s')"
           "    .querySelector('.enter-button').click();",
-          user_id_1_.c_str())));
+          account_id_1_.GetUserEmail().c_str())));
 
   WaitForSessionStart();
 
@@ -1944,7 +1947,7 @@
           "    document.getElementById('pod-row').getPodWithUsername_('%s');"
           "pod.click();"
           "domAutomationController.send(pod.classList.contains('advanced'));",
-          user_id_1_.c_str()),
+          account_id_1_.GetUserEmail().c_str()),
       &advanced));
   EXPECT_FALSE(advanced);
   EXPECT_EQ(l10n_util::GetLanguage(initial_locale_),
@@ -1956,7 +1959,7 @@
       base::StringPrintf(
           "document.getElementById('pod-row').getPodWithUsername_('%s')"
           "    .querySelector('.enter-button').click();",
-          user_id_1_.c_str())));
+          account_id_1_.GetUserEmail().c_str())));
 
   WaitForSessionStart();
 
@@ -2049,8 +2052,7 @@
           "var event = document.createEvent('HTMLEvents');"
           "event.initEvent('change', false, true);"
           "languageSelect.dispatchEvent(event);",
-          user_id_1_.c_str(),
-          kPublicSessionLocale)));
+          account_id_1_.GetUserEmail().c_str(), kPublicSessionLocale)));
 
   // The UI will have requested an updated list of keyboard layouts at this
   // point. Wait for the constructions of this list to finish.
@@ -2076,7 +2078,7 @@
           "    document.getElementById('pod-row').getPodWithUsername_('%s');"
           "pod.querySelector('.keyboard-select').value = '%s';"
           "pod.querySelector('.enter-button').click();",
-          user_id_1_.c_str(),
+          account_id_1_.GetUserEmail().c_str(),
           public_session_input_method_id_.c_str())));
 
   // Spin the loop until the login observer fires. Then, unregister the
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc
index f857846..fc12d3d 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -216,12 +216,12 @@
     return scoped_ptr<policy::DeviceLocalAccount>();
   const user_manager::User* const user =
       user_manager::UserManager::Get()->GetActiveUser();
-  const std::string user_id = user->GetUserID();
   const std::vector<policy::DeviceLocalAccount> accounts =
       policy::GetDeviceLocalAccounts(settings);
 
   for (const auto& device_local_account : accounts) {
-    if (device_local_account.user_id == user_id) {
+    if (AccountId::FromUserEmail(device_local_account.user_id) ==
+        user->GetAccountId()) {
       return make_scoped_ptr(
           new policy::DeviceLocalAccount(device_local_account)).Pass();
     }
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
index ec8f3955..c24d867 100644
--- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -378,7 +378,8 @@
     std::vector<DeviceLocalAccount> accounts;
     accounts.push_back(account);
     SetDeviceLocalAccounts(owner_settings_service_.get(), accounts);
-    user_manager_->CreateKioskAppUser(account.user_id);
+    user_manager_->CreateKioskAppUser(
+        AccountId::FromUserEmail(account.user_id));
     EXPECT_CALL(*user_manager_, IsLoggedInAsKioskApp()).WillRepeatedly(
         Return(true));
   }
@@ -772,13 +773,22 @@
 }
 
 TEST_F(DeviceStatusCollectorTest, ReportUsers) {
-  user_manager_->CreatePublicAccountUser("public@localhost");
-  user_manager_->AddUserWithAffiliation("user0@managed.com", true);
-  user_manager_->AddUserWithAffiliation("user1@managed.com", true);
-  user_manager_->AddUserWithAffiliation("user2@managed.com", true);
-  user_manager_->AddUserWithAffiliation("user3@unmanaged.com", false);
-  user_manager_->AddUserWithAffiliation("user4@managed.com", true);
-  user_manager_->AddUserWithAffiliation("user5@managed.com", true);
+  const AccountId public_account_id(
+      AccountId::FromUserEmail("public@localhost"));
+  const AccountId account_id0(AccountId::FromUserEmail("user0@managed.com"));
+  const AccountId account_id1(AccountId::FromUserEmail("user1@managed.com"));
+  const AccountId account_id2(AccountId::FromUserEmail("user2@managed.com"));
+  const AccountId account_id3(AccountId::FromUserEmail("user3@unmanaged.com"));
+  const AccountId account_id4(AccountId::FromUserEmail("user4@managed.com"));
+  const AccountId account_id5(AccountId::FromUserEmail("user5@managed.com"));
+
+  user_manager_->CreatePublicAccountUser(public_account_id);
+  user_manager_->AddUserWithAffiliation(account_id0, true);
+  user_manager_->AddUserWithAffiliation(account_id1, true);
+  user_manager_->AddUserWithAffiliation(account_id2, true);
+  user_manager_->AddUserWithAffiliation(account_id3, false);
+  user_manager_->AddUserWithAffiliation(account_id4, true);
+  user_manager_->AddUserWithAffiliation(account_id5, true);
 
   // Verify that users are reported by default.
   GetStatus();
@@ -789,17 +799,17 @@
   GetStatus();
   EXPECT_EQ(6, status_.user_size());
   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(0).type());
-  EXPECT_EQ("user0@managed.com", status_.user(0).email());
+  EXPECT_EQ(account_id0.GetUserEmail(), status_.user(0).email());
   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(1).type());
-  EXPECT_EQ("user1@managed.com", status_.user(1).email());
+  EXPECT_EQ(account_id1.GetUserEmail(), status_.user(1).email());
   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(2).type());
-  EXPECT_EQ("user2@managed.com", status_.user(2).email());
+  EXPECT_EQ(account_id2.GetUserEmail(), status_.user(2).email());
   EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED, status_.user(3).type());
   EXPECT_FALSE(status_.user(3).has_email());
   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(4).type());
-  EXPECT_EQ("user4@managed.com", status_.user(4).email());
+  EXPECT_EQ(account_id4.GetUserEmail(), status_.user(4).email());
   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(5).type());
-  EXPECT_EQ("user5@managed.com", status_.user(5).email());
+  EXPECT_EQ(account_id5.GetUserEmail(), status_.user(5).email());
 
   // Verify that users are no longer reported if setting is disabled.
   settings_helper_.SetBoolean(chromeos::kReportDeviceUsers, false);
@@ -1293,7 +1303,8 @@
 
 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, ReportIfPublicSession) {
   // Report netowork state for public accounts.
-  user_manager_->CreatePublicAccountUser(kPublicAccountId);
+  user_manager_->CreatePublicAccountUser(
+      AccountId::FromUserEmail(kPublicAccountId));
   EXPECT_CALL(*user_manager_, IsLoggedInAsPublicAccount())
       .WillRepeatedly(Return(true));
 
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
index 8f75d38..45367bdf 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
@@ -25,6 +25,7 @@
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/policy_service_impl.h"
 #include "components/policy/core/common/policy_types.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_type.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -53,7 +54,7 @@
 
 class FakeUser : public user_manager::User {
  public:
-  FakeUser() : User(kFakeUserEmail) {
+  FakeUser() : User(AccountId::FromUserEmail(kFakeUserEmail)) {
     set_display_email(kFakeUserEmail);
     set_username_hash(kFakeUsernameHash);
   }
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
index 466fd01..98c3026 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
@@ -69,7 +69,8 @@
     // logged-in session is not possible. Fix this either by delaying the
     // cryptohome deletion operation or by getting rid of the in-session
     // wildcard check.
-    user_manager::UserManager::Get()->RemoveUserFromList(username);
+    user_manager::UserManager::Get()->RemoveUserFromList(
+        AccountId::FromUserEmail(username));
     chrome::AttemptUserExit();
   }
 }
diff --git a/chrome/browser/chromeos/power/extension_event_observer_unittest.cc b/chrome/browser/chromeos/power/extension_event_observer_unittest.cc
index 455fb6a..06fff499 100644
--- a/chrome/browser/chromeos/power/extension_event_observer_unittest.cc
+++ b/chrome/browser/chromeos/power/extension_event_observer_unittest.cc
@@ -68,9 +68,11 @@
     ASSERT_TRUE(profile_manager_->SetUp());
 
     const char kUserProfile[] = "profile1@example.com";
-    fake_user_manager_->AddUser(kUserProfile);
-    fake_user_manager_->LoginUser(kUserProfile);
-    profile_ = profile_manager_->CreateTestingProfile(kUserProfile);
+    const AccountId account_id(AccountId::FromUserEmail(kUserProfile));
+    fake_user_manager_->AddUser(account_id);
+    fake_user_manager_->LoginUser(account_id);
+    profile_ =
+        profile_manager_->CreateTestingProfile(account_id.GetUserEmail());
 
     profile_manager_->SetLoggedIn(true);
   }
diff --git a/chrome/browser/chromeos/power/power_prefs_unittest.cc b/chrome/browser/chromeos/power/power_prefs_unittest.cc
index 00586c3..194e4698 100644
--- a/chrome/browser/chromeos/power/power_prefs_unittest.cc
+++ b/chrome/browser/chromeos/power/power_prefs_unittest.cc
@@ -241,10 +241,11 @@
 
   // Set up user profile.
   const char test_user1[] = "test-user1@example.com";
-  user_manager->AddUser(test_user1);
-  user_manager->LoginUser(test_user1);
+  const AccountId test_account_id1(AccountId::FromUserEmail(test_user1));
+  user_manager->AddUser(test_account_id1);
+  user_manager->LoginUser(test_account_id1);
   TestingProfile* user_profile =
-      profile_manager_.CreateTestingProfile(test_user1);
+      profile_manager_.CreateTestingProfile(test_account_id1.GetUserEmail());
 
   profile_manager_.SetLoggedIn(true);
 
@@ -260,10 +261,11 @@
             GetCurrentAllowScreenWakeLocks());
 
   const char test_user2[] = "test-user2@example.com";
-  user_manager->AddUser(test_user2);
-  user_manager->LoginUser(test_user2);
+  const AccountId test_account_id2(AccountId::FromUserEmail(test_user2));
+  user_manager->AddUser(test_account_id2);
+  user_manager->LoginUser(test_account_id2);
   TestingProfile* other_profile =
-      profile_manager_.CreateTestingProfile(test_user2);
+      profile_manager_.CreateTestingProfile(test_account_id2.GetUserEmail());
 
   // Inform power_prefs_ that an unrelated profile has been destroyed.
   power_prefs_->Observe(chrome::NOTIFICATION_PROFILE_DESTROYED,
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index d32f60a..c5336f7 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -400,7 +400,8 @@
                                    const std::string& pref_name) {
   DCHECK(reason != REASON_PREF_CHANGED || !pref_name.empty());
   const bool user_is_owner =
-      user_manager::UserManager::Get()->GetOwnerEmail() == user_->email();
+      user_manager::UserManager::Get()->GetOwnerAccountId() ==
+      user_->GetAccountId();
   const bool user_is_active = user_->is_active();
 
   system::TouchpadSettings touchpad_settings;
@@ -625,7 +626,7 @@
       reason != REASON_ACTIVE_USER_CHANGED) {
     const bool value = prefs_->GetBoolean(prefs::kUse24HourClock);
     user_manager::UserManager::Get()->SetKnownUserBooleanPref(
-        user_->GetUserID(), prefs::kUse24HourClock, value);
+        user_->GetAccountId(), prefs::kUse24HourClock, value);
   }
 }
 
diff --git a/chrome/browser/chromeos/preferences_chromeos_browsertest.cc b/chrome/browser/chromeos/preferences_chromeos_browsertest.cc
index ef44d88..afbd9f5e 100644
--- a/chrome/browser/chromeos/preferences_chromeos_browsertest.cc
+++ b/chrome/browser/chromeos/preferences_chromeos_browsertest.cc
@@ -41,9 +41,11 @@
 class PreferencesTest : public LoginManagerTest {
  public:
   PreferencesTest()
-      : LoginManagerTest(true),
-        input_settings_(NULL),
-        keyboard_(NULL) {}
+      : LoginManagerTest(true), input_settings_(NULL), keyboard_(NULL) {
+    for (size_t i = 0; i < arraysize(kTestUsers); ++i) {
+      test_users_.push_back(AccountId::FromUserEmail(kTestUsers[i]));
+    }
+  }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     LoginManagerTest::SetUpCommandLine(command_line);
@@ -58,7 +60,7 @@
     static_cast<input_method::InputMethodManagerImpl*>(
         input_method::InputMethodManager::Get())
         ->SetImeKeyboardForTesting(keyboard_);
-    CrosSettings::Get()->SetString(kDeviceOwner, kTestUsers[0]);
+    CrosSettings::Get()->SetString(kDeviceOwner, test_users_[0].GetUserEmail());
   }
 
   // Sets set of preferences in given |prefs|. Value of prefernece depends of
@@ -129,6 +131,8 @@
         chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED);
   }
 
+  std::vector<AccountId> test_users_;
+
  private:
   system::FakeInputDeviceSettings* input_settings_;
   input_method::FakeImeKeyboard* keyboard_;
@@ -137,8 +141,8 @@
 };
 
 IN_PROC_BROWSER_TEST_F(PreferencesTest, PRE_MultiProfiles) {
-  RegisterUser(kTestUsers[0]);
-  RegisterUser(kTestUsers[1]);
+  RegisterUser(test_users_[0].GetUserEmail());
+  RegisterUser(test_users_[1].GetUserEmail());
   chromeos::StartupUtils::MarkOobeCompleted();
 }
 
@@ -147,8 +151,8 @@
 
   // Add first user and init its preferences. Check that corresponding
   // settings has been changed.
-  LoginUser(kTestUsers[0]);
-  const user_manager::User* user1 = user_manager->FindUser(kTestUsers[0]);
+  LoginUser(test_users_[0].GetUserEmail());
+  const user_manager::User* user1 = user_manager->FindUser(test_users_[0]);
   PrefService* prefs1 =
       ProfileHelper::Get()->GetProfileByUserUnsafe(user1)->GetPrefs();
   SetPrefs(prefs1, false);
@@ -159,9 +163,9 @@
   UserAddingScreen::Get()->Start();
   content::RunAllPendingInMessageLoop();
   DisableAnimations();
-  AddUser(kTestUsers[1]);
+  AddUser(test_users_[1].GetUserEmail());
   content::RunAllPendingInMessageLoop();
-  const user_manager::User* user2 = user_manager->FindUser(kTestUsers[1]);
+  const user_manager::User* user2 = user_manager->FindUser(test_users_[1]);
   EXPECT_TRUE(user2->is_active());
   PrefService* prefs2 =
       ProfileHelper::Get()->GetProfileByUserUnsafe(user2)->GetPrefs();
@@ -194,7 +198,7 @@
 
   // Check that changing non-owner prefs doesn't change corresponding local
   // state prefs and vice versa.
-  EXPECT_EQ(user_manager->GetOwnerEmail(), kTestUsers[0]);
+  EXPECT_EQ(user_manager->GetOwnerAccountId(), test_users_[0]);
   CheckLocalStateCorrespondsToPrefs(prefs1);
   prefs2->SetBoolean(prefs::kTapToClickEnabled,
                      !prefs1->GetBoolean(prefs::kTapToClickEnabled));
@@ -204,7 +208,7 @@
   CheckLocalStateCorrespondsToPrefs(prefs1);
 
   // Switch user back.
-  user_manager->SwitchActiveUser(kTestUsers[0]);
+  user_manager->SwitchActiveUser(test_users_[0]);
   CheckSettingsCorrespondToPrefs(prefs1);
   CheckLocalStateCorrespondsToPrefs(prefs1);
 }
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc
index 3875cb37..88936630 100644
--- a/chrome/browser/chromeos/preferences_unittest.cc
+++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -155,9 +155,10 @@
         new chromeos::ScopedUserManagerEnabler(user_manager));
 
     const char test_user_email[] = "test_user@example.com";
-    test_user_ = user_manager->AddUser(test_user_email);
-    user_manager->LoginUser(test_user_email);
-    user_manager->SwitchActiveUser(test_user_email);
+    const AccountId test_account_id(AccountId::FromUserEmail(test_user_email));
+    test_user_ = user_manager->AddUser(test_account_id);
+    user_manager->LoginUser(test_account_id);
+    user_manager->SwitchActiveUser(test_account_id);
 
     test_profile_ = profile_manager_->CreateTestingProfile(
         chrome::kInitialProfile);
diff --git a/chrome/browser/chromeos/printer_detector/printer_detector_unittest.cc b/chrome/browser/chromeos/printer_detector/printer_detector_unittest.cc
index 181cc2e..e547d4a 100644
--- a/chrome/browser/chromeos/printer_detector/printer_detector_unittest.cc
+++ b/chrome/browser/chromeos/printer_detector/printer_detector_unittest.cc
@@ -103,7 +103,8 @@
   }
 
   void AddTestUser() {
-    const user_manager::User* user = user_manager_->AddUser(kTestUserId);
+    const user_manager::User* user =
+        user_manager_->AddUser(AccountId::FromUserEmail(kTestUserId));
     profile_->set_profile_name(kTestUserId);
     chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
         user, profile_.get());
diff --git a/chrome/browser/chromeos/profiles/profile_helper.cc b/chrome/browser/chromeos/profiles/profile_helper.cc
index 24411c3..ddcd388 100644
--- a/chrome/browser/chromeos/profiles/profile_helper.cc
+++ b/chrome/browser/chromeos/profiles/profile_helper.cc
@@ -170,7 +170,8 @@
       ProfileHelper::Get()->GetUserByProfile(profile);
   if (!user)
     return false;
-  return user->email() == user_manager::UserManager::Get()->GetOwnerEmail();
+  return user->GetAccountId() ==
+         user_manager::UserManager::Get()->GetOwnerAccountId();
 }
 
 // static
diff --git a/chrome/browser/chromeos/profiles/profile_list_chromeos_unittest.cc b/chrome/browser/chromeos/profiles/profile_list_chromeos_unittest.cc
index 200eb1e5..c5c751ae 100644
--- a/chrome/browser/chromeos/profiles/profile_list_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/profiles/profile_list_chromeos_unittest.cc
@@ -72,14 +72,15 @@
 
   void AddProfile(base::string16 name, bool log_in) {
     std::string email_string = base::UTF16ToASCII(name) + "@example.com";
+    const AccountId account_id(AccountId::FromUserEmail(email_string));
 
     // Add a user to the fake user manager.
-    GetFakeChromeUserManager()->AddUser(email_string);
+    GetFakeChromeUserManager()->AddUser(account_id);
     if (log_in)
-      GetFakeChromeUserManager()->LoginUser(email_string);
+      GetFakeChromeUserManager()->LoginUser(account_id);
 
     // Create a profile for the user.
-    manager()->CreateTestingProfile(email_string);
+    manager()->CreateTestingProfile(account_id.GetUserEmail());
   }
 
   AvatarMenu* GetAvatarMenu() {
@@ -99,7 +100,8 @@
 
   void ActiveUserChanged(const base::string16& name) {
     std::string email_string = base::UTF16ToASCII(name) + "@example.com";
-    GetFakeChromeUserManager()->SwitchActiveUser(email_string);
+    const AccountId account_id(AccountId::FromUserEmail(email_string));
+    GetFakeChromeUserManager()->SwitchActiveUser(account_id);
   }
 
   TestingProfileManager* manager() { return &manager_; }
@@ -167,7 +169,8 @@
       cache->GetUserDataDir().AppendASCII("p2"), supervised_name, std::string(),
       base::string16(), 0, "TEST_ID");
 
-  GetFakeChromeUserManager()->AddUser(base::UTF16ToASCII(supervised_name));
+  GetFakeChromeUserManager()->AddUser(
+      AccountId::FromUserEmail(base::UTF16ToASCII(supervised_name)));
 
   AvatarMenu* menu = GetAvatarMenu();
   ASSERT_EQ(1U, menu->GetNumberOfItems());
@@ -243,7 +246,8 @@
   // Change name of the first profile, to trigger resorting of the profiles:
   // now the first menu item should be named "beta", and the second be "gamma".
   GetFakeChromeUserManager()->SaveUserDisplayName(
-      base::UTF16ToASCII(name1) + "@example.com", newname1);
+      AccountId::FromUserEmail(base::UTF16ToASCII(name1) + "@example.com"),
+      newname1);
   manager()->profile_info_cache()->SetNameOfProfileAtIndex(0, newname1);
   EXPECT_EQ(1, change_count());
 
diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
index e02000c..754e8ff4 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
@@ -262,7 +262,8 @@
 
 TEST_F(DeviceSettingsProviderTest, SetPrefSucceed) {
   owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   FlushDeviceSettings();
 
   base::FundamentalValue value(true);
@@ -290,7 +291,8 @@
 
 TEST_F(DeviceSettingsProviderTest, SetPrefTwice) {
   owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   FlushDeviceSettings();
 
   EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
@@ -410,7 +412,8 @@
 
 TEST_F(DeviceSettingsProviderTest, OwnerIsStillSetWhenDeviceIsConsumerManaged) {
   owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   device_policy_.policy_data().set_management_mode(
       em::PolicyData::CONSUMER_MANAGED);
   device_policy_.policy_data().set_request_token("test request token");
diff --git a/chrome/browser/chromeos/settings/device_settings_service_unittest.cc b/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
index 78cd3f90..a2e7b56 100644
--- a/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
@@ -170,7 +170,8 @@
             device_settings_service_.status());
 
   owner_key_util_->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey());
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   device_settings_service_.Store(
       device_policy_.GetCopy(),
       base::Bind(&DeviceSettingsServiceTest::SetOperationCompleted,
@@ -243,7 +244,8 @@
   EXPECT_EQ(DeviceSettingsService::OWNERSHIP_TAKEN, ownership_status_);
 
   owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   device_settings_service_.GetOwnershipStatusAsync(
       base::Bind(&DeviceSettingsServiceTest::SetOwnershipStatus,
                  base::Unretained(this)));
@@ -267,7 +269,7 @@
             device_settings_service_.GetOwnershipStatus());
 
   const std::string& user_id = device_policy_.policy_data().username();
-  InitOwner(user_id, false);
+  InitOwner(AccountId::FromUserEmail(user_id), false);
   OwnerSettingsServiceChromeOS* service =
       OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile_.get());
   ASSERT_TRUE(service);
@@ -312,7 +314,7 @@
 
   const std::string& user_id = device_policy_.policy_data().username();
   owner_key_util_->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey());
-  InitOwner(user_id, false);
+  InitOwner(AccountId::FromUserEmail(user_id), false);
   OwnerSettingsServiceChromeOS* service =
       OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile_.get());
   ASSERT_TRUE(service);
@@ -348,7 +350,7 @@
 
   const std::string& user_id = device_policy_.policy_data().username();
   owner_key_util_->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey());
-  InitOwner(user_id, false);
+  InitOwner(AccountId::FromUserEmail(user_id), false);
   OwnerSettingsServiceChromeOS* service =
       OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile_.get());
   ASSERT_TRUE(service);
@@ -392,7 +394,8 @@
   owner_key_util_->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey());
   owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
 
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   ReloadDeviceSettings();
   FlushDeviceSettings();
 
@@ -438,7 +441,8 @@
   EXPECT_CALL(observer_, OwnershipStatusChanged()).Times(1);
   EXPECT_CALL(observer_, DeviceSettingsUpdated()).Times(1);
   owner_key_util_->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey());
-  InitOwner(device_policy_.policy_data().username(), true);
+  InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()),
+            true);
   ReloadDeviceSettings();
   Mock::VerifyAndClearExpectations(&observer_);
 
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.cc b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
index 45236d8..f61155c 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.cc
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
@@ -246,12 +246,12 @@
   FlushDeviceSettings();
 }
 
-void DeviceSettingsTestBase::InitOwner(const std::string& user_id,
+void DeviceSettingsTestBase::InitOwner(const AccountId& account_id,
                                        bool tpm_is_ready) {
-  const user_manager::User* user = user_manager_->FindUser(user_id);
+  const user_manager::User* user = user_manager_->FindUser(account_id);
   if (!user) {
-    user = user_manager_->AddUser(user_id);
-    profile_->set_profile_name(user_id);
+    user = user_manager_->AddUser(account_id);
+    profile_->set_profile_name(account_id.GetUserEmail());
 
     ProfileHelper::Get()->SetUserToProfileMappingForTesting(user,
                                                             profile_.get());
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.h b/chrome/browser/chromeos/settings/device_settings_test_helper.h
index 823c0881..565116a 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.h
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.h
@@ -170,7 +170,7 @@
   // |device_settings_service_| and flushes the resulting load operation.
   void ReloadDeviceSettings();
 
-  void InitOwner(const std::string& user_id, bool tpm_is_ready);
+  void InitOwner(const AccountId& account_id, bool tpm_is_ready);
 
   content::TestBrowserThreadBundle thread_bundle_;
 
diff --git a/chrome/browser/chromeos/status/data_promo_notification_unittest.cc b/chrome/browser/chromeos/status/data_promo_notification_unittest.cc
index 0b79555..9eaede3 100644
--- a/chrome/browser/chromeos/status/data_promo_notification_unittest.cc
+++ b/chrome/browser/chromeos/status/data_promo_notification_unittest.cc
@@ -86,8 +86,9 @@
  protected:
   void SetupUser() {
     scoped_ptr<FakeChromeUserManager> user_manager(new FakeChromeUserManager());
-    user_manager->AddUser(kTestUserName);
-    user_manager->LoginUser(kTestUserName);
+    const AccountId test_account_id(AccountId::FromUserEmail(kTestUserName));
+    user_manager->AddUser(test_account_id);
+    user_manager->LoginUser(test_account_id);
     user_manager_enabler_.reset(
         new ScopedUserManagerEnabler(user_manager.release()));
 
diff --git a/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc b/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc
index d01d4dd..2fcf87d 100644
--- a/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc
+++ b/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc
@@ -112,7 +112,7 @@
 }
 
 void DeviceDisablingManagerTestBase::LogIn() {
-  fake_user_manager_.AddUser(kTestUser);
+  fake_user_manager_.AddUser(AccountId::FromUserEmail(kTestUser));
 }
 
 // Base class for tests that verify device disabling behavior during OOBE, when
diff --git a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
index 2badedad..b6e2b8a 100644
--- a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
+++ b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
@@ -272,7 +272,8 @@
   EXPECT_EQ(ash::user::LOGGED_IN_NONE, GetLoginStatus());
 
   user_manager::UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+      AccountId::FromUserEmail("owner@invalid.domain"), "owner@invalid.domain",
+      true);
   user_manager::UserManager::Get()->SessionStarted();
 
   EXPECT_EQ(ash::user::LOGGED_IN_USER, GetLoginStatus());
@@ -285,7 +286,8 @@
   EXPECT_FALSE(IsTrayIconVisible());
 
   user_manager::UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+      AccountId::FromUserEmail("owner@invalid.domain"), "owner@invalid.domain",
+      true);
   user_manager::UserManager::Get()->SessionStarted();
 
   // Confirms that the icon is invisible just after login.
@@ -350,7 +352,8 @@
 IN_PROC_BROWSER_TEST_P(TrayAccessibilityTest, ShowMenu) {
   // Login
   user_manager::UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+      AccountId::FromUserEmail("owner@invalid.domain"), "owner@invalid.domain",
+      true);
   user_manager::UserManager::Get()->SessionStarted();
 
   SetShowAccessibilityOptionsInSystemTrayMenu(false);
@@ -418,7 +421,8 @@
 IN_PROC_BROWSER_TEST_P(TrayAccessibilityTest, ShowMenuWithShowMenuOption) {
   // Login
   user_manager::UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+      AccountId::FromUserEmail("owner@invalid.domain"), "owner@invalid.domain",
+      true);
   user_manager::UserManager::Get()->SessionStarted();
 
   SetShowAccessibilityOptionsInSystemTrayMenu(true);
diff --git a/chrome/browser/download/notification/download_notification_browsertest.cc b/chrome/browser/download/notification/download_notification_browsertest.cc
index b6578d40..e2698d7 100644
--- a/chrome/browser/download/notification/download_notification_browsertest.cc
+++ b/chrome/browser/download/notification/download_notification_browsertest.cc
@@ -1134,8 +1134,9 @@
     user_manager::UserManager* const user_manager =
         user_manager::UserManager::Get();
     if (log_in)
-      user_manager->UserLoggedIn(info.email, info.hash, false);
-    user_manager->SaveUserDisplayName(info.email,
+      user_manager->UserLoggedIn(AccountId::FromUserEmail(info.email),
+                                 info.hash, false);
+    user_manager->SaveUserDisplayName(AccountId::FromUserEmail(info.email),
                                       base::UTF8ToUTF16(info.display_name));
     SigninManagerFactory::GetForProfile(
         chromeos::ProfileHelper::GetProfileByUserIdHash(info.hash))
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc
index 963f0fd..de9428f 100644
--- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h"
 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/extensions/extension_apitest.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "content/public/test/browser_test.h"
 #include "extensions/common/switches.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -55,9 +56,10 @@
     user_manager_enabler_.reset(
         new chromeos::ScopedUserManagerEnabler(fake_user_manager_));
 
-    const std::string kKiosLogin = "kiosk@foobar.com";
-    fake_user_manager_->AddKioskAppUser(kKiosLogin);
-    fake_user_manager_->LoginUser(kKiosLogin);
+    const AccountId kiosk_account_id(
+        AccountId::FromUserEmail("kiosk@foobar.com"));
+    fake_user_manager_->AddKioskAppUser(kiosk_account_id);
+    fake_user_manager_->LoginUser(kiosk_account_id);
   }
 
   void SetAutoLaunchApp() {
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
index c3358868..dba4fe3f 100644
--- a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
+++ b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
@@ -321,7 +321,7 @@
   scoped_ptr<ScreenLockerTester> tester(ScreenLocker::GetTester());
   // Log in.
   user_manager::UserManager::Get()->UserLoggedIn(
-      kTestUserName, kTestUserName, true);
+      AccountId::FromUserEmail(kTestUserName), kTestUserName, true);
   user_manager::UserManager::Get()->SessionStarted();
   Profile* profile = ProfileManager::GetActiveUserProfile();
   ASSERT_FALSE(
diff --git a/chrome/browser/extensions/api/file_system/file_system_api_unittest.cc b/chrome/browser/extensions/api/file_system/file_system_api_unittest.cc
index e6df024d..62b2775 100644
--- a/chrome/browser/extensions/api/file_system/file_system_api_unittest.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_api_unittest.cc
@@ -366,8 +366,10 @@
                                .SetBoolean("kiosk_enabled", true)
                                .SetBoolean("kiosk_only", true))
             .Build());
-    user_manager_->AddKioskAppUser(auto_launch_kiosk_app->id());
-    user_manager_->LoginUser(auto_launch_kiosk_app->id());
+    user_manager_->AddKioskAppUser(
+        AccountId::FromUserEmail(auto_launch_kiosk_app->id()));
+    user_manager_->LoginUser(
+        AccountId::FromUserEmail(auto_launch_kiosk_app->id()));
 
     TestingConsentProviderDelegate delegate;
     delegate.SetIsAutoLaunched(true);
@@ -393,7 +395,8 @@
                              .SetBoolean("kiosk_enabled", true)
                              .SetBoolean("kiosk_only", true))
           .Build());
-  user_manager_->KioskAppLoggedIn(manual_launch_kiosk_app->id());
+  user_manager_->KioskAppLoggedIn(
+      AccountId::FromUserEmail(manual_launch_kiosk_app->id()));
   {
     TestingConsentProviderDelegate delegate;
     delegate.SetDialogButton(ui::DIALOG_BUTTON_OK);
diff --git a/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc b/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc
index ca86c43..17f4dff 100644
--- a/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_apitest_chromeos.cc
@@ -265,9 +265,10 @@
     user_manager_enabler_.reset(
         new chromeos::ScopedUserManagerEnabler(fake_user_manager_));
 
-    const std::string kKioskLogin = "kiosk@foobar.com";
-    fake_user_manager_->AddKioskAppUser(kKioskLogin);
-    fake_user_manager_->LoginUser(kKioskLogin);
+    const AccountId kiosk_app_account_id =
+        AccountId::FromUserEmail("kiosk@foobar.com");
+    fake_user_manager_->AddKioskAppUser(kiosk_app_account_id);
+    fake_user_manager_->LoginUser(kiosk_app_account_id);
   }
 };
 
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index b2c8a3c..3cced57 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -283,8 +283,8 @@
         settings_private::PolicySource::POLICY_SOURCE_OWNER;
     pref_object->policy_enforcement =
         settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED;
-    pref_object->policy_source_name.reset(
-        new std::string(user_manager::UserManager::Get()->GetOwnerEmail()));
+    pref_object->policy_source_name.reset(new std::string(
+        user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail()));
     return pref_object.Pass();
   }
 #endif
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc
index 4656593..3321e784 100644
--- a/chrome/browser/extensions/crx_installer_browsertest.cc
+++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -535,8 +535,9 @@
   // lifetime of |user_manager|.
   chromeos::FakeChromeUserManager* fake_user_manager =
       new chromeos::FakeChromeUserManager();
-  fake_user_manager->AddKioskAppUser("example@example.com");
-  fake_user_manager->LoginUser("example@example.com");
+  const AccountId account_id(AccountId::FromUserEmail("example@example.com"));
+  fake_user_manager->AddKioskAppUser(account_id);
+  fake_user_manager->LoginUser(account_id);
   chromeos::ScopedUserManagerEnabler scoped_user_manager(fake_user_manager);
   EXPECT_TRUE(InstallExtension(crx_path, 1));
 #endif
diff --git a/chrome/browser/extensions/extension_assets_manager_chromeos.cc b/chrome/browser/extensions/extension_assets_manager_chromeos.cc
index 8fc3425..5498941d 100644
--- a/chrome/browser/extensions/extension_assets_manager_chromeos.cc
+++ b/chrome/browser/extensions/extension_assets_manager_chromeos.cc
@@ -287,7 +287,8 @@
     return;
   }
 
-  if (user_manager->IsUserNonCryptohomeDataEphemeral(user_id) ||
+  if (user_manager->IsUserNonCryptohomeDataEphemeral(
+          AccountId::FromUserEmail(user_id)) ||
       !user_manager->IsLoggedInAsUserWithGaiaAccount()) {
     // Don't cache anything in shared location for ephemeral user or special
     // user types.
@@ -530,7 +531,8 @@
         NOTREACHED();
         return false;
       }
-      const user_manager::User* user = user_manager->FindUser(user_id);
+      const user_manager::User* user =
+          user_manager->FindUser(AccountId::FromUserEmail(user_id));
       bool not_used = false;
       if (!user) {
         not_used = true;
diff --git a/chrome/browser/extensions/extension_garbage_collector_chromeos_unittest.cc b/chrome/browser/extensions/extension_garbage_collector_chromeos_unittest.cc
index d314314..76371fc 100644
--- a/chrome/browser/extensions/extension_garbage_collector_chromeos_unittest.cc
+++ b/chrome/browser/extensions/extension_garbage_collector_chromeos_unittest.cc
@@ -69,8 +69,8 @@
     user_manager_enabler_.reset(new chromeos::ScopedUserManagerEnabler(
         new chromeos::FakeChromeUserManager));
 
-    GetFakeUserManager()->AddUser(chromeos::login::kStubUser);
-    GetFakeUserManager()->LoginUser(chromeos::login::kStubUser);
+    GetFakeUserManager()->AddUser(chromeos::login::StubAccountId());
+    GetFakeUserManager()->LoginUser(chromeos::login::StubAccountId());
     chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
         GetFakeUserManager()->GetActiveUser(), profile_.get());
   }
diff --git a/chrome/browser/memory/tab_manager.cc b/chrome/browser/memory/tab_manager.cc
index dfb7c44..31a095e0 100644
--- a/chrome/browser/memory/tab_manager.cc
+++ b/chrome/browser/memory/tab_manager.cc
@@ -180,6 +180,10 @@
   return stats_list;
 }
 
+bool TabManager::IsTabDiscarded(content::WebContents* contents) const {
+  return GetWebContentsData(contents)->IsDiscarded();
+}
+
 // TODO(jamescook): This should consider tabs with references to other tabs,
 // such as tabs created with JavaScript window.open(). Potentially consider
 // discarding the entire set together, or use that in the priority computation.
@@ -227,15 +231,22 @@
                               TabChangeType change_type) {
   if (change_type != TabChangeType::ALL)
     return;
-
-  bool old_state = WebContentsData::IsRecentlyAudible(contents);
+  auto data = GetWebContentsData(contents);
+  bool old_state = data->IsRecentlyAudible();
   bool current_state = contents->WasRecentlyAudible();
   if (old_state != current_state) {
-    WebContentsData::SetRecentlyAudible(contents, current_state);
-    WebContentsData::SetLastAudioChangeTime(contents, TimeTicks::Now());
+    data->SetRecentlyAudible(current_state);
+    data->SetLastAudioChangeTime(TimeTicks::Now());
   }
 }
 
+void TabManager::ActiveTabChanged(content::WebContents* old_contents,
+                                  content::WebContents* new_contents,
+                                  int index,
+                                  int reason) {
+  GetWebContentsData(new_contents)->SetDiscardState(false);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // TabManager, private:
 
@@ -368,10 +379,10 @@
         stats.is_playing_audio = IsAudioTab(contents);
         stats.is_pinned = model->IsTabPinned(i);
         stats.is_selected = browser_active && model->IsTabSelected(i);
-        stats.is_discarded = WebContentsData::IsDiscarded(contents);
+        stats.is_discarded = GetWebContentsData(contents)->IsDiscarded();
         stats.has_form_entry =
             contents->GetPageImportanceSignals().had_form_interaction;
-        stats.discard_count = WebContentsData::DiscardCount(contents);
+        stats.discard_count = GetWebContentsData(contents)->DiscardCount();
         stats.last_active = contents->GetLastActiveTime();
         stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle();
         stats.child_process_host_id = contents->GetRenderProcessHost()->GetID();
@@ -441,7 +452,7 @@
     return false;
 
   // Do not discard a previously discarded tab if that's the desired behavior.
-  if (discard_once_ && WebContentsData::DiscardCount(web_contents) > 0)
+  if (discard_once_ && GetWebContentsData(web_contents)->DiscardCount() > 0)
     return false;
 
   return true;
@@ -455,7 +466,7 @@
   WebContents* old_contents = model->GetWebContentsAt(index);
 
   // Can't discard tabs that are already discarded.
-  if (WebContentsData::IsDiscarded(old_contents))
+  if (GetWebContentsData(old_contents)->IsDiscarded())
     return nullptr;
 
   // Record statistics before discarding to capture the memory state that leads
@@ -476,8 +487,8 @@
   // Replace the discarded tab with the null version.
   model->ReplaceWebContentsAt(index, null_contents);
   // Mark the tab so it will reload when clicked on.
-  WebContentsData::SetDiscardState(null_contents, true);
-  WebContentsData::IncrementDiscardCount(null_contents);
+  GetWebContentsData(null_contents)->SetDiscardState(true);
+  GetWebContentsData(null_contents)->IncrementDiscardCount();
 
   // Discard the old tab's renderer.
   // TODO(jamescook): This breaks script connections with other tabs.
@@ -508,10 +519,16 @@
   if (contents->WasRecentlyAudible())
     return true;
   auto delta =
-      TimeTicks::Now() - WebContentsData::LastAudioChangeTime(contents);
+      TimeTicks::Now() - GetWebContentsData(contents)->LastAudioChangeTime();
   return delta < TimeDelta::FromSeconds(kAudioProtectionTimeSeconds);
 }
 
+TabManager::WebContentsData* TabManager::GetWebContentsData(
+    content::WebContents* contents) const {
+  WebContentsData::CreateForWebContents(contents);
+  return WebContentsData::FromWebContents(contents);
+}
+
 // static
 bool TabManager::CompareTabStats(TabStats first, TabStats second) {
   // Being currently selected is most important to protect.
diff --git a/chrome/browser/memory/tab_manager.h b/chrome/browser/memory/tab_manager.h
index e4984ad..951319af 100644
--- a/chrome/browser/memory/tab_manager.h
+++ b/chrome/browser/memory/tab_manager.h
@@ -50,8 +50,7 @@
 // support for new platforms is added.
 class TabManager : public TabStripModelObserver {
  public:
-  // TODO(georgesak): Make this private once all external dependencies are
-  // removed.
+  // Needs to be public for DEFINE_WEB_CONTENTS_USER_DATA_KEY.
   class WebContentsData;
 
   TabManager();
@@ -72,6 +71,9 @@
   // thread.
   TabStatsList GetTabStats();
 
+  // Returns true if |contents| is currently discarded.
+  bool IsTabDiscarded(content::WebContents* contents) const;
+
   // Discards a tab to free the memory occupied by its renderer. The tab still
   // exists in the tab-strip; clicking on it will reload it. Returns true if it
   // successfully found a tab and discarded it.
@@ -147,11 +149,19 @@
   void TabChangedAt(content::WebContents* contents,
                     int index,
                     TabChangeType change_type) override;
+  void ActiveTabChanged(content::WebContents* old_contents,
+                        content::WebContents* new_contents,
+                        int index,
+                        int reason) override;
 
   // Returns true if the tab is currently playing audio or has played audio
   // recently.
   bool IsAudioTab(content::WebContents* contents) const;
 
+  // Returns the WebContentsData associated with |contents|. Also takes care of
+  // creating one if needed.
+  WebContentsData* GetWebContentsData(content::WebContents* contents) const;
+
   // Returns true if |first| is considered less desirable to be killed than
   // |second|.
   static bool CompareTabStats(TabStats first, TabStats second);
diff --git a/chrome/browser/memory/tab_manager_browsertest.cc b/chrome/browser/memory/tab_manager_browsertest.cc
index bb0e948a..e28ddde 100644
--- a/chrome/browser/memory/tab_manager_browsertest.cc
+++ b/chrome/browser/memory/tab_manager_browsertest.cc
@@ -95,42 +95,31 @@
   // and was not selected.
   EXPECT_TRUE(tab_manager->DiscardTab());
   EXPECT_EQ(3, tsm->count());
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(0)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(1)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(2)));
+  EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
   EXPECT_TRUE(tab_manager->recent_tab_discard());
 
   // Run discard again, make sure it kills the second tab.
   EXPECT_TRUE(tab_manager->DiscardTab());
   EXPECT_EQ(3, tsm->count());
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(0)));
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(1)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(2)));
+  EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
+  EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
 
   // Kill the third tab. It should not kill the last tab, since it is active
   // tab.
   EXPECT_FALSE(tab_manager->DiscardTab());
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(0)));
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(1)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(2)));
+  EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
+  EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
 
   // Kill the third tab after making second tab active.
   tsm->ActivateTabAt(1, true);
   EXPECT_EQ(1, tsm->active_index());
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(1)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
   tab_manager->DiscardWebContentsAt(2, tsm);
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(2)));
+  EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
 
   // Force creation of the FindBarController.
   browser()->GetFindBarController();
@@ -145,12 +134,9 @@
   EXPECT_EQ(browser()->GetFindBarController()->web_contents(),
             tsm->GetActiveWebContents());
   EXPECT_EQ(0, tsm->active_index());
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(0)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(1)));
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(2)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
+  EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
 
   // Select the third tab. It should reload.
   WindowedNotificationObserver reload2(
@@ -159,12 +145,9 @@
   chrome::SelectNumberedTab(browser(), 2);
   reload2.Wait();
   EXPECT_EQ(2, tsm->active_index());
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(0)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(1)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tsm->GetWebContentsAt(2)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
+  EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
 
   // Navigate the third tab back twice.  We used to crash here due to
   // crbug.com/121373.
diff --git a/chrome/browser/memory/tab_manager_unittest.cc b/chrome/browser/memory/tab_manager_unittest.cc
index afa8ae6..52bad28 100644
--- a/chrome/browser/memory/tab_manager_unittest.cc
+++ b/chrome/browser/memory/tab_manager_unittest.cc
@@ -223,6 +223,7 @@
 
   TabStripDummyDelegate delegate;
   TabStripModel tabstrip(&delegate, profile());
+  tabstrip.AddObserver(&tab_manager);
 
   // Fill it with some tabs.
   WebContents* contents1 = CreateWebContents();
@@ -238,10 +239,8 @@
   // Discard one of the tabs.
   WebContents* null_contents1 = tab_manager.DiscardWebContentsAt(0, &tabstrip);
   ASSERT_EQ(2, tabstrip.count());
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(0)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(1)));
+  EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
+  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
   ASSERT_EQ(null_contents1, tabstrip.GetWebContentsAt(0));
   ASSERT_EQ(contents2, tabstrip.GetWebContentsAt(1));
   ASSERT_EQ(1, tabstrip_observer.NbEvents());
@@ -250,14 +249,12 @@
   tabstrip_observer.Reset();
 
   // Discard the same tab again, after resetting its discard state.
-  TabManager::WebContentsData::SetDiscardState(tabstrip.GetWebContentsAt(0),
-                                               false);
+  tab_manager.GetWebContentsData(tabstrip.GetWebContentsAt(0))
+      ->SetDiscardState(false);
   WebContents* null_contents2 = tab_manager.DiscardWebContentsAt(0, &tabstrip);
   ASSERT_EQ(2, tabstrip.count());
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(0)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(1)));
+  EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
+  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
   ASSERT_EQ(null_contents2, tabstrip.GetWebContentsAt(0));
   ASSERT_EQ(contents2, tabstrip.GetWebContentsAt(1));
   ASSERT_EQ(1, tabstrip_observer.NbEvents());
@@ -267,18 +264,14 @@
   // Activating the tab should clear its discard state.
   tabstrip.ActivateTabAt(0, true /* user_gesture */);
   ASSERT_EQ(2, tabstrip.count());
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(0)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(1)));
+  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
+  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
 
   // Don't discard active tab.
   tab_manager.DiscardWebContentsAt(0, &tabstrip);
   ASSERT_EQ(2, tabstrip.count());
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(0)));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(1)));
+  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
+  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
 
   tabstrip.CloseAllTabs();
   EXPECT_TRUE(tabstrip.empty());
@@ -287,6 +280,10 @@
 // Makes sure that reloading a discarded tab without activating it unmarks the
 // tab as discarded so it won't reload on activation.
 TEST_F(TabManagerTest, ReloadDiscardedTabContextMenu) {
+  // Note that we do not add |tab_manager| as an observer to |tabstrip| here as
+  // the event we are trying to test for is not related to the tab strip, but
+  // the web content instead and therefore should be handled by WebContentsData
+  // (which observes the web content).
   TabManager tab_manager;
   TabStripDummyDelegate delegate;
   TabStripModel tabstrip(&delegate, profile());
@@ -301,17 +298,13 @@
   // so the reload can happen.
   WebContentsTester::For(test_contents)
       ->NavigateAndCommit(GURL("chrome://newtab"));
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(1)));
+  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
 
   tab_manager.DiscardWebContentsAt(1, &tabstrip);
-  EXPECT_TRUE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(1)));
+  EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
 
   tabstrip.GetWebContentsAt(1)->GetController().Reload(false);
-  EXPECT_FALSE(
-      TabManager::WebContentsData::IsDiscarded(tabstrip.GetWebContentsAt(1)));
-
+  EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
   tabstrip.CloseAllTabs();
   EXPECT_TRUE(tabstrip.empty());
 }
@@ -322,6 +315,7 @@
   TabManager tab_manager;
   TabStripDummyDelegate delegate;
   TabStripModel tabstrip(&delegate, profile());
+  tabstrip.AddObserver(&tab_manager);
 
   tabstrip.AppendWebContents(CreateWebContents(), true);
   WebContents* test_contents = CreateWebContents();
diff --git a/chrome/browser/memory/tab_manager_web_contents_data.cc b/chrome/browser/memory/tab_manager_web_contents_data.cc
index d4efa76..42e31f7 100644
--- a/chrome/browser/memory/tab_manager_web_contents_data.cc
+++ b/chrome/browser/memory/tab_manager_web_contents_data.cc
@@ -11,116 +11,82 @@
 using base::TimeTicks;
 using content::WebContents;
 
-namespace {
-
-const char kDiscardStateKey[] = "WebContentsData";
-
-}  // namespace
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(memory::TabManager::WebContentsData);
 
 namespace memory {
 
-// static
-TabManager::WebContentsData* TabManager::WebContentsData::Get(
-    WebContents* web_contents) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  TabManager::WebContentsData* discard_state = static_cast<WebContentsData*>(
-      web_contents->GetUserData(&kDiscardStateKey));
+TabManager::WebContentsData::WebContentsData(content::WebContents* web_contents)
+    : WebContentsObserver(web_contents) {}
 
-  // If this function is called, we probably need to query/change the discard
-  // state. Let's go ahead a add one.
-  if (!discard_state) {
-    discard_state = new WebContentsData;
-    web_contents->SetUserData(&kDiscardStateKey, discard_state);
-  }
+TabManager::WebContentsData::~WebContentsData() {}
 
-  return discard_state;
+void TabManager::WebContentsData::DidStartLoading() {
+  // Marks the tab as no longer discarded if it has been reloaded from another
+  // source (ie: context menu).
+  SetDiscardState(false);
 }
 
-// static
-void TabManager::WebContentsData::Set(WebContents* web_contents,
-                                      WebContentsData* state) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  web_contents->SetUserData(&kDiscardStateKey, state);
+bool TabManager::WebContentsData::IsDiscarded() {
+  return tab_data_.is_discarded_;
+}
+
+void TabManager::WebContentsData::SetDiscardState(bool state) {
+  if (tab_data_.is_discarded_ && !state) {
+    static int reload_count = 0;
+    UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.ReloadCount",
+                                ++reload_count, 1, 1000, 50);
+    auto delta = base::TimeTicks::Now() - tab_data_.last_discard_time_;
+    // Capped to one day for now, will adjust if necessary.
+    UMA_HISTOGRAM_CUSTOM_TIMES("TabManager.Discarding.DiscardToReloadTime",
+                               delta, base::TimeDelta::FromSeconds(1),
+                               base::TimeDelta::FromDays(1), 100);
+  } else if (!tab_data_.is_discarded_ && state) {
+    static int discard_count = 0;
+    UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.DiscardCount",
+                                ++discard_count, 1, 1000, 50);
+    tab_data_.last_discard_time_ = base::TimeTicks::Now();
+  }
+
+  tab_data_.is_discarded_ = state;
+}
+
+int TabManager::WebContentsData::DiscardCount() {
+  return tab_data_.discard_count_;
+}
+
+void TabManager::WebContentsData::IncrementDiscardCount() {
+  tab_data_.discard_count_++;
+}
+
+bool TabManager::WebContentsData::IsRecentlyAudible() {
+  return tab_data_.is_recently_audible_;
+}
+
+void TabManager::WebContentsData::SetRecentlyAudible(bool state) {
+  tab_data_.is_recently_audible_ = state;
+}
+
+TimeTicks TabManager::WebContentsData::LastAudioChangeTime() {
+  return tab_data_.last_audio_change_time_;
+}
+
+void TabManager::WebContentsData::SetLastAudioChangeTime(TimeTicks timestamp) {
+  tab_data_.last_audio_change_time_ = timestamp;
 }
 
 // static
 void TabManager::WebContentsData::CopyState(
     content::WebContents* old_contents,
     content::WebContents* new_contents) {
-  WebContentsData* old_state = Get(old_contents);
-  WebContentsData* new_State = Get(new_contents);
-  *new_State = *old_state;
-}
-
-// static
-bool TabManager::WebContentsData::IsDiscarded(WebContents* web_contents) {
-  return TabManager::WebContentsData::Get(web_contents)->is_discarded_;
-}
-
-// static
-void TabManager::WebContentsData::SetDiscardState(WebContents* web_contents,
-                                                  bool state) {
-  WebContentsData* discard_state =
-      TabManager::WebContentsData::Get(web_contents);
-  if (discard_state->is_discarded_ && !state) {
-    static int reload_count = 0;
-    UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.ReloadCount",
-                                ++reload_count, 1, 1000, 50);
-    auto delta = base::TimeTicks::Now() - discard_state->last_discard_time_;
-    // Capped to one day for now, will adjust if necessary.
-    UMA_HISTOGRAM_CUSTOM_TIMES("TabManager.Discarding.DiscardToReloadTime",
-                               delta, base::TimeDelta::FromSeconds(1),
-                               base::TimeDelta::FromDays(1), 100);
-  } else if (!discard_state->is_discarded_ && state) {
-    static int discard_count = 0;
-    UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.DiscardCount",
-                                ++discard_count, 1, 1000, 50);
-    discard_state->last_discard_time_ = base::TimeTicks::Now();
+  // Only copy if an existing state is found.
+  if (FromWebContents(old_contents)) {
+    CreateForWebContents(new_contents);
+    FromWebContents(new_contents)->tab_data_ =
+        FromWebContents(old_contents)->tab_data_;
   }
-
-  discard_state->is_discarded_ = state;
 }
 
-// static
-int TabManager::WebContentsData::DiscardCount(WebContents* web_contents) {
-  return TabManager::WebContentsData::Get(web_contents)->discard_count_;
-}
-
-// static
-void TabManager::WebContentsData::IncrementDiscardCount(
-    WebContents* web_contents) {
-  TabManager::WebContentsData::Get(web_contents)->discard_count_++;
-}
-
-// static
-bool TabManager::WebContentsData::IsRecentlyAudible(
-    content::WebContents* web_contents) {
-  return TabManager::WebContentsData::Get(web_contents)->is_recently_audible_;
-}
-
-// static
-void TabManager::WebContentsData::SetRecentlyAudible(
-    content::WebContents* web_contents,
-    bool state) {
-  TabManager::WebContentsData::Get(web_contents)->is_recently_audible_ = state;
-}
-
-// static
-TimeTicks TabManager::WebContentsData::LastAudioChangeTime(
-    content::WebContents* web_contents) {
-  return TabManager::WebContentsData::Get(web_contents)
-      ->last_audio_change_time_;
-}
-
-// static
-void TabManager::WebContentsData::SetLastAudioChangeTime(
-    content::WebContents* web_contents,
-    TimeTicks timestamp) {
-  TabManager::WebContentsData::Get(web_contents)->last_audio_change_time_ =
-      timestamp;
-}
-
-TabManager::WebContentsData::WebContentsData()
+TabManager::WebContentsData::Data::Data()
     : is_discarded_(false),
       discard_count_(0),
       is_recently_audible_(false),
diff --git a/chrome/browser/memory/tab_manager_web_contents_data.h b/chrome/browser/memory/tab_manager_web_contents_data.h
index 649da98..11d28af 100644
--- a/chrome/browser/memory/tab_manager_web_contents_data.h
+++ b/chrome/browser/memory/tab_manager_web_contents_data.h
@@ -5,9 +5,11 @@
 #ifndef CHROME_BROWSER_MEMORY_TAB_MANAGER_WEB_CONTENTS_DATA_H_
 #define CHROME_BROWSER_MEMORY_TAB_MANAGER_WEB_CONTENTS_DATA_H_
 
-#include "base/supports_user_data.h"
+#include "base/macros.h"
 #include "base/time/time.h"
 #include "chrome/browser/memory/tab_manager.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
 
 namespace content {
 class WebContents;
@@ -15,69 +17,67 @@
 
 namespace memory {
 
-// Manages the information about the discarding state of a tab. This data is
-// stored in WebContents.
-class TabManager::WebContentsData : public base::SupportsUserData::Data {
+// Internal class used by TabManager to record the needed data for
+// WebContentses.
+class TabManager::WebContentsData
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<TabManager::WebContentsData> {
  public:
-  // Returns the WebContentsData associated with |web_contents|. It will create
-  // one if none exists.
-  static WebContentsData* Get(content::WebContents* web_contents);
+  explicit WebContentsData(content::WebContents* web_contents);
+  ~WebContentsData() override;
 
-  // Sets the WebContentsData of a |web_contents|. The object referenced by
-  // |state| is now owned by |web_contents|
-  static void Set(content::WebContents* web_contents, WebContentsData* state);
+  // WebContentsObserver implementation:
+  void DidStartLoading() override;
+
+  // Returns true if |web_contents| has been discarded to save memory.
+  bool IsDiscarded();
+
+  // Sets/clears the discard state of |web_contents|.
+  void SetDiscardState(bool state);
+
+  // Returns the number of times |web_contents| has been discarded.
+  int DiscardCount();
+
+  // Increments the number of times |web_contents| has been discarded.
+  void IncrementDiscardCount();
+
+  // Returns true if audio has recently been audible from the WebContents.
+  bool IsRecentlyAudible();
+
+  // Set/clears the state of whether audio has recently been audible from the
+  // WebContents.
+  void SetRecentlyAudible(bool state);
+
+  // Returns the timestamp of the last time |web_contents| changed its audio
+  // state.
+  base::TimeTicks LastAudioChangeTime();
+
+  // Sets the timestamp of the last time |web_contents| changed its audio state.
+  void SetLastAudioChangeTime(base::TimeTicks timestamp);
 
   // Copies the discard state from |old_contents| to |new_contents|.
   static void CopyState(content::WebContents* old_contents,
                         content::WebContents* new_contents);
 
-  // Returns true if |web_contents| has been discarded to save memory.
-  static bool IsDiscarded(content::WebContents* web_contents);
-
-  // Sets/clears the discard state of |web_contents|.
-  static void SetDiscardState(content::WebContents* web_contents, bool state);
-
-  // Returns the number of times |web_contents| has been discarded.
-  static int DiscardCount(content::WebContents* web_contents);
-
-  // Increments the number of times |web_contents| has been discarded.
-  static void IncrementDiscardCount(content::WebContents* web_contents);
-
-  // Returns true if audio has recently been audible from the WebContents.
-  static bool IsRecentlyAudible(content::WebContents* web_contents);
-
-  // Set/clears the state of whether audio has recently been audible from the
-  // WebContents.
-  static void SetRecentlyAudible(content::WebContents* web_contents,
-                                 bool state);
-
-  // Returns the timestamp of the last time |web_contents| changed its audio
-  // state.
-  static base::TimeTicks LastAudioChangeTime(
-      content::WebContents* web_contents);
-
-  // Sets the timestamp of the last time |web_contents| changed its audio state.
-  static void SetLastAudioChangeTime(content::WebContents* web_contents,
-                                     base::TimeTicks timestamp);
-
  private:
-  WebContentsData();
+  struct Data {
+    Data();
+    // Is the tab currently discarded?
+    bool is_discarded_;
+    // Number of times the tab has been discarded.
+    int discard_count_;
+    // Is the tab playing audio?
+    bool is_recently_audible_;
+    // Last time the tab started or stopped playing audio (we record the
+    // transition time).
+    base::TimeTicks last_audio_change_time_;
+    // The last time the tab was discarded.
+    base::TimeTicks last_discard_time_;
+  };
 
-  // Is the tab currently discarded?
-  bool is_discarded_;
+  Data tab_data_;
 
-  // Number of times the tab has been discarded.
-  int discard_count_;
-
-  // Is the tab playing audio?
-  bool is_recently_audible_;
-
-  // Last time the tab started or stopped playing audio (we record the
-  // transition time).
-  base::TimeTicks last_audio_change_time_;
-
-  // The last time the tab was discarded.
-  base::TimeTicks last_discard_time_;
+  DISALLOW_COPY_AND_ASSIGN(WebContentsData);
 };
 
 }  // namespace memory
diff --git a/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc b/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc
index 19d02b2..f0fc27d 100644
--- a/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc
+++ b/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc
@@ -115,20 +115,20 @@
 };
 
 TEST_F(ChromeOSMetricsProviderTest, MultiProfileUserCount) {
-  std::string user1("user1@example.com");
-  std::string user2("user2@example.com");
-  std::string user3("user3@example.com");
+  const AccountId account_id1(AccountId::FromUserEmail("user1@example.com"));
+  const AccountId account_id2(AccountId::FromUserEmail("user2@example.com"));
+  const AccountId account_id3(AccountId::FromUserEmail("user3@example.com"));
 
   // |scoped_enabler| takes over the lifetime of |user_manager|.
   chromeos::FakeChromeUserManager* user_manager =
       new chromeos::FakeChromeUserManager();
   chromeos::ScopedUserManagerEnabler scoped_enabler(user_manager);
-  user_manager->AddKioskAppUser(user1);
-  user_manager->AddKioskAppUser(user2);
-  user_manager->AddKioskAppUser(user3);
+  user_manager->AddKioskAppUser(account_id1);
+  user_manager->AddKioskAppUser(account_id2);
+  user_manager->AddKioskAppUser(account_id3);
 
-  user_manager->LoginUser(user1);
-  user_manager->LoginUser(user3);
+  user_manager->LoginUser(account_id1);
+  user_manager->LoginUser(account_id3);
 
   ChromeOSMetricsProvider provider;
   provider.OnDidCreateMetricsLog();
@@ -138,19 +138,19 @@
 }
 
 TEST_F(ChromeOSMetricsProviderTest, MultiProfileCountInvalidated) {
-  std::string user1("user1@example.com");
-  std::string user2("user2@example.com");
-  std::string user3("user3@example.com");
+  const AccountId account_id1(AccountId::FromUserEmail("user1@example.com"));
+  const AccountId account_id2(AccountId::FromUserEmail("user2@example.com"));
+  const AccountId account_id3(AccountId::FromUserEmail("user3@example.com"));
 
   // |scoped_enabler| takes over the lifetime of |user_manager|.
   chromeos::FakeChromeUserManager* user_manager =
       new chromeos::FakeChromeUserManager();
   chromeos::ScopedUserManagerEnabler scoped_enabler(user_manager);
-  user_manager->AddKioskAppUser(user1);
-  user_manager->AddKioskAppUser(user2);
-  user_manager->AddKioskAppUser(user3);
+  user_manager->AddKioskAppUser(account_id1);
+  user_manager->AddKioskAppUser(account_id2);
+  user_manager->AddKioskAppUser(account_id3);
 
-  user_manager->LoginUser(user1);
+  user_manager->LoginUser(account_id1);
 
   ChromeOSMetricsProvider provider;
   provider.OnDidCreateMetricsLog();
@@ -159,7 +159,7 @@
   provider.ProvideSystemProfileMetrics(&system_profile);
   EXPECT_EQ(1u, system_profile.multi_profile_user_count());
 
-  user_manager->LoginUser(user2);
+  user_manager->LoginUser(account_id2);
   provider.ProvideSystemProfileMetrics(&system_profile);
   EXPECT_EQ(0u, system_profile.multi_profile_user_count());
 }
diff --git a/chrome/browser/net/nss_context_chromeos_browsertest.cc b/chrome/browser/net/nss_context_chromeos_browsertest.cc
index bcc869c8..616549c 100644
--- a/chrome/browser/net/nss_context_chromeos_browsertest.cc
+++ b/chrome/browser/net/nss_context_chromeos_browsertest.cc
@@ -136,7 +136,7 @@
   // Log in first user and get their DB.
   LoginUser(kTestUser1);
   Profile* profile1 = chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(
-      user_manager->FindUser(kTestUser1));
+      user_manager->FindUser(AccountId::FromUserEmail(kTestUser1)));
   ASSERT_TRUE(profile1);
 
   DBTester tester1(profile1);
@@ -148,7 +148,7 @@
   AddUser(kTestUser2);
 
   Profile* profile2 = chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(
-      user_manager->FindUser(kTestUser2));
+      user_manager->FindUser(AccountId::FromUserEmail(kTestUser2)));
   ASSERT_TRUE(profile2);
 
   DBTester tester2(profile2);
diff --git a/chrome/browser/notifications/message_center_settings_controller_unittest.cc b/chrome/browser/notifications/message_center_settings_controller_unittest.cc
index 2a671d5..cb5dc53 100644
--- a/chrome/browser/notifications/message_center_settings_controller_unittest.cc
+++ b/chrome/browser/notifications/message_center_settings_controller_unittest.cc
@@ -90,13 +90,13 @@
     TestingProfile* profile =
         MessageCenterSettingsControllerBaseTest::CreateProfile(name);
 
-    GetFakeUserManager()->AddUser(name);
-    GetFakeUserManager()->LoginUser(name);
+    GetFakeUserManager()->AddUser(AccountId::FromUserEmail(name));
+    GetFakeUserManager()->LoginUser(AccountId::FromUserEmail(name));
     return profile;
   }
 
   void SwitchActiveUser(const std::string& name) {
-    GetFakeUserManager()->SwitchActiveUser(name);
+    GetFakeUserManager()->SwitchActiveUser(AccountId::FromUserEmail(name));
     controller()->ActiveUserChanged(GetFakeUserManager()->GetActiveUser());
   }
 
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 213ecd2..6c097adf 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -376,6 +376,9 @@
   { key::kSSLVersionFallbackMin,
     ssl_config::prefs::kSSLVersionFallbackMin,
     base::Value::TYPE_STRING },
+  { key::kRC4Enabled,
+    ssl_config::prefs::kRC4Enabled,
+    base::Value::TYPE_BOOLEAN },
 
 #if !defined(OS_MACOSX) && !defined(OS_IOS)
   { key::kFullscreenAllowed,
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index e029bd8..a9c64e2 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -1132,8 +1132,8 @@
   if (via != APP_LOCALE_CHANGED_VIA_PUBLIC_SESSION_LOGIN)
     local_state->SetString(prefs::kApplicationLocale, new_locale);
 
-  if (user_manager::UserManager::Get()->GetOwnerEmail() ==
-      chromeos::ProfileHelper::Get()->GetUserByProfile(this)->email())
+  if (user_manager::UserManager::Get()->GetOwnerAccountId() ==
+      chromeos::ProfileHelper::Get()->GetUserByProfile(this)->GetAccountId())
     local_state->SetString(prefs::kOwnerLocale, new_locale);
 }
 
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index 89a2af4f..77e352d 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -161,7 +161,7 @@
     const std::string user_id_hash =
         profile_helper->GetUserIdHashByUserIdForTesting(user_id);
     user_manager::UserManager::Get()->UserLoggedIn(
-        user_id, user_id_hash, false);
+        AccountId::FromUserEmail(user_id), user_id_hash, false);
     g_browser_process->profile_manager()->GetProfile(
         profile_helper->GetProfilePathByUserIdHash(user_id_hash));
   }
@@ -227,13 +227,15 @@
             profile_manager->GetInitialProfileDir().value());
 
   const char kTestUserName[] = "test-user@example.com";
+  const AccountId test_account_id(AccountId::FromUserEmail(kTestUserName));
   chromeos::FakeChromeUserManager* user_manager =
       new chromeos::FakeChromeUserManager();
   chromeos::ScopedUserManagerEnabler enabler(user_manager);
 
-  const user_manager::User* active_user = user_manager->AddUser(kTestUserName);
-  user_manager->LoginUser(kTestUserName);
-  user_manager->SwitchActiveUser(kTestUserName);
+  const user_manager::User* active_user =
+      user_manager->AddUser(test_account_id);
+  user_manager->LoginUser(test_account_id);
+  user_manager->SwitchActiveUser(test_account_id);
 
   profile_manager->Observe(
       chrome::NOTIFICATION_LOGIN_USER_CHANGED,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
index 3891232..2036d5c 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -49,6 +49,7 @@
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #endif
 
@@ -109,8 +110,9 @@
 #if defined(OS_CHROMEOS)
     std::string profile_name = base::StringPrintf("NewProfile%d", profile_num);
     user_manager::UserManager::Get()->UserLoggedIn(
-        base::StringPrintf("user%d@test.com", profile_num), profile_name,
-        false);
+        AccountId::FromUserEmail(
+            base::StringPrintf("user%d@test.com", profile_num)),
+        profile_name, false);
     profile_path = profile_path.Append(
         chromeos::ProfileHelper::GetUserProfileDir(profile_name).BaseName());
 #else
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc
index 0247781..ba280aa1d 100644
--- a/chrome/browser/signin/chrome_signin_client.cc
+++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -64,19 +64,19 @@
   if (!user)
     return;
   auto* user_manager = user_manager::UserManager::Get();
-  const std::string& user_id = user->GetUserID();
-  if (user_manager->GetKnownUserDeviceId(user_id).empty()) {
+  const AccountId account_id = user->GetAccountId();
+  if (user_manager->GetKnownUserDeviceId(account_id).empty()) {
     const std::string legacy_device_id =
         GetPrefs()->GetString(prefs::kGoogleServicesSigninScopedDeviceId);
     if (!legacy_device_id.empty()) {
       // Need to move device ID from the old location to the new one, if it has
       // not been done yet.
-      user_manager->SetKnownUserDeviceId(user_id, legacy_device_id);
+      user_manager->SetKnownUserDeviceId(account_id, legacy_device_id);
     } else {
       user_manager->SetKnownUserDeviceId(
-          user_id,
+          account_id,
           GenerateSigninScopedDeviceID(
-              user_manager->IsUserNonCryptohomeDataEphemeral(user_id)));
+              user_manager->IsUserNonCryptohomeDataEphemeral(account_id)));
     }
   }
   GetPrefs()->SetString(prefs::kGoogleServicesSigninScopedDeviceId,
@@ -154,7 +154,8 @@
     return std::string();
 
   const std::string signin_scoped_device_id =
-      user_manager::UserManager::Get()->GetKnownUserDeviceId(user->GetUserID());
+      user_manager::UserManager::Get()->GetKnownUserDeviceId(
+          user->GetAccountId());
   LOG_IF(ERROR, signin_scoped_device_id.empty())
       << "Device ID is not set for user.";
   return signin_scoped_device_id;
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc
index 67bffea0..be5d300 100644
--- a/chrome/browser/signin/easy_unlock_service.cc
+++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -56,6 +56,7 @@
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power_manager_client.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #endif
 
@@ -612,11 +613,9 @@
   DCHECK(key_manager);
 
   key_manager->GetDeviceDataList(
-      chromeos::UserContext(user_id),
+      chromeos::UserContext(AccountId::FromUserEmail(user_id)),
       base::Bind(&EasyUnlockService::OnCryptohomeKeysFetchedForChecking,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 user_id,
-                 paired_devices));
+                 weak_ptr_factory_.GetWeakPtr(), user_id, paired_devices));
 #endif
 }
 
diff --git a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
index fc3c8fb6..279b7a7e 100644
--- a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
+++ b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
@@ -88,7 +88,7 @@
   DCHECK(key_manager);
 
   key_manager->GetDeviceDataList(
-      chromeos::UserContext(user_id),
+      chromeos::UserContext(AccountId::FromUserEmail(user_id)),
       base::Bind(&RetryDataLoadOnError, user_id, backoff_ms, callback));
 }
 
diff --git a/chrome/browser/signin/easy_unlock_service_unittest_chromeos.cc b/chrome/browser/signin/easy_unlock_service_unittest_chromeos.cc
index ffd15e0..74367781 100644
--- a/chrome/browser/signin/easy_unlock_service_unittest_chromeos.cc
+++ b/chrome/browser/signin/easy_unlock_service_unittest_chromeos.cc
@@ -21,6 +21,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_power_manager_client.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/signin/core/browser/signin_manager_base.h"
 #include "components/syncable_prefs/testing_pref_service_syncable.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -218,7 +219,7 @@
     ON_CALL(*mock_user_manager_, IsCurrentUserNonCryptohomeDataEphemeral())
         .WillByDefault(Return(false));
 
-    SetUpProfile(&profile_, kTestUserPrimary);
+    SetUpProfile(&profile_, AccountId::FromUserEmail(kTestUserPrimary));
   }
 
   void TearDown() override {
@@ -262,13 +263,14 @@
   }
 
   void SetUpSecondaryProfile() {
-    SetUpProfile(&secondary_profile_, kTestUserSecondary);
+    SetUpProfile(&secondary_profile_,
+                 AccountId::FromUserEmail(kTestUserSecondary));
   }
 
  private:
   // Sets up a test profile with a user id.
   void SetUpProfile(scoped_ptr<TestingProfile>* profile,
-                    const std::string& user_id) {
+                    const AccountId& account_id) {
     ASSERT_TRUE(profile);
     ASSERT_FALSE(profile->get());
 
@@ -277,12 +279,13 @@
                               &CreateEasyUnlockServiceForTest);
     *profile = builder.Build();
 
-    mock_user_manager_->AddUser(user_id);
-    profile->get()->set_profile_name(user_id);
+    mock_user_manager_->AddUser(account_id);
+    profile->get()->set_profile_name(account_id.GetUserEmail());
 
     SigninManagerBase* signin_manager =
         SigninManagerFactory::GetForProfile(profile->get());
-    signin_manager->SetAuthenticatedAccountInfo(user_id, user_id);
+    signin_manager->SetAuthenticatedAccountInfo(account_id.GetUserEmail(),
+                                                account_id.GetUserEmail());
   }
 
  protected:
diff --git a/chrome/browser/supervised_user/chromeos/manager_password_service.cc b/chrome/browser/supervised_user/chromeos/manager_password_service.cc
index 30f0a05..8dd975f 100644
--- a/chrome/browser/supervised_user/chromeos/manager_password_service.cc
+++ b/chrome/browser/supervised_user/chromeos/manager_password_service.cc
@@ -131,7 +131,7 @@
     return;
   }
 
-  UserContext manager_key(user_id);
+  UserContext manager_key(AccountId::FromUserEmail(user_id));
   manager_key.SetKey(Key(master_key));
   manager_key.SetIsUsingOAuth(false);
 
@@ -240,7 +240,8 @@
 
 void ManagerPasswordService::OnNewManagerKeySuccess(
     const UserContext& master_key_context) {
-  VLOG(1) << "Added new master key for " << master_key_context.GetUserID();
+  VLOG(1) << "Added new master key for "
+          << master_key_context.GetAccountId().GetUserEmail();
   authenticator_->RemoveKey(
       master_key_context,
       kLegacyCryptohomeSupervisedUserKeyLabel,
@@ -252,7 +253,7 @@
 void ManagerPasswordService::OnOldSupervisedUserKeyDeleted(
     const UserContext& master_key_context) {
   VLOG(1) << "Removed old supervised user key for "
-          << master_key_context.GetUserID();
+          << master_key_context.GetAccountId().GetUserEmail();
   authenticator_->RemoveKey(
       master_key_context,
       kLegacyCryptohomeMasterKeyLabel,
@@ -263,7 +264,8 @@
 
 void ManagerPasswordService::OnOldManagerKeyDeleted(
     const UserContext& master_key_context) {
-  VLOG(1) << "Removed old master key for " << master_key_context.GetUserID();
+  VLOG(1) << "Removed old master key for "
+          << master_key_context.GetAccountId().GetUserEmail();
 }
 
 void ManagerPasswordService::Shutdown() {
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index 38104ccd..0df5660 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -851,7 +851,7 @@
   // The active user can be NULL in unit tests.
   if (user_manager::UserManager::Get()->GetActiveUser()) {
     return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
-        user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
+        user_manager::UserManager::Get()->GetActiveUser()->GetAccountId()));
   }
   return std::string();
 #else
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc
index ca2e8ec..5c55de9 100644
--- a/chrome/browser/sync/sync_ui_util.cc
+++ b/chrome/browser/sync/sync_ui_util.cc
@@ -35,6 +35,7 @@
 #include "ui/base/l10n/l10n_util.h"
 
 #if defined(OS_CHROMEOS)
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #endif  // defined(OS_CHROMEOS)
 
@@ -63,7 +64,7 @@
     // On CrOS user email is sanitized and then passed to the signin manager.
     // Original email (containing dots) is stored as "display email".
     user_display_name = user_manager::UserManager::Get()->GetUserDisplayEmail(
-        user_display_name);
+        AccountId::FromUserEmail(user_display_name));
   }
 #endif  // defined(OS_CHROMEOS)
 
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index 44eded23..6d3d08c 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -63,6 +63,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/fake_user_manager.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/test/test_utils.h"
@@ -808,22 +809,23 @@
   // Creates a profile for a given |user_name|. Note that this class will keep
   // the ownership of the created object.
   TestingProfile* CreateMultiUserProfile(const std::string& user_name) {
-    std::string email_string = user_name + "@example.com";
+    const std::string email_string = user_name + "@example.com";
+    const AccountId account_id(AccountId::FromUserEmail(email_string));
     static_cast<ash::test::TestSessionStateDelegate*>(
         ash::Shell::GetInstance()->session_state_delegate())
-        ->AddUser(email_string);
+        ->AddUser(account_id.GetUserEmail());
     // Add a user to the fake user manager.
-    session_delegate()->AddUser(email_string);
-    GetFakeUserManager()->AddUser(email_string);
+    session_delegate()->AddUser(account_id.GetUserEmail());
+    GetFakeUserManager()->AddUser(account_id);
 
-    GetFakeUserManager()->LoginUser(email_string);
+    GetFakeUserManager()->LoginUser(account_id);
 
     TestingProfile* profile =
-        profile_manager()->CreateTestingProfile(email_string);
+        profile_manager()->CreateTestingProfile(account_id.GetUserEmail());
     EXPECT_TRUE(profile);
 
     // Remember the profile name so that we can destroy it upon destruction.
-    created_profiles_[profile] = email_string;
+    created_profiles_[profile] = account_id.GetUserEmail();
     if (chrome::MultiUserWindowManager::GetInstance())
       chrome::MultiUserWindowManager::GetInstance()->AddUser(profile);
     if (launcher_controller_)
@@ -833,18 +835,19 @@
 
   // Switch to another user.
   void SwitchActiveUser(const std::string& name) {
-    session_delegate()->SwitchActiveUser(name);
-    GetFakeUserManager()->SwitchActiveUser(name);
+    const AccountId account_id(AccountId::FromUserEmail(name));
+    session_delegate()->SwitchActiveUser(account_id.GetUserEmail());
+    GetFakeUserManager()->SwitchActiveUser(account_id);
     chrome::MultiUserWindowManagerChromeOS* manager =
         static_cast<chrome::MultiUserWindowManagerChromeOS*>(
             chrome::MultiUserWindowManager::GetInstance());
     manager->SetAnimationSpeedForTest(
         chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED);
-    manager->ActiveUserChanged(name);
-    launcher_controller_->browser_status_monitor_for_test()->
-        ActiveUserChanged(name);
-    launcher_controller_->app_window_controller_for_test()->
-        ActiveUserChanged(name);
+    manager->ActiveUserChanged(account_id.GetUserEmail());
+    launcher_controller_->browser_status_monitor_for_test()->ActiveUserChanged(
+        account_id.GetUserEmail());
+    launcher_controller_->app_window_controller_for_test()->ActiveUserChanged(
+        account_id.GetUserEmail());
   }
 
   // Creates a browser with a |profile| and load a tab with a |title| and |url|.
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos.cc b/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos.cc
index 41738b9..7d808f1 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "ui/aura/window.h"
@@ -95,7 +96,7 @@
   return model.Pass();
 }
 
-void OnAcceptTeleportWarning(const std::string& user_id,
+void OnAcceptTeleportWarning(const AccountId& account_id,
                              aura::Window* window_,
                              bool no_show_again) {
   PrefService* pref = ProfileManager::GetActiveUserProfile()->GetPrefs();
@@ -104,8 +105,8 @@
   ash::MultiProfileUMA::RecordTeleportAction(
       ash::MultiProfileUMA::TELEPORT_WINDOW_CAPTION_MENU);
 
-  chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(window_,
-                                                                   user_id);
+  chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(
+      window_, account_id.GetUserEmail());
 }
 
 void ExecuteVisitDesktopCommand(int command_id, aura::Window* window) {
@@ -114,14 +115,14 @@
     case IDC_VISIT_DESKTOP_OF_LRU_USER_3: {
       // When running the multi user mode on Chrome OS, windows can "visit"
       // another user's desktop.
-      const std::string& user_id =
+      const AccountId account_id =
           ash::Shell::GetInstance()
               ->session_state_delegate()
               ->GetUserInfo(IDC_VISIT_DESKTOP_OF_LRU_USER_2 == command_id ? 1
                                                                           : 2)
-              ->GetUserID();
+              ->GetAccountId();
       base::Callback<void(bool)> on_accept =
-          base::Bind(&OnAcceptTeleportWarning, user_id, window);
+          base::Bind(&OnAcceptTeleportWarning, account_id, window);
 
       // Don't show warning dialog if any logged in user in multi-profiles
       // session dismissed it.
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc
index 1f3c67fe..f68e6fc 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos_unittest.cc
@@ -82,7 +82,8 @@
     return ash::Shell::GetInstance()
         ->session_state_delegate()
         ->GetUserInfo(0)
-        ->GetUserID();
+        ->GetAccountId()
+        .GetUserEmail();
   }
 
   const message_center::NotificationBlocker* blocker() {
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager.cc
index 497ebe47..11da278 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager.cc
@@ -14,6 +14,7 @@
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_info.h"
 #endif
 
@@ -46,7 +47,8 @@
         new MultiUserWindowManagerChromeOS(ash::Shell::GetInstance()
                                                ->session_state_delegate()
                                                ->GetUserInfo(0)
-                                               ->GetUserID());
+                                               ->GetAccountId()
+                                               .GetUserEmail());
     g_instance = manager;
     manager->Init();
     multi_user_mode_ = MULTI_PROFILE_MODE_SEPARATED;
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
index 7cf0ea87..4faee0c 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
@@ -55,9 +55,9 @@
     const user_manager::UserManager* user_manager =
         user_manager::UserManager::Get();
     const user_manager::User* active_user = user_manager->GetActiveUser();
-    return active_user
-               ? multi_user_util::GetProfileFromUserID(active_user->GetUserID())
-               : NULL;
+    return active_user ? multi_user_util::GetProfileFromUserID(
+                             active_user->GetAccountId().GetUserEmail())
+                       : NULL;
   }
 
   content::BrowserContext* GetBrowserContextByIndex(
@@ -158,8 +158,9 @@
   TestingProfileManager* profile_manager() { return profile_manager_.get(); }
 
   const user_manager::User* AddTestUser(const std::string& user_email) {
-    const user_manager::User* user = fake_user_manager_->AddUser(user_email);
-    fake_user_manager_->LoginUser(user_email);
+    const user_manager::User* user =
+        fake_user_manager_->AddUser(AccountId::FromUserEmail(user_email));
+    fake_user_manager_->LoginUser(AccountId::FromUserEmail(user_email));
     session_state_delegate_->AddUser(user_email);
     TestingProfile* profile =
         profile_manager()->CreateTestingProfile(user_email);
@@ -198,12 +199,13 @@
   // The test session state observer does not automatically call the window
   // manager. This function gets the current user from it and also sets it to
   // the multi user window manager.
-  std::string GetAndValidateCurrentUserFromSessionStateObserver() {
-    const std::string& user =
-        session_state_delegate()->GetActiveUserInfo()->GetUserID();
-    if (user != multi_user_window_manager_->GetCurrentUserForTest())
-      multi_user_window_manager()->ActiveUserChanged(user);
-    return user;
+  AccountId GetAndValidateCurrentUserFromSessionStateObserver() {
+    const AccountId account_id =
+        session_state_delegate()->GetActiveUserInfo()->GetAccountId();
+    if (account_id.GetUserEmail() !=
+        multi_user_window_manager_->GetCurrentUserForTest())
+      multi_user_window_manager()->ActiveUserChanged(account_id.GetUserEmail());
+    return account_id;
   }
 
   // Initiate a user transition.
@@ -796,11 +798,17 @@
 
   // Making the window system modal should not change anything.
   MakeWindowSystemModal(window(0));
-  EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
+  EXPECT_EQ("a", session_state_delegate()
+                     ->GetActiveUserInfo()
+                     ->GetAccountId()
+                     .GetUserEmail());
 
   // Making the window owned by user B should switch users.
   multi_user_window_manager()->SetWindowOwner(window(0), "b");
-  EXPECT_EQ("b", session_state_delegate()->GetActiveUserInfo()->GetUserID());
+  EXPECT_EQ("b", session_state_delegate()
+                     ->GetActiveUserInfo()
+                     ->GetAccountId()
+                     .GetUserEmail());
 }
 
 // Test that a system modal dialog will not switch desktop if active user has
@@ -811,11 +819,17 @@
 
   // Making the window system modal should not change anything.
   MakeWindowSystemModal(window(0));
-  EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
+  EXPECT_EQ("a", session_state_delegate()
+                     ->GetActiveUserInfo()
+                     ->GetAccountId()
+                     .GetUserEmail());
 
   // Making the window owned by user a should not switch users.
   multi_user_window_manager()->SetWindowOwner(window(0), "a");
-  EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
+  EXPECT_EQ("a", session_state_delegate()
+                     ->GetActiveUserInfo()
+                     ->GetAccountId()
+                     .GetUserEmail());
 }
 
 // Test that a system modal dialog will not switch if shown on correct desktop
@@ -831,7 +845,10 @@
   MakeWindowSystemModal(window(0));
   // Showing the window should trigger no user switch.
   window(0)->Show();
-  EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
+  EXPECT_EQ("a", session_state_delegate()
+                     ->GetActiveUserInfo()
+                     ->GetAccountId()
+                     .GetUserEmail());
 }
 
 // Test that a system modal dialog will switch if shown on incorrect desktop but
@@ -847,7 +864,10 @@
   MakeWindowSystemModal(window(0));
   // Showing the window should trigger a user switch.
   window(0)->Show();
-  EXPECT_EQ("b", session_state_delegate()->GetActiveUserInfo()->GetUserID());
+  EXPECT_EQ("b", session_state_delegate()
+                     ->GetActiveUserInfo()
+                     ->GetAccountId()
+                     .GetUserEmail());
 }
 
 // Test that using the full user switch animations are working as expected.
@@ -1129,26 +1149,31 @@
   EXPECT_EQ("S[a], H[b], H[c]", GetStatus());
 
   // SetWindowOwner should not have changed the active user.
-  EXPECT_EQ("a", GetAndValidateCurrentUserFromSessionStateObserver());
+  EXPECT_EQ("a",
+            GetAndValidateCurrentUserFromSessionStateObserver().GetUserEmail());
 
   // Check that teleporting the window of the currently active user will
   // teleport to the new desktop.
   multi_user_window_manager()->ShowWindowForUser(window(0), "b");
-  EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
+  EXPECT_EQ("b",
+            GetAndValidateCurrentUserFromSessionStateObserver().GetUserEmail());
   EXPECT_EQ("S[a,b], S[b], H[c]", GetStatus());
 
   // Check that teleporting a window from a currently inactive user will not
   // trigger a switch.
   multi_user_window_manager()->ShowWindowForUser(window(2), "a");
-  EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
+  EXPECT_EQ("b",
+            GetAndValidateCurrentUserFromSessionStateObserver().GetUserEmail());
   EXPECT_EQ("S[a,b], S[b], H[c,a]", GetStatus());
   multi_user_window_manager()->ShowWindowForUser(window(2), "b");
-  EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
+  EXPECT_EQ("b",
+            GetAndValidateCurrentUserFromSessionStateObserver().GetUserEmail());
   EXPECT_EQ("S[a,b], S[b], S[c,b]", GetStatus());
 
   // Check that teleporting back will also change the desktop.
   multi_user_window_manager()->ShowWindowForUser(window(2), "c");
-  EXPECT_EQ("c", GetAndValidateCurrentUserFromSessionStateObserver());
+  EXPECT_EQ("c",
+            GetAndValidateCurrentUserFromSessionStateObserver().GetUserEmail());
   EXPECT_EQ("H[a,b], H[b], S[c]", GetStatus());
 }
 
@@ -1304,7 +1329,7 @@
   wm::GetWindowState(window(2))->Minimize();
 
   // Windows belonging to user2 (window #2 and #3) can't be activated by user1.
-  user_manager()->SwitchActiveUser(user1);
+  user_manager()->SwitchActiveUser(AccountId::FromUserEmail(user1));
   multi_user_window_manager()->ActiveUserChanged(user1);
   EXPECT_TRUE(::wm::CanActivateWindow(window(0)));
   EXPECT_TRUE(::wm::CanActivateWindow(window(1)));
@@ -1312,7 +1337,7 @@
   EXPECT_FALSE(::wm::CanActivateWindow(window(3)));
 
   // Windows belonging to user1 (window #0 and #1) can't be activated by user2.
-  user_manager()->SwitchActiveUser(user2);
+  user_manager()->SwitchActiveUser(AccountId::FromUserEmail(user2));
   multi_user_window_manager()->ActiveUserChanged(user2);
   EXPECT_FALSE(::wm::CanActivateWindow(window(0)));
   EXPECT_FALSE(::wm::CanActivateWindow(window(1)));
@@ -1333,7 +1358,7 @@
   multi_user_window_manager()->SetWindowOwner(window(0), user1);
   multi_user_window_manager()->SetWindowOwner(window(1), user2);
 
-  user_manager()->SwitchActiveUser(user1);
+  user_manager()->SwitchActiveUser(AccountId::FromUserEmail(user1));
   multi_user_window_manager()->ActiveUserChanged(user1);
   EXPECT_TRUE(::wm::CanActivateWindow(window(0)));
   EXPECT_FALSE(::wm::CanActivateWindow(window(1)));
@@ -1344,7 +1369,7 @@
   EXPECT_FALSE(::wm::CanActivateWindow(window(0)));
 
   // Test that window #0 can be activated by user2.
-  user_manager()->SwitchActiveUser(user2);
+  user_manager()->SwitchActiveUser(AccountId::FromUserEmail(user2));
   multi_user_window_manager()->ActiveUserChanged(user2);
   EXPECT_TRUE(::wm::CanActivateWindow(window(0)));
   EXPECT_TRUE(::wm::CanActivateWindow(window(1)));
diff --git a/chrome/browser/ui/ash/session_state_delegate_chromeos.cc b/chrome/browser/ui/ash/session_state_delegate_chromeos.cc
index e144b7d..c37dd6d 100644
--- a/chrome/browser/ui/ash/session_state_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/session_state_delegate_chromeos.cc
@@ -26,6 +26,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "chromeos/login/login_state.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_info.h"
 #include "components/user_manager/user_manager.h"
@@ -269,7 +270,8 @@
 }
 
 void DoSwitchUser(const std::string& user_id) {
-  user_manager::UserManager::Get()->SwitchActiveUser(user_id);
+  user_manager::UserManager::Get()->SwitchActiveUser(
+      AccountId::FromUserEmail(user_id));
 }
 
 void SessionStateDelegateChromeos::TryToSwitchUser(
diff --git a/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc b/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc
index 6d58b79..04a620f 100644
--- a/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc
@@ -19,6 +19,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "net/cert/x509_certificate.h"
@@ -81,9 +82,9 @@
   }
 
   // Add and log in a user to the session.
-  void UserAddedToSession(const std::string& user) {
-    user_manager()->AddUser(user);
-    user_manager()->LoginUser(user);
+  void UserAddedToSession(std::string user) {
+    user_manager()->AddUser(AccountId::FromUserEmail(user));
+    user_manager()->LoginUser(AccountId::FromUserEmail(user));
   }
 
   // Get the active user.
@@ -101,12 +102,13 @@
         new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
     ASSERT_TRUE(profile_manager_->SetUp());
 
-    const std::string user_email(kUser);
-    const user_manager::User* user = user_manager()->AddUser(user_email);
+    const AccountId account_id(AccountId::FromUserEmail(kUser));
+    const user_manager::User* user = user_manager()->AddUser(account_id);
 
     // Note that user profiles are created after user login in reality.
-    user_profile_ = profile_manager_->CreateTestingProfile(user_email);
-    user_profile_->set_profile_name(user_email);
+    user_profile_ =
+        profile_manager_->CreateTestingProfile(account_id.GetUserEmail());
+    user_profile_->set_profile_name(account_id.GetUserEmail());
     chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
         user, user_profile_);
   }
@@ -172,8 +174,8 @@
   InitForMultiProfile();
   EXPECT_TRUE(
       session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
-  const std::string user_email(kUser);
-  user_manager()->LoginUser(user_email);
+  const AccountId account_id(AccountId::FromUserEmail(kUser));
+  user_manager()->LoginUser(account_id);
   EXPECT_TRUE(
       session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
 
@@ -188,11 +190,12 @@
 TEST_F(SessionStateDelegateChromeOSTest,
        MultiProfileDisallowedByPolicyCertificates) {
   InitForMultiProfile();
-  const std::string user_email(kUser);
-  user_manager()->LoginUser(user_email);
+  const AccountId account_id(AccountId::FromUserEmail(kUser));
+  user_manager()->LoginUser(account_id);
   EXPECT_TRUE(
       session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
-  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(user_email);
+  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
+      account_id.GetUserEmail());
   EXPECT_FALSE(
       session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
 
@@ -204,8 +207,8 @@
 TEST_F(SessionStateDelegateChromeOSTest,
        MultiProfileDisallowedByPrimaryUserCertificatesInMemory) {
   InitForMultiProfile();
-  const std::string user_email(kUser);
-  user_manager()->LoginUser(user_email);
+  const AccountId account_id(AccountId::FromUserEmail(kUser));
+  user_manager()->LoginUser(account_id);
   EXPECT_TRUE(
       session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
   cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure()));
@@ -239,8 +242,8 @@
 
   EXPECT_TRUE(
       session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
-  const std::string user_email(kUser);
-  user_manager()->LoginUser(user_email);
+  const AccountId account_id(AccountId::FromUserEmail(kUser));
+  user_manager()->LoginUser(account_id);
   while (session_state_delegate()->NumberOfLoggedInUsers() <
          session_state_delegate()->GetMaximumNumberOfLoggedInUsers()) {
     UserAddedToSession("bb@b.b");
@@ -260,8 +263,8 @@
 
   EXPECT_TRUE(
       session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
-  const std::string user_email(kUser);
-  user_manager()->LoginUser(user_email);
+  const AccountId account_id(AccountId::FromUserEmail(kUser));
+  user_manager()->LoginUser(account_id);
   UserAddedToSession("bb@b.b");
   EXPECT_FALSE(
       session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
@@ -277,12 +280,12 @@
 
   EXPECT_TRUE(
       session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
-  const std::string user_email(kUser);
-  user_manager()->LoginUser(user_email);
+  const AccountId account_id(AccountId::FromUserEmail(kUser));
+  user_manager()->LoginUser(account_id);
   user_profile_->GetPrefs()->SetString(
       prefs::kMultiProfileUserBehavior,
       chromeos::MultiProfileUserController::kBehaviorNotAllowed);
-  user_manager()->AddUser("bb@b.b");
+  user_manager()->AddUser(AccountId::FromUserEmail("bb@b.b"));
   EXPECT_FALSE(
       session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
   EXPECT_EQ(ash::SessionStateDelegate::ADD_USER_ERROR_NOT_ALLOWED_PRIMARY_USER,
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
index f0cfb39..55d34c0 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -820,8 +820,8 @@
 SystemTrayDelegateChromeOS::GetUserAccountsDelegate(
     const std::string& user_id) {
   if (!accounts_delegates_.contains(user_id)) {
-    const user_manager::User* user =
-        user_manager::UserManager::Get()->FindUser(user_id);
+    const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+        AccountId::FromUserEmail(user_id));
     Profile* user_profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
     CHECK(user_profile);
     accounts_delegates_.set(
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc
index 47827b7..6d28e8e 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc
@@ -79,42 +79,47 @@
 class SystemTrayDelegateChromeOSTest : public LoginManagerTest {
  protected:
   SystemTrayDelegateChromeOSTest()
-      : LoginManagerTest(false /* should_launch_browser */) {}
+      : LoginManagerTest(false /* should_launch_browser */),
+        account_id1_(AccountId::FromUserEmail(kUser1)),
+        account_id2_(AccountId::FromUserEmail(kUser2)) {}
 
   ~SystemTrayDelegateChromeOSTest() override {}
 
-  void SetupUserProfile(const std::string& user_name, bool use_24_hour_clock) {
+  void SetupUserProfile(const AccountId& account_id, bool use_24_hour_clock) {
     const user_manager::User* user =
-        user_manager::UserManager::Get()->FindUser(user_name);
+        user_manager::UserManager::Get()->FindUser(account_id);
     Profile* profile = ProfileHelper::Get()->GetProfileByUser(user);
     profile->GetPrefs()->SetBoolean(prefs::kUse24HourClock, use_24_hour_clock);
   }
 
+  const AccountId account_id1_;
+  const AccountId account_id2_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(SystemTrayDelegateChromeOSTest);
 };
 
 IN_PROC_BROWSER_TEST_F(SystemTrayDelegateChromeOSTest,
                        PRE_TestMultiProfile24HourClock) {
-  RegisterUser(kUser1);
-  RegisterUser(kUser2);
+  RegisterUser(account_id1_.GetUserEmail());
+  RegisterUser(account_id2_.GetUserEmail());
   StartupUtils::MarkOobeCompleted();
 }
 
 // Test that clock type is taken from user profile for current active user.
 IN_PROC_BROWSER_TEST_F(SystemTrayDelegateChromeOSTest,
                        TestMultiProfile24HourClock) {
-  LoginUser(kUser1);
-  SetupUserProfile(kUser1, true /* Use_24_hour_clock. */);
+  LoginUser(account_id1_.GetUserEmail());
+  SetupUserProfile(account_id1_, true /* Use_24_hour_clock. */);
   CreateDefaultView();
   EXPECT_EQ(base::k24HourClock, GetHourType());
   UserAddingScreen::Get()->Start();
   content::RunAllPendingInMessageLoop();
-  AddUser(kUser2);
-  SetupUserProfile(kUser2, false /* Use_24_hour_clock. */);
+  AddUser(account_id2_.GetUserEmail());
+  SetupUserProfile(account_id2_, false /* Use_24_hour_clock. */);
   CreateDefaultView();
   EXPECT_EQ(base::k12HourClock, GetHourType());
-  user_manager::UserManager::Get()->SwitchActiveUser(kUser1);
+  user_manager::UserManager::Get()->SwitchActiveUser(account_id1_);
   CreateDefaultView();
   EXPECT_EQ(base::k24HourClock, GetHourType());
 }
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 400702a..4f6a754 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1053,7 +1053,7 @@
   // Discarded tabs always get reloaded.
   // TODO(georgesak): Validate the usefulness of this. And if needed then move
   // to TabManager.
-  if (memory::TabManager::WebContentsData::IsDiscarded(new_contents))
+  if (g_browser_process->GetTabManager()->IsTabDiscarded(new_contents))
     chrome::Reload(this, CURRENT_TAB);
 
   // If we have any update pending, do it now.
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index 3a705537..5f3d5b1 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/tab_helper.h"
-#include "chrome/browser/memory/tab_manager_web_contents_data.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper_delegate.h"
@@ -161,10 +160,6 @@
   // is properly removed from the tab strip.
   void WebContentsDestroyed() override;
 
-  // Marks the tab as no longer discarded if it has been reloaded from another
-  // source (ie: context menu).
-  void DidStartLoading() override;
-
   // The WebContents being tracked by this WebContentsData. The
   // WebContentsObserver does keep a reference, but when the WebContents is
   // deleted, the WebContentsObserver reference is NULLed and thus inaccessible.
@@ -231,11 +226,6 @@
   tab_strip_model_->DetachWebContentsAt(index);
 }
 
-void TabStripModel::WebContentsData::DidStartLoading() {
-  // TODO(georgesak): move this into tab_manager.cc.
-  memory::TabManager::WebContentsData::SetDiscardState(contents_, false);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // TabStripModel, public:
 
@@ -1267,8 +1257,6 @@
                          active_index(),
                          reason));
     in_notify_ = false;
-    // TODO(georgesak): move this into tab_manager.cc.
-    memory::TabManager::WebContentsData::SetDiscardState(new_contents, false);
   }
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 1aa96e0..bf2598e 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -436,27 +436,35 @@
   UpdateState(error_reason);
 }
 
-std::string GaiaScreenHandler::GetCanonicalEmail(
+AccountId GaiaScreenHandler::GetAccountId(
     const std::string& authenticated_email,
     const std::string& gaia_id) const {
-  const std::string sanitized_email = gaia::SanitizeEmail(authenticated_email);
-
   const std::string canonicalized_email =
-      gaia::CanonicalizeEmail(sanitized_email);
+      gaia::CanonicalizeEmail(gaia::SanitizeEmail(authenticated_email));
+  const AccountId authenticated_account_id(
+      AccountId::FromUserEmailGaiaId(canonicalized_email, gaia_id));
+
+  // If we don't have UserManager instance (i.e. we are in unit test),
+  // or a known user has authenticated, just log in.
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
-  if (user_manager && !user_manager->IsKnownUser(canonicalized_email)) {
-    std::string old_canonical_email;
-    if (user_manager->GetKnownUserCanonicalEmail(gaia_id,
-                                                 &old_canonical_email)) {
-      if (old_canonical_email != canonicalized_email) {
-        LOG(WARNING) << "Existing user '" << old_canonical_email
-                     << "' authenticated by alias '" << sanitized_email << "'.";
-        return old_canonical_email;
-      }
-    }
+  if (!user_manager || user_manager->IsKnownUser(authenticated_account_id))
+    return authenticated_account_id;
+
+  // If [part of] user id has changed, update stored data and connect user
+  // to existing home directory.
+  AccountId old_account_id(EmptyAccountId());
+  if (!user_manager->GetKnownUserAccountId(authenticated_account_id,
+                                           &old_account_id)) {
+    return authenticated_account_id;
   }
-  // For compatibility reasons, sanitized email is used.
-  return sanitized_email;
+
+  if (old_account_id.GetUserEmail() != canonicalized_email) {
+    LOG(WARNING) << "Existing user '" << old_account_id.GetUserEmail()
+                 << "' authenticated by alias '" << canonicalized_email << "'.";
+    return old_account_id;
+  }
+
+  return authenticated_account_id;
 }
 
 void GaiaScreenHandler::HandleCompleteAuthentication(
@@ -474,8 +482,7 @@
   const std::string sanitized_email = gaia::SanitizeEmail(email);
   Delegate()->SetDisplayEmail(sanitized_email);
 
-  const std::string canonical_email = GetCanonicalEmail(email, gaia_id);
-  UserContext user_context(canonical_email);
+  UserContext user_context(GetAccountId(email, gaia_id));
   user_context.SetGaiaID(gaia_id);
   user_context.SetKey(Key(password));
   user_context.SetAuthCode(auth_code);
@@ -508,7 +515,7 @@
 
   // Consumer management enrollment is in progress.
   const std::string owner_email =
-      user_manager::UserManager::Get()->GetOwnerEmail();
+      user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail();
   if (typed_email != owner_email) {
     // Show Gaia sign-in screen again, since we only allow the owner to sign
     // in.
@@ -595,8 +602,7 @@
   DCHECK(!gaia_id.empty());
   const std::string sanitized_email = gaia::SanitizeEmail(typed_email);
   Delegate()->SetDisplayEmail(sanitized_email);
-  const std::string canonical_email = GetCanonicalEmail(typed_email, gaia_id);
-  UserContext user_context(canonical_email);
+  UserContext user_context(GetAccountId(typed_email, gaia_id));
   user_context.SetGaiaID(gaia_id);
   user_context.SetKey(Key(password));
   user_context.SetAuthFlow(using_saml
@@ -755,7 +761,7 @@
     std::vector<std::string> input_methods =
         imm->GetInputMethodUtil()->GetHardwareLoginInputMethodIds();
     const std::string owner_im = SigninScreenHandler::GetUserLRUInputMethod(
-        user_manager::UserManager::Get()->GetOwnerEmail());
+        user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail());
     const std::string system_im = g_browser_process->local_state()->GetString(
         language_prefs::kPreferredKeyboardLayout);
 
@@ -839,7 +845,8 @@
   context.is_enrolling_consumer_management = is_enrolling_consumer_management_;
 
   std::string gaia_id;
-  if (user_manager::UserManager::Get()->FindGaiaID(context.email, &gaia_id))
+  if (user_manager::UserManager::Get()->FindGaiaID(
+          AccountId::FromUserEmail(context.email), &gaia_id))
     context.gaia_id = gaia_id;
 
   if (Delegate()) {
@@ -849,7 +856,7 @@
   if (!context.email.empty()) {
     context.gaps_cookie =
         user_manager::UserManager::Get()->GetKnownUserGAPSCookie(
-            gaia::CanonicalizeEmail(context.email));
+            AccountId::FromUserEmail(gaia::CanonicalizeEmail(context.email)));
   }
 
   populated_email_.clear();
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
index 250d74c..d37fa1a 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -17,6 +17,8 @@
 #include "chromeos/network/portal_detector/network_portal_detector.h"
 #include "net/base/net_errors.h"
 
+class AccountId;
+
 namespace policy {
 class ConsumerManagementService;
 }
@@ -215,8 +217,8 @@
 
   // Returns user canonical e-mail. Finds already used account alias, if
   // user has already signed in.
-  std::string GetCanonicalEmail(const std::string& authenticated_email,
-                                const std::string& gaia_id) const;
+  AccountId GetAccountId(const std::string& authenticated_email,
+                         const std::string& gaia_id) const;
 
   // Returns current visible screen.
   // TODO(jdufault): This definition exists in multiple locations. Refactor it
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 47f0628..3e4f6e6 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -992,7 +992,8 @@
                                                  const std::string& password) {
   if (!delegate_)
     return;
-  UserContext user_context(gaia::SanitizeEmail(username));
+  UserContext user_context(
+      AccountId::FromUserEmail(gaia::SanitizeEmail(username)));
   user_context.SetKey(Key(password));
   delegate_->Login(user_context, SigninSpecifics());
 }
@@ -1072,7 +1073,7 @@
     args->GetString(0, &email);
   gaia_screen_handler_->set_populated_email(email);
   if (!email.empty())
-    SendReauthReason(email);
+    SendReauthReason(AccountId::FromUserEmail(email));
   OnShowAddUser();
 }
 
@@ -1175,7 +1176,8 @@
 void SigninScreenHandler::HandleCancelPasswordChangedFlow(
     const std::string& user_id) {
   if (!user_id.empty())
-    RecordReauthReason(user_id, ReauthReason::PASSWORD_UPDATE_SKIPPED);
+    RecordReauthReason(AccountId::FromUserEmail(user_id),
+                       ReauthReason::PASSWORD_UPDATE_SKIPPED);
   gaia_screen_handler_->StartClearingCookies(
       base::Bind(&SigninScreenHandler::CancelPasswordChangedFlowInternal,
                  weak_factory_.GetWeakPtr()));
@@ -1248,7 +1250,8 @@
 
   bool use_24hour_clock = false;
   if (user_manager::UserManager::Get()->GetKnownUserBooleanPref(
-          user_id, prefs::kUse24HourClock, &use_24hour_clock)) {
+          AccountId::FromUserEmail(user_id), prefs::kUse24HourClock,
+          &use_24hour_clock)) {
     g_browser_process->platform_part()
         ->GetSystemClock()
         ->SetLastFocusedPodHourClockType(use_24hour_clock ? base::k24HourClock
@@ -1320,7 +1323,8 @@
 
 void SigninScreenHandler::HandleMaxIncorrectPasswordAttempts(
     const std::string& email) {
-  RecordReauthReason(email, ReauthReason::INCORRECT_PASSWORD_ENTERED);
+  RecordReauthReason(AccountId::FromUserEmail(email),
+                     ReauthReason::INCORRECT_PASSWORD_ENTERED);
 }
 
 bool SigninScreenHandler::AllWhitelistedUsersPresent() {
@@ -1341,7 +1345,8 @@
     std::string whitelisted_user;
     // NB: Wildcards in the whitelist are also detected as not present here.
     if (!whitelist->GetString(i, &whitelisted_user) ||
-        !user_manager->IsKnownUser(whitelisted_user)) {
+        !user_manager->IsKnownUser(
+            AccountId::FromUserEmail(whitelisted_user))) {
       return false;
     }
   }
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc b/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
index ed1d6f3..952afcd 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
@@ -49,12 +49,13 @@
     fake_user_manager_->set_multi_profile_user_controller(controller_.get());
 
     for (size_t i = 0; i < arraysize(kUsersPublic); ++i)
-      fake_user_manager_->AddPublicAccountUser(kUsersPublic[i]);
+      fake_user_manager_->AddPublicAccountUser(
+          AccountId::FromUserEmail(kUsersPublic[i]));
 
     for (size_t i = 0; i < arraysize(kUsers); ++i)
-      fake_user_manager_->AddUser(kUsers[i]);
+      fake_user_manager_->AddUser(AccountId::FromUserEmail(kUsers[i]));
 
-    fake_user_manager_->set_owner_email(kOwner);
+    fake_user_manager_->set_owner_id(AccountId::FromUserEmail(kOwner));
   }
 
   void TearDown() override {
@@ -84,8 +85,10 @@
   EXPECT_EQ(kMaxUsers, users_to_send.size());
   EXPECT_EQ(kOwner, users_to_send.back()->email());
 
-  fake_user_manager_->RemoveUserFromList("a16@gmail.com");
-  fake_user_manager_->RemoveUserFromList("a17@gmail.com");
+  fake_user_manager_->RemoveUserFromList(
+      AccountId::FromUserEmail("a16@gmail.com"));
+  fake_user_manager_->RemoveUserFromList(
+      AccountId::FromUserEmail("a17@gmail.com"));
   users_to_send = UserSelectionScreen::PrepareUserListForSending(
       fake_user_manager_->GetUsers(),
       kOwner,
diff --git a/chrome/browser/ui/webui/chromeos/ui_account_tweaks.cc b/chrome/browser/ui/webui/chromeos/ui_account_tweaks.cc
index 3e1727b7..85a7c7cf1 100644
--- a/chrome/browser/ui/webui/chromeos/ui_account_tweaks.cc
+++ b/chrome/browser/ui/webui/chromeos/ui_account_tweaks.cc
@@ -23,7 +23,8 @@
   CrosSettings::Get()->GetString(kDeviceOwner, &owner_email);
   // Translate owner's email to the display email.
   std::string display_email =
-      user_manager::UserManager::Get()->GetUserDisplayEmail(owner_email);
+      user_manager::UserManager::Get()->GetUserDisplayEmail(
+          AccountId::FromUserEmail(owner_email));
   localized_strings->SetString("ownerUserId", display_email);
 
   localized_strings->SetBoolean("currentUserIsOwner",
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc b/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc
index 33c6c55..3dcb20f 100644
--- a/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc
+++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc
@@ -37,6 +37,9 @@
     : LoginManagerTest(false),
       device_settings_provider_(NULL) {
     stub_settings_provider_.Set(kDeviceOwner, base::StringValue(kTestUsers[0]));
+    for (size_t i = 0; i < arraysize(kTestUsers); ++i) {
+      test_users_.push_back(AccountId::FromUserEmail(kTestUsers[i]));
+    }
   }
 
   ~AccountsOptionsTest() override {}
@@ -117,28 +120,29 @@
 
   StubCrosSettingsProvider stub_settings_provider_;
   CrosSettingsProvider* device_settings_provider_;
+  std::vector<AccountId> test_users_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AccountsOptionsTest);
 };
 
 IN_PROC_BROWSER_TEST_F(AccountsOptionsTest, PRE_MultiProfilesAccountsOptions) {
-  RegisterUser(kTestUsers[0]);
-  RegisterUser(kTestUsers[1]);
+  RegisterUser(test_users_[0].GetUserEmail());
+  RegisterUser(test_users_[1].GetUserEmail());
   StartupUtils::MarkOobeCompleted();
 }
 
 IN_PROC_BROWSER_TEST_F(AccountsOptionsTest, MultiProfilesAccountsOptions) {
-  LoginUser(kTestUsers[0]);
+  LoginUser(test_users_[0].GetUserEmail());
   UserAddingScreen::Get()->Start();
   content::RunAllPendingInMessageLoop();
-  AddUser(kTestUsers[1]);
+  AddUser(test_users_[1].GetUserEmail());
 
   user_manager::UserManager* manager = user_manager::UserManager::Get();
   ASSERT_EQ(2u, manager->GetLoggedInUsers().size());
 
-  CheckAccountsUI(manager->FindUser(kTestUsers[0]), true /* is_owner */);
-  CheckAccountsUI(manager->FindUser(kTestUsers[1]), false /* is_owner */);
+  CheckAccountsUI(manager->FindUser(test_users_[0]), true /* is_owner */);
+  CheckAccountsUI(manager->FindUser(test_users_[1]), false /* is_owner */);
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
index 40b639d..ada7049 100644
--- a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
@@ -129,7 +129,8 @@
           OwnerSettingsServiceChromeOS::FromWebUI(web_ui())) {
     service->RemoveFromList(kAccountsPrefUsers, canonical_email);
   }
-  user_manager::UserManager::Get()->RemoveUser(email, NULL);
+  user_manager::UserManager::Get()->RemoveUser(AccountId::FromUserEmail(email),
+                                               nullptr);
 }
 
 void AccountsOptionsHandler::HandleUpdateWhitelist(
diff --git a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
index b6de55d1..1ceeaa7 100644
--- a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
@@ -305,7 +305,7 @@
 
 void ChangePictureOptionsHandler::UpdateProfileImage() {
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(GetUser()->email());
+      ChromeUserManager::Get()->GetUserImageManager(GetUser()->GetAccountId());
   // If we have a downloaded profile image and haven't sent it in
   // |SendSelectedImage|, send it now (without selecting).
   if (previous_image_index_ != user_manager::User::USER_IMAGE_PROFILE &&
@@ -336,7 +336,7 @@
   DCHECK(!image_type.empty());
 
   UserImageManager* user_image_manager =
-      ChromeUserManager::Get()->GetUserImageManager(GetUser()->email());
+      ChromeUserManager::Get()->GetUserImageManager(GetUser()->GetAccountId());
   int image_index = user_manager::User::USER_IMAGE_INVALID;
   bool waiting_for_camera_photo = false;
 
@@ -396,7 +396,7 @@
                                                int index,
                                                void* params) {
   ChromeUserManager::Get()
-      ->GetUserImageManager(GetUser()->email())
+      ->GetUserImageManager(GetUser()->GetAccountId())
       ->SaveUserImageFromFile(path);
   UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice",
                             user_manager::kHistogramImageFromFile,
@@ -407,7 +407,7 @@
 void ChangePictureOptionsHandler::SetImageFromCamera(
     const gfx::ImageSkia& photo) {
   ChromeUserManager::Get()
-      ->GetUserImageManager(GetUser()->email())
+      ->GetUserImageManager(GetUser()->GetAccountId())
       ->SaveUserImage(user_manager::UserImage::CreateAndEncode(photo));
   UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice",
                             user_manager::kHistogramImageFromCamera,
diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
index 91f53821..daed4a8 100644
--- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
@@ -71,7 +71,9 @@
   user_dict->SetString("name", display_email);
   user_dict->SetString("email", display_name);
 
-  bool is_owner = user_manager::UserManager::Get()->GetOwnerEmail() == username;
+  const bool is_owner =
+      user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail() ==
+      username;
   user_dict->SetBoolean("owner", is_owner);
   return user_dict;
 }
@@ -89,7 +91,8 @@
     std::string email;
     if ((*i)->GetAsString(&email)) {
       // Translate email to the display email.
-      std::string display_email = user_manager->GetUserDisplayEmail(email);
+      const std::string display_email =
+          user_manager->GetUserDisplayEmail(AccountId::FromUserEmail(email));
       // TODO(ivankr): fetch display name for existing users.
       user_list->Append(CreateUserInfo(email, display_email, std::string()));
     }
@@ -361,10 +364,12 @@
     // Managed machines have no "owner".
     localized_strings->SetString("controlledSettingOwner", base::string16());
   } else {
-    localized_strings->SetString("controlledSettingOwner",
+    localized_strings->SetString(
+        "controlledSettingOwner",
         l10n_util::GetStringFUTF16(
             IDS_OPTIONS_CONTROLLED_SETTING_OWNER,
-            base::ASCIIToUTF16(user_manager->GetOwnerEmail())));
+            base::ASCIIToUTF16(
+                user_manager->GetOwnerAccountId().GetUserEmail())));
   }
 }
 
diff --git a/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc b/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc
index 9ec75fe5..1055a8d 100644
--- a/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc
+++ b/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc
@@ -86,8 +86,10 @@
 class SharedOptionsTest : public LoginManagerTest {
  public:
   SharedOptionsTest()
-    : LoginManagerTest(false),
-      device_settings_provider_(NULL) {
+      : LoginManagerTest(false),
+        device_settings_provider_(NULL),
+        test_owner_account_id_(AccountId::FromUserEmail(kTestOwner)),
+        test_non_owner_account_id_(AccountId::FromUserEmail(kTestNonOwner)) {
     stub_settings_provider_.Set(kDeviceOwner, base::StringValue(kTestOwner));
   }
 
@@ -266,40 +268,43 @@
   StubAccountSettingsProvider stub_settings_provider_;
   CrosSettingsProvider* device_settings_provider_;
 
+  const AccountId test_owner_account_id_;
+  const AccountId test_non_owner_account_id_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(SharedOptionsTest);
 };
 
 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_SharedOptions) {
-  RegisterUser(kTestOwner);
-  RegisterUser(kTestNonOwner);
+  RegisterUser(test_owner_account_id_.GetUserEmail());
+  RegisterUser(test_non_owner_account_id_.GetUserEmail());
   StartupUtils::MarkOobeCompleted();
 }
 
 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, SharedOptions) {
   // Log in the owner first, then add a secondary user.
-  LoginUser(kTestOwner);
+  LoginUser(test_owner_account_id_.GetUserEmail());
   UserAddingScreen::Get()->Start();
   content::RunAllPendingInMessageLoop();
-  AddUser(kTestNonOwner);
+  AddUser(test_non_owner_account_id_.GetUserEmail());
 
   user_manager::UserManager* manager = user_manager::UserManager::Get();
   ASSERT_EQ(2u, manager->GetLoggedInUsers().size());
   {
     SCOPED_TRACE("Checking settings for owner, primary user.");
-    CheckOptionsUI(manager->FindUser(manager->GetOwnerEmail()), true, true);
+    CheckOptionsUI(manager->FindUser(manager->GetOwnerAccountId()), true, true);
   }
   {
     SCOPED_TRACE("Checking settings for non-owner, secondary user.");
-    CheckOptionsUI(manager->FindUser(kTestNonOwner), false, false);
+    CheckOptionsUI(manager->FindUser(test_non_owner_account_id_), false, false);
   }
   // TODO(michaelpg): Add tests for non-primary owner and primary non-owner
   // when the owner-only multiprofile restriction is removed, probably M38.
 }
 
 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_ScreenLockPreferencePrimary) {
-  RegisterUser(kTestOwner);
-  RegisterUser(kTestNonOwner);
+  RegisterUser(test_owner_account_id_.GetUserEmail());
+  RegisterUser(test_non_owner_account_id_.GetUserEmail());
   StartupUtils::MarkOobeCompleted();
 }
 
@@ -309,14 +314,15 @@
 // other signed-in user has enabled this preference, the shared setting
 // indicator explains this.)
 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, ScreenLockPreferencePrimary) {
-  LoginUser(kTestOwner);
+  LoginUser(test_owner_account_id_.GetUserEmail());
   UserAddingScreen::Get()->Start();
   content::RunAllPendingInMessageLoop();
-  AddUser(kTestNonOwner);
+  AddUser(test_non_owner_account_id_.GetUserEmail());
 
   user_manager::UserManager* manager = user_manager::UserManager::Get();
-  const user_manager::User* user1 = manager->FindUser(kTestOwner);
-  const user_manager::User* user2 = manager->FindUser(kTestNonOwner);
+  const user_manager::User* user1 = manager->FindUser(test_owner_account_id_);
+  const user_manager::User* user2 =
+      manager->FindUser(test_non_owner_account_id_);
 
   PrefService* prefs1 =
       ProfileHelper::Get()->GetProfileByUserUnsafe(user1)->GetPrefs();
@@ -369,8 +375,8 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_ScreenLockPreferenceSecondary) {
-  RegisterUser(kTestOwner);
-  RegisterUser(kTestNonOwner);
+  RegisterUser(test_owner_account_id_.GetUserEmail());
+  RegisterUser(test_non_owner_account_id_.GetUserEmail());
   StartupUtils::MarkOobeCompleted();
 }
 
@@ -380,14 +386,15 @@
 // other signed-in user has enabled this preference, the shared setting
 // indicator explains this.)
 IN_PROC_BROWSER_TEST_F(SharedOptionsTest, ScreenLockPreferenceSecondary) {
-  LoginUser(kTestOwner);
+  LoginUser(test_owner_account_id_.GetUserEmail());
   UserAddingScreen::Get()->Start();
   content::RunAllPendingInMessageLoop();
-  AddUser(kTestNonOwner);
+  AddUser(test_non_owner_account_id_.GetUserEmail());
 
   user_manager::UserManager* manager = user_manager::UserManager::Get();
-  const user_manager::User* user1 = manager->FindUser(kTestOwner);
-  const user_manager::User* user2 = manager->FindUser(kTestNonOwner);
+  const user_manager::User* user1 = manager->FindUser(test_owner_account_id_);
+  const user_manager::User* user2 =
+      manager->FindUser(test_non_owner_account_id_);
 
   PrefService* prefs1 =
       ProfileHelper::Get()->GetProfileByUserUnsafe(user1)->GetPrefs();
diff --git a/chrome/browser/ui/webui/options/chromeos/user_image_source.cc b/chrome/browser/ui/webui/options/chromeos/user_image_source.cc
index 71a03b7..46572be 100644
--- a/chrome/browser/ui/webui/options/chromeos/user_image_source.cc
+++ b/chrome/browser/ui/webui/options/chromeos/user_image_source.cc
@@ -8,6 +8,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_split.h"
 #include "chrome/common/url_constants.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_image/default_user_images.h"
 #include "components/user_manager/user_manager.h"
 #include "grit/theme_resources.h"
@@ -37,10 +38,10 @@
 
 // Static.
 base::RefCountedMemory* UserImageSource::GetUserImage(
-    const std::string& email,
+    const AccountId& account_id,
     ui::ScaleFactor scale_factor) {
   const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(email);
+      user_manager::UserManager::Get()->FindUser(account_id);
   if (user) {
     if (user->has_raw_image()) {
       return new base::RefCountedBytes(user->raw_image());
@@ -78,7 +79,8 @@
   std::string email;
   GURL url(chrome::kChromeUIUserImageURL + path);
   ParseRequest(url, &email);
-  callback.Run(GetUserImage(email, ui::SCALE_FACTOR_100P));
+  const AccountId account_id(AccountId::FromUserEmail(email));
+  callback.Run(GetUserImage(account_id, ui::SCALE_FACTOR_100P));
 }
 
 std::string UserImageSource::GetMimeType(const std::string& path) const {
diff --git a/chrome/browser/ui/webui/options/chromeos/user_image_source.h b/chrome/browser/ui/webui/options/chromeos/user_image_source.h
index ad11d6a..87ffa12 100644
--- a/chrome/browser/ui/webui/options/chromeos/user_image_source.h
+++ b/chrome/browser/ui/webui/options/chromeos/user_image_source.h
@@ -13,6 +13,8 @@
 #include "content/public/browser/url_data_source.h"
 #include "ui/base/layout.h"
 
+class AccountId;
+
 namespace base {
 class RefCountedMemory;
 }
@@ -35,9 +37,9 @@
       const content::URLDataSource::GotDataCallback& callback) override;
   std::string GetMimeType(const std::string& path) const override;
 
-  // Returns PNG encoded image for user with specified email. If there's
-  // no user with such email, returns the first default image.
-  static base::RefCountedMemory* GetUserImage(const std::string& email,
+  // Returns PNG encoded image for user with specified |account_id|. If there's
+  // no user with such an id, returns the first default image.
+  static base::RefCountedMemory* GetUserImage(const AccountId& account_id,
                                               ui::ScaleFactor scale_factor);
 
  private:
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index e96914c..7c3fd77 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -1800,6 +1800,16 @@
     "pref_mappings": []
   },
 
+  "RC4Enabled": {
+    "os": ["win", "linux", "mac", "chromeos"],
+    "test_policy": { "RC4Enabled": true },
+    "pref_mappings": [
+      { "pref": "ssl.rc4_enabled",
+        "local_state": true
+      }
+    ]
+  },
+
   "WelcomePageOnOSUpgradeEnabled": {
     "os": ["win"],
     "test_policy": { "WelcomePageOnOSUpgradeEnabled": false },
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index c897806..2c1ce3dc 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -201,10 +201,6 @@
 const char kIgnoreUserProfileMappingForTests[] =
     "ignore-user-profile-mapping-for-tests";
 
-// File to load internal display ICC file from.
-const char kInternalDisplayColorProfileFile[] =
-    "internal-display-color-profile-file";
-
 // Enables Chrome-as-a-login-manager behavior.
 const char kLoginManager[] = "login-manager";
 
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 1244a6ba..133a1cc 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -80,7 +80,6 @@
 CHROMEOS_EXPORT extern const char kHomedir[];
 CHROMEOS_EXPORT extern const char kHostPairingOobe[];
 CHROMEOS_EXPORT extern const char kIgnoreUserProfileMappingForTests[];
-CHROMEOS_EXPORT extern const char kInternalDisplayColorProfileFile[];
 CHROMEOS_EXPORT extern const char kLoginManager[];
 CHROMEOS_EXPORT extern const char kLoginProfile[];
 CHROMEOS_EXPORT extern const char kLoginUser[];
diff --git a/chromeos/login/auth/cryptohome_authenticator.cc b/chromeos/login/auth/cryptohome_authenticator.cc
index 156a66d..e9e10174 100644
--- a/chromeos/login/auth/cryptohome_authenticator.cc
+++ b/chromeos/login/auth/cryptohome_authenticator.cc
@@ -148,9 +148,9 @@
   }
 
   cryptohome::HomedirMethods::GetInstance()->MountEx(
-      cryptohome::Identification(attempt->user_context.GetUserID()),
-      cryptohome::Authorization(auth_key),
-      mount,
+      cryptohome::Identification(
+          attempt->user_context.GetAccountId().GetUserEmail()),
+      cryptohome::Authorization(auth_key), mount,
       base::Bind(&OnMount, attempt, resolver));
 }
 
@@ -266,13 +266,10 @@
   }
 
   cryptohome::HomedirMethods::GetInstance()->GetKeyDataEx(
-      cryptohome::Identification(attempt->user_context.GetUserID()),
-      kCryptohomeGAIAKeyLabel,
-      base::Bind(&OnGetKeyDataEx,
-                 attempt,
-                 resolver,
-                 ephemeral,
-                 create_if_nonexistent));
+      cryptohome::Identification(
+          attempt->user_context.GetAccountId().GetUserEmail()),
+      kCryptohomeGAIAKeyLabel, base::Bind(&OnGetKeyDataEx, attempt, resolver,
+                                          ephemeral, create_if_nonexistent));
 }
 
 // Calls cryptohome's mount method for guest and also get the user hash from
@@ -286,7 +283,7 @@
                  attempt,
                  resolver));
   cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername(
-      attempt->user_context.GetUserID(),
+      attempt->user_context.GetAccountId().GetUserEmail(),
       base::Bind(&TriggerResolveHash, attempt, resolver));
 }
 
@@ -295,14 +292,11 @@
                  scoped_refptr<CryptohomeAuthenticator> resolver,
                  int flags) {
   cryptohome::AsyncMethodCaller::GetInstance()->AsyncMountPublic(
-      attempt->user_context.GetUserID(),
-      flags,
+      attempt->user_context.GetAccountId().GetUserEmail(), flags,
       base::Bind(&TriggerResolveWithLoginTimeMarker,
-                 "CryptohomeMountPublic-End",
-                 attempt,
-                 resolver));
+                 "CryptohomeMountPublic-End", attempt, resolver));
   cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername(
-      attempt->user_context.GetUserID(),
+      attempt->user_context.GetAccountId().GetUserEmail(),
       base::Bind(&TriggerResolveHash, attempt, resolver));
 }
 
@@ -324,21 +318,17 @@
   scoped_ptr<Key> new_key =
       TransformKeyIfNeeded(*attempt->user_context.GetKey(), system_salt);
   if (passing_old_hash) {
-    caller->AsyncMigrateKey(attempt->user_context.GetUserID(),
-                            old_key->GetSecret(),
-                            new_key->GetSecret(),
-                            base::Bind(&TriggerResolveWithLoginTimeMarker,
-                                       "CryptohomeMount-End",
-                                       attempt,
-                                       resolver));
+    caller->AsyncMigrateKey(
+        attempt->user_context.GetAccountId().GetUserEmail(),
+        old_key->GetSecret(), new_key->GetSecret(),
+        base::Bind(&TriggerResolveWithLoginTimeMarker, "CryptohomeMount-End",
+                   attempt, resolver));
   } else {
-    caller->AsyncMigrateKey(attempt->user_context.GetUserID(),
-                            new_key->GetSecret(),
-                            old_key->GetSecret(),
-                            base::Bind(&TriggerResolveWithLoginTimeMarker,
-                                       "CryptohomeMount-End",
-                                       attempt,
-                                       resolver));
+    caller->AsyncMigrateKey(
+        attempt->user_context.GetAccountId().GetUserEmail(),
+        new_key->GetSecret(), old_key->GetSecret(),
+        base::Bind(&TriggerResolveWithLoginTimeMarker, "CryptohomeMount-End",
+                   attempt, resolver));
   }
 }
 
@@ -348,11 +338,9 @@
   chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker(
       "CryptohomeRemove-Start", false);
   cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
-      attempt->user_context.GetUserID(),
-      base::Bind(&TriggerResolveWithLoginTimeMarker,
-                 "CryptohomeRemove-End",
-                 attempt,
-                 resolver));
+      attempt->user_context.GetAccountId().GetUserEmail(),
+      base::Bind(&TriggerResolveWithLoginTimeMarker, "CryptohomeRemove-End",
+                 attempt, resolver));
 }
 
 // Calls cryptohome's key check method.
@@ -362,8 +350,7 @@
   scoped_ptr<Key> key =
       TransformKeyIfNeeded(*attempt->user_context.GetKey(), system_salt);
   cryptohome::AsyncMethodCaller::GetInstance()->AsyncCheckKey(
-      attempt->user_context.GetUserID(),
-      key->GetSecret(),
+      attempt->user_context.GetAccountId().GetUserEmail(), key->GetSecret(),
       base::Bind(&TriggerResolve, attempt, resolver));
 }
 
diff --git a/chromeos/login/auth/extended_authenticator_impl.cc b/chromeos/login/auth/extended_authenticator_impl.cc
index 0aa10e5..88ec3cf 100644
--- a/chromeos/login/auth/extended_authenticator_impl.cc
+++ b/chromeos/login/auth/extended_authenticator_impl.cc
@@ -17,6 +17,7 @@
 #include "chromeos/login/auth/key.h"
 #include "chromeos/login/auth/user_context.h"
 #include "chromeos/login_event_recorder.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "crypto/sha2.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 
@@ -91,7 +92,7 @@
   for (size_t i = 0; i < keys.size(); i++) {
     mount.create_keys.push_back(keys[i]);
   }
-  UserContext context(user_id);
+  UserContext context(AccountId::FromUserEmail(user_id));
   Key key(keys.front().secret);
   key.SetLabel(keys.front().label);
   context.SetKey(key);
@@ -186,7 +187,8 @@
     const UserContext& user_context) {
   RecordStartMarker("MountEx");
 
-  std::string canonicalized = gaia::CanonicalizeEmail(user_context.GetUserID());
+  const std::string canonicalized =
+      gaia::CanonicalizeEmail(user_context.GetAccountId().GetUserEmail());
   cryptohome::Identification id(canonicalized);
   const Key* const key = user_context.GetKey();
   cryptohome::Authorization auth(key->GetSecret(), key->GetLabel());
@@ -208,7 +210,8 @@
     const UserContext& user_context) {
   RecordStartMarker("CheckKeyEx");
 
-  std::string canonicalized = gaia::CanonicalizeEmail(user_context.GetUserID());
+  const std::string canonicalized =
+      gaia::CanonicalizeEmail(user_context.GetAccountId().GetUserEmail());
   cryptohome::Identification id(canonicalized);
   const Key* const key = user_context.GetKey();
   cryptohome::Authorization auth(key->GetSecret(), key->GetLabel());
@@ -229,7 +232,8 @@
                                      const UserContext& user_context) {
   RecordStartMarker("AddKeyEx");
 
-  std::string canonicalized = gaia::CanonicalizeEmail(user_context.GetUserID());
+  const std::string canonicalized =
+      gaia::CanonicalizeEmail(user_context.GetAccountId().GetUserEmail());
   cryptohome::Identification id(canonicalized);
   const Key* const auth_key = user_context.GetKey();
   cryptohome::Authorization auth(auth_key->GetSecret(), auth_key->GetLabel());
@@ -253,7 +257,8 @@
     const UserContext& user_context) {
   RecordStartMarker("UpdateKeyAuthorized");
 
-  std::string canonicalized = gaia::CanonicalizeEmail(user_context.GetUserID());
+  const std::string canonicalized =
+      gaia::CanonicalizeEmail(user_context.GetAccountId().GetUserEmail());
   cryptohome::Identification id(canonicalized);
   const Key* const auth_key = user_context.GetKey();
   cryptohome::Authorization auth(auth_key->GetSecret(), auth_key->GetLabel());
@@ -275,7 +280,8 @@
                                         const UserContext& user_context) {
   RecordStartMarker("RemoveKeyEx");
 
-  std::string canonicalized = gaia::CanonicalizeEmail(user_context.GetUserID());
+  const std::string canonicalized =
+      gaia::CanonicalizeEmail(user_context.GetAccountId().GetUserEmail());
   cryptohome::Identification id(canonicalized);
   const Key* const auth_key = user_context.GetKey();
   cryptohome::Authorization auth(auth_key->GetSecret(), auth_key->GetLabel());
diff --git a/chromeos/login/auth/fake_extended_authenticator.cc b/chromeos/login/auth/fake_extended_authenticator.cc
index 90b569b..e57755b9 100644
--- a/chromeos/login/auth/fake_extended_authenticator.cc
+++ b/chromeos/login/auth/fake_extended_authenticator.cc
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "chromeos/login/auth/auth_status_consumer.h"
+#include "components/signin/core/account_id/account_id.h"
 
 namespace chromeos {
 
@@ -37,7 +38,8 @@
     const ResultCallback& success_callback) {
   if (expected_user_context_ == context) {
     UserContext reported_user_context(context);
-    const std::string mount_hash = reported_user_context.GetUserID() + "-hash";
+    const std::string mount_hash =
+        reported_user_context.GetAccountId().GetUserEmail() + "-hash";
     reported_user_context.SetUserIDHash(mount_hash);
     if (!success_callback.is_null())
       success_callback.Run(mount_hash);
diff --git a/chromeos/login/auth/login_performer.cc b/chromeos/login/auth/login_performer.cc
index ba4e82b..b988f1d 100644
--- a/chromeos/login/auth/login_performer.cc
+++ b/chromeos/login/auth/login_performer.cc
@@ -18,6 +18,7 @@
 #include "chromeos/login/user_names.h"
 #include "chromeos/login_event_recorder.h"
 #include "chromeos/settings/cros_settings_names.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "net/cookies/cookie_monster.h"
 #include "net/cookies/cookie_store.h"
@@ -107,7 +108,8 @@
 
 void LoginPerformer::NotifyWhitelistCheckFailure() {
   if (delegate_)
-    delegate_->WhiteListCheckFailed(user_context_.GetUserID());
+    delegate_->WhiteListCheckFailed(
+        user_context_.GetAccountId().GetUserEmail());
   else
     NOTREACHED();
 }
@@ -128,7 +130,8 @@
 
 void LoginPerformer::DoPerformLogin(const UserContext& user_context,
                                     AuthorizationMode auth_mode) {
-  std::string email = gaia::CanonicalizeEmail(user_context.GetUserID());
+  const std::string email =
+      gaia::CanonicalizeEmail(user_context.GetAccountId().GetUserEmail());
   bool wildcard_match = false;
 
   if (!IsUserWhitelisted(email, &wildcard_match)) {
@@ -137,7 +140,7 @@
   }
 
   if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_EASY_UNLOCK)
-    SetupEasyUnlockUserFlow(user_context.GetUserID());
+    SetupEasyUnlockUserFlow(user_context.GetAccountId().GetUserEmail());
 
   switch (auth_mode_) {
     case AUTH_MODE_EXTENSION: {
@@ -156,8 +159,9 @@
 }
 
 void LoginPerformer::LoginAsSupervisedUser(const UserContext& user_context) {
-  DCHECK_EQ(chromeos::login::kSupervisedUserDomain,
-            gaia::ExtractDomainName(user_context.GetUserID()));
+  DCHECK_EQ(
+      chromeos::login::kSupervisedUserDomain,
+      gaia::ExtractDomainName(user_context.GetAccountId().GetUserEmail()));
 
   user_context_ = user_context;
   user_context_.SetUserType(user_manager::USER_TYPE_SUPERVISED);
@@ -174,11 +178,11 @@
     const UserContext& user_context) {
   if (!AreSupervisedUsersAllowed()) {
     LOG(ERROR) << "Login attempt of supervised user detected.";
-    delegate_->WhiteListCheckFailed(user_context.GetUserID());
+    delegate_->WhiteListCheckFailed(user_context.GetAccountId().GetUserEmail());
     return;
   }
 
-  SetupSupervisedUserFlow(user_context.GetUserID());
+  SetupSupervisedUserFlow(user_context.GetAccountId().GetUserEmail());
   UserContext user_context_copy = TransformSupervisedKey(user_context);
 
   if (UseExtendedAuthenticatorForSupervisedUser(user_context)) {
@@ -202,7 +206,7 @@
 }
 
 void LoginPerformer::LoginAsPublicSession(const UserContext& user_context) {
-  if (!CheckPolicyForUser(user_context.GetUserID())) {
+  if (!CheckPolicyForUser(user_context.GetAccountId().GetUserEmail())) {
     DCHECK(delegate_);
     if (delegate_)
       delegate_->PolicyLoadFailed();
diff --git a/chromeos/login/auth/stub_authenticator.cc b/chromeos/login/auth/stub_authenticator.cc
index 6a183a4..371453d8 100644
--- a/chromeos/login/auth/stub_authenticator.cc
+++ b/chromeos/login/auth/stub_authenticator.cc
@@ -38,7 +38,7 @@
   authentication_context_ = context;
   // Don't compare the entire |expected_user_context_| to |user_context| because
   // during non-online re-auth |user_context| does not have a gaia id.
-  if (expected_user_context_.GetUserID() == user_context.GetUserID() &&
+  if (expected_user_context_.GetAccountId() == user_context.GetAccountId() &&
       *expected_user_context_.GetKey() == *user_context.GetKey()) {
     task_runner_->PostTask(FROM_HERE,
                            base::Bind(&StubAuthenticator::OnAuthSuccess, this));
@@ -57,7 +57,8 @@
 
 void StubAuthenticator::LoginAsSupervisedUser(const UserContext& user_context) {
   UserContext new_user_context = user_context;
-  new_user_context.SetUserIDHash(user_context.GetUserID() + kUserIdHashSuffix);
+  new_user_context.SetUserIDHash(user_context.GetAccountId().GetUserEmail() +
+                                 kUserIdHashSuffix);
   consumer_->OnAuthSuccess(new_user_context);
 }
 
@@ -68,17 +69,18 @@
 void StubAuthenticator::LoginAsPublicSession(const UserContext& user_context) {
   UserContext logged_in_user_context = user_context;
   logged_in_user_context.SetIsUsingOAuth(false);
-  logged_in_user_context.SetUserIDHash(logged_in_user_context.GetUserID() +
-                                       kUserIdHashSuffix);
+  logged_in_user_context.SetUserIDHash(
+      logged_in_user_context.GetAccountId().GetUserEmail() + kUserIdHashSuffix);
   consumer_->OnAuthSuccess(logged_in_user_context);
 }
 
-void StubAuthenticator::LoginAsKioskAccount(const std::string& app_user_id,
-                                            bool use_guest_mount) {
-  UserContext user_context(expected_user_context_.GetUserID());
+void StubAuthenticator::LoginAsKioskAccount(
+    const std::string& /* app_user_id */,
+    bool use_guest_mount) {
+  UserContext user_context(expected_user_context_.GetAccountId());
   user_context.SetIsUsingOAuth(false);
-  user_context.SetUserIDHash(expected_user_context_.GetUserID() +
-                             kUserIdHashSuffix);
+  user_context.SetUserIDHash(
+      expected_user_context_.GetAccountId().GetUserEmail() + kUserIdHashSuffix);
   consumer_->OnAuthSuccess(user_context);
 }
 
@@ -86,8 +88,8 @@
   // If we want to be more like the real thing, we could save the user ID
   // in AuthenticateToLogin, but there's not much of a point.
   UserContext user_context(expected_user_context_);
-  user_context.SetUserIDHash(expected_user_context_.GetUserID() +
-                             kUserIdHashSuffix);
+  user_context.SetUserIDHash(
+      expected_user_context_.GetAccountId().GetUserEmail() + kUserIdHashSuffix);
   consumer_->OnAuthSuccess(user_context);
 }
 
diff --git a/chromeos/login/auth/user_context.cc b/chromeos/login/auth/user_context.cc
index 1f630c2..0060e3c4 100644
--- a/chromeos/login/auth/user_context.cc
+++ b/chromeos/login/auth/user_context.cc
@@ -7,14 +7,10 @@
 
 namespace chromeos {
 
-UserContext::UserContext()
-    : is_using_oauth_(true),
-      auth_flow_(AUTH_FLOW_OFFLINE),
-      user_type_(user_manager::USER_TYPE_REGULAR) {
-}
+UserContext::UserContext() : account_id_(EmptyAccountId()) {}
 
 UserContext::UserContext(const UserContext& other)
-    : user_id_(other.user_id_),
+    : account_id_(other.account_id_),
       gaia_id_(other.gaia_id_),
       key_(other.key_),
       auth_code_(other.auth_code_),
@@ -27,32 +23,28 @@
       public_session_locale_(other.public_session_locale_),
       public_session_input_method_(other.public_session_input_method_),
       device_id_(other.device_id_),
-      gaps_cookie_(other.gaps_cookie_) {
-}
+      gaps_cookie_(other.gaps_cookie_) {}
 
-UserContext::UserContext(const std::string& user_id)
-    : user_id_(login::CanonicalizeUserID(user_id)),
-      is_using_oauth_(true),
-      auth_flow_(AUTH_FLOW_OFFLINE),
-      user_type_(user_manager::USER_TYPE_REGULAR) {
+UserContext::UserContext(const AccountId& account_id)
+    : account_id_(account_id) {
+  account_id_.SetUserEmail(
+      login::CanonicalizeUserID(account_id.GetUserEmail()));
 }
 
 UserContext::UserContext(user_manager::UserType user_type,
                          const std::string& user_id)
-    : is_using_oauth_(true),
-      auth_flow_(AUTH_FLOW_OFFLINE),
-      user_type_(user_type) {
+    : account_id_(EmptyAccountId()), user_type_(user_type) {
   if (user_type_ == user_manager::USER_TYPE_REGULAR)
-    user_id_ = login::CanonicalizeUserID(user_id);
+    account_id_ = AccountId::FromUserEmail(login::CanonicalizeUserID(user_id));
   else
-    user_id_ = user_id;
+    account_id_ = AccountId::FromUserEmail(user_id);
 }
 
 UserContext::~UserContext() {
 }
 
 bool UserContext::operator==(const UserContext& context) const {
-  return context.user_id_ == user_id_ && context.gaia_id_ == gaia_id_ &&
+  return context.account_id_ == account_id_ && context.gaia_id_ == gaia_id_ &&
          context.key_ == key_ && context.auth_code_ == auth_code_ &&
          context.refresh_token_ == refresh_token_ &&
          context.access_token_ == access_token_ &&
@@ -67,8 +59,8 @@
   return !(*this == context);
 }
 
-const std::string& UserContext::GetUserID() const {
-  return user_id_;
+const AccountId& UserContext::GetAccountId() const {
+  return account_id_;
 }
 
 const std::string& UserContext::GetGaiaID() const {
@@ -128,12 +120,12 @@
 }
 
 bool UserContext::HasCredentials() const {
-  return (!user_id_.empty() && !key_.GetSecret().empty()) ||
+  return (account_id_.is_valid() && !key_.GetSecret().empty()) ||
          !auth_code_.empty();
 }
 
 void UserContext::SetUserID(const std::string& user_id) {
-  user_id_ = login::CanonicalizeUserID(user_id);
+  account_id_ = AccountId::FromUserEmail(login::CanonicalizeUserID(user_id));
 }
 
 void UserContext::SetGaiaID(const std::string& gaia_id) {
diff --git a/chromeos/login/auth/user_context.h b/chromeos/login/auth/user_context.h
index 4dbd71b..a4440cc 100644
--- a/chromeos/login/auth/user_context.h
+++ b/chromeos/login/auth/user_context.h
@@ -9,12 +9,16 @@
 
 #include "chromeos/chromeos_export.h"
 #include "chromeos/login/auth/key.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_type.h"
 
+class AccountId;
+
 namespace chromeos {
 
 // Information that is passed around while authentication is in progress. The
-// credentials may consist of a |user_id_|, |key_| pair or a GAIA |auth_code_|.
+// credentials may consist of a |account_id_|, |key_| pair or a GAIA
+// |auth_code_|.
 // The |user_id_hash_| is used to locate the user's home directory
 // mount point for the user. It is set when the mount has been completed.
 class CHROMEOS_EXPORT UserContext {
@@ -35,14 +39,14 @@
 
   UserContext();
   UserContext(const UserContext& other);
-  explicit UserContext(const std::string& user_id);
+  explicit UserContext(const AccountId& account_id);
   UserContext(user_manager::UserType user_type, const std::string& user_id);
   ~UserContext();
 
   bool operator==(const UserContext& context) const;
   bool operator!=(const UserContext& context) const;
 
-  const std::string& GetUserID() const;
+  const AccountId& GetAccountId() const;
   const std::string& GetGaiaID() const;
   const Key* GetKey() const;
   Key* GetKey();
@@ -78,16 +82,16 @@
   void ClearSecrets();
 
  private:
-  std::string user_id_;
+  AccountId account_id_;
   std::string gaia_id_;
   Key key_;
   std::string auth_code_;
   std::string refresh_token_;
   std::string access_token_;  // OAuthLogin scoped access token.
   std::string user_id_hash_;
-  bool is_using_oauth_;
-  AuthFlow auth_flow_;
-  user_manager::UserType user_type_;
+  bool is_using_oauth_ = true;
+  AuthFlow auth_flow_ = AUTH_FLOW_OFFLINE;
+  user_manager::UserType user_type_ = user_manager::USER_TYPE_REGULAR;
   std::string public_session_locale_;
   std::string public_session_input_method_;
   std::string device_id_;
diff --git a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
index 9316a7c..4307b35 100644
--- a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
+++ b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
@@ -53,19 +53,6 @@
         }
 
         /**
-         * Creates a config from a JSON string, which was serialized using
-         * {@link #toString}.
-         *
-         * @param context Android {@link Context} for engine to use.
-         * @param json JSON string of configuration parameters, which was
-         *         serialized using {@link #toString}.
-         */
-        public Builder(Context context, String json) throws JSONException {
-            mConfig = new JSONObject(json);
-            mContext = context;
-        }
-
-        /**
          * Constructs a User-Agent string including Cronet version, and
          * application name and version.
          *
@@ -334,10 +321,9 @@
         }
 
         /**
-         * Get JSON string representation of the builder.
+         * Gets a JSON string representation of the builder.
          */
-        @Override
-        public String toString() {
+        String toJSONString() {
             return mConfig.toString();
         }
 
diff --git a/components/cronet/android/api/src/org/chromium/net/HttpUrlRequestFactoryConfig.java b/components/cronet/android/api/src/org/chromium/net/HttpUrlRequestFactoryConfig.java
index 65434e46..6f7c158 100644
--- a/components/cronet/android/api/src/org/chromium/net/HttpUrlRequestFactoryConfig.java
+++ b/components/cronet/android/api/src/org/chromium/net/HttpUrlRequestFactoryConfig.java
@@ -4,8 +4,6 @@
 
 package org.chromium.net;
 
-import org.json.JSONException;
-
 /**
  * A config for HttpUrlRequestFactory, which allows runtime configuration of
  * HttpUrlRequestFactory.
@@ -20,11 +18,4 @@
     public HttpUrlRequestFactoryConfig() {
         super();
     }
-
-    /**
-     * Create config from json serialized using @toString.
-     */
-    public HttpUrlRequestFactoryConfig(String json) throws JSONException {
-        super(json);
-    }
 }
diff --git a/components/cronet/android/api/src/org/chromium/net/UrlRequestContextConfig.java b/components/cronet/android/api/src/org/chromium/net/UrlRequestContextConfig.java
index ff0c7779..0e55fc6 100644
--- a/components/cronet/android/api/src/org/chromium/net/UrlRequestContextConfig.java
+++ b/components/cronet/android/api/src/org/chromium/net/UrlRequestContextConfig.java
@@ -4,8 +4,6 @@
 
 package org.chromium.net;
 
-import org.json.JSONException;
-
 /**
  * A config for CronetEngine, which allows runtime configuration of
  * CronetEngine.
@@ -17,10 +15,4 @@
         // or ChromiumUrlRequestContext is created.
         super(null);
     }
-
-    public UrlRequestContextConfig(String json) throws JSONException {
-        // Context will be passed in later when the ChromiumUrlRequestFactory
-        // or ChromiumUrlRequestContext is created.
-        super(null, json);
-    }
 }
diff --git a/components/cronet/android/api/src/org/chromium/net/UrlResponseInfo.java b/components/cronet/android/api/src/org/chromium/net/UrlResponseInfo.java
index d1f26b89..73e55ae 100644
--- a/components/cronet/android/api/src/org/chromium/net/UrlResponseInfo.java
+++ b/components/cronet/android/api/src/org/chromium/net/UrlResponseInfo.java
@@ -76,7 +76,20 @@
         }
     }
 
-    UrlResponseInfo(List<String> urlChain, int httpStatusCode, String httpStatusText,
+    /**
+     * Creates a {@link UrlResponseInfo} object.  Provided to facilitate testing.
+     *
+     * @param urlChain the URL chain. The first entry is the originally requested URL;
+     *         the following entries are redirects followed.
+     * @param httpStatusCode the HTTP status code.
+     * @param httpStatusText the HTTP status text of the status line.
+     * @param allHeadersList list of response header field and value pairs.
+     * @param wasCached {@code true} if the response came from the cache, {@code false}
+     *         otherwise.
+     * @param negotiatedProtocol the protocol negotiated with the server.
+     * @param proxyServer the proxy server that was used for the request.
+     */
+    public UrlResponseInfo(List<String> urlChain, int httpStatusCode, String httpStatusText,
             List<Map.Entry<String, String>> allHeadersList, boolean wasCached,
             String negotiatedProtocol, String proxyServer) {
         mResponseInfoUrlChain = Collections.unmodifiableList(urlChain);
@@ -99,7 +112,7 @@
     }
 
     /**
-     * Returns the URL chain. The first entry is the origianlly requested URL;
+     * Returns the URL chain. The first entry is the originally requested URL;
      * the following entries are redirects followed.
      * @return the URL chain.
      */
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
index 6c875e1..40d6642 100644
--- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
@@ -36,8 +36,8 @@
     protected ChromiumUrlRequestContext(
             final Context context, String userAgent, CronetEngine.Builder config) {
         CronetLibraryLoader.ensureInitialized(context, config);
-        mChromiumUrlRequestContextAdapter =
-                nativeCreateRequestContextAdapter(userAgent, getLoggingLevel(), config.toString());
+        mChromiumUrlRequestContextAdapter = nativeCreateRequestContextAdapter(
+                userAgent, getLoggingLevel(), config.toJSONString());
         if (mChromiumUrlRequestContextAdapter == 0) {
             throw new NullPointerException("Context Adapter creation failed");
         }
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
index 84ac0a8..1faf35f 100644
--- a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
@@ -73,7 +73,7 @@
     public CronetUrlRequestContext(CronetEngine.Builder builder) {
         CronetLibraryLoader.ensureInitialized(builder.getContext(), builder);
         nativeSetMinLogLevel(getLoggingLevel());
-        mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(builder.toString());
+        mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(builder.toJSONString());
         if (mUrlRequestContextAdapter == 0) {
             throw new NullPointerException("Context Adapter creation failed.");
         }
diff --git a/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CriteriaHelper.java b/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CriteriaHelper.java
deleted file mode 100644
index c63a459..0000000
--- a/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CriteriaHelper.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2014 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.
-
-package org.chromium.cronet_sample_apk;
-
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
-
-import android.os.SystemClock;
-
-/**
- * Helper methods for creating and managing criteria.
- * <p>
- * If possible, use callbacks or testing delegates instead of criteria as they
- * do not introduce any polling delays. Should only use Criteria if no suitable
- * other approach exists.
- */
-public class CriteriaHelper {
-
-    /** The default maximum time to wait for a criteria to become valid. */
-    public static final long DEFAULT_MAX_TIME_TO_POLL = scaleTimeout(3000);
-
-    /**
-     * The default polling interval to wait between checking for a satisfied
-     * criteria.
-     */
-    public static final long DEFAULT_POLLING_INTERVAL = 50;
-
-    /**
-     * Checks whether the given Criteria is satisfied at a given interval, until
-     * either the criteria is satisfied, or the specified maxTimeoutMs number of
-     * ms has elapsed.
-     *
-     * @param criteria The Criteria that will be checked.
-     * @param maxTimeoutMs The maximum number of ms that this check will be
-     *            performed for before timeout.
-     * @param checkIntervalMs The number of ms between checks.
-     * @return {@code true} iff checking has ended with the criteria being
-     *            satisfied.
-     * @throws InterruptedException
-     */
-    public static boolean pollForCriteria(Criteria criteria, long maxTimeoutMs,
-            long checkIntervalMs) throws InterruptedException {
-        boolean isSatisfied = criteria.isSatisfied();
-        long startTime = SystemClock.uptimeMillis();
-        while (!isSatisfied && SystemClock.uptimeMillis() - startTime < maxTimeoutMs) {
-            Thread.sleep(checkIntervalMs);
-            isSatisfied = criteria.isSatisfied();
-        }
-        return isSatisfied;
-    }
-
-    /**
-     * Checks whether the given Criteria is satisfied polling at a default
-     * interval.
-     *
-     * @param criteria The Criteria that will be checked.
-     * @return iff checking has ended with the criteria being satisfied.
-     * @throws InterruptedException
-     * @see #pollForCriteria(Criteria, long, long)
-     */
-    public static boolean pollForCriteria(Criteria criteria)
-            throws InterruptedException {
-        return pollForCriteria(criteria, DEFAULT_MAX_TIME_TO_POLL,
-                DEFAULT_POLLING_INTERVAL);
-    }
-
-    /**
-     * Performs the runnable action, then checks whether the given criteria are
-     * satisfied until the specified timeout, using the pollForCriteria method.
-     * If not, then the runnable action is performed again, to a maximum of
-     * maxAttempts tries.
-     */
-    public static boolean runUntilCriteria(Runnable runnable, Criteria criteria,
-            int maxAttempts, long maxTimeoutMs, long checkIntervalMs)
-            throws InterruptedException {
-        int count = 0;
-        boolean success = false;
-        while (count < maxAttempts && !success) {
-            count++;
-            runnable.run();
-            success = pollForCriteria(criteria, maxTimeoutMs, checkIntervalMs);
-        }
-        return success;
-    }
-}
diff --git a/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java b/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
index 1c39c75a..a686a57 100644
--- a/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
+++ b/components/cronet/android/sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java
@@ -7,31 +7,21 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.net.Uri;
+import android.os.ConditionVariable;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.text.TextUtils;
-
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.widget.TextView;
 
 import org.chromium.base.test.util.Feature;
 
-import java.util.concurrent.atomic.AtomicBoolean;
-
 /**
  * Base test class for all CronetSample based tests.
  */
 public class CronetSampleTest extends
         ActivityInstrumentationTestCase2<CronetSampleActivity> {
 
-    /**
-     * The maximum time the waitForActiveShellToBeDoneLoading method will wait.
-     */
-    private static final long
-            WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT = scaleTimeout(10000);
-
-    protected static final long
-            WAIT_PAGE_LOADING_TIMEOUT_SECONDS = scaleTimeout(15);
-
     // URL used for base tests.
     private static final String URL = "http://127.0.0.1:8000";
 
@@ -46,9 +36,28 @@
 
         // Make sure the activity was created as expected.
         assertNotNull(activity);
-        // Make sure that the URL is set as expected.
-        assertEquals(URL, activity.getUrl());
-        assertEquals(200, activity.getHttpStatusCode());
+
+        // Verify successful fetch.
+        final TextView textView = (TextView) activity.findViewById(R.id.resultView);
+        final ConditionVariable done = new ConditionVariable();
+        final TextWatcher textWatcher = new TextWatcher() {
+            @Override
+            public void afterTextChanged(Editable s) {}
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                if (s.equals("Completed " + URL + " (200)")) {
+                    done.open();
+                }
+            }
+        };
+        textView.addTextChangedListener(textWatcher);
+        // Check current text in case it changed before |textWatcher| was added.
+        textWatcher.onTextChanged(textView.getText(), 0, 0, 0);
+        done.block();
     }
 
     /**
@@ -63,59 +72,6 @@
                 getInstrumentation().getTargetContext(),
                 CronetSampleActivity.class));
         setActivityIntent(intent);
-        try {
-            waitForActiveShellToBeDoneLoading();
-        } catch (Throwable e) {
-            fail("Active shell has failed to load.");
-        }
         return getActivity();
     }
-
-    /**
-     * Waits for the Active shell to finish loading. This times out after
-     * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds and it shouldn't be
-     * used for long loading pages. Instead it should be used more for test
-     * initialization. The proper way to wait is to use a
-     * TestCallbackHelperContainer after the initial load is completed.
-     *
-     * @return Whether or not the Shell was actually finished loading.
-     * @throws InterruptedException
-     */
-    protected boolean waitForActiveShellToBeDoneLoading()
-            throws InterruptedException {
-        final CronetSampleActivity activity = getActivity();
-
-        // Wait for the Content Shell to be initialized.
-        return CriteriaHelper.pollForCriteria(new Criteria() {
-                @Override
-            public boolean isSatisfied() {
-                try {
-                    final AtomicBoolean isLoaded = new AtomicBoolean(false);
-                    runTestOnUiThread(new Runnable() {
-                            @Override
-                        public void run() {
-                            if (activity != null) {
-                                // There are two cases here that need to be
-                                // accounted for.
-                                // The first is that we've just created a Shell
-                                // and it isn't
-                                // loading because it has no URL set yet. The
-                                // second is that
-                                // we've set a URL and it actually is loading.
-                                isLoaded.set(!activity.isLoading() && !TextUtils
-                                        .isEmpty(activity.getUrl()));
-                            } else {
-                                isLoaded.set(false);
-                            }
-                        }
-                    });
-
-                    return isLoaded.get();
-                } catch (Throwable e) {
-                    return false;
-                }
-            }
-        }, WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT,
-                CriteriaHelper.DEFAULT_POLLING_INTERVAL);
-    }
 }
diff --git a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java
index ea89061..fc2f6a1 100644
--- a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java
+++ b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java
@@ -39,8 +39,6 @@
     private CronetEngine mCronetEngine;
 
     private String mUrl;
-    private boolean mLoading = false;
-    private int mHttpStatusCode = 0;
     private TextView mResultText;
     private TextView mReceiveDataText;
 
@@ -79,16 +77,14 @@
 
         @Override
         public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
-            mHttpStatusCode = info.getHttpStatusCode();
-            Log.i(TAG, "****** Request Completed, status code is " + mHttpStatusCode
+            Log.i(TAG, "****** Request Completed, status code is " + info.getHttpStatusCode()
                             + ", total received bytes is " + info.getReceivedBytesCount());
 
             final String receivedData = mBytesReceived.toString();
             final String url = info.getUrl();
-            final String text = "Completed " + url + " (" + mHttpStatusCode + ")";
+            final String text = "Completed " + url + " (" + info.getHttpStatusCode() + ")";
             CronetSampleActivity.this.runOnUiThread(new Runnable() {
                 public void run() {
-                    mLoading = false;
                     mResultText.setText(text);
                     mReceiveDataText.setText(receivedData);
                     promptForURL(url);
@@ -104,7 +100,6 @@
             final String text = "Failed " + mUrl + " (" + error.getMessage() + ")";
             CronetSampleActivity.this.runOnUiThread(new Runnable() {
                 public void run() {
-                    mLoading = false;
                     mResultText.setText(text);
                     promptForURL(url);
                 }
@@ -208,7 +203,6 @@
     private void startWithURL(String url, String postData) {
         Log.i(TAG, "Cronet started: " + url);
         mUrl = url;
-        mLoading = false;
 
         Executor executor = Executors.newSingleThreadExecutor();
         UrlRequest.Callback callback = new SimpleUrlRequestCallback();
@@ -217,27 +211,6 @@
         builder.build().start();
     }
 
-    /**
-     * This method is used in testing.
-     */
-    public String getUrl() {
-        return mUrl;
-    }
-
-    /**
-     * This method is used in testing.
-     */
-    public boolean isLoading() {
-        return mLoading;
-    }
-
-    /**
-     * This method is used in testing.
-     */
-    public int getHttpStatusCode() {
-        return mHttpStatusCode;
-    }
-
     private void startNetLog() {
         mCronetEngine.startNetLogToFile(
                 Environment.getExternalStorageDirectory().getPath() + "/cronet_sample_netlog.json",
diff --git a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java
index ca1c502..dc19cff 100644
--- a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java
+++ b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java
@@ -10,8 +10,4 @@
  * Application for managing the Cronet Sample.
  */
 public class CronetSampleApplication extends Application {
-    @Override
-    public void onCreate() {
-        super.onCreate();
-    }
 }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CriteriaHelper.java b/components/cronet/android/test/javatests/src/org/chromium/net/CriteriaHelper.java
deleted file mode 100644
index 8a9ac7a7..0000000
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CriteriaHelper.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2014 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.
-
-package org.chromium.net;
-
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
-
-import android.os.SystemClock;
-
-/**
- * Helper methods for creating and managing criteria.
- * <p>
- * If possible, use callbacks or testing delegates instead of criteria as they
- * do not introduce any polling delays. Should only use Criteria if no suitable
- * other approach exists.
- */
-public class CriteriaHelper {
-
-    /** The default maximum time to wait for a criteria to become valid. */
-    public static final long DEFAULT_MAX_TIME_TO_POLL = scaleTimeout(3000);
-
-    /**
-     * The default polling interval to wait between checking for a satisfied
-     * criteria.
-     */
-    public static final long DEFAULT_POLLING_INTERVAL = 50;
-
-    /**
-     * Checks whether the given Criteria is satisfied at a given interval, until
-     * either the criteria is satisfied, or the specified maxTimeoutMs number of
-     * ms has elapsed.
-     *
-     * @param criteria The Criteria that will be checked.
-     * @param maxTimeoutMs The maximum number of ms that this check will be
-     *         performed for before timeout.
-     * @param checkIntervalMs The number of ms between checks.
-     * @return {@code true} if checking has ended with the criteria being
-     *         satisfied.
-     * @throws InterruptedException
-     */
-    public static boolean pollForCriteria(Criteria criteria, long maxTimeoutMs,
-            long checkIntervalMs) throws InterruptedException {
-        boolean isSatisfied = criteria.isSatisfied();
-        long startTime = SystemClock.uptimeMillis();
-        while (!isSatisfied
-               && SystemClock.uptimeMillis() - startTime < maxTimeoutMs) {
-            Thread.sleep(checkIntervalMs);
-            isSatisfied = criteria.isSatisfied();
-        }
-        return isSatisfied;
-    }
-
-    /**
-     * Checks whether the given Criteria is satisfied polling at a default
-     * interval.
-     *
-     * @param criteria The Criteria that will be checked.
-     * @return {@code true} if checking has ended with the criteria being
-     *         satisfied.
-     * @throws InterruptedException
-     * @see #pollForCriteria(Criteria, long, long)
-     */
-    public static boolean pollForCriteria(Criteria criteria)
-            throws InterruptedException {
-        return pollForCriteria(criteria, DEFAULT_MAX_TIME_TO_POLL,
-                DEFAULT_POLLING_INTERVAL);
-    }
-
-    /**
-     * Performs the runnable action, then checks whether the given criteria are
-     * satisfied until the specified timeout, using the pollForCriteria method.
-     * If not, then the runnable action is performed again, to a maximum of
-     * maxAttempts tries.
-     */
-    public static boolean runUntilCriteria(Runnable runnable, Criteria criteria,
-            int maxAttempts, long maxTimeoutMs, long checkIntervalMs)
-            throws InterruptedException {
-        int count = 0;
-        boolean success = false;
-        while (count < maxAttempts && !success) {
-            count++;
-            runnable.run();
-            success = pollForCriteria(criteria, maxTimeoutMs, checkIntervalMs);
-        }
-        return success;
-    }
-}
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
index a7c5856..ed8f586 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
@@ -6,6 +6,8 @@
 
 import android.test.AndroidTestCase;
 
+import org.chromium.base.PathUtils;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -17,13 +19,21 @@
  * Base test class for all CronetTest based tests.
  */
 public class CronetTestBase extends AndroidTestCase {
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "cronet_test";
+
     private CronetTestFramework mCronetTestFramework;
 
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, getContext());
+    }
+
     /**
      * Starts the CronetTest framework.
      */
     protected CronetTestFramework startCronetTestFramework() {
-        return startCronetTestFrameworkWithUrlAndCommandLineArgs(null, null);
+        return startCronetTestFrameworkWithUrlAndCronetEngineBuilder(null, null);
     }
 
     /**
@@ -31,7 +41,17 @@
      * null.
      */
     protected CronetTestFramework startCronetTestFrameworkWithUrl(String url) {
-        return startCronetTestFrameworkWithUrlAndCommandLineArgs(url, null);
+        return startCronetTestFrameworkWithUrlAndCronetEngineBuilder(url, null);
+    }
+
+    /**
+     * Starts the CronetTest framework using the provided CronetEngine.Builder
+     * and loads the given URL. The URL can be null.
+     */
+    protected CronetTestFramework startCronetTestFrameworkWithUrlAndCronetEngineBuilder(
+            String url, CronetEngine.Builder builder) {
+        mCronetTestFramework = new CronetTestFramework(url, null, getContext(), builder);
+        return mCronetTestFramework;
     }
 
     /**
@@ -40,7 +60,7 @@
      */
     protected CronetTestFramework startCronetTestFrameworkWithUrlAndCommandLineArgs(
             String url, String[] commandLineArgs) {
-        mCronetTestFramework = new CronetTestFramework(url, commandLineArgs, getContext());
+        mCronetTestFramework = new CronetTestFramework(url, commandLineArgs, getContext(), null);
         return mCronetTestFramework;
     }
 
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
index 6603afc..9b023ac7f 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -128,9 +128,8 @@
         CronetEngine.Builder cronetEngineBuilder = new CronetEngine.Builder(getContext());
         cronetEngineBuilder.setUserAgent(userAgentValue);
         cronetEngineBuilder.setLibraryName("cronet_tests");
-        String[] commandLineArgs = {CronetTestFramework.CONFIG_KEY, cronetEngineBuilder.toString()};
-        mTestFramework =
-                startCronetTestFrameworkWithUrlAndCommandLineArgs(TEST_URL, commandLineArgs);
+        mTestFramework = startCronetTestFrameworkWithUrlAndCronetEngineBuilder(
+                TEST_URL, cronetEngineBuilder);
         assertTrue(NativeTestServer.startNativeTestServer(getContext()));
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
         UrlRequest.Builder urlRequestBuilder =
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlTest.java
index c9ea5895..86ac30a 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlTest.java
@@ -133,14 +133,12 @@
     @SmallTest
     @Feature({"Cronet"})
     public void testLegacyLoadUrl() throws Exception {
-        HttpUrlRequestFactoryConfig config = new HttpUrlRequestFactoryConfig();
-        config.enableLegacyMode(true);
+        CronetEngine.Builder builder = new CronetEngine.Builder(getContext());
+        builder.enableLegacyMode(true);
         // TODO(mef) fix tests so that library isn't loaded for legacy stack
-        config.setLibraryName("cronet_tests");
 
-        String[] commandLineArgs = {CronetTestFramework.CONFIG_KEY, config.toString()};
         CronetTestFramework testFramework =
-                startCronetTestFrameworkWithUrlAndCommandLineArgs(URL, commandLineArgs);
+                startCronetTestFrameworkWithUrlAndCronetEngineBuilder(URL, builder);
 
         // Make sure that the URL is set as expected.
         assertEquals(URL, testFramework.getUrl());
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/HttpUrlRequestFactoryTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/HttpUrlRequestFactoryTest.java
index d7791be..0e758e70 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/HttpUrlRequestFactoryTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/HttpUrlRequestFactoryTest.java
@@ -24,14 +24,13 @@
     @SmallTest
     @Feature({"Cronet"})
     public void testCreateFactory() throws Throwable {
-        HttpUrlRequestFactoryConfig config = new HttpUrlRequestFactoryConfig();
-        config.enableQUIC(true);
-        config.addQuicHint("www.google.com", 443, 443);
-        config.addQuicHint("www.youtube.com", 443, 443);
-        config.setLibraryName("cronet_tests");
-        String[] commandLineArgs = {CronetTestFramework.CONFIG_KEY, config.toString()};
+        CronetEngine.Builder builder = new CronetEngine.Builder(getContext());
+        builder.enableQUIC(true);
+        builder.addQuicHint("www.google.com", 443, 443);
+        builder.addQuicHint("www.youtube.com", 443, 443);
+        builder.setLibraryName("cronet_tests");
         CronetTestFramework testFramework =
-                startCronetTestFrameworkWithUrlAndCommandLineArgs(URL, commandLineArgs);
+                startCronetTestFrameworkWithUrlAndCronetEngineBuilder(URL, builder);
         HttpUrlRequestFactory factory = testFramework.mRequestFactory;
         assertNotNull("Factory should be created", factory);
         assertTrue("Factory should be Chromium/n.n.n.n@r but is "
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
index 458554b5..f18eb36 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
@@ -38,10 +38,10 @@
                 QuicTestServer.getServerPort());
         builder.setExperimentalQuicConnectionOptions("PACE,IW10,FOO,DEADBEEF");
         builder.setMockCertVerifierForTesting(MockCertVerifier.createMockCertVerifier(CERTS_USED));
+        builder.setStoragePath(CronetTestFramework.getTestStorage(getContext()));
+        builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 1000 * 1024);
 
-        String[] commandLineArgs = {CronetTestFramework.CONFIG_KEY, builder.toString(),
-                CronetTestFramework.CACHE_KEY, CronetTestFramework.CACHE_DISK_NO_HTTP};
-        mTestFramework = startCronetTestFrameworkWithUrlAndCommandLineArgs(null, commandLineArgs);
+        mTestFramework = startCronetTestFrameworkWithUrlAndCronetEngineBuilder(null, builder);
     }
 
     @Override
@@ -124,7 +124,7 @@
 
         // Make another request using a new context but with no QUIC hints.
         CronetEngine.Builder builder = new CronetEngine.Builder(getContext());
-        builder.setStoragePath(mTestFramework.getTestStorage());
+        builder.setStoragePath(CronetTestFramework.getTestStorage(getContext()));
         builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, 1000 * 1024);
         builder.enableQUIC(true);
         builder.setMockCertVerifierForTesting(MockCertVerifier.createMockCertVerifier(CERTS_USED));
@@ -148,7 +148,7 @@
     // Returns whether a file contains a particular string.
     @SuppressFBWarnings("OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE")
     private boolean fileContainsString(String filename, String content) throws IOException {
-        File file = new File(mTestFramework.getTestStorage() + "/" + filename);
+        File file = new File(CronetTestFramework.getTestStorage(getContext()) + "/" + filename);
         FileInputStream fileInputStream = new FileInputStream(file);
         byte[] data = new byte[(int) file.length()];
         fileInputStream.read(data);
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java
index ee6d898..e5517ba 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java
@@ -267,7 +267,7 @@
     // Returns whether a file contains a particular string.
     private boolean fileContainsString(String filename, String content) throws IOException {
         BufferedReader reader = new BufferedReader(
-                new FileReader(mTestFramework.getTestStorage() + "/" + filename));
+                new FileReader(CronetTestFramework.getTestStorage(getContext()) + "/" + filename));
         String line;
         while ((line = reader.readLine()) != null) {
             if (line.contains(content)) {
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/UrlResponseInfoTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/UrlResponseInfoTest.java
new file mode 100644
index 0000000..4615342
--- /dev/null
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/UrlResponseInfoTest.java
@@ -0,0 +1,68 @@
+// Copyright 2015 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.
+
+package org.chromium.net;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.test.util.Feature;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Tests for {@link UrlResponseInfo}.
+ */
+public class UrlResponseInfoTest extends AndroidTestCase {
+    /**
+     * Test for public API of {@link UrlResponseInfo}.
+     */
+    @SmallTest
+    @Feature({"Cronet"})
+    public void testPublicAPI() throws Exception {
+        final List<String> urlChain = new ArrayList<String>();
+        urlChain.add("chromium.org");
+        final int httpStatusCode = 200;
+        final String httpStatusText = "OK";
+        final List<Map.Entry<String, String>> allHeadersList =
+                new ArrayList<Map.Entry<String, String>>();
+        allHeadersList.add(new AbstractMap.SimpleImmutableEntry<String, String>(
+                "Date", "Fri, 30 Oct 2015 14:26:41 GMT"));
+        final boolean wasCached = true;
+        final String negotiatedProtocol = "quic/1+spdy/3";
+        final String proxyServer = "example.com";
+
+        final UrlResponseInfo info = new UrlResponseInfo(urlChain, httpStatusCode, httpStatusText,
+                allHeadersList, wasCached, negotiatedProtocol, proxyServer);
+        assertEquals(info.getUrlChain(), urlChain);
+        try {
+            info.getUrlChain().add("example.com");
+            fail("getUrlChain() returned modifyable list.");
+        } catch (UnsupportedOperationException e) {
+            // Expected.
+        }
+        assertEquals(info.getHttpStatusCode(), httpStatusCode);
+        assertEquals(info.getHttpStatusText(), httpStatusText);
+        assertEquals(info.getAllHeadersAsList(), allHeadersList);
+        try {
+            info.getAllHeadersAsList().add(
+                    new AbstractMap.SimpleImmutableEntry<String, String>("X", "Y"));
+            fail("getAllHeadersAsList() returned modifyable list.");
+        } catch (UnsupportedOperationException e) {
+            // Expected.
+        }
+        assertEquals(info.getAllHeaders().size(), allHeadersList.size());
+        assertEquals(info.getAllHeaders().get(allHeadersList.get(0).getKey()).size(), 1);
+        assertEquals(info.getAllHeaders().get(allHeadersList.get(0).getKey()).get(0),
+                allHeadersList.get(0).getValue());
+        assertEquals(info.wasCached(), wasCached);
+        assertEquals(info.getNegotiatedProtocol(), negotiatedProtocol);
+        assertEquals(info.getProxyServer(), proxyServer);
+    }
+}
\ No newline at end of file
diff --git a/components/cronet/android/test/src/org/chromium/net/CronetTestApplication.java b/components/cronet/android/test/src/org/chromium/net/CronetTestApplication.java
index 4169547..1185ecd6 100644
--- a/components/cronet/android/test/src/org/chromium/net/CronetTestApplication.java
+++ b/components/cronet/android/test/src/org/chromium/net/CronetTestApplication.java
@@ -5,28 +5,9 @@
 package org.chromium.net;
 
 import android.app.Application;
-import android.content.Context;
-import android.util.Log;
-
-import org.chromium.base.PathUtils;
 
 /**
  * Application for managing the Cronet Test.
  */
 public class CronetTestApplication extends Application {
-    private static final String TAG = "CronetTestApplication";
-
-    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "cronet_test";
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        initializeApplicationParameters(this);
-    }
-
-    public static void initializeApplicationParameters(Context context) {
-        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context);
-        Log.i(TAG, "CronetTestApplication.initializeApplicationParameters()"
-                + " success.");
-    }
 }
diff --git a/components/cronet/android/test/src/org/chromium/net/CronetTestFramework.java b/components/cronet/android/test/src/org/chromium/net/CronetTestFramework.java
index 2428a53..b202abae11 100644
--- a/components/cronet/android/test/src/org/chromium/net/CronetTestFramework.java
+++ b/components/cronet/android/test/src/org/chromium/net/CronetTestFramework.java
@@ -10,7 +10,6 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
 
 import org.chromium.base.Log;
 import org.chromium.base.PathUtils;
@@ -33,7 +32,6 @@
 
     public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs";
     public static final String POST_DATA_KEY = "postData";
-    public static final String CONFIG_KEY = "config";
     public static final String CACHE_KEY = "cache";
     public static final String SDCH_KEY = "sdch";
 
@@ -74,7 +72,6 @@
     private final Context mContext;
 
     private String mUrl;
-    private boolean mLoading = false;
     private int mHttpStatusCode = 0;
 
     // CronetEngine.Builder used for this activity.
@@ -93,7 +90,6 @@
 
         @Override
         public void onRequestComplete(HttpUrlRequest request) {
-            mLoading = false;
             mComplete.open();
         }
 
@@ -104,7 +100,8 @@
 
     // TODO(crbug.com/547160): Fix this findbugs error and remove the suppression.
     @SuppressFBWarnings("EI_EXPOSE_REP2")
-    public CronetTestFramework(String appUrl, String[] commandLine, Context context) {
+    public CronetTestFramework(
+            String appUrl, String[] commandLine, Context context, CronetEngine.Builder builder) {
         mCommandLine = commandLine;
         mContext = context;
         prepareTestStorage();
@@ -119,8 +116,7 @@
         }
 
         // Initializes CronetEngine.Builder from commandLine args.
-        mCronetEngineBuilder = initializeCronetEngineBuilder();
-        Log.i(TAG, "Using Config: " + mCronetEngineBuilder.toString());
+        mCronetEngineBuilder = initializeCronetEngineBuilderWithPresuppliedBuilder(builder);
 
         String initString = getCommandLineArg(LIBRARY_INIT_KEY);
         if (LIBRARY_INIT_SKIP.equals(initString)) {
@@ -149,15 +145,15 @@
      * Prepares the path for the test storage (http cache, QUIC server info).
      */
     private void prepareTestStorage() {
-        File storage = new File(getTestStorage());
+        File storage = new File(getTestStorage(mContext));
         if (storage.exists()) {
             assertTrue(recursiveDelete(storage));
         }
         assertTrue(storage.mkdir());
     }
 
-    String getTestStorage() {
-        return PathUtils.getDataDirectory(mContext) + "/test_storage";
+    static String getTestStorage(Context context) {
+        return PathUtils.getDataDirectory(context) + "/test_storage";
     }
 
     @SuppressFBWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
@@ -176,31 +172,28 @@
         return mCronetEngineBuilder;
     }
 
-    private CronetEngine.Builder initializeCronetEngineBuilder() {
-        return createCronetEngineBuilder(mContext);
+    private CronetEngine.Builder initializeCronetEngineBuilderWithPresuppliedBuilder(
+            CronetEngine.Builder builder) {
+        return createCronetEngineBuilderWithPresuppliedBuilder(mContext, builder);
     }
 
     CronetEngine.Builder createCronetEngineBuilder(Context context) {
-        CronetEngine.Builder cronetEngineBuilder = new CronetEngine.Builder(context);
-        cronetEngineBuilder.enableHTTP2(true).enableQUIC(true);
+        return createCronetEngineBuilderWithPresuppliedBuilder(context, null);
+    }
 
-        // Override config if it is passed from the launcher.
-        String configString = getCommandLineArg(CONFIG_KEY);
-        if (configString != null) {
-            try {
-                cronetEngineBuilder = new CronetEngine.Builder(mContext, configString);
-            } catch (org.json.JSONException e) {
-                fail("Invalid Config." + e);
-                return null;
-            }
+    private CronetEngine.Builder createCronetEngineBuilderWithPresuppliedBuilder(
+            Context context, CronetEngine.Builder cronetEngineBuilder) {
+        if (cronetEngineBuilder == null) {
+            cronetEngineBuilder = new CronetEngine.Builder(context);
+            cronetEngineBuilder.enableHTTP2(true).enableQUIC(true);
         }
 
         String cacheString = getCommandLineArg(CACHE_KEY);
         if (CACHE_DISK.equals(cacheString)) {
-            cronetEngineBuilder.setStoragePath(getTestStorage());
+            cronetEngineBuilder.setStoragePath(getTestStorage(context));
             cronetEngineBuilder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, 1000 * 1024);
         } else if (CACHE_DISK_NO_HTTP.equals(cacheString)) {
-            cronetEngineBuilder.setStoragePath(getTestStorage());
+            cronetEngineBuilder.setStoragePath(getTestStorage(context));
             cronetEngineBuilder.enableHttpCache(
                     CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 1000 * 1024);
         } else if (CACHE_IN_MEMORY.equals(cacheString)) {
@@ -255,7 +248,6 @@
     public void startWithURL(String url) {
         Log.i(TAG, "Cronet started: " + url);
         mUrl = url;
-        mLoading = true;
 
         HashMap<String, String> headers = new HashMap<String, String>();
         TestHttpUrlRequestListener listener = new TestHttpUrlRequestListener();
@@ -270,10 +262,6 @@
         return mUrl;
     }
 
-    public boolean isLoading() {
-        return mLoading;
-    }
-
     public int getHttpStatusCode() {
         return mHttpStatusCode;
     }
diff --git a/components/mus/gles2/command_buffer_local.cc b/components/mus/gles2/command_buffer_local.cc
index 4bdad2f..2e0535bb 100644
--- a/components/mus/gles2/command_buffer_local.cc
+++ b/components/mus/gles2/command_buffer_local.cc
@@ -166,7 +166,7 @@
   scoped_ptr<gfx::GpuMemoryBuffer> buffer(MojoGpuMemoryBufferImpl::Create(
       gfx::Size(static_cast<int>(width), static_cast<int>(height)),
       gpu::ImageFactory::DefaultBufferFormatForImageFormat(internalformat),
-      gfx::BufferUsage::GPU_READ_WRITE));
+      gfx::BufferUsage::SCANOUT));
   if (!buffer)
     return -1;
   return CreateImage(buffer->AsClientBuffer(), width, height, internalformat);
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index ddd184f..b282589 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -134,7 +134,7 @@
 #   persistent IDs for all fields (but not for groups!) are needed. These are
 #   specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
 #   because doing so would break the deployed wire format!
-#   For your editing convenience: highest ID currently used: 309
+#   For your editing convenience: highest ID currently used: 310
 #
 # Placeholders:
 #   The following placeholder strings are automatically substituted:
@@ -7757,6 +7757,30 @@
       A setting of "tls1.2" disables all fallback but this may have a significant compatibility impact.''',
     },
     {
+      'name': 'RC4Enabled',
+      'type': 'main',
+      'schema': {
+        'type': 'boolean',
+      },
+      'supported_on': [
+        'chrome.*:48-52',
+        'chrome_os:48-52',
+        'android:48-52',
+        'ios:48-52',
+      ],
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': False,
+      },
+      'example_value': False,
+      'id': 310,
+      'caption': '''Whether RC4 cipher suites in TLS are enabled''',
+      'tags': ['system-security'],
+      'desc': '''Warning: RC4 will be completely removed from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> after version 52 (around September 2016) and this policy will stop working then.
+
+      If the policy is not set, or is set to false, then RC4 cipher suites in TLS will not be enabled. Otherwise it may be set to true to retain compatibility with an outdated server. This is a stopgap measure and the server should be reconfigured.''',
+    },
+    {
       'name': 'ContextualSearchEnabled',
       'type': 'main',
       'schema': { 'type': 'boolean' },
diff --git a/components/scheduler/renderer/renderer_scheduler_impl.cc b/components/scheduler/renderer/renderer_scheduler_impl.cc
index 51015be..24f98749 100644
--- a/components/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/components/scheduler/renderer/renderer_scheduler_impl.cc
@@ -610,11 +610,13 @@
   }
 
   Policy new_policy;
-  bool block_expensive_tasks = false;
+  bool block_expensive_loading_tasks = false;
+  bool block_expensive_timer_tasks = false;
   switch (use_case) {
     case UseCase::COMPOSITOR_GESTURE:
       if (touchstart_expected_soon) {
-        block_expensive_tasks = true;
+        block_expensive_loading_tasks = true;
+        block_expensive_timer_tasks = true;
       } else {
         // What we really want to do is priorize loading tasks, but that doesn't
         // seem to be safe. Instead we do that by proxy by deprioritizing
@@ -625,20 +627,29 @@
       break;
 
     case UseCase::MAIN_THREAD_GESTURE:
+      // In main thread gestures we don't have perfect knowledge about which
+      // things we should be prioritizing. The following is best guess
+      // heuristic which lets us produce frames quickly but does not prevent
+      // loading of additional content.
       new_policy.compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
-      block_expensive_tasks = true;
+      block_expensive_loading_tasks = false;
+      block_expensive_timer_tasks = true;
       break;
 
     case UseCase::TOUCHSTART:
       new_policy.compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
       new_policy.loading_queue_priority = TaskQueue::DISABLED_PRIORITY;
       new_policy.timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
-      block_expensive_tasks = true;  // NOTE this is a nop due to the above.
+      // NOTE these are nops due to the above.
+      block_expensive_loading_tasks = true;
+      block_expensive_timer_tasks = true;
       break;
 
     case UseCase::NONE:
-      if (touchstart_expected_soon)
-        block_expensive_tasks = true;
+      if (touchstart_expected_soon) {
+        block_expensive_loading_tasks = true;
+        block_expensive_timer_tasks = true;
+      }
       break;
 
     case UseCase::LOADING:
@@ -651,17 +662,21 @@
   }
 
   // Don't block expensive tasks unless we have actually seen something.
-  if (!MainThreadOnly().have_seen_a_begin_main_frame)
-    block_expensive_tasks = false;
+  if (!MainThreadOnly().have_seen_a_begin_main_frame) {
+    block_expensive_loading_tasks = false;
+    block_expensive_timer_tasks = false;
+  }
 
   // Don't block expensive tasks if we are expecting a navigation.
-  if (MainThreadOnly().navigation_task_expected_count > 0)
-    block_expensive_tasks = false;
+  if (MainThreadOnly().navigation_task_expected_count > 0) {
+    block_expensive_loading_tasks = false;
+    block_expensive_timer_tasks = false;
+  }
 
-  if (block_expensive_tasks && loading_tasks_seem_expensive)
+  if (block_expensive_loading_tasks && loading_tasks_seem_expensive)
     new_policy.loading_queue_priority = TaskQueue::DISABLED_PRIORITY;
 
-  if ((block_expensive_tasks && timer_tasks_seem_expensive) ||
+  if ((block_expensive_timer_tasks && timer_tasks_seem_expensive) ||
       MainThreadOnly().timer_queue_suspend_count != 0 ||
       MainThreadOnly().timer_queue_suspended_when_backgrounded) {
     new_policy.timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
diff --git a/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc b/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
index 7e339c2..2382399 100644
--- a/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
+++ b/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
@@ -2150,6 +2150,27 @@
   EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
 }
 
+TEST_F(RendererSchedulerImplTest,
+       ExpensiveLoadingTasksNotBlockedDuringMainThreadGestures) {
+  std::vector<std::string> run_order;
+
+  SimulateExpensiveTasks(loading_task_runner_);
+
+  // Loading tasks should not be disabled during main thread user user
+  // interactions.
+  PostTestTasks(&run_order, "C1 L1");
+
+  // Trigger main_thread_gesture UseCase
+  WillBeginMainThreadGestureFrame();
+  RunUntilIdle();
+  EXPECT_EQ(RendererScheduler::UseCase::MAIN_THREAD_GESTURE, CurrentUseCase());
+
+  EXPECT_TRUE(LoadingTasksSeemExpensive());
+  EXPECT_FALSE(TimerTasksSeemExpensive());
+  EXPECT_THAT(run_order,
+              testing::ElementsAre(std::string("C1"), std::string("L1")));
+}
+
 TEST_F(RendererSchedulerImplTest, ModeratelyExpensiveTimer_NotBlocked) {
   scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
   for (int i = 0; i < 20; i++) {
diff --git a/components/ssl_config/ssl_config_prefs.cc b/components/ssl_config/ssl_config_prefs.cc
index ba664d0..ccaf0a1 100644
--- a/components/ssl_config/ssl_config_prefs.cc
+++ b/components/ssl_config/ssl_config_prefs.cc
@@ -15,6 +15,7 @@
 const char kSSLVersionMax[] = "ssl.version_max";
 const char kSSLVersionFallbackMin[] = "ssl.version_fallback_min";
 const char kCipherSuiteBlacklist[] = "ssl.cipher_suites.blacklist";
+const char kRC4Enabled[] = "ssl.rc4_enabled";
 
 }  // namespace prefs
 }  // namespace ssl_config
diff --git a/components/ssl_config/ssl_config_prefs.h b/components/ssl_config/ssl_config_prefs.h
index e1eb115d..c565864d 100644
--- a/components/ssl_config/ssl_config_prefs.h
+++ b/components/ssl_config/ssl_config_prefs.h
@@ -14,6 +14,7 @@
 extern const char kSSLVersionMax[];
 extern const char kSSLVersionFallbackMin[];
 extern const char kCipherSuiteBlacklist[];
+extern const char kRC4Enabled[];
 
 }  // namespace prefs
 }  // namespace ssl_config
diff --git a/components/ssl_config/ssl_config_service_manager_pref.cc b/components/ssl_config/ssl_config_service_manager_pref.cc
index 0f7329f..d9c567f 100644
--- a/components/ssl_config/ssl_config_service_manager_pref.cc
+++ b/components/ssl_config/ssl_config_service_manager_pref.cc
@@ -15,6 +15,8 @@
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/single_thread_task_runner.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
 #include "components/content_settings/core/browser/content_settings_utils.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/ssl_config/ssl_config_prefs.h"
@@ -78,6 +80,12 @@
   return version;
 }
 
+bool IsRC4EnabledByDefault() {
+  const std::string group_name =
+      base::FieldTrialList::FindFullName("RC4Ciphers");
+  return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE);
+}
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -164,6 +172,7 @@
   StringPrefMember ssl_version_min_;
   StringPrefMember ssl_version_max_;
   StringPrefMember ssl_version_fallback_min_;
+  BooleanPrefMember rc4_enabled_;
 
   // The cached list of disabled SSL cipher suites.
   std::vector<uint16> disabled_cipher_suites_;
@@ -182,6 +191,10 @@
       io_task_runner_(io_task_runner) {
   DCHECK(local_state);
 
+  local_state->SetDefaultPrefValue(
+      ssl_config::prefs::kRC4Enabled,
+      new base::FundamentalValue(IsRC4EnabledByDefault()));
+
   PrefChangeRegistrar::NamedChangeCallback local_state_callback =
       base::Bind(&SSLConfigServiceManagerPref::OnPreferenceChanged,
                  base::Unretained(this), local_state);
@@ -197,6 +210,8 @@
                         local_state_callback);
   ssl_version_fallback_min_.Init(ssl_config::prefs::kSSLVersionFallbackMin,
                                  local_state, local_state_callback);
+  rc4_enabled_.Init(ssl_config::prefs::kRC4Enabled, local_state,
+                    local_state_callback);
 
   local_state_change_registrar_.Init(local_state);
   local_state_change_registrar_.Add(ssl_config::prefs::kCipherSuiteBlacklist,
@@ -225,6 +240,8 @@
   registry->RegisterStringPref(ssl_config::prefs::kSSLVersionFallbackMin,
                                std::string());
   registry->RegisterListPref(ssl_config::prefs::kCipherSuiteBlacklist);
+  registry->RegisterBooleanPref(ssl_config::prefs::kRC4Enabled,
+                                default_config.rc4_enabled);
 }
 
 net::SSLConfigService* SSLConfigServiceManagerPref::Get() {
@@ -279,6 +296,7 @@
     config->version_fallback_min = version_fallback_min;
   }
   config->disabled_cipher_suites = disabled_cipher_suites_;
+  config->rc4_enabled = rc4_enabled_.GetValue();
 }
 
 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange(
diff --git a/components/tracing/child_trace_message_filter_browsertest.cc b/components/tracing/child_trace_message_filter_browsertest.cc
index 6dec6a3..a87e976c 100644
--- a/components/tracing/child_trace_message_filter_browsertest.cc
+++ b/components/tracing/child_trace_message_filter_browsertest.cc
@@ -50,7 +50,7 @@
     // registered itself by now; this cannot be prevented easily.
     mock_dump_provider_.reset(new MockDumpProvider());
     MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        mock_dump_provider_.get());
+        mock_dump_provider_.get(), "MockDumpProvider", nullptr);
     MemoryDumpManager::GetInstance()
         ->set_dumper_registrations_ignored_for_testing(true);
 
diff --git a/components/user_manager.gypi b/components/user_manager.gypi
index de4297c..67f090d 100644
--- a/components/user_manager.gypi
+++ b/components/user_manager.gypi
@@ -8,7 +8,6 @@
     'user_manager_shared_sources': [
       'user_manager/empty_user_info.cc',
       'user_manager/empty_user_info.h',
-      'user_manager/user_id.h',
       'user_manager/user_info.cc',
       'user_manager/user_info.h',
       'user_manager/user_info_impl.cc',
@@ -36,6 +35,7 @@
     'type': '<(component)',
     'dependencies': [
       '<(DEPTH)/base/base.gyp:base',
+      '<(DEPTH)/components/components.gyp:signin_core_account_id',
       '<(DEPTH)/skia/skia.gyp:skia',
       '<(DEPTH)/ui/gfx/gfx.gyp:gfx',
     ],
diff --git a/components/user_manager/BUILD.gn b/components/user_manager/BUILD.gn
index 0dfc852..55ab2a2 100644
--- a/components/user_manager/BUILD.gn
+++ b/components/user_manager/BUILD.gn
@@ -6,7 +6,6 @@
   sources = [
     "empty_user_info.cc",
     "empty_user_info.h",
-    "user_id.h",
     "user_info.cc",
     "user_info.h",
     "user_info_impl.cc",
@@ -16,6 +15,7 @@
 
   deps = [
     "//base",
+    "//components/signin/core/account_id",
     "//skia",
     "//ui/gfx",
   ]
@@ -60,6 +60,7 @@
     deps = [
       ":user_manager",
       "//base",
+      "//components/signin/core/account_id",
       "//skia",
       "//ui/base",
     ]
diff --git a/components/user_manager/DEPS b/components/user_manager/DEPS
index c21fe3c..5c77f80 100644
--- a/components/user_manager/DEPS
+++ b/components/user_manager/DEPS
@@ -4,6 +4,7 @@
 "+chromeos/login/login_state.h",
 "+chromeos/login/user_names.h",
 "+components/session_manager/core/session_manager.h",
+"+components/signin/core/account_id/account_id.h",
 "+google_apis/gaia/gaia_auth_util.h",
 "+third_party/skia/include",
 "+ui/base/l10n",
diff --git a/components/user_manager/empty_user_info.cc b/components/user_manager/empty_user_info.cc
index ab886f1..08d4a19f 100644
--- a/components/user_manager/empty_user_info.cc
+++ b/components/user_manager/empty_user_info.cc
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/signin/core/account_id/account_id.h"
 
 namespace user_manager {
 
@@ -30,9 +31,9 @@
   return std::string();
 }
 
-std::string EmptyUserInfo::GetUserID() const {
+AccountId EmptyUserInfo::GetAccountId() const {
   NOTIMPLEMENTED();
-  return std::string();
+  return EmptyAccountId();
 }
 
 const gfx::ImageSkia& EmptyUserInfo::GetImage() const {
diff --git a/components/user_manager/empty_user_info.h b/components/user_manager/empty_user_info.h
index 52d677c..76c0d16 100644
--- a/components/user_manager/empty_user_info.h
+++ b/components/user_manager/empty_user_info.h
@@ -25,7 +25,7 @@
   base::string16 GetDisplayName() const override;
   base::string16 GetGivenName() const override;
   std::string GetEmail() const override;
-  std::string GetUserID() const override;
+  AccountId GetAccountId() const override;
   const gfx::ImageSkia& GetImage() const override;
 
  private:
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc
index 39f63f1..4caa1b3 100644
--- a/components/user_manager/fake_user_manager.cc
+++ b/components/user_manager/fake_user_manager.cc
@@ -31,28 +31,30 @@
 
 FakeUserManager::FakeUserManager()
     : UserManagerBase(new FakeTaskRunner(), new FakeTaskRunner()),
-      primary_user_(NULL),
-      owner_email_(std::string()) {
-}
+      primary_user_(nullptr) {}
 
 FakeUserManager::~FakeUserManager() {
 }
 
-const user_manager::User* FakeUserManager::AddUser(const std::string& email) {
-  return AddUserWithAffiliation(email, false);
+const user_manager::User* FakeUserManager::AddUser(
+    const AccountId& account_id) {
+  return AddUserWithAffiliation(account_id, false);
 }
 
 const user_manager::User* FakeUserManager::AddUserWithAffiliation(
-    const std::string& email, bool is_affiliated) {
-  user_manager::User* user = user_manager::User::CreateRegularUser(email);
+    const AccountId& account_id,
+    bool is_affiliated) {
+  user_manager::User* user = user_manager::User::CreateRegularUser(account_id);
   user->set_affiliation(is_affiliated);
   users_.push_back(user);
   return user;
 }
 
-void FakeUserManager::RemoveUserFromList(const std::string& email) {
+void FakeUserManager::RemoveUserFromList(const AccountId& account_id) {
   user_manager::UserList::iterator it = users_.begin();
-  while (it != users_.end() && (*it)->email() != email)
+  // TODO (alemate): Chenge this to GetAccountId(), once a real AccountId is
+  // passed. crbug.com/546876
+  while (it != users_.end() && (*it)->GetEmail() != account_id.GetUserEmail())
     ++it;
   if (it != users_.end()) {
     delete *it;
@@ -79,7 +81,7 @@
   return logged_in_users_;
 }
 
-void FakeUserManager::UserLoggedIn(const std::string& email,
+void FakeUserManager::UserLoggedIn(const AccountId& account_id,
                                    const std::string& username_hash,
                                    bool browser_restart) {
   for (user_manager::UserList::const_iterator it = users_.begin();
@@ -97,17 +99,20 @@
 }
 
 user_manager::User* FakeUserManager::GetActiveUserInternal() const {
-  if (users_.size()) {
-    if (!active_user_id_.empty()) {
+  if (!users_.empty()) {
+    if (active_account_id_.is_valid()) {
       for (user_manager::UserList::const_iterator it = users_.begin();
            it != users_.end(); ++it) {
-        if ((*it)->email() == active_user_id_)
+        // TODO (alemate): Chenge this to GetAccountId(), once a real AccountId
+        // is
+        // passed. crbug.com/546876
+        if ((*it)->GetEmail() == active_account_id_.GetUserEmail())
           return *it;
       }
     }
     return users_[0];
   }
-  return NULL;
+  return nullptr;
 }
 
 const user_manager::User* FakeUserManager::GetActiveUser() const {
@@ -118,14 +123,15 @@
   return GetActiveUserInternal();
 }
 
-void FakeUserManager::SwitchActiveUser(const std::string& email) {
-}
+void FakeUserManager::SwitchActiveUser(const AccountId& account_id) {}
 
-void FakeUserManager::SaveUserDisplayName(const std::string& username,
+void FakeUserManager::SaveUserDisplayName(const AccountId& account_id,
                                           const base::string16& display_name) {
   for (user_manager::UserList::iterator it = users_.begin(); it != users_.end();
        ++it) {
-    if ((*it)->email() == username) {
+    // TODO (alemate): Chenge this to GetAccountId(), once a real AccountId is
+    // passed. crbug.com/546876
+    if ((*it)->GetEmail() == account_id.GetUserEmail()) {
       (*it)->set_display_name(display_name);
       return;
     }
@@ -140,36 +146,38 @@
   return users_;
 }
 
-const std::string& FakeUserManager::GetOwnerEmail() const {
-  return owner_email_;
+const AccountId& FakeUserManager::GetOwnerAccountId() const {
+  return owner_account_id_;
 }
 
-bool FakeUserManager::IsKnownUser(const std::string& email) const {
+bool FakeUserManager::IsKnownUser(const AccountId& account_id) const {
   return true;
 }
 
 const user_manager::User* FakeUserManager::FindUser(
-    const std::string& email) const {
+    const AccountId& account_id) const {
   const user_manager::UserList& users = GetUsers();
   for (user_manager::UserList::const_iterator it = users.begin();
        it != users.end(); ++it) {
-    if ((*it)->email() == email)
+    // TODO (alemate): Chenge this to GetAccountId(), once a real AccountId is
+    // passed. crbug.com/546876
+    if ((*it)->GetEmail() == account_id.GetUserEmail())
       return *it;
   }
-  return NULL;
+  return nullptr;
 }
 
 user_manager::User* FakeUserManager::FindUserAndModify(
-    const std::string& email) {
-  return NULL;
+    const AccountId& account_id) {
+  return nullptr;
 }
 
 const user_manager::User* FakeUserManager::GetLoggedInUser() const {
-  return NULL;
+  return nullptr;
 }
 
 user_manager::User* FakeUserManager::GetLoggedInUser() {
-  return NULL;
+  return nullptr;
 }
 
 const user_manager::User* FakeUserManager::GetPrimaryUser() const {
@@ -177,12 +185,12 @@
 }
 
 base::string16 FakeUserManager::GetUserDisplayName(
-    const std::string& username) const {
+    const AccountId& account_id) const {
   return base::string16();
 }
 
 std::string FakeUserManager::GetUserDisplayEmail(
-    const std::string& username) const {
+    const AccountId& account_id) const {
   return std::string();
 }
 
@@ -238,7 +246,7 @@
 }
 
 bool FakeUserManager::IsUserNonCryptohomeDataEphemeral(
-    const std::string& email) const {
+    const AccountId& account_id) const {
   return false;
 }
 
@@ -256,23 +264,23 @@
 }
 
 PrefService* FakeUserManager::GetLocalState() const {
-  return NULL;
+  return nullptr;
 }
 
 bool FakeUserManager::IsEnterpriseManaged() const {
   return false;
 }
 
-bool FakeUserManager::IsDemoApp(const std::string& user_id) const {
+bool FakeUserManager::IsDemoApp(const AccountId& account_id) const {
   return false;
 }
 
-bool FakeUserManager::IsKioskApp(const std::string& user_id) const {
+bool FakeUserManager::IsKioskApp(const AccountId& account_id) const {
   return false;
 }
 
 bool FakeUserManager::IsPublicAccountMarkedForRemoval(
-    const std::string& user_id) const {
+    const AccountId& account_id) const {
   return false;
 }
 
diff --git a/components/user_manager/fake_user_manager.h b/components/user_manager/fake_user_manager.h
index a40eed6e..77f1649 100644
--- a/components/user_manager/fake_user_manager.h
+++ b/components/user_manager/fake_user_manager.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/memory/scoped_ptr.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager_base.h"
 
@@ -23,15 +24,16 @@
 
   // Create and add a new user. Created user is not affiliated with the domain,
   // that owns the device.
-  virtual const user_manager::User* AddUser(const std::string& email);
+  virtual const user_manager::User* AddUser(const AccountId& account_id);
 
   // The same as AddUser() but allows to specify user affiliation with the
   // domain, that owns the device.
   virtual const user_manager::User* AddUserWithAffiliation(
-      const std::string& email, bool is_affiliated);
+      const AccountId& account_id,
+      bool is_affiliated);
 
   // Calculates the user name hash and calls UserLoggedIn to login a user.
-  void LoginUser(const std::string& email);
+  void LoginUser(const AccountId& account_id);
 
   // UserManager overrides.
   const user_manager::UserList& GetUsers() const override;
@@ -39,42 +41,43 @@
   const user_manager::UserList& GetLoggedInUsers() const override;
 
   // Set the user as logged in.
-  void UserLoggedIn(const std::string& email,
+  void UserLoggedIn(const AccountId& account_id,
                     const std::string& username_hash,
                     bool browser_restart) override;
 
   const user_manager::User* GetActiveUser() const override;
   user_manager::User* GetActiveUser() override;
-  void SwitchActiveUser(const std::string& email) override;
-  void SaveUserDisplayName(const std::string& username,
+  void SwitchActiveUser(const AccountId& account_id) override;
+  void SaveUserDisplayName(const AccountId& account_id,
                            const base::string16& display_name) override;
 
   // Not implemented.
-  void UpdateUserAccountData(const std::string& user_id,
+  void UpdateUserAccountData(const AccountId& account_id,
                              const UserAccountData& account_data) override {}
   void Shutdown() override {}
   const user_manager::UserList& GetLRULoggedInUsers() const override;
   user_manager::UserList GetUnlockUsers() const override;
-  const std::string& GetOwnerEmail() const override;
+  const AccountId& GetOwnerAccountId() const override;
   void SessionStarted() override {}
-  void RemoveUser(const std::string& email,
+  void RemoveUser(const AccountId& account_id,
                   user_manager::RemoveUserDelegate* delegate) override {}
-  void RemoveUserFromList(const std::string& email) override;
-  bool IsKnownUser(const std::string& email) const override;
-  const user_manager::User* FindUser(const std::string& email) const override;
-  user_manager::User* FindUserAndModify(const std::string& email) override;
+  void RemoveUserFromList(const AccountId& account_id) override;
+  bool IsKnownUser(const AccountId& account_id) const override;
+  const user_manager::User* FindUser(
+      const AccountId& account_id) const override;
+  user_manager::User* FindUserAndModify(const AccountId& account_id) override;
   const user_manager::User* GetLoggedInUser() const override;
   user_manager::User* GetLoggedInUser() override;
   const user_manager::User* GetPrimaryUser() const override;
   void SaveUserOAuthStatus(
-      const std::string& username,
+      const AccountId& account_id,
       user_manager::User::OAuthTokenStatus oauth_token_status) override {}
-  void SaveForceOnlineSignin(const std::string& user_id,
+  void SaveForceOnlineSignin(const AccountId& account_id,
                              bool force_online_signin) override {}
-  base::string16 GetUserDisplayName(const std::string& username) const override;
-  void SaveUserDisplayEmail(const std::string& username,
+  base::string16 GetUserDisplayName(const AccountId& account_id) const override;
+  void SaveUserDisplayEmail(const AccountId& account_id,
                             const std::string& display_email) override {}
-  std::string GetUserDisplayEmail(const std::string& username) const override;
+  std::string GetUserDisplayEmail(const AccountId& account_id) const override;
   bool IsCurrentUserOwner() const override;
   bool IsCurrentUserNew() const override;
   bool IsCurrentUserNonCryptohomeDataEphemeral() const override;
@@ -88,7 +91,7 @@
   bool IsLoggedInAsStub() const override;
   bool IsSessionStarted() const override;
   bool IsUserNonCryptohomeDataEphemeral(
-      const std::string& email) const override;
+      const AccountId& account_id) const override;
   void AddObserver(Observer* obs) override {}
   void RemoveObserver(Observer* obs) override {}
   void AddSessionStateObserver(UserSessionStateObserver* obs) override {}
@@ -101,37 +104,36 @@
   const std::string& GetApplicationLocale() const override;
   PrefService* GetLocalState() const override;
   void HandleUserOAuthTokenStatusChange(
-      const std::string& user_id,
+      const AccountId& account_id,
       user_manager::User::OAuthTokenStatus status) const override {}
   bool IsEnterpriseManaged() const override;
-  void LoadPublicAccounts(std::set<std::string>* public_sessions_set) override {
-  }
+  void LoadPublicAccounts(std::set<AccountId>* public_sessions_set) override {}
   void PerformPreUserListLoadingActions() override {}
   void PerformPostUserListLoadingActions() override {}
   void PerformPostUserLoggedInActions(bool browser_restart) override {}
-  bool IsDemoApp(const std::string& user_id) const override;
-  bool IsKioskApp(const std::string& user_id) const override;
+  bool IsDemoApp(const AccountId& account_id) const override;
+  bool IsKioskApp(const AccountId& account_id) const override;
   bool IsPublicAccountMarkedForRemoval(
-      const std::string& user_id) const override;
+      const AccountId& account_id) const override;
   void DemoAccountLoggedIn() override {}
-  void KioskAppLoggedIn(const std::string& app_id) override {}
+  void KioskAppLoggedIn(const AccountId& kiosk_app_account_id) override {}
   void PublicAccountUserLoggedIn(user_manager::User* user) override {}
-  void SupervisedUserLoggedIn(const std::string& user_id) override {}
-  void OnUserRemoved(const std::string& user_id) override {}
+  void SupervisedUserLoggedIn(const AccountId& account_id) override {}
+  void OnUserRemoved(const AccountId& account_id) override {}
 
  protected:
   user_manager::User* primary_user_;
 
   // If set this is the active user. If empty, the first created user is the
   // active user.
-  std::string active_user_id_;
+  AccountId active_account_id_ = EmptyAccountId();
 
  private:
   // We use this internal function for const-correctness.
   user_manager::User* GetActiveUserInternal() const;
 
-  // stub, always empty string.
-  std::string owner_email_;
+  // stub, always empty.
+  AccountId owner_account_id_ = EmptyAccountId();
 
   DISALLOW_COPY_AND_ASSIGN(FakeUserManager);
 };
diff --git a/components/user_manager/user.cc b/components/user_manager/user.cc
index defc1173..39ef430d5 100644
--- a/components/user_manager/user.cc
+++ b/components/user_manager/user.cc
@@ -9,6 +9,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
 #include "chromeos/login/user_names.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_image/default_user_images.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -34,10 +35,14 @@
          user_type == USER_TYPE_CHILD;
 }
 
+const std::string& User::email() const {
+  return account_id_.GetUserEmail();
+}
+
 // Also used for regular supervised users.
 class RegularUser : public User {
  public:
-  explicit RegularUser(const std::string& email);
+  explicit RegularUser(const AccountId& account_id);
   ~RegularUser() override;
 
   // Overridden from User:
@@ -46,7 +51,7 @@
   void SetIsChild(bool is_child) override;
 
  private:
-  bool is_child_;
+  bool is_child_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(RegularUser);
 };
@@ -65,7 +70,7 @@
 
 class KioskAppUser : public User {
  public:
-  explicit KioskAppUser(const std::string& app_id);
+  explicit KioskAppUser(const AccountId& kiosk_app_account_id);
   ~KioskAppUser() override;
 
   // Overridden from User:
@@ -77,7 +82,7 @@
 
 class SupervisedUser : public User {
  public:
-  explicit SupervisedUser(const std::string& username);
+  explicit SupervisedUser(const AccountId& account_id);
   ~SupervisedUser() override;
 
   // Overridden from User:
@@ -90,7 +95,7 @@
 
 class PublicAccountUser : public User {
  public:
-  explicit PublicAccountUser(const std::string& email);
+  explicit PublicAccountUser(const AccountId& account_id);
   ~PublicAccountUser() override;
 
   // Overridden from User:
@@ -118,8 +123,9 @@
   return user_image_.image();
 }
 
-UserID User::GetUserID() const {
-  return gaia::CanonicalizeEmail(gaia::SanitizeEmail(email()));
+AccountId User::GetAccountId() const {
+  return AccountId::FromUserEmail(
+      gaia::CanonicalizeEmail(gaia::SanitizeEmail(email())));
 }
 
 void User::SetIsChild(bool is_child) {
@@ -144,7 +150,7 @@
   if (use_display_email && !display_email_.empty())
     return GetUserName(display_email_);
   else
-    return GetUserName(email_);
+    return GetUserName(account_id_.GetUserEmail());
 }
 
 bool User::HasDefaultImage() const {
@@ -175,39 +181,27 @@
   return is_active_;
 }
 
-User* User::CreateRegularUser(const std::string& email) {
-  return new RegularUser(email);
+User* User::CreateRegularUser(const AccountId& account_id) {
+  return new RegularUser(account_id);
 }
 
 User* User::CreateGuestUser() {
   return new GuestUser;
 }
 
-User* User::CreateKioskAppUser(const std::string& kiosk_app_username) {
-  return new KioskAppUser(kiosk_app_username);
+User* User::CreateKioskAppUser(const AccountId& kiosk_app_account_id) {
+  return new KioskAppUser(kiosk_app_account_id);
 }
 
-User* User::CreateSupervisedUser(const std::string& username) {
-  return new SupervisedUser(username);
+User* User::CreateSupervisedUser(const AccountId& account_id) {
+  return new SupervisedUser(account_id);
 }
 
-User* User::CreatePublicAccountUser(const std::string& email) {
-  return new PublicAccountUser(email);
+User* User::CreatePublicAccountUser(const AccountId& account_id) {
+  return new PublicAccountUser(account_id);
 }
 
-User::User(const std::string& email)
-    : email_(email),
-      oauth_token_status_(OAUTH_TOKEN_STATUS_UNKNOWN),
-      force_online_signin_(false),
-      image_index_(USER_IMAGE_INVALID),
-      image_is_stub_(false),
-      image_is_loading_(false),
-      can_lock_(false),
-      is_logged_in_(false),
-      is_active_(false),
-      profile_is_created_(false),
-      is_affiliated_(false){
-}
+User::User(const AccountId& account_id) : account_id_(account_id) {}
 
 User::~User() {
 }
@@ -237,10 +231,9 @@
   image_is_loading_ = is_loading;
 }
 
-RegularUser::RegularUser(const std::string& email)
-    : User(email), is_child_(false) {
+RegularUser::RegularUser(const AccountId& account_id) : User(account_id) {
   set_can_lock(true);
-  set_display_email(email);
+  set_display_email(account_id.GetUserEmail());
 }
 
 RegularUser::~RegularUser() {
@@ -260,7 +253,7 @@
   is_child_ = is_child;
 }
 
-GuestUser::GuestUser() : User(chromeos::login::kGuestUserName) {
+GuestUser::GuestUser() : User(chromeos::login::GuestAccountId()) {
   set_display_email(std::string());
 }
 
@@ -271,9 +264,9 @@
   return user_manager::USER_TYPE_GUEST;
 }
 
-KioskAppUser::KioskAppUser(const std::string& kiosk_app_username)
-    : User(kiosk_app_username) {
-  set_display_email(kiosk_app_username);
+KioskAppUser::KioskAppUser(const AccountId& kiosk_app_account_id)
+    : User(kiosk_app_account_id) {
+  set_display_email(kiosk_app_account_id.GetUserEmail());
 }
 
 KioskAppUser::~KioskAppUser() {
@@ -283,7 +276,7 @@
   return user_manager::USER_TYPE_KIOSK_APP;
 }
 
-SupervisedUser::SupervisedUser(const std::string& username) : User(username) {
+SupervisedUser::SupervisedUser(const AccountId& account_id) : User(account_id) {
   set_can_lock(true);
 }
 
@@ -298,8 +291,8 @@
   return base::UTF16ToUTF8(display_name());
 }
 
-PublicAccountUser::PublicAccountUser(const std::string& email) : User(email) {
-}
+PublicAccountUser::PublicAccountUser(const AccountId& account_id)
+    : User(account_id) {}
 
 PublicAccountUser::~PublicAccountUser() {
 }
diff --git a/components/user_manager/user.h b/components/user_manager/user.h
index d961acf..fe0899ef1 100644
--- a/components/user_manager/user.h
+++ b/components/user_manager/user.h
@@ -10,7 +10,7 @@
 
 #include "base/basictypes.h"
 #include "base/strings/string16.h"
-#include "components/user_manager/user_id.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user_image/user_image.h"
 #include "components/user_manager/user_info.h"
 #include "components/user_manager/user_manager_export.h"
@@ -83,7 +83,8 @@
   virtual UserType GetType() const = 0;
 
   // The email the user used to log in.
-  const std::string& email() const { return email_; }
+  // TODO(alemate): rename this to GetUserEmail() (see crbug.com/548923)
+  const std::string& email() const;
 
   // The displayed user name.
   base::string16 display_name() const { return display_name_; }
@@ -96,7 +97,7 @@
   base::string16 GetDisplayName() const override;
   base::string16 GetGivenName() const override;
   const gfx::ImageSkia& GetImage() const override;
-  UserID GetUserID() const override;
+  AccountId GetAccountId() const override;
 
   // Allows managing child status of the user. Used for RegularUser.
   virtual void SetIsChild(bool is_child);
@@ -182,13 +183,13 @@
   friend class chromeos::UserAddingScreenTest;
 
   // Do not allow anyone else to create new User instances.
-  static User* CreateRegularUser(const UserID& email);
+  static User* CreateRegularUser(const AccountId& account_id);
   static User* CreateGuestUser();
-  static User* CreateKioskAppUser(const UserID& kiosk_app_username);
-  static User* CreateSupervisedUser(const UserID& username);
-  static User* CreatePublicAccountUser(const UserID& email);
+  static User* CreateKioskAppUser(const AccountId& kiosk_app_account_id);
+  static User* CreateSupervisedUser(const AccountId& account_id);
+  static User* CreatePublicAccountUser(const AccountId& account_id);
 
-  explicit User(const std::string& email);
+  explicit User(const AccountId& account_id);
   ~User() override;
 
   const std::string* GetAccountLocale() const { return account_locale_.get(); }
@@ -251,15 +252,15 @@
   }
 
  private:
-  std::string email_;
+  AccountId account_id_;
   base::string16 display_name_;
   base::string16 given_name_;
   // The displayed user email, defaults to |email_|.
   std::string display_email_;
-  bool using_saml_;
+  bool using_saml_ = false;
   UserImage user_image_;
-  OAuthTokenStatus oauth_token_status_;
-  bool force_online_signin_;
+  OAuthTokenStatus oauth_token_status_ = OAUTH_TOKEN_STATUS_UNKNOWN;
+  bool force_online_signin_ = false;
 
   // This is set to chromeos locale if account data has been downloaded.
   // (Or failed to download, but at least one download attempt finished).
@@ -272,34 +273,34 @@
 
   // Either index of a default image for the user, |USER_IMAGE_EXTERNAL| or
   // |USER_IMAGE_PROFILE|.
-  int image_index_;
+  int image_index_ = USER_IMAGE_INVALID;
 
   // True if current user image is a stub set by a |SetStubImage| call.
-  bool image_is_stub_;
+  bool image_is_stub_ = false;
 
   // True if current user image is being loaded from file.
-  bool image_is_loading_;
+  bool image_is_loading_ = false;
 
   // True if user is able to lock screen.
-  bool can_lock_;
+  bool can_lock_ = false;
 
   // True if user is currently logged in in current session.
-  bool is_logged_in_;
+  bool is_logged_in_ = false;
 
   // True if user is currently logged in and active in current session.
-  bool is_active_;
+  bool is_active_ = false;
 
   // True if user Profile is created
-  bool profile_is_created_;
+  bool profile_is_created_ = false;
 
   // True if the user is affiliated to the device.
-  bool is_affiliated_;
+  bool is_affiliated_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(User);
 };
 
 // List of known users.
-typedef std::vector<User*> UserList;
+using UserList = std::vector<User*>;
 
 }  // namespace user_manager
 
diff --git a/components/user_manager/user_id.h b/components/user_manager/user_id.h
deleted file mode 100644
index bf8730a..0000000
--- a/components/user_manager/user_id.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 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 COMPONENTS_USER_MANAGER_USER_ID_H_
-#define COMPONENTS_USER_MANAGER_USER_ID_H_
-
-#include <string>
-
-namespace user_manager {
-
-// Type that contains enough information to identify user on ChromeOS.
-typedef std::string UserID;
-
-}  // namespace user_manager
-
-#endif  // COMPONENTS_USER_MANAGER_USER_ID_H_
diff --git a/components/user_manager/user_info.h b/components/user_manager/user_info.h
index cc613c1..2f0cf19 100644
--- a/components/user_manager/user_info.h
+++ b/components/user_manager/user_info.h
@@ -8,9 +8,10 @@
 #include <string>
 
 #include "base/strings/string16.h"
-#include "components/user_manager/user_id.h"
 #include "components/user_manager/user_manager_export.h"
 
+class AccountId;
+
 namespace gfx {
 class ImageSkia;
 }
@@ -34,9 +35,8 @@
   // as well as capitalized letters. For example: "Foo.Bar@mock.com".
   virtual std::string GetEmail() const = 0;
 
-  // Gets the user id (sanitized email address) for the user.
-  // The function would return something like "foobar@mock.com".
-  virtual UserID GetUserID() const = 0;
+  // Returns AccountId for the user.
+  virtual AccountId GetAccountId() const = 0;
 
   // Gets the avatar image for the user.
   virtual const gfx::ImageSkia& GetImage() const = 0;
diff --git a/components/user_manager/user_info_impl.cc b/components/user_manager/user_info_impl.cc
index 6aa21a8..cf6d2ad3 100644
--- a/components/user_manager/user_info_impl.cc
+++ b/components/user_manager/user_info_impl.cc
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/signin/core/account_id/account_id.h"
 
 namespace user_manager {
 
@@ -27,8 +28,8 @@
   return "stub-user@domain.com";
 }
 
-std::string UserInfoImpl::GetUserID() const {
-  return GetEmail();
+AccountId UserInfoImpl::GetAccountId() const {
+  return AccountId::FromUserEmail(GetEmail());
 }
 
 const gfx::ImageSkia& UserInfoImpl::GetImage() const {
diff --git a/components/user_manager/user_info_impl.h b/components/user_manager/user_info_impl.h
index d23ca0c..4922e36 100644
--- a/components/user_manager/user_info_impl.h
+++ b/components/user_manager/user_info_impl.h
@@ -24,7 +24,7 @@
   base::string16 GetDisplayName() const override;
   base::string16 GetGivenName() const override;
   std::string GetEmail() const override;
-  std::string GetUserID() const override;
+  AccountId GetAccountId() const override;
   const gfx::ImageSkia& GetImage() const override;
 
  private:
diff --git a/components/user_manager/user_manager.h b/components/user_manager/user_manager.h
index 24b8c9a..03a08d75 100644
--- a/components/user_manager/user_manager.h
+++ b/components/user_manager/user_manager.h
@@ -8,10 +8,11 @@
 #include <string>
 
 #include "components/user_manager/user.h"
-#include "components/user_manager/user_id.h"
 #include "components/user_manager/user_manager_export.h"
 #include "components/user_manager/user_type.h"
 
+class AccountId;
+
 namespace base {
 class DictionaryValue;
 }
@@ -54,7 +55,7 @@
     virtual void UserAddedToSession(const User* added_user);
 
     // Called right before notifying on user change so that those who rely
-    // on user_id hash would be accessing up-to-date value.
+    // on account_id hash would be accessing up-to-date value.
     virtual void ActiveUserHashChanged(const std::string& hash);
 
     // Called when child status has changed.
@@ -138,21 +139,22 @@
   // All users that are unable to perform unlock are excluded from this list.
   virtual UserList GetUnlockUsers() const = 0;
 
-  // Returns the email of the owner user. Returns an empty string if there is
+  // Returns account Id of the owner user. Returns an empty Id if there is
   // no owner for the device.
-  virtual const std::string& GetOwnerEmail() const = 0;
+  virtual const AccountId& GetOwnerAccountId() const = 0;
 
-  // Indicates that a user with the given |user_id| has just logged in. The
+  // Indicates that a user with the given |account_id| has just logged in. The
   // persistent list is updated accordingly if the user is not ephemeral.
   // |browser_restart| is true when reloading Chrome after crash to distinguish
   // from normal sign in flow.
   // |username_hash| is used to identify homedir mount point.
-  virtual void UserLoggedIn(const std::string& user_id,
+  virtual void UserLoggedIn(const AccountId& account_id,
                             const std::string& username_hash,
                             bool browser_restart) = 0;
 
-  // Switches to active user identified by |user_id|. User has to be logged in.
-  virtual void SwitchActiveUser(const std::string& user_id) = 0;
+  // Switches to active user identified by |account_id|. User has to be logged
+  // in.
+  virtual void SwitchActiveUser(const AccountId& account_id) = 0;
 
   // Switches to the last active user (called after crash happens and session
   // restore has completed).
@@ -170,25 +172,25 @@
   // Removes the user from the device. Note, it will verify that the given user
   // isn't the owner, so calling this method for the owner will take no effect.
   // Note, |delegate| can be NULL.
-  virtual void RemoveUser(const std::string& user_id,
+  virtual void RemoveUser(const AccountId& account_id,
                           RemoveUserDelegate* delegate) = 0;
 
   // Removes the user from the persistent list only. Also removes the user's
   // picture.
-  virtual void RemoveUserFromList(const std::string& user_id) = 0;
+  virtual void RemoveUserFromList(const AccountId& account_id) = 0;
 
-  // Returns true if a user with the given user id is found in the persistent
+  // Returns true if a user with the given account id is found in the persistent
   // list or currently logged in as ephemeral.
-  virtual bool IsKnownUser(const std::string& user_id) const = 0;
+  virtual bool IsKnownUser(const AccountId& account_id) const = 0;
 
-  // Returns the user with the given user id if found in the persistent
+  // Returns the user with the given account id if found in the persistent
   // list or currently logged in as ephemeral. Returns |NULL| otherwise.
-  virtual const User* FindUser(const std::string& user_id) const = 0;
+  virtual const User* FindUser(const AccountId& account_id) const = 0;
 
-  // Returns the user with the given user id if found in the persistent
+  // Returns the user with the given account id if found in the persistent
   // list or currently logged in as ephemeral. Returns |NULL| otherwise.
   // Same as FindUser but returns non-const pointer to User object.
-  virtual User* FindUserAndModify(const std::string& user_id) = 0;
+  virtual User* FindUserAndModify(const AccountId& account_id) = 0;
 
   // Returns the logged-in user.
   // TODO(nkostylev): Deprecate this call, move clients to GetActiveUser().
@@ -208,42 +210,43 @@
 
   // Saves user's oauth token status in local state preferences.
   virtual void SaveUserOAuthStatus(
-      const std::string& user_id,
+      const AccountId& account_id,
       User::OAuthTokenStatus oauth_token_status) = 0;
 
   // Saves a flag indicating whether online authentication against GAIA should
   // be enforced during the user's next sign-in.
-  virtual void SaveForceOnlineSignin(const std::string& user_id,
+  virtual void SaveForceOnlineSignin(const AccountId& account_id,
                                      bool force_online_signin) = 0;
 
   // Saves user's displayed name in local state preferences.
   // Ignored If there is no such user.
-  virtual void SaveUserDisplayName(const std::string& user_id,
+  virtual void SaveUserDisplayName(const AccountId& account_id,
                                    const base::string16& display_name) = 0;
 
   // Updates data upon User Account download.
-  virtual void UpdateUserAccountData(const std::string& user_id,
+  virtual void UpdateUserAccountData(const AccountId& account_id,
                                      const UserAccountData& account_data) = 0;
 
-  // Returns the display name for user |user_id| if it is known (was
+  // Returns the display name for user |account_id| if it is known (was
   // previously set by a |SaveUserDisplayName| call).
   // Otherwise, returns an empty string.
   virtual base::string16 GetUserDisplayName(
-      const std::string& user_id) const = 0;
+      const AccountId& account_id) const = 0;
 
   // Saves user's displayed (non-canonical) email in local state preferences.
   // Ignored If there is no such user.
-  virtual void SaveUserDisplayEmail(const std::string& user_id,
+  virtual void SaveUserDisplayEmail(const AccountId& account_id,
                                     const std::string& display_email) = 0;
 
-  // Returns the display email for user |user_id| if it is known (was
+  // Returns the display email for user |account_id| if it is known (was
   // previously set by a |SaveUserDisplayEmail| call).
-  // Otherwise, returns |user_id| itself.
-  virtual std::string GetUserDisplayEmail(const std::string& user_id) const = 0;
+  // Otherwise, returns |account_id| itself.
+  virtual std::string GetUserDisplayEmail(
+      const AccountId& account_id) const = 0;
 
-  // Saves user's type for user |user_id| into local state preferences.
+  // Saves user's type for user |account_id| into local state preferences.
   // Ignored If there is no such user.
-  virtual void SaveUserType(const std::string& user_id,
+  virtual void SaveUserType(const AccountId& account_id,
                             const UserType& user_type) = 0;
 
   // Returns true if current user is an owner.
@@ -290,11 +293,12 @@
   // or restart after crash.
   virtual bool IsSessionStarted() const = 0;
 
-  // Returns true if data stored or cached for the user with the given user id
+  // Returns true if data stored or cached for the user with the given
+  // |account_id|
   // address outside that user's cryptohome (wallpaper, avatar, OAuth token
   // status, display name, display email) is to be treated as ephemeral.
   virtual bool IsUserNonCryptohomeDataEphemeral(
-      const std::string& user_id) const = 0;
+      const AccountId& account_id) const = 0;
 
   virtual void AddObserver(Observer* obs) = 0;
   virtual void RemoveObserver(Observer* obs) = 0;
@@ -313,95 +317,101 @@
 
   // Methods for storage/retrieval of per-user properties in Local State.
 
-  // Performs a lookup of properties associated with |user_id|. If found,
+  // Performs a lookup of properties associated with |account_id|. If found,
   // returns |true| and fills |out_value|. |out_value| can be NULL, if
   // only existence check is required.
-  virtual bool FindKnownUserPrefs(const UserID& user_id,
+  virtual bool FindKnownUserPrefs(const AccountId& account_id,
                                   const base::DictionaryValue** out_value) = 0;
 
-  // Updates (or creates) properties associated with |user_id| based
+  // Updates (or creates) properties associated with |account_id| based
   // on |values|. |clear| defines if existing properties are cleared (|true|)
   // or if it is just a incremental update (|false|).
-  virtual void UpdateKnownUserPrefs(const UserID& user_id,
+  virtual void UpdateKnownUserPrefs(const AccountId& account_id,
                                     const base::DictionaryValue& values,
                                     bool clear) = 0;
 
-  // Returns true if |user_id| preference by |path| does exist,
+  // Returns true if |account_id| preference by |path| does exist,
   // fills in |out_value|. Otherwise returns false.
-  virtual bool GetKnownUserStringPref(const UserID& user_id,
+  virtual bool GetKnownUserStringPref(const AccountId& account_id,
                                       const std::string& path,
                                       std::string* out_value) = 0;
 
-  // Updates user's identified by |user_id| string preference |path|.
-  virtual void SetKnownUserStringPref(const UserID& user_id,
+  // Updates user's identified by |account_id| string preference |path|.
+  virtual void SetKnownUserStringPref(const AccountId& account_id,
                                       const std::string& path,
                                       const std::string& in_value) = 0;
 
-  // Returns true if |user_id| preference by |path| does exist,
+  // Returns true if |account_id| preference by |path| does exist,
   // fills in |out_value|. Otherwise returns false.
-  virtual bool GetKnownUserBooleanPref(const UserID& user_id,
+  virtual bool GetKnownUserBooleanPref(const AccountId& account_id,
                                        const std::string& path,
                                        bool* out_value) = 0;
 
-  // Updates user's identified by |user_id| boolean preference |path|.
-  virtual void SetKnownUserBooleanPref(const UserID& user_id,
+  // Updates user's identified by |account_id| boolean preference |path|.
+  virtual void SetKnownUserBooleanPref(const AccountId& account_id,
                                        const std::string& path,
                                        const bool in_value) = 0;
 
-  // Returns true if |user_id| preference by |path| does exist,
+  // Returns true if |account_id| preference by |path| does exist,
   // fills in |out_value|. Otherwise returns false.
-  virtual bool GetKnownUserIntegerPref(const UserID& user_id,
+  virtual bool GetKnownUserIntegerPref(const AccountId& account_id,
                                        const std::string& path,
                                        int* out_value) = 0;
 
-  // Updates user's identified by |user_id| integer preference |path|.
-  virtual void SetKnownUserIntegerPref(const UserID& user_id,
+  // Updates user's identified by |account_id| integer preference |path|.
+  virtual void SetKnownUserIntegerPref(const AccountId& account_id,
                                        const std::string& path,
                                        const int in_value) = 0;
 
-  // Returns true if user's canonical email was found.
-  // Returns it in |out_email|.
-  virtual bool GetKnownUserCanonicalEmail(const UserID& user_id,
-                                          std::string* out_email) = 0;
+  // Returns true if user's AccountId was found.
+  // Returns it in |out_account_id|.
+  virtual bool GetKnownUserAccountId(const AccountId& authenticated_account_id,
+                                     AccountId* out_account_id) = 0;
 
-  // Updates |gaia_id| for user with |user_id|.
-  // TODO(antrim): Update this once UserID contains GAIA ID.
-  virtual void UpdateGaiaID(const UserID& user_id,
+  // Updates |gaia_id| for user with |account_id|.
+  // TODO(alemate): Update this once AccountId contains GAIA ID
+  // (crbug.com/548926).
+  virtual void UpdateGaiaID(const AccountId& account_id,
                             const std::string& gaia_id) = 0;
 
-  // Find GAIA ID for user with |user_id|, fill in |out_value| and return true
+  // Find GAIA ID for user with |account_id|, fill in |out_value| and return
+  // true
   // if GAIA ID was found or false otherwise.
-  // TODO(antrim): Update this once UserID contains GAIA ID.
-  virtual bool FindGaiaID(const UserID& user_id, std::string* out_value) = 0;
+  // TODO(antrim): Update this once AccountId contains GAIA ID
+  // (crbug.com/548926).
+  virtual bool FindGaiaID(const AccountId& account_id,
+                          std::string* out_value) = 0;
 
   // Saves whether the user authenticates using SAML.
-  virtual void UpdateUsingSAML(const UserID& user_id,
+  virtual void UpdateUsingSAML(const AccountId& account_id,
                                const bool using_saml) = 0;
 
   // Returns if SAML needs to be used for authentication of the user with
-  // |user_id|, if it is known (was set by a |UpdateUsingSaml| call). Otherwise
+  // |account_id|, if it is known (was set by a |UpdateUsingSaml| call).
+  // Otherwise
   // returns false.
-  virtual bool FindUsingSAML(const UserID& user_id) = 0;
+  virtual bool FindUsingSAML(const AccountId& account_id) = 0;
 
   // Setter and getter for DeviceId known user string preference.
-  virtual void SetKnownUserDeviceId(const UserID& user_id,
+  virtual void SetKnownUserDeviceId(const AccountId& account_id,
                                     const std::string& device_id) = 0;
-  virtual std::string GetKnownUserDeviceId(const UserID& user_id) = 0;
+  virtual std::string GetKnownUserDeviceId(const AccountId& account_id) = 0;
 
   // Setter and getter for GAPSCookie known user string preference.
-  virtual void SetKnownUserGAPSCookie(const UserID& user_id,
+  virtual void SetKnownUserGAPSCookie(const AccountId& account_id,
                                       const std::string& gaps_cookie) = 0;
 
-  virtual std::string GetKnownUserGAPSCookie(const UserID& user_id) = 0;
+  virtual std::string GetKnownUserGAPSCookie(const AccountId& account_id) = 0;
 
   // Saves why the user has to go through re-auth flow.
-  virtual void UpdateReauthReason(const UserID& user_id,
+  virtual void UpdateReauthReason(const AccountId& account_id,
                                   const int reauth_reason) = 0;
 
-  // Returns the reason why the user with |user_id| has to go through the
+  // Returns the reason why the user with |account_id| has to go through the
   // re-auth flow. Returns true if such a reason was recorded or false
   // otherwise.
-  virtual bool FindReauthReason(const UserID& user_id, int* out_value) = 0;
+  virtual bool FindReauthReason(const AccountId& account_id,
+                                int* out_value) = 0;
 
  protected:
   // Sets UserManager instance.
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index 3bcb61c2..81a68ffa2 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -115,25 +115,26 @@
   ignore_result(l10n_util::CheckAndResolveLocale(raw_locale, resolved_locale));
 }
 
-// Checks if values in |dict| correspond with |user_id| identity.
-bool UserMatches(const UserID& user_id, const base::DictionaryValue& dict) {
+// Checks if values in |dict| correspond with |account_id| identity.
+bool UserMatches(const AccountId& account_id,
+                 const base::DictionaryValue& dict) {
   std::string value;
 
   bool has_email = dict.GetString(kCanonicalEmail, &value);
-  if (has_email && user_id == value)
+  if (has_email && account_id.GetUserEmail() == value)
     return true;
 
   // TODO(antrim): update code once user id is really a struct.
   bool has_gaia_id = dict.GetString(kGAIAIdKey, &value);
-  if (has_gaia_id && user_id == value)
+  if (has_gaia_id && account_id.GetUserEmail() == value)
     return true;
 
   return false;
 }
 
-// Fills relevant |dict| values based on |user_id|.
-void UpdateIdentity(const UserID& user_id, base::DictionaryValue& dict) {
-  dict.SetString(kCanonicalEmail, user_id);
+// Fills relevant |dict| values based on |account_id|.
+void UpdateIdentity(const AccountId& account_id, base::DictionaryValue& dict) {
+  dict.SetString(kCanonicalEmail, account_id.GetUserEmail());
 }
 
 }  // namespace
@@ -155,17 +156,7 @@
 UserManagerBase::UserManagerBase(
     scoped_refptr<base::TaskRunner> task_runner,
     scoped_refptr<base::TaskRunner> blocking_task_runner)
-    : active_user_(NULL),
-      primary_user_(NULL),
-      user_loading_stage_(STAGE_NOT_LOADED),
-      session_started_(false),
-      is_current_user_owner_(false),
-      is_current_user_new_(false),
-      is_current_user_ephemeral_regular_user_(false),
-      ephemeral_users_enabled_(false),
-      manager_creation_time_(base::TimeTicks::Now()),
-      last_session_active_user_initialized_(false),
-      task_runner_(task_runner),
+    : task_runner_(task_runner),
       blocking_task_runner_(blocking_task_runner),
       weak_factory_(this) {
   UpdateLoginState();
@@ -201,21 +192,22 @@
   return lru_logged_in_users_;
 }
 
-const std::string& UserManagerBase::GetOwnerEmail() const {
-  return owner_email_;
+const AccountId& UserManagerBase::GetOwnerAccountId() const {
+  return owner_account_id_;
 }
 
-void UserManagerBase::UserLoggedIn(const std::string& user_id,
+void UserManagerBase::UserLoggedIn(const AccountId& account_id,
                                    const std::string& username_hash,
                                    bool browser_restart) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
-  if (!last_session_active_user_initialized_) {
-    last_session_active_user_ = GetLocalState()->GetString(kLastActiveUser);
-    last_session_active_user_initialized_ = true;
+  if (!last_session_active_account_id_initialized_) {
+    last_session_active_account_id_ =
+        AccountId::FromUserEmail(GetLocalState()->GetString(kLastActiveUser));
+    last_session_active_account_id_initialized_ = true;
   }
 
-  User* user = FindUserInListAndModify(user_id);
+  User* user = FindUserInListAndModify(account_id);
   if (active_user_ && user) {
     user->set_is_logged_in(true);
     user->set_username_hash(username_hash);
@@ -229,11 +221,11 @@
     return;
   }
 
-  if (user_id == chromeos::login::kGuestUserName) {
+  if (account_id == chromeos::login::GuestAccountId()) {
     GuestUserLoggedIn();
-  } else if (IsKioskApp(user_id)) {
-    KioskAppLoggedIn(user_id);
-  } else if (IsDemoApp(user_id)) {
+  } else if (IsKioskApp(account_id)) {
+    KioskAppLoggedIn(account_id);
+  } else if (IsDemoApp(account_id)) {
     DemoAccountLoggedIn();
   } else {
     EnsureUsersLoaded();
@@ -242,16 +234,16 @@
       PublicAccountUserLoggedIn(user);
     } else if ((user && user->GetType() == USER_TYPE_SUPERVISED) ||
                (!user &&
-                gaia::ExtractDomainName(user_id) ==
+                gaia::ExtractDomainName(account_id.GetUserEmail()) ==
                     chromeos::login::kSupervisedUserDomain)) {
-      SupervisedUserLoggedIn(user_id);
-    } else if (browser_restart && IsPublicAccountMarkedForRemoval(user_id)) {
-      PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
-    } else if (user_id != GetOwnerEmail() && !user &&
+      SupervisedUserLoggedIn(account_id);
+    } else if (browser_restart && IsPublicAccountMarkedForRemoval(account_id)) {
+      PublicAccountUserLoggedIn(User::CreatePublicAccountUser(account_id));
+    } else if (account_id != GetOwnerAccountId() && !user &&
                (AreEphemeralUsersEnabled() || browser_restart)) {
-      RegularUserLoggedInAsEphemeral(user_id);
+      RegularUserLoggedInAsEphemeral(account_id);
     } else {
-      RegularUserLoggedIn(user_id);
+      RegularUserLoggedIn(account_id);
     }
   }
 
@@ -267,21 +259,22 @@
   if (!primary_user_) {
     primary_user_ = active_user_;
     if (primary_user_->HasGaiaAccount())
-      SendGaiaUserLoginMetrics(user_id);
+      SendGaiaUserLoginMetrics(account_id);
   }
 
   UMA_HISTOGRAM_ENUMERATION(
       "UserManager.LoginUserType", active_user_->GetType(), NUM_USER_TYPES);
 
   GetLocalState()->SetString(
-      kLastLoggedInGaiaUser, active_user_->HasGaiaAccount() ? user_id : "");
+      kLastLoggedInGaiaUser,
+      active_user_->HasGaiaAccount() ? account_id.GetUserEmail() : "");
 
   NotifyOnLogin();
   PerformPostUserLoggedInActions(browser_restart);
 }
 
-void UserManagerBase::SwitchActiveUser(const std::string& user_id) {
-  User* user = FindUserAndModify(user_id);
+void UserManagerBase::SwitchActiveUser(const AccountId& account_id) {
+  User* user = FindUserAndModify(account_id);
   if (!user) {
     NOTREACHED() << "Switching to a non-existing user";
     return;
@@ -317,14 +310,15 @@
 }
 
 void UserManagerBase::SwitchToLastActiveUser() {
-  if (last_session_active_user_.empty())
+  if (!last_session_active_account_id_.is_valid())
     return;
 
-  if (GetActiveUser()->email() != last_session_active_user_)
-    SwitchActiveUser(last_session_active_user_);
+  if (AccountId::FromUserEmail(GetActiveUser()->email()) !=
+      last_session_active_account_id_)
+    SwitchActiveUser(last_session_active_account_id_);
 
   // Make sure that this function gets run only once.
-  last_session_active_user_.clear();
+  last_session_active_account_id_.clear();
 }
 
 void UserManagerBase::SessionStarted() {
@@ -341,47 +335,48 @@
   }
 }
 
-void UserManagerBase::RemoveUser(const std::string& user_id,
+void UserManagerBase::RemoveUser(const AccountId& account_id,
                                  RemoveUserDelegate* delegate) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
-  if (!CanUserBeRemoved(FindUser(user_id)))
+  if (!CanUserBeRemoved(FindUser(account_id)))
     return;
 
-  RemoveUserInternal(user_id, delegate);
+  RemoveUserInternal(account_id, delegate);
 }
 
-void UserManagerBase::RemoveUserInternal(const std::string& user_email,
+void UserManagerBase::RemoveUserInternal(const AccountId& account_id,
                                          RemoveUserDelegate* delegate) {
-  RemoveNonOwnerUserInternal(user_email, delegate);
+  RemoveNonOwnerUserInternal(account_id, delegate);
 }
 
-void UserManagerBase::RemoveNonOwnerUserInternal(const std::string& user_email,
+void UserManagerBase::RemoveNonOwnerUserInternal(const AccountId& account_id,
                                                  RemoveUserDelegate* delegate) {
   if (delegate)
-    delegate->OnBeforeUserRemoved(user_email);
-  RemoveUserFromList(user_email);
+    delegate->OnBeforeUserRemoved(account_id.GetUserEmail());
+  RemoveUserFromList(account_id);
   cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
-      user_email, base::Bind(&OnRemoveUserComplete, user_email));
+      account_id.GetUserEmail(),
+      base::Bind(&OnRemoveUserComplete, account_id.GetUserEmail()));
 
   if (delegate)
-    delegate->OnUserRemoved(user_email);
+    delegate->OnUserRemoved(account_id.GetUserEmail());
 }
 
-void UserManagerBase::RemoveUserFromList(const std::string& user_id) {
+void UserManagerBase::RemoveUserFromList(const AccountId& account_id) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
-  RemoveNonCryptohomeData(user_id);
+  RemoveNonCryptohomeData(account_id);
   if (user_loading_stage_ == STAGE_LOADED) {
-    DeleteUser(RemoveRegularOrSupervisedUserFromList(user_id));
+    DeleteUser(RemoveRegularOrSupervisedUserFromList(account_id));
   } else if (user_loading_stage_ == STAGE_LOADING) {
-    DCHECK(gaia::ExtractDomainName(user_id) ==
+    DCHECK(gaia::ExtractDomainName(account_id.GetUserEmail()) ==
                chromeos::login::kSupervisedUserDomain ||
-           HasPendingBootstrap(user_id));
+           HasPendingBootstrap(account_id));
     // Special case, removing partially-constructed supervised user or
     // boostrapping user during user list loading.
     ListPrefUpdate users_update(GetLocalState(), kRegularUsers);
-    users_update->Remove(base::StringValue(user_id), NULL);
-    OnUserRemoved(user_id);
+    users_update->Remove(base::StringValue(account_id.GetUserEmail()), nullptr);
+    OnUserRemoved(account_id);
   } else {
     NOTREACHED() << "Users are not loaded yet.";
     return;
@@ -391,22 +386,22 @@
   GetLocalState()->CommitPendingWrite();
 }
 
-bool UserManagerBase::IsKnownUser(const std::string& user_id) const {
-  return FindUser(user_id) != NULL;
+bool UserManagerBase::IsKnownUser(const AccountId& account_id) const {
+  return FindUser(account_id) != nullptr;
 }
 
-const User* UserManagerBase::FindUser(const std::string& user_id) const {
+const User* UserManagerBase::FindUser(const AccountId& account_id) const {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
-  if (active_user_ && active_user_->email() == user_id)
+  if (active_user_ && active_user_->GetAccountId() == account_id)
     return active_user_;
-  return FindUserInList(user_id);
+  return FindUserInList(account_id);
 }
 
-User* UserManagerBase::FindUserAndModify(const std::string& user_id) {
+User* UserManagerBase::FindUserAndModify(const AccountId& account_id) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
-  if (active_user_ && active_user_->email() == user_id)
+  if (active_user_ && active_user_->GetAccountId() == account_id)
     return active_user_;
-  return FindUserInListAndModify(user_id);
+  return FindUserInListAndModify(account_id);
 }
 
 const User* UserManagerBase::GetLoggedInUser() const {
@@ -435,73 +430,73 @@
 }
 
 void UserManagerBase::SaveUserOAuthStatus(
-    const std::string& user_id,
+    const AccountId& account_id,
     User::OAuthTokenStatus oauth_token_status) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
   DVLOG(1) << "Saving user OAuth token status in Local State";
-  User* user = FindUserAndModify(user_id);
+  User* user = FindUserAndModify(account_id);
   if (user)
     user->set_oauth_token_status(oauth_token_status);
 
   // Do not update local state if data stored or cached outside the user's
   // cryptohome is to be treated as ephemeral.
-  if (IsUserNonCryptohomeDataEphemeral(user_id))
+  if (IsUserNonCryptohomeDataEphemeral(account_id))
     return;
 
   DictionaryPrefUpdate oauth_status_update(GetLocalState(),
                                            kUserOAuthTokenStatus);
   oauth_status_update->SetWithoutPathExpansion(
-      user_id,
+      account_id.GetUserEmail(),
       new base::FundamentalValue(static_cast<int>(oauth_token_status)));
 }
 
-void UserManagerBase::SaveForceOnlineSignin(const std::string& user_id,
+void UserManagerBase::SaveForceOnlineSignin(const AccountId& account_id,
                                             bool force_online_signin) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
   // Do not update local state if data stored or cached outside the user's
   // cryptohome is to be treated as ephemeral.
-  if (IsUserNonCryptohomeDataEphemeral(user_id))
+  if (IsUserNonCryptohomeDataEphemeral(account_id))
     return;
 
   DictionaryPrefUpdate force_online_update(GetLocalState(),
                                            kUserForceOnlineSignin);
-  force_online_update->SetBooleanWithoutPathExpansion(user_id,
+  force_online_update->SetBooleanWithoutPathExpansion(account_id.GetUserEmail(),
                                                       force_online_signin);
 }
 
-void UserManagerBase::SaveUserDisplayName(const std::string& user_id,
+void UserManagerBase::SaveUserDisplayName(const AccountId& account_id,
                                           const base::string16& display_name) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
-  if (User* user = FindUserAndModify(user_id)) {
+  if (User* user = FindUserAndModify(account_id)) {
     user->set_display_name(display_name);
 
     // Do not update local state if data stored or cached outside the user's
     // cryptohome is to be treated as ephemeral.
-    if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
+    if (!IsUserNonCryptohomeDataEphemeral(account_id)) {
       DictionaryPrefUpdate display_name_update(GetLocalState(),
                                                kUserDisplayName);
       display_name_update->SetWithoutPathExpansion(
-          user_id, new base::StringValue(display_name));
+          account_id.GetUserEmail(), new base::StringValue(display_name));
     }
   }
 }
 
 base::string16 UserManagerBase::GetUserDisplayName(
-    const std::string& user_id) const {
-  const User* user = FindUser(user_id);
+    const AccountId& account_id) const {
+  const User* user = FindUser(account_id);
   return user ? user->display_name() : base::string16();
 }
 
-void UserManagerBase::SaveUserDisplayEmail(const std::string& user_id,
+void UserManagerBase::SaveUserDisplayEmail(const AccountId& account_id,
                                            const std::string& display_email) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
-  User* user = FindUserAndModify(user_id);
+  User* user = FindUserAndModify(account_id);
   if (!user) {
-    LOG(ERROR) << "User not found: " << user_id;
+    LOG(ERROR) << "User not found: " << account_id.GetUserEmail();
     return;  // Ignore if there is no such user.
   }
 
@@ -509,88 +504,89 @@
 
   // Do not update local state if data stored or cached outside the user's
   // cryptohome is to be treated as ephemeral.
-  if (IsUserNonCryptohomeDataEphemeral(user_id))
+  if (IsUserNonCryptohomeDataEphemeral(account_id))
     return;
 
   DictionaryPrefUpdate display_email_update(GetLocalState(), kUserDisplayEmail);
   display_email_update->SetWithoutPathExpansion(
-      user_id, new base::StringValue(display_email));
+      account_id.GetUserEmail(), new base::StringValue(display_email));
 }
 
 std::string UserManagerBase::GetUserDisplayEmail(
-    const std::string& user_id) const {
-  const User* user = FindUser(user_id);
-  return user ? user->display_email() : user_id;
+    const AccountId& account_id) const {
+  const User* user = FindUser(account_id);
+  return user ? user->display_email() : account_id.GetUserEmail();
 }
 
-void UserManagerBase::SaveUserType(const std::string& user_id,
+void UserManagerBase::SaveUserType(const AccountId& account_id,
                                    const UserType& user_type) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
-  User* user = FindUserAndModify(user_id);
+  User* user = FindUserAndModify(account_id);
   if (!user) {
-    LOG(ERROR) << "User not found: " << user_id;
+    LOG(ERROR) << "User not found: " << account_id.GetUserEmail();
     return;  // Ignore if there is no such user.
   }
 
   // Do not update local state if data stored or cached outside the user's
   // cryptohome is to be treated as ephemeral.
-  if (IsUserNonCryptohomeDataEphemeral(user_id))
+  if (IsUserNonCryptohomeDataEphemeral(account_id))
     return;
 
   DictionaryPrefUpdate user_type_update(GetLocalState(), kUserType);
   user_type_update->SetWithoutPathExpansion(
-      user_id, new base::FundamentalValue(static_cast<int>(user_type)));
+      account_id.GetUserEmail(),
+      new base::FundamentalValue(static_cast<int>(user_type)));
   GetLocalState()->CommitPendingWrite();
 }
 
-void UserManagerBase::UpdateUsingSAML(const std::string& user_id,
+void UserManagerBase::UpdateUsingSAML(const AccountId& account_id,
                                       const bool using_saml) {
-  SetKnownUserBooleanPref(user_id, kUsingSAMLKey, using_saml);
+  SetKnownUserBooleanPref(account_id, kUsingSAMLKey, using_saml);
 }
 
-bool UserManagerBase::FindUsingSAML(const std::string& user_id) {
+bool UserManagerBase::FindUsingSAML(const AccountId& account_id) {
   bool using_saml;
-  if (GetKnownUserBooleanPref(user_id, kUsingSAMLKey, &using_saml))
+  if (GetKnownUserBooleanPref(account_id, kUsingSAMLKey, &using_saml))
     return using_saml;
   return false;
 }
 
-void UserManagerBase::UpdateReauthReason(const std::string& user_id,
+void UserManagerBase::UpdateReauthReason(const AccountId& account_id,
                                          const int reauth_reason) {
-  SetKnownUserIntegerPref(user_id, kReauthReasonKey, reauth_reason);
+  SetKnownUserIntegerPref(account_id, kReauthReasonKey, reauth_reason);
 }
 
-bool UserManagerBase::FindReauthReason(const std::string& user_id,
+bool UserManagerBase::FindReauthReason(const AccountId& account_id,
                                        int* out_value) {
-  return GetKnownUserIntegerPref(user_id, kReauthReasonKey, out_value);
+  return GetKnownUserIntegerPref(account_id, kReauthReasonKey, out_value);
 }
 
 void UserManagerBase::UpdateUserAccountData(
-    const std::string& user_id,
+    const AccountId& account_id,
     const UserAccountData& account_data) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
-  SaveUserDisplayName(user_id, account_data.display_name());
+  SaveUserDisplayName(account_id, account_data.display_name());
 
-  if (User* user = FindUserAndModify(user_id)) {
+  if (User* user = FindUserAndModify(account_id)) {
     base::string16 given_name = account_data.given_name();
     user->set_given_name(given_name);
-    if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
+    if (!IsUserNonCryptohomeDataEphemeral(account_id)) {
       DictionaryPrefUpdate given_name_update(GetLocalState(), kUserGivenName);
       given_name_update->SetWithoutPathExpansion(
-          user_id, new base::StringValue(given_name));
+          account_id.GetUserEmail(), new base::StringValue(given_name));
     }
   }
 
-  UpdateUserAccountLocale(user_id, account_data.locale());
+  UpdateUserAccountLocale(account_id, account_data.locale());
 }
 
 // static
 void UserManagerBase::ParseUserList(const base::ListValue& users_list,
-                                    const std::set<std::string>& existing_users,
-                                    std::vector<std::string>* users_vector,
-                                    std::set<std::string>* users_set) {
+                                    const std::set<AccountId>& existing_users,
+                                    std::vector<AccountId>* users_vector,
+                                    std::set<AccountId>* users_set) {
   users_vector->clear();
   users_set->clear();
   for (size_t i = 0; i < users_list.GetSize(); ++i) {
@@ -599,12 +595,13 @@
       LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
       continue;
     }
-    if (existing_users.find(email) != existing_users.end() ||
-        !users_set->insert(email).second) {
+    const AccountId account_id(AccountId::FromUserEmail(email));
+    if (existing_users.find(account_id) != existing_users.end() ||
+        !users_set->insert(account_id).second) {
       LOG(ERROR) << "Duplicate user: " << email;
       continue;
     }
-    users_vector->push_back(email);
+    users_vector->push_back(account_id);
   }
 }
 
@@ -631,7 +628,7 @@
 bool UserManagerBase::IsCurrentUserNonCryptohomeDataEphemeral() const {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
   return IsUserLoggedIn() &&
-         IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
+         IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->GetAccountId());
 }
 
 bool UserManagerBase::CanCurrentUserLock() const {
@@ -687,17 +684,17 @@
 }
 
 bool UserManagerBase::IsUserNonCryptohomeDataEphemeral(
-    const std::string& user_id) const {
+    const AccountId& account_id) const {
   // Data belonging to the guest and stub users is always ephemeral.
-  if (user_id == chromeos::login::kGuestUserName ||
-      user_id == chromeos::login::kStubUser) {
+  if (account_id == chromeos::login::GuestAccountId() ||
+      account_id == chromeos::login::StubAccountId()) {
     return true;
   }
 
   // Data belonging to the owner, anyone found on the user list and obsolete
   // public accounts whose data has not been removed yet is not ephemeral.
-  if (user_id == GetOwnerEmail() || UserExistsInList(user_id) ||
-      IsPublicAccountMarkedForRemoval(user_id)) {
+  if (account_id == GetOwnerAccountId() || UserExistsInList(account_id) ||
+      IsPublicAccountMarkedForRemoval(account_id)) {
     return false;
   }
 
@@ -706,7 +703,7 @@
   //    policy was enabled.
   //    - or -
   // b) The user logged into any other account type.
-  if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
+  if (IsUserLoggedIn() && (account_id == GetLoggedInUser()->GetAccountId()) &&
       (is_current_user_ephemeral_regular_user_ ||
        !IsLoggedInAsUserWithGaiaAccount())) {
     return true;
@@ -786,20 +783,20 @@
   is_current_user_new_ = is_new;
 }
 
-bool UserManagerBase::HasPendingBootstrap(const std::string& user_id) const {
+bool UserManagerBase::HasPendingBootstrap(const AccountId& account_id) const {
   return false;
 }
 
-void UserManagerBase::SetOwnerEmail(const std::string& owner_user_id) {
-  owner_email_ = owner_user_id;
+void UserManagerBase::SetOwnerId(const AccountId& owner_account_id) {
+  owner_account_id_ = owner_account_id;
 }
 
-const std::string& UserManagerBase::GetPendingUserSwitchID() const {
+const AccountId& UserManagerBase::GetPendingUserSwitchID() const {
   return pending_user_switch_;
 }
 
-void UserManagerBase::SetPendingUserSwitchID(const std::string& user_id) {
-  pending_user_switch_ = user_id;
+void UserManagerBase::SetPendingUserSwitchId(const AccountId& account_id) {
+  pending_user_switch_ = account_id;
 }
 
 void UserManagerBase::EnsureUsersLoaded() {
@@ -827,27 +824,27 @@
       local_state->GetDictionary(kUserType);
 
   // Load public sessions first.
-  std::set<std::string> public_sessions_set;
+  std::set<AccountId> public_sessions_set;
   LoadPublicAccounts(&public_sessions_set);
 
   // Load regular users and supervised users.
-  std::vector<std::string> regular_users;
-  std::set<std::string> regular_users_set;
+  std::vector<AccountId> regular_users;
+  std::set<AccountId> regular_users_set;
   ParseUserList(*prefs_regular_users,
                 public_sessions_set,
                 &regular_users,
                 &regular_users_set);
-  for (std::vector<std::string>::const_iterator it = regular_users.begin();
-       it != regular_users.end();
-       ++it) {
-    User* user = NULL;
-    const std::string domain = gaia::ExtractDomainName(*it);
+  for (std::vector<AccountId>::const_iterator it = regular_users.begin();
+       it != regular_users.end(); ++it) {
+    User* user = nullptr;
+    const std::string domain = gaia::ExtractDomainName(it->GetUserEmail());
     if (domain == chromeos::login::kSupervisedUserDomain) {
       user = User::CreateSupervisedUser(*it);
     } else {
       user = User::CreateRegularUser(*it);
       int user_type;
-      if (prefs_user_types->GetIntegerWithoutPathExpansion(*it, &user_type) &&
+      if (prefs_user_types->GetIntegerWithoutPathExpansion(it->GetUserEmail(),
+                                                           &user_type) &&
           user_type == USER_TYPE_CHILD) {
         ChangeUserChildStatus(user, true /* is child */);
       }
@@ -858,18 +855,19 @@
     users_.push_back(user);
 
     base::string16 display_name;
-    if (prefs_display_names->GetStringWithoutPathExpansion(*it,
+    if (prefs_display_names->GetStringWithoutPathExpansion(it->GetUserEmail(),
                                                            &display_name)) {
       user->set_display_name(display_name);
     }
 
     base::string16 given_name;
-    if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
+    if (prefs_given_names->GetStringWithoutPathExpansion(it->GetUserEmail(),
+                                                         &given_name)) {
       user->set_given_name(given_name);
     }
 
     std::string display_email;
-    if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
+    if (prefs_display_emails->GetStringWithoutPathExpansion(it->GetUserEmail(),
                                                             &display_email)) {
       user->set_display_email(display_email);
     }
@@ -885,32 +883,32 @@
   return users_;
 }
 
-const User* UserManagerBase::FindUserInList(const std::string& user_id) const {
+const User* UserManagerBase::FindUserInList(const AccountId& account_id) const {
   const UserList& users = GetUsers();
   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
-    if ((*it)->email() == user_id)
+    if ((*it)->GetAccountId() == account_id)
       return *it;
   }
-  return NULL;
+  return nullptr;
 }
 
-bool UserManagerBase::UserExistsInList(const std::string& user_id) const {
+bool UserManagerBase::UserExistsInList(const AccountId& account_id) const {
   const base::ListValue* user_list = GetLocalState()->GetList(kRegularUsers);
   for (size_t i = 0; i < user_list->GetSize(); ++i) {
     std::string email;
-    if (user_list->GetString(i, &email) && (user_id == email))
+    if (user_list->GetString(i, &email) && (account_id.GetUserEmail() == email))
       return true;
   }
   return false;
 }
 
-User* UserManagerBase::FindUserInListAndModify(const std::string& user_id) {
+User* UserManagerBase::FindUserInListAndModify(const AccountId& account_id) {
   UserList& users = GetUsersAndModify();
   for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
-    if ((*it)->email() == user_id)
+    if ((*it)->GetAccountId() == account_id)
       return *it;
   }
-  return NULL;
+  return nullptr;
 }
 
 void UserManagerBase::GuestUserLoggedIn() {
@@ -925,16 +923,16 @@
   users_.insert(users_.begin(), user);
 }
 
-void UserManagerBase::RegularUserLoggedIn(const std::string& user_id) {
+void UserManagerBase::RegularUserLoggedIn(const AccountId& account_id) {
   // Remove the user from the user list.
-  active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
+  active_user_ = RemoveRegularOrSupervisedUserFromList(account_id);
 
   // If the user was not found on the user list, create a new user.
   SetIsCurrentUserNew(!active_user_);
   if (IsCurrentUserNew()) {
-    active_user_ = User::CreateRegularUser(user_id);
-    active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
-    SaveUserDisplayName(active_user_->email(),
+    active_user_ = User::CreateRegularUser(account_id);
+    active_user_->set_oauth_token_status(LoadUserOAuthStatus(account_id));
+    SaveUserDisplayName(active_user_->GetAccountId(),
                         base::UTF8ToUTF16(active_user_->GetAccountName(true)));
   }
 
@@ -945,11 +943,11 @@
 }
 
 void UserManagerBase::RegularUserLoggedInAsEphemeral(
-    const std::string& user_id) {
+    const AccountId& account_id) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
   SetIsCurrentUserNew(true);
   is_current_user_ephemeral_regular_user_ = true;
-  active_user_ = User::CreateRegularUser(user_id);
+  active_user_ = User::CreateRegularUser(account_id);
 }
 
 void UserManagerBase::NotifyOnLogin() {
@@ -961,77 +959,83 @@
 }
 
 User::OAuthTokenStatus UserManagerBase::LoadUserOAuthStatus(
-    const std::string& user_id) const {
+    const AccountId& account_id) const {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
   const base::DictionaryValue* prefs_oauth_status =
       GetLocalState()->GetDictionary(kUserOAuthTokenStatus);
   int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
   if (prefs_oauth_status &&
-      prefs_oauth_status->GetIntegerWithoutPathExpansion(user_id,
-                                                         &oauth_token_status)) {
+      prefs_oauth_status->GetIntegerWithoutPathExpansion(
+          account_id.GetUserEmail(), &oauth_token_status)) {
     User::OAuthTokenStatus status =
         static_cast<User::OAuthTokenStatus>(oauth_token_status);
-    HandleUserOAuthTokenStatusChange(user_id, status);
+    HandleUserOAuthTokenStatusChange(account_id, status);
 
     return status;
   }
   return User::OAUTH_TOKEN_STATUS_UNKNOWN;
 }
 
-bool UserManagerBase::LoadForceOnlineSignin(const std::string& user_id) const {
+bool UserManagerBase::LoadForceOnlineSignin(const AccountId& account_id) const {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
 
   const base::DictionaryValue* prefs_force_online =
       GetLocalState()->GetDictionary(kUserForceOnlineSignin);
   bool force_online_signin = false;
   if (prefs_force_online) {
-    prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
-                                                       &force_online_signin);
+    prefs_force_online->GetBooleanWithoutPathExpansion(
+        account_id.GetUserEmail(), &force_online_signin);
   }
   return force_online_signin;
 }
 
-void UserManagerBase::RemoveNonCryptohomeData(const std::string& user_id) {
+void UserManagerBase::RemoveNonCryptohomeData(const AccountId& account_id) {
   PrefService* prefs = GetLocalState();
   DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
-  prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
+  prefs_display_name_update->RemoveWithoutPathExpansion(
+      account_id.GetUserEmail(), nullptr);
 
   DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
-  prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
+  prefs_given_name_update->RemoveWithoutPathExpansion(account_id.GetUserEmail(),
+                                                      nullptr);
 
   DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
-  prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
+  prefs_display_email_update->RemoveWithoutPathExpansion(
+      account_id.GetUserEmail(), nullptr);
 
   DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
-  prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
+  prefs_oauth_update->RemoveWithoutPathExpansion(account_id.GetUserEmail(),
+                                                 nullptr);
 
   DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
-  prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
+  prefs_force_online_update->RemoveWithoutPathExpansion(
+      account_id.GetUserEmail(), nullptr);
 
-  RemoveKnownUserPrefs(user_id);
+  RemoveKnownUserPrefs(account_id);
 
-  std::string last_active_user = GetLocalState()->GetString(kLastActiveUser);
-  if (user_id == last_active_user)
+  const AccountId last_active_user =
+      AccountId::FromUserEmail(GetLocalState()->GetString(kLastActiveUser));
+  if (account_id == last_active_user)
     GetLocalState()->SetString(kLastActiveUser, std::string());
 }
 
 bool UserManagerBase::FindKnownUserPrefs(
-    const UserID& user_id,
+    const AccountId& account_id,
     const base::DictionaryValue** out_value) {
   PrefService* local_state = GetLocalState();
 
   // Local State may not be initialized in tests.
   if (!local_state)
     return false;
-  if (IsUserNonCryptohomeDataEphemeral(user_id))
+  if (IsUserNonCryptohomeDataEphemeral(account_id))
     return false;
 
   const base::ListValue* known_users = local_state->GetList(kKnownUsers);
   for (size_t i = 0; i < known_users->GetSize(); ++i) {
     const base::DictionaryValue* element = nullptr;
     if (known_users->GetDictionary(i, &element)) {
-      if (UserMatches(user_id, *element)) {
+      if (UserMatches(account_id, *element)) {
         known_users->GetDictionary(i, out_value);
         return true;
       }
@@ -1040,7 +1044,7 @@
   return false;
 }
 
-void UserManagerBase::UpdateKnownUserPrefs(const UserID& user_id,
+void UserManagerBase::UpdateKnownUserPrefs(const AccountId& account_id,
                                            const base::DictionaryValue& values,
                                            bool clear) {
   PrefService* local_state = GetLocalState();
@@ -1049,39 +1053,39 @@
   if (!local_state)
     return;
 
-  if (IsUserNonCryptohomeDataEphemeral(user_id))
+  if (IsUserNonCryptohomeDataEphemeral(account_id))
     return;
 
   ListPrefUpdate update(local_state, kKnownUsers);
   for (size_t i = 0; i < update->GetSize(); ++i) {
     base::DictionaryValue* element = nullptr;
     if (update->GetDictionary(i, &element)) {
-      if (UserMatches(user_id, *element)) {
+      if (UserMatches(account_id, *element)) {
         if (clear)
           element->Clear();
         element->MergeDictionary(&values);
-        UpdateIdentity(user_id, *element);
+        UpdateIdentity(account_id, *element);
         return;
       }
     }
   }
   scoped_ptr<base::DictionaryValue> new_value(new base::DictionaryValue());
   new_value->MergeDictionary(&values);
-  UpdateIdentity(user_id, *new_value);
+  UpdateIdentity(account_id, *new_value);
   update->Append(new_value.release());
 }
 
-bool UserManagerBase::GetKnownUserStringPref(const UserID& user_id,
+bool UserManagerBase::GetKnownUserStringPref(const AccountId& account_id,
                                              const std::string& path,
                                              std::string* out_value) {
   const base::DictionaryValue* user_pref_dict = nullptr;
-  if (!FindKnownUserPrefs(user_id, &user_pref_dict))
+  if (!FindKnownUserPrefs(account_id, &user_pref_dict))
     return false;
 
   return user_pref_dict->GetString(path, out_value);
 }
 
-void UserManagerBase::SetKnownUserStringPref(const UserID& user_id,
+void UserManagerBase::SetKnownUserStringPref(const AccountId& account_id,
                                              const std::string& path,
                                              const std::string& in_value) {
   PrefService* local_state = GetLocalState();
@@ -1093,20 +1097,20 @@
   ListPrefUpdate update(local_state, kKnownUsers);
   base::DictionaryValue dict;
   dict.SetString(path, in_value);
-  UpdateKnownUserPrefs(user_id, dict, false);
+  UpdateKnownUserPrefs(account_id, dict, false);
 }
 
-bool UserManagerBase::GetKnownUserBooleanPref(const UserID& user_id,
+bool UserManagerBase::GetKnownUserBooleanPref(const AccountId& account_id,
                                               const std::string& path,
                                               bool* out_value) {
   const base::DictionaryValue* user_pref_dict = nullptr;
-  if (!FindKnownUserPrefs(user_id, &user_pref_dict))
+  if (!FindKnownUserPrefs(account_id, &user_pref_dict))
     return false;
 
   return user_pref_dict->GetBoolean(path, out_value);
 }
 
-void UserManagerBase::SetKnownUserBooleanPref(const UserID& user_id,
+void UserManagerBase::SetKnownUserBooleanPref(const AccountId& account_id,
                                               const std::string& path,
                                               const bool in_value) {
   PrefService* local_state = GetLocalState();
@@ -1118,19 +1122,19 @@
   ListPrefUpdate update(local_state, kKnownUsers);
   base::DictionaryValue dict;
   dict.SetBoolean(path, in_value);
-  UpdateKnownUserPrefs(user_id, dict, false);
+  UpdateKnownUserPrefs(account_id, dict, false);
 }
 
-bool UserManagerBase::GetKnownUserIntegerPref(const UserID& user_id,
+bool UserManagerBase::GetKnownUserIntegerPref(const AccountId& account_id,
                                               const std::string& path,
                                               int* out_value) {
   const base::DictionaryValue* user_pref_dict = nullptr;
-  if (!FindKnownUserPrefs(user_id, &user_pref_dict))
+  if (!FindKnownUserPrefs(account_id, &user_pref_dict))
     return false;
   return user_pref_dict->GetInteger(path, out_value);
 }
 
-void UserManagerBase::SetKnownUserIntegerPref(const UserID& user_id,
+void UserManagerBase::SetKnownUserIntegerPref(const AccountId& account_id,
                                               const std::string& path,
                                               const int in_value) {
   PrefService* local_state = GetLocalState();
@@ -1142,80 +1146,92 @@
   ListPrefUpdate update(local_state, kKnownUsers);
   base::DictionaryValue dict;
   dict.SetInteger(path, in_value);
-  UpdateKnownUserPrefs(user_id, dict, false);
+  UpdateKnownUserPrefs(account_id, dict, false);
 }
 
-bool UserManagerBase::GetKnownUserCanonicalEmail(const UserID& user_id,
-                                                 std::string* out_email) {
-  return GetKnownUserStringPref(user_id, kCanonicalEmail, out_email);
+bool UserManagerBase::GetKnownUserAccountId(
+    const AccountId& authenticated_account_id,
+    AccountId* out_account_id) {
+  DCHECK(!authenticated_account_id.GetGaiaId().empty());
+  std::string canonical_email;
+  if (!GetKnownUserStringPref(
+          AccountId::FromGaiaId(authenticated_account_id.GetGaiaId()),
+          kCanonicalEmail, &canonical_email))
+    return false;
+
+  *out_account_id = authenticated_account_id;
+  out_account_id->SetUserEmail(canonical_email);
+  return true;
 }
 
-void UserManagerBase::UpdateGaiaID(const UserID& user_id,
+void UserManagerBase::UpdateGaiaID(const AccountId& account_id,
                                    const std::string& gaia_id) {
-  SetKnownUserStringPref(user_id, kGAIAIdKey, gaia_id);
+  SetKnownUserStringPref(account_id, kGAIAIdKey, gaia_id);
 }
 
-bool UserManagerBase::FindGaiaID(const UserID& user_id,
+bool UserManagerBase::FindGaiaID(const AccountId& account_id,
                                  std::string* out_value) {
-  return GetKnownUserStringPref(user_id, kGAIAIdKey, out_value);
+  return GetKnownUserStringPref(account_id, kGAIAIdKey, out_value);
 }
 
-void UserManagerBase::SetKnownUserDeviceId(const UserID& user_id,
+void UserManagerBase::SetKnownUserDeviceId(const AccountId& account_id,
                                            const std::string& device_id) {
-  const std::string known_device_id = GetKnownUserDeviceId(user_id);
+  const std::string known_device_id = GetKnownUserDeviceId(account_id);
   if (!known_device_id.empty() && device_id != known_device_id) {
     NOTREACHED() << "Trying to change device ID for known user.";
   }
-  SetKnownUserStringPref(user_id, kDeviceId, device_id);
+  SetKnownUserStringPref(account_id, kDeviceId, device_id);
 }
 
-std::string UserManagerBase::GetKnownUserDeviceId(const UserID& user_id) {
+std::string UserManagerBase::GetKnownUserDeviceId(const AccountId& account_id) {
   std::string device_id;
-  if (GetKnownUserStringPref(user_id, kDeviceId, &device_id)) {
+  if (GetKnownUserStringPref(account_id, kDeviceId, &device_id)) {
     return device_id;
   }
   return std::string();
 }
 
-void UserManagerBase::SetKnownUserGAPSCookie(const UserID& user_id,
+void UserManagerBase::SetKnownUserGAPSCookie(const AccountId& account_id,
                                              const std::string& gaps_cookie) {
-  SetKnownUserStringPref(user_id, kGAPSCookie, gaps_cookie);
+  SetKnownUserStringPref(account_id, kGAPSCookie, gaps_cookie);
 }
 
-std::string UserManagerBase::GetKnownUserGAPSCookie(const UserID& user_id) {
+std::string UserManagerBase::GetKnownUserGAPSCookie(
+    const AccountId& account_id) {
   std::string gaps_cookie;
-  if (GetKnownUserStringPref(user_id, kGAPSCookie, &gaps_cookie)) {
+  if (GetKnownUserStringPref(account_id, kGAPSCookie, &gaps_cookie)) {
     return gaps_cookie;
   }
   return std::string();
 }
 
 User* UserManagerBase::RemoveRegularOrSupervisedUserFromList(
-    const std::string& user_id) {
+    const AccountId& account_id) {
   ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
   prefs_users_update->Clear();
-  User* user = NULL;
+  User* user = nullptr;
   for (UserList::iterator it = users_.begin(); it != users_.end();) {
-    const std::string user_email = (*it)->email();
-    if (user_email == user_id) {
+    if ((*it)->GetAccountId() == account_id) {
       user = *it;
       it = users_.erase(it);
     } else {
-      if ((*it)->HasGaiaAccount() || (*it)->IsSupervised())
+      if ((*it)->HasGaiaAccount() || (*it)->IsSupervised()) {
+        const std::string user_email = (*it)->email();
         prefs_users_update->Append(new base::StringValue(user_email));
+      }
       ++it;
     }
   }
-  OnUserRemoved(user_id);
+  OnUserRemoved(account_id);
   return user;
 }
 
-void UserManagerBase::RemoveKnownUserPrefs(const UserID& user_id) {
+void UserManagerBase::RemoveKnownUserPrefs(const AccountId& account_id) {
   ListPrefUpdate update(GetLocalState(), kKnownUsers);
   for (size_t i = 0; i < update->GetSize(); ++i) {
     base::DictionaryValue* element = nullptr;
     if (update->GetDictionary(i, &element)) {
-      if (UserMatches(user_id, *element)) {
+      if (UserMatches(account_id, *element)) {
         update->Remove(i, nullptr);
         break;
       }
@@ -1250,8 +1266,9 @@
   if (user->IsSupervised() == is_child)
     return;
   user->SetIsChild(is_child);
-  SaveUserType(user->email(), is_child ? user_manager::USER_TYPE_CHILD
-                                       : user_manager::USER_TYPE_REGULAR);
+  SaveUserType(user->GetAccountId(), is_child
+                                         ? user_manager::USER_TYPE_CHILD
+                                         : user_manager::USER_TYPE_REGULAR);
   FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
                     session_state_observer_list_,
                     UserChangedChildStatus(user));
@@ -1301,7 +1318,7 @@
   lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
 }
 
-void UserManagerBase::SendGaiaUserLoginMetrics(const std::string& user_id) {
+void UserManagerBase::SendGaiaUserLoginMetrics(const AccountId& account_id) {
   // If this isn't the first time Chrome was run after the system booted,
   // assume that Chrome was restarted because a previous session ended.
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -1310,7 +1327,8 @@
         GetLocalState()->GetString(kLastLoggedInGaiaUser);
     const base::TimeDelta time_to_login =
         base::TimeTicks::Now() - manager_creation_time_;
-    if (!last_email.empty() && user_id != last_email &&
+    if (!last_email.empty() &&
+        account_id != AccountId::FromUserEmail(last_email) &&
         time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
       UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
                                   time_to_login.InSeconds(),
@@ -1321,31 +1339,29 @@
   }
 }
 
-void UserManagerBase::UpdateUserAccountLocale(const std::string& user_id,
+void UserManagerBase::UpdateUserAccountLocale(const AccountId& account_id,
                                               const std::string& locale) {
   scoped_ptr<std::string> resolved_locale(new std::string());
   if (!locale.empty() && locale != GetApplicationLocale()) {
-    // base::Pased will NULL out |resolved_locale|, so cache the underlying ptr.
+    // base::Pased will nullptr out |resolved_locale|, so cache the underlying
+    // ptr.
     std::string* raw_resolved_locale = resolved_locale.get();
     blocking_task_runner_->PostTaskAndReply(
-        FROM_HERE,
-        base::Bind(ResolveLocale,
-                   locale,
-                   base::Unretained(raw_resolved_locale)),
+        FROM_HERE, base::Bind(ResolveLocale, locale,
+                              base::Unretained(raw_resolved_locale)),
         base::Bind(&UserManagerBase::DoUpdateAccountLocale,
-                   weak_factory_.GetWeakPtr(),
-                   user_id,
+                   weak_factory_.GetWeakPtr(), account_id,
                    base::Passed(&resolved_locale)));
   } else {
     resolved_locale.reset(new std::string(locale));
-    DoUpdateAccountLocale(user_id, resolved_locale.Pass());
+    DoUpdateAccountLocale(account_id, resolved_locale.Pass());
   }
 }
 
 void UserManagerBase::DoUpdateAccountLocale(
-    const std::string& user_id,
+    const AccountId& account_id,
     scoped_ptr<std::string> resolved_locale) {
-  User* user = FindUserAndModify(user_id);
+  User* user = FindUserAndModify(account_id);
   if (user && resolved_locale)
     user->SetAccountLocale(*resolved_locale);
 }
@@ -1354,7 +1370,7 @@
   const bool is_active_user = (user == active_user_);
   delete user;
   if (is_active_user)
-    active_user_ = NULL;
+    active_user_ = nullptr;
 }
 
 }  // namespace user_manager
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h
index a5f5f8f..ead7d449 100644
--- a/components/user_manager/user_manager_base.h
+++ b/components/user_manager/user_manager_base.h
@@ -15,8 +15,8 @@
 #include "base/observer_list.h"
 #include "base/synchronization/lock.h"
 #include "base/time/time.h"
+#include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/user.h"
-#include "components/user_manager/user_id.h"
 #include "components/user_manager/user_manager.h"
 #include "components/user_manager/user_manager_export.h"
 #include "components/user_manager/user_type.h"
@@ -51,37 +51,37 @@
   const UserList& GetUsers() const override;
   const UserList& GetLoggedInUsers() const override;
   const UserList& GetLRULoggedInUsers() const override;
-  const std::string& GetOwnerEmail() const override;
-  void UserLoggedIn(const std::string& user_id,
+  const AccountId& GetOwnerAccountId() const override;
+  void UserLoggedIn(const AccountId& account_id,
                     const std::string& user_id_hash,
                     bool browser_restart) override;
-  void SwitchActiveUser(const std::string& user_id) override;
+  void SwitchActiveUser(const AccountId& account_id) override;
   void SwitchToLastActiveUser() override;
   void SessionStarted() override;
-  void RemoveUser(const std::string& user_id,
+  void RemoveUser(const AccountId& account_id,
                   RemoveUserDelegate* delegate) override;
-  void RemoveUserFromList(const std::string& user_id) override;
-  bool IsKnownUser(const std::string& user_id) const override;
-  const User* FindUser(const std::string& user_id) const override;
-  User* FindUserAndModify(const std::string& user_id) override;
+  void RemoveUserFromList(const AccountId& account_id) override;
+  bool IsKnownUser(const AccountId& account_id) const override;
+  const User* FindUser(const AccountId& account_id) const override;
+  User* FindUserAndModify(const AccountId& account_id) override;
   const User* GetLoggedInUser() const override;
   User* GetLoggedInUser() override;
   const User* GetActiveUser() const override;
   User* GetActiveUser() override;
   const User* GetPrimaryUser() const override;
-  void SaveUserOAuthStatus(const std::string& user_id,
+  void SaveUserOAuthStatus(const AccountId& account_id,
                            User::OAuthTokenStatus oauth_token_status) override;
-  void SaveForceOnlineSignin(const std::string& user_id,
+  void SaveForceOnlineSignin(const AccountId& account_id,
                              bool force_online_signin) override;
-  void SaveUserDisplayName(const std::string& user_id,
+  void SaveUserDisplayName(const AccountId& account_id,
                            const base::string16& display_name) override;
-  base::string16 GetUserDisplayName(const std::string& user_id) const override;
-  void SaveUserDisplayEmail(const std::string& user_id,
+  base::string16 GetUserDisplayName(const AccountId& account_id) const override;
+  void SaveUserDisplayEmail(const AccountId& account_id,
                             const std::string& display_email) override;
-  std::string GetUserDisplayEmail(const std::string& user_id) const override;
-  void SaveUserType(const std::string& user_id,
+  std::string GetUserDisplayEmail(const AccountId& account_id) const override;
+  void SaveUserType(const AccountId& account_id,
                     const UserType& user_type) override;
-  void UpdateUserAccountData(const std::string& user_id,
+  void UpdateUserAccountData(const AccountId& account_id,
                              const UserAccountData& account_data) override;
   bool IsCurrentUserOwner() const override;
   bool IsCurrentUserNew() const override;
@@ -97,7 +97,7 @@
   bool IsLoggedInAsStub() const override;
   bool IsSessionStarted() const override;
   bool IsUserNonCryptohomeDataEphemeral(
-      const std::string& user_id) const override;
+      const AccountId& account_id) const override;
   void AddObserver(UserManager::Observer* obs) override;
   void RemoveObserver(UserManager::Observer* obs) override;
   void AddSessionStateObserver(
@@ -106,58 +106,61 @@
       UserManager::UserSessionStateObserver* obs) override;
   void NotifyLocalStateChanged() override;
   void ChangeUserChildStatus(User* user, bool is_child) override;
-  bool FindKnownUserPrefs(const UserID& user_id,
+  bool FindKnownUserPrefs(const AccountId& account_id,
                           const base::DictionaryValue** out_value) override;
-  void UpdateKnownUserPrefs(const UserID& user_id,
+  void UpdateKnownUserPrefs(const AccountId& account_id,
                             const base::DictionaryValue& values,
                             bool clear) override;
-  bool GetKnownUserStringPref(const UserID& user_id,
+  bool GetKnownUserStringPref(const AccountId& account_id,
                               const std::string& path,
                               std::string* out_value) override;
-  void SetKnownUserStringPref(const UserID& user_id,
+  void SetKnownUserStringPref(const AccountId& account_id,
                               const std::string& path,
                               const std::string& in_value) override;
-  bool GetKnownUserBooleanPref(const UserID& user_id,
+  bool GetKnownUserBooleanPref(const AccountId& account_id,
                                const std::string& path,
                                bool* out_value) override;
-  void SetKnownUserBooleanPref(const UserID& user_id,
+  void SetKnownUserBooleanPref(const AccountId& account_id,
                                const std::string& path,
                                const bool in_value) override;
-  bool GetKnownUserIntegerPref(const UserID& user_id,
+  bool GetKnownUserIntegerPref(const AccountId& account_id,
                                const std::string& path,
                                int* out_value) override;
-  void SetKnownUserIntegerPref(const UserID& user_id,
+  void SetKnownUserIntegerPref(const AccountId& account_id,
                                const std::string& path,
-                               const int in_value) override;
-  bool GetKnownUserCanonicalEmail(const UserID& user_id,
-                                  std::string* out_email) override;
-  void UpdateGaiaID(const UserID& user_id, const std::string& gaia_id) override;
-  bool FindGaiaID(const UserID& user_id, std::string* out_value) override;
-  void UpdateUsingSAML(const std::string& user_id,
+                               int in_value) override;
+  bool GetKnownUserAccountId(const AccountId& authenticated_account_id,
+                             AccountId* out_account_id) override;
+  void UpdateGaiaID(const AccountId& account_id,
+                    const std::string& gaia_id) override;
+  bool FindGaiaID(const AccountId& account_id, std::string* out_value) override;
+  void UpdateUsingSAML(const AccountId& account_id,
                        const bool using_saml) override;
-  bool FindUsingSAML(const std::string& user_id) override;
-  void SetKnownUserDeviceId(const UserID& user_id,
+  bool FindUsingSAML(const AccountId& account_id) override;
+  void SetKnownUserDeviceId(const AccountId& account_id,
                             const std::string& device_id) override;
-  std::string GetKnownUserDeviceId(const UserID& user_id) override;
-  void SetKnownUserGAPSCookie(const UserID& user_id,
+  std::string GetKnownUserDeviceId(const AccountId& account_id) override;
+  void SetKnownUserGAPSCookie(const AccountId& account_id,
                               const std::string& gaps_cookie) override;
-  std::string GetKnownUserGAPSCookie(const UserID& user_id) override;
-  void UpdateReauthReason(const std::string& user_id,
-                          const int reauth_reason) override;
-  bool FindReauthReason(const std::string& user_id, int* out_value) override;
+  std::string GetKnownUserGAPSCookie(const AccountId& account_id) override;
+  void UpdateReauthReason(const AccountId& account_id,
+                          int reauth_reason) override;
+  bool FindReauthReason(const AccountId& account_id, int* out_value) override;
 
+  // This method updates "User was added to the device in this session nad is
+  // not full initialized yet" flag.
   virtual void SetIsCurrentUserNew(bool is_new);
 
   // TODO(xiyuan): Figure out a better way to expose this info.
-  virtual bool HasPendingBootstrap(const std::string& user_id) const;
+  virtual bool HasPendingBootstrap(const AccountId& account_id) const;
 
   // Helper function that copies users from |users_list| to |users_vector| and
   // |users_set|. Duplicates and users already present in |existing_users| are
   // skipped.
   static void ParseUserList(const base::ListValue& users_list,
-                            const std::set<std::string>& existing_users,
-                            std::vector<std::string>* users_vector,
-                            std::set<std::string>* users_set);
+                            const std::set<AccountId>& existing_users,
+                            std::vector<AccountId>* users_vector,
+                            std::set<AccountId>* users_set);
 
   // Returns true if trusted device policies have successfully been retrieved
   // and ephemeral users are enabled.
@@ -185,9 +188,9 @@
   // Subsequent calls have no effect. Must be called on the UI thread.
   virtual void EnsureUsersLoaded();
 
-  // Handle OAuth token |status| change for |user_id|.
+  // Handle OAuth token |status| change for |account_id|.
   virtual void HandleUserOAuthTokenStatusChange(
-      const std::string& user_id,
+      const AccountId& account_id,
       User::OAuthTokenStatus status) const = 0;
 
   // Returns true if device is enterprise managed.
@@ -198,8 +201,7 @@
   // skipped.
   // Loads public accounts from the Local state and fills in
   // |public_sessions_set|.
-  virtual void LoadPublicAccounts(
-      std::set<std::string>* public_sessions_set) = 0;
+  virtual void LoadPublicAccounts(std::set<AccountId>* public_sessions_set) = 0;
 
   // Notifies that user has logged in.
   virtual void NotifyOnLogin();
@@ -224,36 +226,36 @@
 
   // Implementation for RemoveUser method. It is synchronous. It is called from
   // RemoveUserInternal after owner check.
-  virtual void RemoveNonOwnerUserInternal(const std::string& user_email,
+  virtual void RemoveNonOwnerUserInternal(const AccountId& account_id,
                                           RemoveUserDelegate* delegate);
 
   // Removes a regular or supervised user from the user list.
   // Returns the user if found or NULL otherwise.
   // Also removes the user from the persistent user list.
-  User* RemoveRegularOrSupervisedUserFromList(const std::string& user_id);
+  User* RemoveRegularOrSupervisedUserFromList(const AccountId& account_id);
 
   // Implementation for RemoveUser method. This is an asynchronous part of the
   // method, that verifies that owner will not get deleted, and calls
   // |RemoveNonOwnerUserInternal|.
-  virtual void RemoveUserInternal(const std::string& user_email,
+  virtual void RemoveUserInternal(const AccountId& account_id,
                                   RemoveUserDelegate* delegate);
 
   // Removes data stored or cached outside the user's cryptohome (wallpaper,
   // avatar, OAuth token status, display name, display email).
-  virtual void RemoveNonCryptohomeData(const std::string& user_id);
+  virtual void RemoveNonCryptohomeData(const AccountId& account_id);
 
   // Check for a particular user type.
 
-  // Returns true if |user_id| represents demo app.
-  virtual bool IsDemoApp(const std::string& user_id) const = 0;
+  // Returns true if |account_id| represents demo app.
+  virtual bool IsDemoApp(const AccountId& account_id) const = 0;
 
-  // Returns true if |user_id| represents kiosk app.
-  virtual bool IsKioskApp(const std::string& user_id) const = 0;
+  // Returns true if |account_id| represents kiosk app.
+  virtual bool IsKioskApp(const AccountId& account_id) const = 0;
 
-  // Returns true if |user_id| represents public account that has been marked
+  // Returns true if |account_id| represents public account that has been marked
   // for deletion.
   virtual bool IsPublicAccountMarkedForRemoval(
-      const std::string& user_id) const = 0;
+      const AccountId& account_id) const = 0;
 
   // These methods are called when corresponding user type has signed in.
 
@@ -264,22 +266,22 @@
   virtual void GuestUserLoggedIn();
 
   // Indicates that a kiosk app robot just logged in.
-  virtual void KioskAppLoggedIn(const std::string& app_id) = 0;
+  virtual void KioskAppLoggedIn(const AccountId& kiosk_app_account_id) = 0;
 
   // Indicates that a user just logged into a public session.
   virtual void PublicAccountUserLoggedIn(User* user) = 0;
 
   // Indicates that a regular user just logged in.
-  virtual void RegularUserLoggedIn(const std::string& user_id);
+  virtual void RegularUserLoggedIn(const AccountId& account_id);
 
   // Indicates that a regular user just logged in as ephemeral.
-  virtual void RegularUserLoggedInAsEphemeral(const std::string& user_id);
+  virtual void RegularUserLoggedInAsEphemeral(const AccountId& account_id);
 
   // Indicates that a supervised user just logged in.
-  virtual void SupervisedUserLoggedIn(const std::string& user_id) = 0;
+  virtual void SupervisedUserLoggedIn(const AccountId& account_id) = 0;
 
   // Should be called when regular user was removed.
-  virtual void OnUserRemoved(const std::string& user_id) = 0;
+  virtual void OnUserRemoved(const AccountId& account_id) = 0;
 
   // Getters/setters for private members.
 
@@ -288,20 +290,20 @@
   virtual bool GetEphemeralUsersEnabled() const;
   virtual void SetEphemeralUsersEnabled(bool enabled);
 
-  virtual void SetOwnerEmail(const std::string& owner_user_id);
+  virtual void SetOwnerId(const AccountId& owner_account_id);
 
-  virtual const std::string& GetPendingUserSwitchID() const;
-  virtual void SetPendingUserSwitchID(const std::string& user_id);
+  virtual const AccountId& GetPendingUserSwitchID() const;
+  virtual void SetPendingUserSwitchId(const AccountId& account_id);
 
   // The logged-in user that is currently active in current session.
   // NULL until a user has logged in, then points to one
   // of the User instances in |users_|, the |guest_user_| instance or an
   // ephemeral user instance.
-  User* active_user_;
+  User* active_user_ = nullptr;
 
   // The primary user of the current session. It is recorded for the first
   // signed-in user and does not change thereafter.
-  User* primary_user_;
+  User* primary_user_ = nullptr;
 
   // List of all known users. User instances are owned by |this|. Regular users
   // are removed by |RemoveUserFromList|, public accounts by
@@ -328,21 +330,21 @@
 
   // Returns the user with the given email address if found in the persistent
   // list. Returns |NULL| otherwise.
-  const User* FindUserInList(const std::string& user_id) const;
+  const User* FindUserInList(const AccountId& account_id) const;
 
   // Returns |true| if user with the given id is found in the persistent list.
   // Returns |false| otherwise. Does not trigger user loading.
-  bool UserExistsInList(const std::string& user_id) const;
+  bool UserExistsInList(const AccountId& account_id) const;
 
   // Same as FindUserInList but returns non-const pointer to User object.
-  User* FindUserInListAndModify(const std::string& user_id);
+  User* FindUserInListAndModify(const AccountId& account_id);
 
   // Reads user's oauth token status from local state preferences.
-  User::OAuthTokenStatus LoadUserOAuthStatus(const std::string& user_id) const;
+  User::OAuthTokenStatus LoadUserOAuthStatus(const AccountId& account_id) const;
 
   // Read a flag indicating whether online authentication against GAIA should
   // be enforced during the user's next sign-in from local state preferences.
-  bool LoadForceOnlineSignin(const std::string& user_id) const;
+  bool LoadForceOnlineSignin(const AccountId& account_id) const;
 
   // Notifies observers that merge session state had changed.
   void NotifyMergeSessionStateChanged();
@@ -350,7 +352,7 @@
   // Notifies observers that active user has changed.
   void NotifyActiveUserChanged(const User* active_user);
 
-  // Notifies observers that active user_id hash has changed.
+  // Notifies observers that active account_id hash has changed.
   void NotifyActiveUserHashChanged(const std::string& hash);
 
   // Update the global LoginState.
@@ -360,49 +362,49 @@
   void SetLRUUser(User* user);
 
   // Sends metrics in response to a user with gaia account (regular) logging in.
-  void SendGaiaUserLoginMetrics(const std::string& user_id);
+  void SendGaiaUserLoginMetrics(const AccountId& account_id);
 
-  // Sets account locale for user with id |user_id|.
-  virtual void UpdateUserAccountLocale(const std::string& user_id,
+  // Sets account locale for user with id |account_id|.
+  virtual void UpdateUserAccountLocale(const AccountId& account_id,
                                        const std::string& locale);
 
   // Updates user account after locale was resolved.
-  void DoUpdateAccountLocale(const std::string& user_id,
+  void DoUpdateAccountLocale(const AccountId& account_id,
                              scoped_ptr<std::string> resolved_locale);
 
-  // Removes all user preferences associated with |user_id|.
-  void RemoveKnownUserPrefs(const UserID& user_id);
+  // Removes all user preferences associated with |account_id|.
+  void RemoveKnownUserPrefs(const AccountId& account_id);
 
   // Indicates stage of loading user from prefs.
-  UserLoadStage user_loading_stage_;
+  UserLoadStage user_loading_stage_ = STAGE_NOT_LOADED;
 
   // True if SessionStarted() has been called.
-  bool session_started_;
+  bool session_started_ = false;
 
   // Cached flag of whether currently logged-in user is owner or not.
   // May be accessed on different threads, requires locking.
-  bool is_current_user_owner_;
+  bool is_current_user_owner_ = false;
   mutable base::Lock is_current_user_owner_lock_;
 
   // Cached flag of whether the currently logged-in user existed before this
   // login.
-  bool is_current_user_new_;
+  bool is_current_user_new_ = false;
 
   // Cached flag of whether the currently logged-in user is a regular user who
   // logged in as ephemeral. Storage of persistent information is avoided for
   // such users by not adding them to the persistent user list, not downloading
   // their custom avatars and mounting their cryptohomes using tmpfs. Defaults
   // to |false|.
-  bool is_current_user_ephemeral_regular_user_;
+  bool is_current_user_ephemeral_regular_user_ = false;
 
   // Cached flag indicating whether the ephemeral user policy is enabled.
   // Defaults to |false| if the value has not been read from trusted device
   // policy yet.
-  bool ephemeral_users_enabled_;
+  bool ephemeral_users_enabled_ = false;
 
-  // Cached name of device owner. Defaults to empty string if the value has not
+  // Cached name of device owner. Defaults to empty if the value has not
   // been read from trusted device policy yet.
-  std::string owner_email_;
+  AccountId owner_account_id_ = EmptyAccountId();
 
   base::ObserverList<UserManager::Observer> observer_list_;
 
@@ -411,17 +413,17 @@
       session_state_observer_list_;
 
   // Time at which this object was created.
-  base::TimeTicks manager_creation_time_;
+  base::TimeTicks manager_creation_time_ = base::TimeTicks::Now();
 
   // ID of the user just added to the session that needs to be activated
   // as soon as user's profile is loaded.
-  std::string pending_user_switch_;
+  AccountId pending_user_switch_ = EmptyAccountId();
 
   // ID of the user that was active in the previous session.
   // Preference value is stored here before first user signs in
   // because pref will be overidden once session restore starts.
-  std::string last_session_active_user_;
-  bool last_session_active_user_initialized_;
+  AccountId last_session_active_account_id_ = EmptyAccountId();
+  bool last_session_active_account_id_initialized_ = false;
 
   // TaskRunner for UI thread.
   scoped_refptr<base::TaskRunner> task_runner_;
diff --git a/components/wallpaper/wallpaper_manager_base.cc b/components/wallpaper/wallpaper_manager_base.cc
index 8afdc1c..cd0bf89 100644
--- a/components/wallpaper/wallpaper_manager_base.cc
+++ b/components/wallpaper/wallpaper_manager_base.cc
@@ -501,8 +501,8 @@
 void WallpaperManagerBase::SetPolicyControlledWallpaper(
     const std::string& user_id,
     const user_manager::UserImage& user_image) {
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(user_id);
+  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
+      AccountId::FromUserEmail(user_id));
   if (!user) {
     NOTREACHED() << "Unknown user.";
     return;
@@ -886,7 +886,7 @@
     info.location = base::FilePath(user_id_hash).Append(info.location).value();
     bool is_persistent =
         !user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
-            user_id);
+            AccountId::FromUserEmail(user_id));
     SetUserWallpaperInfo(user_id, info, is_persistent);
   }
 }
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 32298516..2dd1dfc 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -667,11 +667,11 @@
   // Enable memory-infra dump providers.
   InitSkiaEventTracer();
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      HostSharedBitmapManager::current());
+      HostSharedBitmapManager::current(), "HostSharedBitmapManager", nullptr);
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      skia::SkiaMemoryDumpProvider::GetInstance());
+      skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      sql::SqlMemoryDumpProvider::GetInstance());
+      sql::SqlMemoryDumpProvider::GetInstance(), "Sql", nullptr);
 
 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
   trace_memory_controller_.reset(new base::trace_event::TraceMemoryController(
@@ -1195,10 +1195,12 @@
   // unregistration happens on the IO thread (See
   // BrowserProcessSubThread::IOThreadPreCleanUp).
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      BrowserGpuMemoryBufferManager::current(), io_thread_->task_runner());
+      BrowserGpuMemoryBufferManager::current(), "BrowserGpuMemoryBufferManager",
+      io_thread_->task_runner());
 #if defined(OS_ANDROID)
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      tracing::GraphicsMemoryDumpProvider::GetInstance());
+      tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
+      nullptr);
 #endif
 
   {
diff --git a/content/browser/device_sensors/data_fetcher_shared_memory_base.cc b/content/browser/device_sensors/data_fetcher_shared_memory_base.cc
index 385aa185..17efaa5b 100644
--- a/content/browser/device_sensors/data_fetcher_shared_memory_base.cc
+++ b/content/browser/device_sensors/data_fetcher_shared_memory_base.cc
@@ -91,7 +91,7 @@
   if (!fetcher_->Stop(consumer_type))
     return;
 
-  consumers_bitmask_ ^= consumer_type;
+  consumers_bitmask_ &= ~consumer_type;
 
   if (!consumers_bitmask_)
     timer_.reset();  // will also stop the timer.
diff --git a/content/browser/frame_host/render_frame_host_delegate.cc b/content/browser/frame_host/render_frame_host_delegate.cc
index 1c8ecd93..69b9e98 100644
--- a/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/content/browser/frame_host/render_frame_host_delegate.cc
@@ -66,6 +66,10 @@
   return NULL;
 }
 
+WakeLockServiceContext* RenderFrameHostDelegate::GetWakeLockServiceContext() {
+  return nullptr;
+}
+
 bool RenderFrameHostDelegate::ShouldRouteMessageEvent(
     RenderFrameHost* target_rfh,
     SiteInstance* source_site_instance) const {
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
index 0f8e555..57f6af3 100644
--- a/content/browser/frame_host/render_frame_host_delegate.h
+++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -29,6 +29,7 @@
 namespace content {
 class GeolocationServiceContext;
 class RenderFrameHost;
+class WakeLockServiceContext;
 class WebContents;
 struct AXEventNotificationDetails;
 struct ContextMenuParams;
@@ -136,6 +137,9 @@
   // Gets the GeolocationServiceContext associated with this delegate.
   virtual GeolocationServiceContext* GetGeolocationServiceContext();
 
+  // Gets the WakeLockServiceContext associated with this delegate.
+  virtual WakeLockServiceContext* GetWakeLockServiceContext();
+
   // Notification that the frame wants to go into fullscreen mode.
   // |origin| represents the origin of the frame that requests fullscreen.
   virtual void EnterFullscreenMode(const GURL& origin) {}
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index a9cd3bf..66e303c 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -42,6 +42,7 @@
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
+#include "content/browser/wake_lock/wake_lock_service_context.h"
 #include "content/common/accessibility_messages.h"
 #include "content/common/frame_messages.h"
 #include "content/common/input_messages.h"
@@ -1630,6 +1631,18 @@
                               base::Unretained(this))));
   }
 
+  WakeLockServiceContext* wake_lock_service_context =
+      delegate_ ? delegate_->GetWakeLockServiceContext() : nullptr;
+  if (wake_lock_service_context) {
+    // WakeLockServiceContext is owned by WebContentsImpl so it will outlive
+    // this RenderFrameHostImpl, hence a raw pointer can be bound to service
+    // factory callback.
+    GetServiceRegistry()->AddService<WakeLockService>(
+        base::Bind(&WakeLockServiceContext::CreateService,
+                   base::Unretained(wake_lock_service_context),
+                   GetProcess()->GetID(), GetRoutingID()));
+  }
+
   if (!permission_service_context_)
     permission_service_context_.reset(new PermissionServiceContext(this));
 
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
index 427a518..189f0c5e 100644
--- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
+++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -130,7 +130,7 @@
         gfx::BufferFormat::RGBA_8888, gfx::BufferFormat::BGRA_8888,
         gfx::BufferFormat::UYVY_422,  gfx::BufferFormat::YUV_420_BIPLANAR};
     const gfx::BufferUsage kNativeUsages[] = {
-        gfx::BufferUsage::GPU_READ, gfx::BufferUsage::GPU_READ_WRITE,
+        gfx::BufferUsage::GPU_READ, gfx::BufferUsage::SCANOUT,
         gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
         gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT};
     for (auto& format : kNativeFormats) {
@@ -148,9 +148,9 @@
         gfx::BufferFormat::UYVY_422,  gfx::BufferFormat::YUV_420_BIPLANAR};
     for (auto& format : kGPUReadWriteFormats) {
       if (IsNativeGpuMemoryBufferFactoryConfigurationSupported(
-              format, gfx::BufferUsage::GPU_READ_WRITE)) {
+              format, gfx::BufferUsage::SCANOUT)) {
         configurations.insert(
-            std::make_pair(format, gfx::BufferUsage::GPU_READ_WRITE));
+            std::make_pair(format, gfx::BufferUsage::SCANOUT));
       }
     }
   }
@@ -291,7 +291,7 @@
     int32 surface_id) {
   DCHECK_GT(surface_id, 0);
   return AllocateGpuMemoryBufferForSurface(
-      size, format, gfx::BufferUsage::GPU_READ_WRITE, surface_id);
+      size, format, gfx::BufferUsage::SCANOUT, surface_id);
 }
 
 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc
index 70779d8..eb85106 100644
--- a/content/browser/gpu/gpu_internals_ui.cc
+++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -272,8 +272,8 @@
   switch (usage) {
     case gfx::BufferUsage::GPU_READ:
       return "GPU_READ";
-    case gfx::BufferUsage::GPU_READ_WRITE:
-      return "GPU_READ_WRITE";
+    case gfx::BufferUsage::SCANOUT:
+      return "SCANOUT";
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
       return "GPU_READ_CPU_READ_WRITE";
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc
index b12f283c3..75523f1e 100644
--- a/content/browser/renderer_host/input/touch_action_filter.cc
+++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -87,8 +87,7 @@
 
     case WebInputEvent::GesturePinchBegin:
       DCHECK(!drop_pinch_gesture_events_);
-      if (allowed_touch_action_ == TOUCH_ACTION_AUTO ||
-          allowed_touch_action_ & TOUCH_ACTION_PINCH_ZOOM) {
+      if (allowed_touch_action_ & TOUCH_ACTION_PINCH_ZOOM) {
         // Pinch events are always bracketed by scroll events, and the W3C
         // standard touch-action provides no way to disable scrolling without
         // also disabling pinching (validated by the IPC ENUM traits).
@@ -124,7 +123,7 @@
     case WebInputEvent::GestureTapUnconfirmed:
       DCHECK_EQ(1, gesture_event->data.tap.tapCount);
       allow_current_double_tap_event_ =
-          allowed_touch_action_ == TOUCH_ACTION_AUTO;
+          (allowed_touch_action_ & TOUCH_ACTION_DOUBLE_TAP_ZOOM) != 0;
       if (!allow_current_double_tap_event_) {
         gesture_event->type = WebInputEvent::GestureTap;
         drop_current_tap_ending_event_ = true;
@@ -133,7 +132,7 @@
 
     case WebInputEvent::GestureTap:
       allow_current_double_tap_event_ =
-          allowed_touch_action_ == TOUCH_ACTION_AUTO;
+          (allowed_touch_action_ & TOUCH_ACTION_DOUBLE_TAP_ZOOM) != 0;
       // Fall through.
     case WebInputEvent::GestureTapCancel:
       if (drop_current_tap_ending_event_) {
@@ -176,7 +175,7 @@
   //    down "at once" will be deterministic.
   // 2. Only subtractive - eg. can't trigger scrolling on a element that
   //    otherwise has scrolling disabling by the addition of a finger.
-  allowed_touch_action_ = Intersect(allowed_touch_action_, touch_action);
+  allowed_touch_action_ &= touch_action;
 }
 
 void TouchActionFilter::ResetTouchAction() {
@@ -188,9 +187,11 @@
 bool TouchActionFilter::ShouldSuppressScroll(
     const blink::WebGestureEvent& gesture_event) {
   DCHECK_EQ(gesture_event.type, WebInputEvent::GestureScrollBegin);
-  if (allowed_touch_action_ == TOUCH_ACTION_AUTO)
+  if ((allowed_touch_action_ & TOUCH_ACTION_PAN) == TOUCH_ACTION_PAN)
+    // All possible panning is enabled.
     return false;
-  if (allowed_touch_action_ == TOUCH_ACTION_NONE)
+  if (!(allowed_touch_action_ & TOUCH_ACTION_PAN))
+    // No panning is enabled.
     return true;
 
   // If there's no hint or it's perfectly diagonal, then allow the scroll.
@@ -224,18 +225,4 @@
   }
 }
 
-TouchAction TouchActionFilter::Intersect(TouchAction ta1, TouchAction ta2) {
-  if (ta1 == TOUCH_ACTION_NONE || ta2 == TOUCH_ACTION_NONE)
-    return TOUCH_ACTION_NONE;
-  if (ta1 == TOUCH_ACTION_AUTO)
-    return ta2;
-  if (ta2 == TOUCH_ACTION_AUTO)
-    return ta1;
-
-  // Only the true flags are left - take their intersection.
-  if (!(ta1 & ta2))
-    return TOUCH_ACTION_NONE;
-  return static_cast<TouchAction>(ta1 & ta2);
-}
-
 }  // namespace content
diff --git a/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
index c435d1e6..a114b79 100644
--- a/content/browser/renderer_host/input/touch_action_filter_unittest.cc
+++ b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
@@ -299,7 +299,7 @@
   {
     // Scrolls hinted in the X axis are permitted and unmodified.
     filter.ResetTouchAction();
-    filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
+    filter.OnSetTouchAction(TOUCH_ACTION_PAN);
     WebGestureEvent scroll_begin =
         SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6);
     EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
@@ -321,7 +321,7 @@
   {
     // Scrolls hinted in the Y axis are permitted and unmodified.
     filter.ResetTouchAction();
-    filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
+    filter.OnSetTouchAction(TOUCH_ACTION_PAN);
     WebGestureEvent scroll_begin =
         SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7);
     EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
@@ -342,25 +342,17 @@
   filter.ResetTouchAction();
 }
 
-TEST(TouchActionFilterTest, Intersect) {
-  EXPECT_EQ(TOUCH_ACTION_NONE,
-      TouchActionFilter::Intersect(TOUCH_ACTION_NONE, TOUCH_ACTION_AUTO));
-  EXPECT_EQ(TOUCH_ACTION_NONE,
-      TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_NONE));
-  EXPECT_EQ(TOUCH_ACTION_PAN_X,
-      TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_PAN_X));
-  EXPECT_EQ(TOUCH_ACTION_PAN_Y,
-      TouchActionFilter::Intersect(TOUCH_ACTION_PAN_Y, TOUCH_ACTION_AUTO));
+TEST(TouchActionFilterTest, BitMath) {
+  // Verify that the simple flag mixing properties we depend on are now
+  // trivially true.
+  EXPECT_EQ(TOUCH_ACTION_NONE, TOUCH_ACTION_NONE & TOUCH_ACTION_AUTO);
+  EXPECT_EQ(TOUCH_ACTION_NONE, TOUCH_ACTION_PAN_Y & TOUCH_ACTION_PAN_X);
+  EXPECT_EQ(TOUCH_ACTION_PAN, TOUCH_ACTION_AUTO & TOUCH_ACTION_PAN);
+  EXPECT_EQ(TOUCH_ACTION_MANIPULATION,
+            TOUCH_ACTION_AUTO & ~TOUCH_ACTION_DOUBLE_TAP_ZOOM);
+  EXPECT_EQ(TOUCH_ACTION_PAN_X, TOUCH_ACTION_PAN_LEFT | TOUCH_ACTION_PAN_RIGHT);
   EXPECT_EQ(TOUCH_ACTION_AUTO,
-      TouchActionFilter::Intersect(TOUCH_ACTION_AUTO, TOUCH_ACTION_AUTO));
-  EXPECT_EQ(TOUCH_ACTION_PAN_X,
-      TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X_Y, TOUCH_ACTION_PAN_X));
-  EXPECT_EQ(TOUCH_ACTION_PAN_Y,
-      TouchActionFilter::Intersect(TOUCH_ACTION_PAN_Y, TOUCH_ACTION_PAN_X_Y));
-  EXPECT_EQ(TOUCH_ACTION_PAN_X_Y,
-      TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X_Y, TOUCH_ACTION_AUTO));
-  EXPECT_EQ(TOUCH_ACTION_NONE,
-      TouchActionFilter::Intersect(TOUCH_ACTION_PAN_X, TOUCH_ACTION_PAN_Y));
+            TOUCH_ACTION_MANIPULATION | TOUCH_ACTION_DOUBLE_TAP_ZOOM);
 }
 
 TEST(TouchActionFilterTest, MultiTouch) {
@@ -391,7 +383,7 @@
   filter.ResetTouchAction();
   filter.OnSetTouchAction(TOUCH_ACTION_PAN_X);
   filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y);
-  filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
+  filter.OnSetTouchAction(TOUCH_ACTION_PAN);
   EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin));
   EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update));
   EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end));
@@ -433,7 +425,7 @@
 
   // Pinch is not allowed with touch-action: pan-x pan-y.
   filter.ResetTouchAction();
-  filter.OnSetTouchAction(TOUCH_ACTION_PAN_X_Y);
+  filter.OnSetTouchAction(TOUCH_ACTION_PAN);
   EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin));
   EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin));
   EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update));
diff --git a/content/browser/renderer_host/render_widget_host_delegate.cc b/content/browser/renderer_host/render_widget_host_delegate.cc
index fd9c1cb..7b8def6 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.cc
+++ b/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -47,10 +47,4 @@
   return nullptr;
 }
 
-// If a delegate does not override this, the RenderWidgetHostView will
-// assume its own RenderWidgetHost should consume keyboard events.
-RenderWidgetHostImpl* RenderWidgetHostDelegate::GetFocusedRenderWidgetHost() {
-  return nullptr;
-}
-
 }  // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h
index 708d2b9..e9c043e9 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -105,12 +105,6 @@
   // current FrameTree, not including the main frame's SiteInstance.
   virtual void ReplicatePageFocus(bool is_focused) {}
 
-  // Get the RenderWidgetHost of the currently focused frame.  With
-  // out-of-process iframes, multiple RenderWidgetHosts may be involved in
-  // rendering a page, and this function determines which RenderWidgetHost
-  // should consume a keyboard input event.
-  virtual RenderWidgetHostImpl* GetFocusedRenderWidgetHost();
-
 #if defined(OS_WIN)
   virtual gfx::NativeViewAccessible GetParentNativeViewAccessible();
 #endif
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 47357ac3..3b3fb8a3 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1675,21 +1675,8 @@
 
 void RenderWidgetHostViewAndroid::SendKeyEvent(
     const NativeWebKeyboardEvent& event) {
-  if (!host_)
-    return;
-
-  RenderWidgetHostImpl* target_host = host_;
-
-  // If there are multiple widgets on the page (such as when there are
-  // out-of-process iframes), pick the one that should process this event.
-  if (host_->delegate()) {
-    RenderWidgetHostImpl* focused_host =
-        host_->delegate()->GetFocusedRenderWidgetHost();
-    if (focused_host)
-      target_host = focused_host;
-  }
-
-  target_host->ForwardKeyboardEvent(event);
+  if (host_)
+    host_->ForwardKeyboardEvent(event);
 }
 
 void RenderWidgetHostViewAndroid::SendMouseEvent(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 4dada34..bbb79c9 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2738,17 +2738,6 @@
 
 void RenderWidgetHostViewAura::ForwardKeyboardEvent(
     const NativeWebKeyboardEvent& event) {
-  RenderWidgetHostImpl* target_host = host_;
-
-  // If there are multiple widgets on the page (such as when there are
-  // out-of-process iframes), pick the one that should process this event.
-  if (host_->delegate()) {
-    RenderWidgetHostImpl* focused_host =
-        host_->delegate()->GetFocusedRenderWidgetHost();
-    if (focused_host)
-      target_host = focused_host;
-  }
-
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   ui::TextEditKeyBindingsDelegateAuraLinux* keybinding_delegate =
       ui::GetTextEditKeyBindingsDelegate();
@@ -2764,19 +2753,16 @@
       edit_commands.push_back(EditCommand(it->GetCommandString(),
                                           it->argument()));
     }
-    // TODO(alexmos): This needs to be refactored to work with subframe
-    // RenderWidgetHosts for OOPIF.  See https://crbug.com/549334.
-    target_host->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
-        target_host->GetRoutingID(), edit_commands));
-
+    host_->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
+        host_->GetRoutingID(), edit_commands));
     NativeWebKeyboardEvent copy_event(event);
     copy_event.match_edit_command = true;
-    target_host->ForwardKeyboardEvent(event);
+    host_->ForwardKeyboardEvent(copy_event);
     return;
   }
 #endif
 
-  target_host->ForwardKeyboardEvent(event);
+  host_->ForwardKeyboardEvent(event);
 }
 
 void RenderWidgetHostViewAura::SelectionUpdated(bool is_editable,
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index b349033..fb89516 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -2092,15 +2092,6 @@
     return;
   }
 
-  // If there are multiple widgets on the page (such as when there are
-  // out-of-process iframes), pick the one that should process this event.
-  if (widgetHost->delegate()) {
-    RenderWidgetHostImpl* focusedHost =
-        widgetHost->delegate()->GetFocusedRenderWidgetHost();
-    if (focusedHost)
-      widgetHost = focusedHost;
-  }
-
   // Suppress the escape key up event if necessary.
   if (event.windowsKeyCode == ui::VKEY_ESCAPE && suppressNextEscapeKeyUp_) {
     if (event.type == NativeWebKeyboardEvent::KeyUp)
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index f4beb0be..6bb654a 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -97,18 +97,6 @@
   EXPECT_TRUE(success);
 }
 
-// Helper function to generate a click on the given RenderWidgetHost.  The
-// mouse event is forwarded directly to the RenderWidgetHost without any
-// hit-testing.
-void SimulateMouseClick(RenderWidgetHost* rwh, int x, int y) {
-  blink::WebMouseEvent mouse_event;
-  mouse_event.type = blink::WebInputEvent::MouseDown;
-  mouse_event.button = blink::WebPointerProperties::ButtonLeft;
-  mouse_event.x = x;
-  mouse_event.y = y;
-  rwh->ForwardMouseEvent(mouse_event);
-}
-
 class RedirectNotificationObserver : public NotificationObserver {
  public:
   // Register to listen for notifications of the given type from either a
@@ -3500,8 +3488,14 @@
   DOMMessageQueue msg_queue;
 
   // Click on the cross-process subframe.
-  SimulateMouseClick(
-      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);
+  blink::WebMouseEvent mouse_event;
+  mouse_event.type = blink::WebInputEvent::MouseDown;
+  mouse_event.button = blink::WebPointerProperties::ButtonLeft;
+  mouse_event.x = 1;
+  mouse_event.y = 1;
+  RenderWidgetHost* rwh_child =
+      root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
+  rwh_child->ForwardMouseEvent(mouse_event);
 
   // Check that the main frame lost focus and fired blur event on the input
   // text field.
@@ -3515,8 +3509,8 @@
   EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
 
   // Click on the root frame.
-  SimulateMouseClick(
-      shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1);
+  shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
+      mouse_event);
 
   // Check that the subframe lost focus and fired blur event on its
   // document's body.
@@ -3632,47 +3626,4 @@
   EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url);
 }
 
-// Ensure that a cross-process subframe can receive keyboard events when in
-// focus.
-IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
-                       SubframeKeyboardEventRouting) {
-  GURL main_url(embedded_test_server()->GetURL(
-      "a.com", "/frame_tree/page_with_one_frame.html"));
-  EXPECT_TRUE(NavigateToURL(shell(), main_url));
-
-  WebContentsImpl* web_contents =
-      static_cast<WebContentsImpl*>(shell()->web_contents());
-  FrameTreeNode* root = web_contents->GetFrameTree()->root();
-
-  GURL frame_url(
-      embedded_test_server()->GetURL("b.com", "/page_with_input_field.html"));
-  NavigateFrameToURL(root->child_at(0), frame_url);
-  EXPECT_TRUE(WaitForRenderFrameReady(root->child_at(0)->current_frame_host()));
-
-  // Click on the subframe to focus it.
-  SimulateMouseClick(
-      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);
-
-  // Focus the input field in the subframe.  The return value "input-focus"
-  // will be sent once the input field's focus event fires.
-  std::string result;
-  EXPECT_TRUE(ExecuteScriptAndExtractString(
-      root->child_at(0)->current_frame_host(), "focusInputField()", &result));
-  EXPECT_EQ(result, "input-focus");
-
-  // The subframe should now be focused.
-  EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
-
-  // Generate a few keyboard events and route them to currently focused frame.
-  SimulateKeyPress(web_contents, ui::VKEY_F, false, false, false, false);
-  SimulateKeyPress(web_contents, ui::VKEY_O, false, false, false, false);
-  SimulateKeyPress(web_contents, ui::VKEY_O, false, false, false, false);
-
-  // Verify that the input field in the subframe received the keystrokes.
-  EXPECT_TRUE(ExecuteScriptAndExtractString(
-      root->child_at(0)->current_frame_host(),
-      "window.domAutomationController.send(getInputFieldText());", &result));
-  EXPECT_EQ("FOO", result);
-}
-
 }  // namespace content
diff --git a/content/browser/tracing/background_tracing_config_impl.cc b/content/browser/tracing/background_tracing_config_impl.cc
index 2e25b22d..57daf1b 100644
--- a/content/browser/tracing/background_tracing_config_impl.cc
+++ b/content/browser/tracing/background_tracing_config_impl.cc
@@ -27,6 +27,7 @@
 const char kConfigCategoryBenchmarkGPU[] = "BENCHMARK_GPU";
 const char kConfigCategoryBenchmarkIPC[] = "BENCHMARK_IPC";
 const char kConfigCategoryBenchmarkStartup[] = "BENCHMARK_STARTUP";
+const char kConfigCategoryBlinkStyle[] = "BLINK_STYLE";
 
 }  // namespace
 
@@ -50,6 +51,8 @@
       return kConfigCategoryBenchmarkIPC;
     case BackgroundTracingConfigImpl::BENCHMARK_STARTUP:
       return kConfigCategoryBenchmarkStartup;
+    case BackgroundTracingConfigImpl::BLINK_STYLE:
+      return kConfigCategoryBlinkStyle;
   }
   NOTREACHED();
   return "";
@@ -83,6 +86,11 @@
     return true;
   }
 
+  if (category_preset_string == kConfigCategoryBlinkStyle) {
+    *category_preset = BackgroundTracingConfigImpl::BLINK_STYLE;
+    return true;
+  }
+
   return false;
 }
 
diff --git a/content/browser/tracing/background_tracing_config_impl.h b/content/browser/tracing/background_tracing_config_impl.h
index 03963b2..717696000 100644
--- a/content/browser/tracing/background_tracing_config_impl.h
+++ b/content/browser/tracing/background_tracing_config_impl.h
@@ -29,6 +29,7 @@
     BENCHMARK_GPU,
     BENCHMARK_IPC,
     BENCHMARK_STARTUP,
+    BLINK_STYLE
   };
 
   CategoryPreset category_preset() const { return category_preset_; }
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc
index 23524a50..21d6125b 100644
--- a/content/browser/tracing/background_tracing_manager_impl.cc
+++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -583,6 +583,8 @@
       return "benchmark,toplevel,startup,disabled-by-default-file,"
              "disabled-by-default-toplevel.flow,"
              "disabled-by-default-ipc.flow";
+    case BackgroundTracingConfigImpl::CategoryPreset::BLINK_STYLE:
+      return "blink_style";
   }
   NOTREACHED();
   return "";
diff --git a/content/browser/tracing/memory_tracing_browsertest.cc b/content/browser/tracing/memory_tracing_browsertest.cc
index b9261d0..64519ac 100644
--- a/content/browser/tracing/memory_tracing_browsertest.cc
+++ b/content/browser/tracing/memory_tracing_browsertest.cc
@@ -72,7 +72,7 @@
 
     mock_dump_provider_.reset(new MockDumpProvider());
     MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        mock_dump_provider_.get());
+        mock_dump_provider_.get(), "MockDumpProvider", nullptr);
     MemoryDumpManager::GetInstance()
         ->set_dumper_registrations_ignored_for_testing(false);
     ContentBrowserTest::SetUp();
diff --git a/content/browser/wake_lock/wake_lock_browsertest.cc b/content/browser/wake_lock/wake_lock_browsertest.cc
new file mode 100644
index 0000000..6e7d2d9
--- /dev/null
+++ b/content/browser/wake_lock/wake_lock_browsertest.cc
@@ -0,0 +1,376 @@
+// Copyright 2015 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.
+
+#include "base/command_line.h"
+#include "base/test/test_timeouts.h"
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace content {
+
+namespace {
+
+const char kBlinkWakeLockFeature[] = "WakeLock";
+
+}  // namespace
+
+class WakeLockTest : public ContentBrowserTest {
+ public:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
+                                    kBlinkWakeLockFeature);
+    command_line->AppendSwitch(switches::kSitePerProcess);
+  }
+
+  void SetUpOnMainThread() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+    EXPECT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+    // To prevent occlusion events from changing page visibility.
+    GetWebContents()->IncrementCapturerCount(gfx::Size());
+  }
+
+  void TearDownOnMainThread() override {
+    GetWebContents()->DecrementCapturerCount();
+  }
+
+ protected:
+  WebContents* GetWebContents() { return shell()->web_contents(); }
+
+  WebContentsImpl* GetWebContentsImpl() {
+    return static_cast<WebContentsImpl*>(GetWebContents());
+  }
+
+  RenderFrameHost* GetMainFrame() { return GetWebContents()->GetMainFrame(); }
+
+  FrameTreeNode* GetNestedFrameNode() {
+    FrameTreeNode* root = GetWebContentsImpl()->GetFrameTree()->root();
+    CHECK_EQ(1U, root->child_count());
+    return root->child_at(0);
+  }
+
+  RenderFrameHost* GetNestedFrame() {
+    return GetNestedFrameNode()->current_frame_host();
+  }
+
+  WakeLockServiceContext* GetWakeLockServiceContext() {
+    return GetWebContentsImpl()->GetWakeLockServiceContext();
+  }
+
+  bool HasWakeLock() {
+    return GetWakeLockServiceContext()->HasWakeLockForTests();
+  }
+
+  void WaitForPossibleUpdate() {
+    // As Mojo channels have no common FIFO order in respect to each other and
+    // to the Chromium IPC, we cannot assume that when screen.keepAwake state
+    // is changed from within a script, WakeLockService will receive an update
+    // request before ExecuteScript() returns. Therefore, some time slack is
+    // needed to make sure that WakeLockService has received any possible update
+    // requests before checking the resulting wake lock state.
+    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
+    RunAllPendingInMessageLoop();
+  }
+
+  void ScreenWakeLockInMainFrame() {
+    EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+    WaitForPossibleUpdate();
+    EXPECT_TRUE(HasWakeLock());
+  }
+
+  bool EvaluateAsBool(const ToRenderFrameHost& adapter,
+                      const std::string& expr) {
+    bool result;
+    CHECK(ExecuteScriptAndExtractBool(
+        adapter, "window.domAutomationController.send(" + expr + ");",
+        &result));
+    return result;
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, WakeLockApiIsPresent) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+  EXPECT_TRUE(
+      EvaluateAsBool(GetMainFrame(), "typeof screen.keepAwake !== undefined"));
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, LockAndUnlockScreenInMainFrame) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+
+  // Should not have screen wake lock initially.
+  EXPECT_FALSE(HasWakeLock());
+
+  // Check attribute 'screen.keepAwake' in main frame.
+  EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+  // Set keep awake flag in main frame.
+  EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  // Keep awake flag should be set in main frame.
+  EXPECT_TRUE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+  // Should create screen wake lock.
+  EXPECT_TRUE(HasWakeLock());
+
+  // Reset keep awake flag in main frame.
+  EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;"));
+  WaitForPossibleUpdate();
+
+  // Keep awake flag should not be set in main frame.
+  EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+  // Should release screen wake lock.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, MultipleLockThenUnlock) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+
+  // Set keep awake flag.
+  EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  // Set keep awake flag again.
+  EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  // Screen should still be locked.
+  EXPECT_TRUE(HasWakeLock());
+
+  // Reset keep awake flag.
+  EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;"));
+  WaitForPossibleUpdate();
+
+  // Should release screen wake lock.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, LockInMainFrameAndNestedFrame) {
+  NavigateToURL(shell(),
+                embedded_test_server()->GetURL("/frame_tree/2-4.html"));
+  EXPECT_FALSE(HasWakeLock());
+
+  // Lock screen in nested frame.
+  EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  // Should create screen wake lock.
+  EXPECT_TRUE(HasWakeLock());
+
+  // screen.keepAwake should be false in the main frame.
+  EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+  // Lock screen in main frame.
+  EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  // screen.keepAwake should be true in the main frame.
+  EXPECT_TRUE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake"));
+
+  // Screen wake lock should not change.
+  EXPECT_TRUE(HasWakeLock());
+
+  // Unlock screen in nested frame.
+  EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = false;"));
+  WaitForPossibleUpdate();
+
+  // Screen wake lock should be present, as the main frame is still requesting
+  // it.
+  EXPECT_TRUE(HasWakeLock());
+
+  // Unlock screen in main frame.
+  EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;"));
+  WaitForPossibleUpdate();
+
+  // Screen wake lock should be released, as no frames are requesting it.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, FrameRemoved) {
+  NavigateToURL(shell(),
+                embedded_test_server()->GetURL("/frame_tree/2-4.html"));
+  EXPECT_FALSE(HasWakeLock());
+
+  // Lock screen in nested frame.
+  EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  EXPECT_TRUE(HasWakeLock());
+
+  // Remove nested frame.
+  EXPECT_TRUE(ExecuteScript(GetMainFrame(),
+                            "var iframe = document.getElementById('3-1-id');"
+                            "iframe.parentNode.removeChild(iframe);"));
+
+  // Screen wake lock should be released.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterTabCrashed) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+  ScreenWakeLockInMainFrame();
+
+  // Crash the tab.
+  CrashTab(GetWebContents());
+
+  // Screen wake lock should be released.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterNavigation) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+  ScreenWakeLockInMainFrame();
+
+  // Navigate to a different document.
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
+
+  // Screen wake lock should be released after navigation.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterNavigationToSelf) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+  ScreenWakeLockInMainFrame();
+
+  // Navigate to the same document.
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+
+  // Screen wake lock should be released after navigation to the same URL.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, KeepLockAfterInPageNavigation) {
+  GURL test_url(
+      embedded_test_server()->GetURL("/session_history/fragment.html"));
+  GURL test_in_page_url(test_url.spec() + "#a");
+
+  NavigateToURL(shell(), test_url);
+  ScreenWakeLockInMainFrame();
+
+  NavigateToURL(shell(), test_in_page_url);
+  EXPECT_TRUE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterReload) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html"));
+  ScreenWakeLockInMainFrame();
+
+  shell()->Reload();
+  WaitForLoadStop(GetWebContents());
+
+  // Screen wake lock should be released after reload.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, BrowserInitiatedFrameNavigation) {
+  NavigateToURL(shell(),
+                embedded_test_server()->GetURL("/frame_tree/2-4.html"));
+
+  EXPECT_FALSE(HasWakeLock());
+
+  // Lock screen in nested frame.
+  EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  // Screen wake lock should be present.
+  EXPECT_TRUE(HasWakeLock());
+
+  // Navigate the nested frame (browser-initiated).
+  NavigateFrameToURL(GetNestedFrameNode(),
+                     embedded_test_server()->GetURL("/simple_page.html"));
+  WaitForPossibleUpdate();
+
+  // Screen wake lock should be released.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, RendererInitiatedFrameNavigation) {
+  NavigateToURL(shell(),
+                embedded_test_server()->GetURL("/frame_tree/2-4.html"));
+
+  EXPECT_FALSE(HasWakeLock());
+
+  // Lock screen in nested frame.
+  EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  // Screen wake lock should be present.
+  EXPECT_TRUE(HasWakeLock());
+
+  // Navigate the nested frame (renderer-initiated).
+  NavigateIframeToURL(GetWebContents(), "3-1-id",
+                      embedded_test_server()->GetURL("/simple_page.html"));
+  WaitForPossibleUpdate();
+
+  // Screen wake lock should be released.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, OutOfProcessFrame) {
+  NavigateToURL(shell(), embedded_test_server()->GetURL(
+                             "a.com", "/cross_site_iframe_factory.html?a(a)"));
+  EXPECT_FALSE(HasWakeLock());
+
+  // Ensure that the nested frame is same-process.
+  EXPECT_FALSE(GetNestedFrame()->IsCrossProcessSubframe());
+
+  // Lock screen in same-site nested frame.
+  EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+  EXPECT_TRUE(HasWakeLock());
+
+  // Navigate nested frame to a cross-site document.
+  NavigateFrameToURL(GetNestedFrameNode(), embedded_test_server()->GetURL(
+                                               "b.com", "/simple_page.html"));
+  WaitForPossibleUpdate();
+
+  // Ensure that a new process has been created for the nested frame.
+  EXPECT_TRUE(GetNestedFrame()->IsCrossProcessSubframe());
+
+  // Screen wake lock should be released.
+  EXPECT_FALSE(HasWakeLock());
+
+  // Lock screen in the cross-site nested frame.
+  EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+
+  // Screen wake lock should be created.
+  EXPECT_TRUE(HasWakeLock());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterCrashOutOfProcessFrame) {
+  // Load a page with cross-site iframe.
+  NavigateToURL(shell(), embedded_test_server()->GetURL(
+                             "a.com", "/cross_site_iframe_factory.html?a(b)"));
+  EXPECT_FALSE(HasWakeLock());
+
+  // Ensure that a new process has been created for the nested frame.
+  EXPECT_TRUE(GetNestedFrame()->IsCrossProcessSubframe());
+
+  // Lock screen in cross-site nested frame.
+  EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;"));
+  WaitForPossibleUpdate();
+  EXPECT_TRUE(HasWakeLock());
+
+  // Crash process that owns the out-of-process frame.
+  RenderProcessHostWatcher watcher(
+      GetNestedFrame()->GetProcess(),
+      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+  GetNestedFrame()->GetProcess()->Shutdown(0, false);
+  watcher.Wait();
+
+  // Screen wake lock should be released.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+}  // namespace content
diff --git a/content/browser/wake_lock/wake_lock_service_context.cc b/content/browser/wake_lock/wake_lock_service_context.cc
new file mode 100644
index 0000000..582ea58d
--- /dev/null
+++ b/content/browser/wake_lock/wake_lock_service_context.cc
@@ -0,0 +1,89 @@
+// Copyright 2015 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.
+
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+
+#include "base/bind.h"
+#include "content/browser/power_save_blocker_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/power_save_blocker.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/service_registry.h"
+
+namespace content {
+
+WakeLockServiceContext::WakeLockServiceContext(WebContents* web_contents)
+    : WebContentsObserver(web_contents), weak_factory_(this) {}
+
+WakeLockServiceContext::~WakeLockServiceContext() {}
+
+void WakeLockServiceContext::CreateService(
+    int render_process_id,
+    int render_frame_id,
+    mojo::InterfaceRequest<WakeLockService> request) {
+  new WakeLockServiceImpl(weak_factory_.GetWeakPtr(), render_process_id,
+                          render_frame_id, request.Pass());
+}
+
+void WakeLockServiceContext::RenderFrameDeleted(
+    RenderFrameHost* render_frame_host) {
+  CancelWakeLock(render_frame_host->GetProcess()->GetID(),
+                 render_frame_host->GetRoutingID());
+}
+
+void WakeLockServiceContext::RequestWakeLock(int render_process_id,
+                                             int render_frame_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (!RenderFrameHost::FromID(render_process_id, render_frame_id))
+    return;
+
+  frames_requesting_lock_.insert(
+      std::pair<int, int>(render_process_id, render_frame_id));
+  UpdateWakeLock();
+}
+
+void WakeLockServiceContext::CancelWakeLock(int render_process_id,
+                                            int render_frame_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  frames_requesting_lock_.erase(
+      std::pair<int, int>(render_process_id, render_frame_id));
+  UpdateWakeLock();
+}
+
+bool WakeLockServiceContext::HasWakeLockForTests() const {
+  return wake_lock_;
+}
+
+void WakeLockServiceContext::CreateWakeLock() {
+  DCHECK(!wake_lock_);
+  wake_lock_ = PowerSaveBlocker::Create(
+      PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
+      PowerSaveBlocker::kReasonOther, "Wake Lock API");
+
+#if defined(OS_ANDROID)
+  // On Android, additionaly associate the blocker with this WebContents.
+  DCHECK(web_contents());
+
+  static_cast<PowerSaveBlockerImpl*>(wake_lock_.get())
+      ->InitDisplaySleepBlocker(web_contents());
+#endif
+}
+
+void WakeLockServiceContext::RemoveWakeLock() {
+  DCHECK(wake_lock_);
+  wake_lock_.reset();
+}
+
+void WakeLockServiceContext::UpdateWakeLock() {
+  if (!frames_requesting_lock_.empty()) {
+    if (!wake_lock_)
+      CreateWakeLock();
+  } else {
+    if (wake_lock_)
+      RemoveWakeLock();
+  }
+}
+
+}  // namespace content
diff --git a/content/browser/wake_lock/wake_lock_service_context.h b/content/browser/wake_lock/wake_lock_service_context.h
new file mode 100644
index 0000000..f3114d7
--- /dev/null
+++ b/content/browser/wake_lock/wake_lock_service_context.h
@@ -0,0 +1,68 @@
+// Copyright 2015 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 CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_CONTEXT_H_
+#define CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_CONTEXT_H_
+
+#include <set>
+#include <utility>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/wake_lock/wake_lock_service_impl.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+
+namespace content {
+
+class PowerSaveBlocker;
+class RenderFrameHost;
+class WebContents;
+
+class CONTENT_EXPORT WakeLockServiceContext : public WebContentsObserver {
+ public:
+  explicit WakeLockServiceContext(WebContents* web_contents);
+  ~WakeLockServiceContext() override;
+
+  // Creates a WakeLockServiceImpl that is strongly bound to |request|.
+  void CreateService(int render_process_id,
+                     int render_frame_id,
+                     mojo::InterfaceRequest<WakeLockService> request);
+
+  // WebContentsObserver implementation.
+  void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
+
+  // Requests wake lock for RenderFrame identified by |render_process_id| and
+  // |render_frame_id|.
+  void RequestWakeLock(int render_process_id, int render_frame_id);
+
+  // Cancels wake lock request for RenderFrame identified by
+  // |render_process_id| and |render_frame_id|.
+  void CancelWakeLock(int render_process_id, int render_frame_id);
+
+  // Used by tests.
+  bool HasWakeLockForTests() const;
+
+ private:
+  void CreateWakeLock();
+  void RemoveWakeLock();
+  void UpdateWakeLock();
+
+  // Set of (render_process_id, render_frame_id) pairs identifying all
+  // RenderFrames requesting wake lock.
+  std::set<std::pair<int, int>> frames_requesting_lock_;
+
+  // The actual power save blocker for screen.
+  scoped_ptr<PowerSaveBlocker> wake_lock_;
+
+  base::WeakPtrFactory<WakeLockServiceContext> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(WakeLockServiceContext);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_CONTEXT_H_
diff --git a/content/browser/wake_lock/wake_lock_service_context_unittest.cc b/content/browser/wake_lock/wake_lock_service_context_unittest.cc
new file mode 100644
index 0000000..4921158
--- /dev/null
+++ b/content/browser/wake_lock/wake_lock_service_context_unittest.cc
@@ -0,0 +1,96 @@
+// Copyright 2015 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.
+
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/process/kill.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/test_renderer_host.h"
+
+namespace content {
+
+class RenderFrameHost;
+
+class WakeLockServiceContextTest : public RenderViewHostTestHarness {
+ protected:
+  void RequestWakeLock(RenderFrameHost* rfh) {
+    GetWakeLockServiceContext()->RequestWakeLock(rfh->GetProcess()->GetID(),
+                                                 rfh->GetRoutingID());
+  }
+
+  void CancelWakeLock(RenderFrameHost* rfh) {
+    GetWakeLockServiceContext()->CancelWakeLock(rfh->GetProcess()->GetID(),
+                                                rfh->GetRoutingID());
+  }
+
+  WakeLockServiceContext* GetWakeLockServiceContext() {
+    WebContentsImpl* web_contents_impl =
+        static_cast<WebContentsImpl*>(web_contents());
+    return web_contents_impl->GetWakeLockServiceContext();
+  }
+
+  bool HasWakeLock() {
+    return GetWakeLockServiceContext()->HasWakeLockForTests();
+  }
+};
+
+TEST_F(WakeLockServiceContextTest, NoLockInitially) {
+  EXPECT_FALSE(HasWakeLock());
+}
+
+TEST_F(WakeLockServiceContextTest, LockUnlock) {
+  ASSERT_TRUE(GetWakeLockServiceContext());
+  ASSERT_TRUE(web_contents());
+  ASSERT_TRUE(main_rfh());
+
+  // Request wake lock for main frame.
+  RequestWakeLock(main_rfh());
+
+  // Should set the blocker.
+  EXPECT_TRUE(HasWakeLock());
+
+  // Remove wake lock request for main frame.
+  CancelWakeLock(main_rfh());
+
+  // Should remove the blocker.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+TEST_F(WakeLockServiceContextTest, RenderFrameDeleted) {
+  ASSERT_TRUE(GetWakeLockServiceContext());
+  ASSERT_TRUE(web_contents());
+  ASSERT_TRUE(main_rfh());
+
+  // Request wake lock for main frame.
+  RequestWakeLock(main_rfh());
+
+  // Should set the blocker.
+  EXPECT_TRUE(HasWakeLock());
+
+  // Simulate render frame deletion.
+  GetWakeLockServiceContext()->RenderFrameDeleted(main_rfh());
+
+  // Should remove the blocker.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+TEST_F(WakeLockServiceContextTest, NoLockForBogusFrameId) {
+  ASSERT_TRUE(GetWakeLockServiceContext());
+  ASSERT_TRUE(web_contents());
+
+  // Request wake lock for non-existent render frame id.
+  int non_existent_render_frame_id =
+      main_rfh()->GetProcess()->GetNextRoutingID();
+  GetWakeLockServiceContext()->RequestWakeLock(
+      main_rfh()->GetProcess()->GetID(), non_existent_render_frame_id);
+
+  // Should not set the blocker.
+  EXPECT_FALSE(HasWakeLock());
+}
+
+}  // namespace content
diff --git a/content/browser/wake_lock/wake_lock_service_impl.cc b/content/browser/wake_lock/wake_lock_service_impl.cc
new file mode 100644
index 0000000..913a1378
--- /dev/null
+++ b/content/browser/wake_lock/wake_lock_service_impl.cc
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+#include "content/browser/wake_lock/wake_lock_service_impl.h"
+
+#include "content/browser/wake_lock/wake_lock_service_context.h"
+
+namespace content {
+
+WakeLockServiceImpl::WakeLockServiceImpl(
+    base::WeakPtr<WakeLockServiceContext> context,
+    int render_process_id,
+    int render_frame_id,
+    mojo::InterfaceRequest<WakeLockService> request)
+    : context_(context),
+      render_process_id_(render_process_id),
+      render_frame_id_(render_frame_id),
+      binding_(this, request.Pass()) {}
+
+WakeLockServiceImpl::~WakeLockServiceImpl() {}
+
+void WakeLockServiceImpl::RequestWakeLock() {
+  if (context_)
+    context_->RequestWakeLock(render_process_id_, render_frame_id_);
+}
+
+void WakeLockServiceImpl::CancelWakeLock() {
+  if (context_)
+    context_->CancelWakeLock(render_process_id_, render_frame_id_);
+}
+
+}  // namespace content
diff --git a/content/browser/wake_lock/wake_lock_service_impl.h b/content/browser/wake_lock/wake_lock_service_impl.h
new file mode 100644
index 0000000..903f5057
--- /dev/null
+++ b/content/browser/wake_lock/wake_lock_service_impl.h
@@ -0,0 +1,41 @@
+// Copyright 2015 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 CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_IMPL_H_
+#define CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_IMPL_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/wake_lock_service.mojom.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace content {
+
+class WakeLockServiceContext;
+
+class WakeLockServiceImpl : public WakeLockService {
+ public:
+  WakeLockServiceImpl(base::WeakPtr<WakeLockServiceContext> context,
+                      int render_process_id,
+                      int render_frame_id,
+                      mojo::InterfaceRequest<WakeLockService> request);
+  ~WakeLockServiceImpl() override;
+
+  // WakeLockSevice implementation.
+  void RequestWakeLock() override;
+  void CancelWakeLock() override;
+
+ private:
+  base::WeakPtr<WakeLockServiceContext> context_;
+  const int render_process_id_;
+  const int render_frame_id_;
+  mojo::StrongBinding<WakeLockService> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(WakeLockServiceImpl);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_WAKE_LOCK_WAKE_LOCK_SERVICE_IMPL_H_
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 605876b..e01a4d5 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -58,6 +58,7 @@
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h"
 #include "content/browser/site_instance_impl.h"
+#include "content/browser/wake_lock/wake_lock_service_context.h"
 #include "content/browser/web_contents/web_contents_view_guest.h"
 #include "content/browser/webui/generic_handler.h"
 #include "content/browser/webui/web_ui_controller_factory_registry.h"
@@ -421,6 +422,8 @@
 #if defined(ENABLE_BROWSER_CDMS)
   media_web_contents_observer_.reset(new MediaWebContentsObserver(this));
 #endif
+
+  wake_lock_service_context_.reset(new WakeLockServiceContext(this));
 }
 
 WebContentsImpl::~WebContentsImpl() {
@@ -1607,18 +1610,6 @@
   frame_tree_.ReplicatePageFocus(is_focused);
 }
 
-RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost() {
-  if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
-    return GetMainFrame()->GetRenderWidgetHost();
-
-  FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame();
-  if (!focused_frame)
-    return GetMainFrame()->GetRenderWidgetHost();
-
-  return RenderWidgetHostImpl::From(
-      focused_frame->current_frame_host()->GetView()->GetRenderWidgetHost());
-}
-
 void WebContentsImpl::EnterFullscreenMode(const GURL& origin) {
   // This method is being called to enter renderer-initiated fullscreen mode.
   // Make sure any existing fullscreen widget is shut down first.
@@ -2102,6 +2093,10 @@
   return geolocation_service_context_.get();
 }
 
+WakeLockServiceContext* WebContentsImpl::GetWakeLockServiceContext() {
+  return wake_lock_service_context_.get();
+}
+
 void WebContentsImpl::OnShowValidationMessage(
     const gfx::Rect& anchor_in_root_view,
     const base::string16& main_text,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 01dd05d9..60cde3c9 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -67,6 +67,7 @@
 class ScreenOrientationDispatcherHost;
 class SiteInstance;
 class TestWebContents;
+class WakeLockServiceContext;
 class WebContentsAudioMuter;
 class WebContentsDelegate;
 class WebContentsImpl;
@@ -430,6 +431,7 @@
       RenderFrameHost* render_frame_host,
       int browser_plugin_instance_id) override;
   GeolocationServiceContext* GetGeolocationServiceContext() override;
+  WakeLockServiceContext* GetWakeLockServiceContext() override;
   void EnterFullscreenMode(const GURL& origin) override;
   void ExitFullscreenMode() override;
   bool ShouldRouteMessageEvent(
@@ -592,7 +594,6 @@
       override;
   RenderWidgetHostInputEventRouter* GetInputEventRouter() override;
   void ReplicatePageFocus(bool is_focused) override;
-  RenderWidgetHostImpl* GetFocusedRenderWidgetHost() override;
 
   // RenderFrameHostManager::Delegate ------------------------------------------
 
@@ -1289,6 +1290,8 @@
 
   scoped_ptr<GeolocationServiceContext> geolocation_service_context_;
 
+  scoped_ptr<WakeLockServiceContext> wake_lock_service_context_;
+
   scoped_ptr<ScreenOrientationDispatcherHost>
       screen_orientation_dispatcher_host_;
 
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 135cc72..c885851 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -710,7 +710,7 @@
 }
 
 void BlinkPlatformImpl::registerMemoryDumpProvider(
-    blink::WebMemoryDumpProvider* wmdp) {
+    blink::WebMemoryDumpProvider* wmdp, const char* name) {
   WebMemoryDumpProviderAdapter* wmdp_adapter =
       new WebMemoryDumpProviderAdapter(wmdp);
   bool did_insert =
@@ -719,7 +719,7 @@
     return;
   wmdp_adapter->set_is_registered(true);
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      wmdp_adapter, base::ThreadTaskRunnerHandle::Get());
+      wmdp_adapter, name, base::ThreadTaskRunnerHandle::Get());
 }
 
 void BlinkPlatformImpl::unregisterMemoryDumpProvider(
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index 4f235752..6e7f834a 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -144,7 +144,8 @@
   void updateTraceEventDuration(const unsigned char* category_group_enabled,
                                 const char* name,
                                 TraceEventHandle) override;
-  void registerMemoryDumpProvider(blink::WebMemoryDumpProvider* wmdp) override;
+  void registerMemoryDumpProvider(blink::WebMemoryDumpProvider* wmdp,
+                                  const char* name) override;
   void unregisterMemoryDumpProvider(
       blink::WebMemoryDumpProvider* wmdp) override;
   blink::WebProcessMemoryDump* createProcessMemoryDump() override;
diff --git a/content/child/child_discardable_shared_memory_manager.cc b/content/child/child_discardable_shared_memory_manager.cc
index 1069fa7..8eed389a 100644
--- a/content/child/child_discardable_shared_memory_manager.cc
+++ b/content/child/child_discardable_shared_memory_manager.cc
@@ -87,7 +87,8 @@
     ThreadSafeSender* sender)
     : heap_(base::GetPageSize()), sender_(sender) {
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this, base::ThreadTaskRunnerHandle::Get());
+      this, "ChildDiscardableSharedMemoryManager",
+      base::ThreadTaskRunnerHandle::Get());
 }
 
 ChildDiscardableSharedMemoryManager::~ChildDiscardableSharedMemoryManager() {
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index e945af17..8444df4 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -521,6 +521,7 @@
     "service_port_service.mojom",
     "service_worker/embedded_worker_setup.mojom",
     "vr_service.mojom",
+    "wake_lock_service.mojom",
   ]
 
   import_dirs = [ "//mojo/services" ]
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc
index 4ae3741..c3c84192 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.cc
+++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -462,7 +462,7 @@
       channel_->gpu_memory_buffer_manager()->AllocateGpuMemoryBuffer(
           gfx::Size(width, height),
           gpu::ImageFactory::DefaultBufferFormatForImageFormat(internalformat),
-          gfx::BufferUsage::GPU_READ_WRITE));
+          gfx::BufferUsage::SCANOUT));
   if (!buffer)
     return -1;
 
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
index 84312e6..2054aa2 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
@@ -17,7 +17,7 @@
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
       return kIOSurfaceLockAvoidSync;
     case gfx::BufferUsage::GPU_READ:
-    case gfx::BufferUsage::GPU_READ_WRITE:
+    case gfx::BufferUsage::SCANOUT:
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
       return 0;
   }
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
index fb5fff98..9a36a3b 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
@@ -98,7 +98,7 @@
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
       return true;
-    case gfx::BufferUsage::GPU_READ_WRITE:
+    case gfx::BufferUsage::SCANOUT:
       return false;
   }
   NOTREACHED();
diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
index 337bdf49..2615906 100644
--- a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
+++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
@@ -99,7 +99,7 @@
     gfx::BufferUsage usage) {
   switch (usage) {
     case gfx::BufferUsage::GPU_READ:
-    case gfx::BufferUsage::GPU_READ_WRITE:
+    case gfx::BufferUsage::SCANOUT:
       return format == gfx::BufferFormat::BGRA_8888 ||
              format == gfx::BufferFormat::RGBA_8888;
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc
index a9913c84..a4cf15e 100644
--- a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc
+++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc
@@ -22,7 +22,7 @@
                                             gfx::BufferUsage usage) {
   switch (usage) {
     case gfx::BufferUsage::GPU_READ:
-    case gfx::BufferUsage::GPU_READ_WRITE:
+    case gfx::BufferUsage::SCANOUT:
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
       return false;
     case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
diff --git a/content/common/gpu/media/vaapi_drm_picture.cc b/content/common/gpu/media/vaapi_drm_picture.cc
index 183d4ae..d344a1b5 100644
--- a/content/common/gpu/media/vaapi_drm_picture.cc
+++ b/content/common/gpu/media/vaapi_drm_picture.cc
@@ -97,7 +97,7 @@
   // Create a buffer from Ozone.
   return factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size,
                                      gfx::BufferFormat::BGRX_8888,
-                                     gfx::BufferUsage::GPU_READ_WRITE);
+                                     gfx::BufferUsage::SCANOUT);
 }
 
 bool VaapiDrmPicture::Initialize() {
diff --git a/content/common/host_discardable_shared_memory_manager.cc b/content/common/host_discardable_shared_memory_manager.cc
index 2ea9821..e2b89cd 100644
--- a/content/common/host_discardable_shared_memory_manager.cc
+++ b/content/common/host_discardable_shared_memory_manager.cc
@@ -135,7 +135,7 @@
       base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy,
                  weak_ptr_factory_.GetWeakPtr());
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this);
+      this, "HostDiscardableSharedMemoryManager", nullptr);
 }
 
 HostDiscardableSharedMemoryManager::~HostDiscardableSharedMemoryManager() {
diff --git a/content/common/input/touch_action.h b/content/common/input/touch_action.h
index 89f000d..2a00a03 100644
--- a/content/common/input/touch_action.h
+++ b/content/common/input/touch_action.h
@@ -11,33 +11,52 @@
 // (panning and zooming) are currently permitted via touch input.
 // See http://www.w3.org/TR/pointerevents/#the-touch-action-css-property.
 enum TouchAction {
-  // All actions are pemitted (the default).
-  TOUCH_ACTION_AUTO = 0,
-
   // No scrolling or zooming allowed.
-  TOUCH_ACTION_NONE = 1 << 0,
+  TOUCH_ACTION_NONE = 0,
 
-  TOUCH_ACTION_PAN_LEFT = 1 << 1,
+  TOUCH_ACTION_PAN_LEFT = 1 << 0,
 
-  TOUCH_ACTION_PAN_RIGHT = 1 << 2,
+  TOUCH_ACTION_PAN_RIGHT = 1 << 1,
 
   TOUCH_ACTION_PAN_X = TOUCH_ACTION_PAN_LEFT | TOUCH_ACTION_PAN_RIGHT,
 
-  TOUCH_ACTION_PAN_UP = 1 << 3,
+  TOUCH_ACTION_PAN_UP = 1 << 2,
 
-  TOUCH_ACTION_PAN_DOWN = 1 << 4,
+  TOUCH_ACTION_PAN_DOWN = 1 << 3,
 
   TOUCH_ACTION_PAN_Y = TOUCH_ACTION_PAN_UP | TOUCH_ACTION_PAN_DOWN,
 
-  TOUCH_ACTION_PAN_X_Y = TOUCH_ACTION_PAN_X | TOUCH_ACTION_PAN_Y,
+  TOUCH_ACTION_PAN = TOUCH_ACTION_PAN_X | TOUCH_ACTION_PAN_Y,
 
-  TOUCH_ACTION_PINCH_ZOOM = 1 << 5,
+  TOUCH_ACTION_PINCH_ZOOM = 1 << 4,
 
-  TOUCH_ACTION_MANIPULATION = TOUCH_ACTION_PAN_X_Y | TOUCH_ACTION_PINCH_ZOOM,
+  TOUCH_ACTION_MANIPULATION = TOUCH_ACTION_PAN | TOUCH_ACTION_PINCH_ZOOM,
+
+  TOUCH_ACTION_DOUBLE_TAP_ZOOM = 1 << 5,
+
+  // All actions are permitted (the default).
+  TOUCH_ACTION_AUTO = TOUCH_ACTION_MANIPULATION | TOUCH_ACTION_DOUBLE_TAP_ZOOM,
 
   TOUCH_ACTION_MAX = (1 << 6) - 1
 };
 
+inline TouchAction operator| (TouchAction a, TouchAction b)
+{
+  return static_cast<TouchAction>(int(a) | int(b));
+}
+inline TouchAction& operator|= (TouchAction& a, TouchAction b)
+{
+  return a = a | b;
+}
+inline TouchAction operator& (TouchAction a, TouchAction b)
+{
+  return static_cast<TouchAction>(int(a) & int(b));
+}
+inline TouchAction& operator&= (TouchAction& a, TouchAction b)
+{
+  return a = a & b;
+}
+
 }  // namespace content
 
 #endif  // CONTENT_COMMON_INPUT_TOUCH_ACTION_H_
diff --git a/content/common/wake_lock_service.mojom b/content/common/wake_lock_service.mojom
new file mode 100644
index 0000000..3d6e6d8
--- /dev/null
+++ b/content/common/wake_lock_service.mojom
@@ -0,0 +1,11 @@
+// Copyright 2015 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.
+
+module content;
+
+// WebLockService receives per-frame wake lock preference from its client.
+interface WakeLockService {
+  RequestWakeLock();
+  CancelWakeLock();
+};
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index e956edd0..b000f21 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -1534,6 +1534,10 @@
       'browser/user_metrics.cc',
       'browser/utility_process_host_impl.cc',
       'browser/utility_process_host_impl.h',
+      'browser/wake_lock/wake_lock_service_context.cc',
+      'browser/wake_lock/wake_lock_service_context.h',
+      'browser/wake_lock/wake_lock_service_impl.cc',
+      'browser/wake_lock/wake_lock_service_impl.h',
       'browser/web_contents/aura/gesture_nav_simple.cc',
       'browser/web_contents/aura/gesture_nav_simple.h',
       'browser/web_contents/aura/overscroll_navigation_overlay.cc',
diff --git a/content/content_common_mojo_bindings.gyp b/content/content_common_mojo_bindings.gyp
index 5ab1fdd..f8205961 100644
--- a/content/content_common_mojo_bindings.gyp
+++ b/content/content_common_mojo_bindings.gyp
@@ -20,8 +20,9 @@
           'common/process_control.mojom',
           'common/render_frame_setup.mojom',
           'common/service_port_service.mojom',
-          'common/vr_service.mojom',
           'common/service_worker/embedded_worker_setup.mojom',
+          'common/vr_service.mojom',
+          'common/wake_lock_service.mojom',
 
           # NOTE: Sources duplicated in
           # //content/public/common/BUILD.gn:mojo_bindings.
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 8584672..5e0f001 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -440,6 +440,8 @@
       'renderer/usb/web_usb_client_impl.h',
       'renderer/usb/web_usb_device_impl.cc',
       'renderer/usb/web_usb_device_impl.h',
+      'renderer/wake_lock/wake_lock_dispatcher.cc',
+      'renderer/wake_lock/wake_lock_dispatcher.h',
       'renderer/web_ui_extension.cc',
       'renderer/web_ui_extension.h',
       'renderer/web_ui_extension_data.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index dd6c0547..da67d09 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -257,6 +257,7 @@
       'browser/tracing/memory_tracing_browsertest.cc',
       'browser/tracing/tracing_controller_browsertest.cc',
       'browser/vibration_manager_integration_browsertest.cc',
+      'browser/wake_lock/wake_lock_browsertest.cc',
       'browser/web_contents/opened_by_dom_browsertest.cc',
       'browser/web_contents/web_contents_impl_browsertest.cc',
       'browser/web_contents/web_contents_view_aura_browsertest.cc',
@@ -592,6 +593,7 @@
       'browser/streams/stream_url_request_job_unittest.cc',
       'browser/system_message_window_win_unittest.cc',
       'browser/tracing/background_tracing_config_unittest.cc',
+      'browser/wake_lock/wake_lock_service_context_unittest.cc',
       'browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc',
       'browser/web_contents/aura/overscroll_window_animation_unittest.cc',
       'browser/web_contents/aura/overscroll_window_delegate_unittest.cc',
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index 4344f04..0a3f550 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -392,7 +392,8 @@
 
 #if defined(OS_ANDROID)
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      tracing::GraphicsMemoryDumpProvider::GetInstance());
+      tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
+      nullptr);
 #endif
 
   {
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 631d5456..0848458 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -227,9 +227,7 @@
                        int modifiers) {
   NativeWebKeyboardEvent event;
   BuildSimpleWebKeyEvent(type, key_code, native_key_code, modifiers, &event);
-  static_cast<WebContentsImpl*>(web_contents)
-      ->GetFocusedRenderWidgetHost()
-      ->ForwardKeyboardEvent(event);
+  web_contents->GetRenderViewHost()->GetWidget()->ForwardKeyboardEvent(event);
 }
 
 void GetCookiesCallback(std::string* cookies_out,
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index 4e6db86..69ec1a7 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -635,8 +635,11 @@
 
   unsigned textureId = static_cast<unsigned>(
     (bitmap_.getTexture())->getTextureHandle());
-  if (!copyVideoTextureToPlatformTexture(context3D, textureId,
-      GL_RGBA, GL_UNSIGNED_BYTE, true, false)) {
+  if (!copyVideoTextureToPlatformTexture(
+          context3D,
+          CopyVideoTextureParams(CopyVideoTextureParams::FullCopy,
+                                 GL_TEXTURE_2D, textureId, GL_RGBA,
+                                 GL_UNSIGNED_BYTE, 0, 0, 0, true, false))) {
     return;
   }
 
@@ -660,12 +663,12 @@
 
 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture(
     blink::WebGraphicsContext3D* web_graphics_context,
-    unsigned int texture,
-    unsigned int internal_format,
-    unsigned int type,
-    bool premultiply_alpha,
-    bool flip_y) {
+    const CopyVideoTextureParams& params) {
   DCHECK(main_thread_checker_.CalledOnValidThread());
+  DCHECK((params.copyType == CopyVideoTextureParams::FullCopy &&
+          !params.xoffset && !params.yoffset) ||
+         (params.copyType == CopyVideoTextureParams::SubCopy &&
+          !params.internalFormat && !params.type));
   // Don't allow clients to copy an encrypted video frame.
   if (needs_external_surface_)
     return false;
@@ -696,9 +699,17 @@
   // value down to get the expected result.
   // flip_y==true means to reverse the video orientation while
   // flip_y==false means to keep the intrinsic orientation.
-  web_graphics_context->copyTextureCHROMIUM(
-      GL_TEXTURE_2D, src_texture, texture, internal_format, type,
-      flip_y, premultiply_alpha, false);
+  if (params.copyType == CopyVideoTextureParams::FullCopy) {
+    web_graphics_context->copyTextureCHROMIUM(
+        params.target, src_texture, params.texture, params.internalFormat,
+        params.type, params.flipY, params.premultiplyAlpha, false);
+  } else {
+    web_graphics_context->copySubTextureCHROMIUM(
+        params.target, src_texture, params.texture, params.xoffset,
+        params.yoffset, 0, 0, video_frame->natural_size().width(),
+        video_frame->natural_size().height(), params.flipY,
+        params.premultiplyAlpha, false);
+  }
 
   web_graphics_context->deleteTexture(src_texture);
   web_graphics_context->flush();
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h
index bb33815..6b8090f 100644
--- a/content/renderer/media/android/webmediaplayer_android.h
+++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -138,11 +138,7 @@
 
   bool copyVideoTextureToPlatformTexture(
       blink::WebGraphicsContext3D* web_graphics_context,
-      unsigned int texture,
-      unsigned int internal_format,
-      unsigned int type,
-      bool premultiply_alpha,
-      bool flip_y) override;
+      const CopyVideoTextureParams& params) override;
 
   // True if the loaded media has a playable video/audio track.
   virtual bool hasVideo() const;
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc
index 586f180..85c41be 100644
--- a/content/renderer/media/webmediaplayer_ms.cc
+++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -352,13 +352,13 @@
 
 bool WebMediaPlayerMS::copyVideoTextureToPlatformTexture(
     blink::WebGraphicsContext3D* web_graphics_context,
-    unsigned int texture,
-    unsigned int internal_format,
-    unsigned int type,
-    bool premultiply_alpha,
-    bool flip_y) {
+    const CopyVideoTextureParams& params) {
   TRACE_EVENT0("media", "WebMediaPlayerMS:copyVideoTextureToPlatformTexture");
   DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK((params.copyType == CopyVideoTextureParams::FullCopy &&
+          !params.xoffset && !params.yoffset) ||
+         (params.copyType == CopyVideoTextureParams::SubCopy &&
+          !params.internalFormat && !params.type));
 
   scoped_refptr<media::VideoFrame> video_frame = compositor_->GetCurrentFrame();
 
@@ -372,9 +372,15 @@
   gpu::gles2::GLES2Interface* const gl =
       static_cast<gpu_blink::WebGraphicsContext3DImpl*>(web_graphics_context)
           ->GetGLInterface();
+  typedef media::SkCanvasVideoRenderer::CopyFrameSingleTextureParams CopyParams;
   media::SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
-      gl, video_frame.get(), texture, internal_format, type, premultiply_alpha,
-      flip_y);
+      gl, video_frame.get(),
+      CopyParams(params.copyType == CopyVideoTextureParams::FullCopy
+                     ? CopyParams::FullCopy
+                     : CopyParams::SubCopy,
+                 params.target, params.texture, params.internalFormat,
+                 params.type, params.level, params.xoffset, params.yoffset,
+                 params.premultiplyAlpha, params.flipY));
   return true;
 }
 
diff --git a/content/renderer/media/webmediaplayer_ms.h b/content/renderer/media/webmediaplayer_ms.h
index ebf62d24..ecd160bc 100644
--- a/content/renderer/media/webmediaplayer_ms.h
+++ b/content/renderer/media/webmediaplayer_ms.h
@@ -134,11 +134,7 @@
 
   bool copyVideoTextureToPlatformTexture(
       blink::WebGraphicsContext3D* web_graphics_context,
-      unsigned int texture,
-      unsigned int internal_format,
-      unsigned int type,
-      bool premultiply_alpha,
-      bool flip_y) override;
+      const CopyVideoTextureParams& params) override;
 
  private:
   // The callback for VideoFrameProvider to signal a new frame is available.
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 945fbb2..a7492bb 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -108,6 +108,7 @@
 #include "content/renderer/shared_worker_repository.h"
 #include "content/renderer/skia_benchmarking_extension.h"
 #include "content/renderer/stats_collection_controller.h"
+#include "content/renderer/wake_lock/wake_lock_dispatcher.h"
 #include "content/renderer/web_ui_extension.h"
 #include "content/renderer/websharedworker_proxy.h"
 #include "gin/modules/module_registry.h"
@@ -760,6 +761,7 @@
 #endif
       has_played_media_(false),
       devtools_agent_(nullptr),
+      wakelock_dispatcher_(nullptr),
       geolocation_dispatcher_(NULL),
       push_messaging_dispatcher_(NULL),
       presentation_dispatcher_(NULL),
@@ -3679,6 +3681,12 @@
   impl->set_render_frame_id(routing_id_);
 }
 
+blink::WebWakeLockClient* RenderFrameImpl::wakeLockClient() {
+  if (!wakelock_dispatcher_)
+    wakelock_dispatcher_ = new WakeLockDispatcher(this);
+  return wakelock_dispatcher_;
+}
+
 blink::WebGeolocationClient* RenderFrameImpl::geolocationClient() {
   if (!geolocation_dispatcher_)
     geolocation_dispatcher_ = new GeolocationDispatcher(this);
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index e5146f41..ab61ca6 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -65,6 +65,7 @@
 class WebPresentationClient;
 class WebPushClient;
 class WebSecurityOrigin;
+class WebWakeLockClient;
 struct WebCompositionUnderline;
 struct WebContextMenuData;
 struct WebCursorInfo;
@@ -121,6 +122,7 @@
 class RenderWidgetFullscreenPepper;
 class ScreenOrientationDispatcher;
 class UserMediaClientImpl;
+class WakeLockDispatcher;
 struct CommonNavigationParams;
 struct CustomContextMenuContext;
 struct FrameReplicationState;
@@ -531,6 +533,7 @@
                            unsigned long long requested_size,
                            blink::WebStorageQuotaCallbacks callbacks) override;
   void willOpenWebSocket(blink::WebSocketHandle* handle) override;
+  blink::WebWakeLockClient* wakeLockClient() override;
   blink::WebGeolocationClient* geolocationClient() override;
   blink::WebPushClient* pushClient() override;
   blink::WebPresentationClient* presentationClient() override;
@@ -1026,6 +1029,8 @@
   // local roots.
   DevToolsAgent* devtools_agent_;
 
+  WakeLockDispatcher* wakelock_dispatcher_;
+
   // The geolocation dispatcher attached to this frame, lazily initialized.
   GeolocationDispatcher* geolocation_dispatcher_;
 
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 4850be4..d57356c 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -688,7 +688,7 @@
 
   InitSkiaEventTracer();
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      skia::SkiaMemoryDumpProvider::GetInstance());
+      skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
 
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index b835799b..04c3102 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -2282,13 +2282,6 @@
     static_assert(int(blink::WebTouchAction##a) == int(TOUCH_ACTION_##b), \
                   "mismatching enums: " #a)
 
-inline content::TouchAction& operator|=(content::TouchAction& a,
-                                        content::TouchAction b) {
-  a = static_cast<content::TouchAction>(static_cast<int>(a) |
-                                        static_cast<int>(b));
-  return a;
-}
-
 void RenderWidget::setTouchAction(
     blink::WebTouchAction web_touch_action) {
 
@@ -2298,7 +2291,6 @@
     return;
 
   // Verify the same values are used by the types so we can cast between them.
-   STATIC_ASSERT_WTI_ENUM_MATCH(Auto,      AUTO);
    STATIC_ASSERT_WTI_ENUM_MATCH(None,      NONE);
    STATIC_ASSERT_WTI_ENUM_MATCH(PanLeft,   PAN_LEFT);
    STATIC_ASSERT_WTI_ENUM_MATCH(PanRight,  PAN_RIGHT);
@@ -2306,7 +2298,11 @@
    STATIC_ASSERT_WTI_ENUM_MATCH(PanUp,     PAN_UP);
    STATIC_ASSERT_WTI_ENUM_MATCH(PanDown,   PAN_DOWN);
    STATIC_ASSERT_WTI_ENUM_MATCH(PanY,      PAN_Y);
+   STATIC_ASSERT_WTI_ENUM_MATCH(Pan,       PAN);
    STATIC_ASSERT_WTI_ENUM_MATCH(PinchZoom, PINCH_ZOOM);
+   STATIC_ASSERT_WTI_ENUM_MATCH(Manipulation, MANIPULATION);
+   STATIC_ASSERT_WTI_ENUM_MATCH(DoubleTapZoom, DOUBLE_TAP_ZOOM);
+   STATIC_ASSERT_WTI_ENUM_MATCH(Auto,      AUTO);
 
    content::TouchAction content_touch_action =
        static_cast<content::TouchAction>(web_touch_action);
diff --git a/content/renderer/wake_lock/wake_lock_dispatcher.cc b/content/renderer/wake_lock/wake_lock_dispatcher.cc
new file mode 100644
index 0000000..47c4a68
--- /dev/null
+++ b/content/renderer/wake_lock/wake_lock_dispatcher.cc
@@ -0,0 +1,30 @@
+// Copyright 2015 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.
+
+#include "content/renderer/wake_lock/wake_lock_dispatcher.h"
+
+#include "content/public/common/service_registry.h"
+#include "content/public/renderer/render_frame.h"
+
+namespace content {
+
+WakeLockDispatcher::WakeLockDispatcher(RenderFrame* render_frame)
+    : RenderFrameObserver(render_frame), blink::WebWakeLockClient() {}
+
+WakeLockDispatcher::~WakeLockDispatcher() {}
+
+void WakeLockDispatcher::requestKeepScreenAwake(bool keepScreenAwake) {
+  if (!wake_lock_service_) {
+    render_frame()->GetServiceRegistry()->ConnectToRemoteService(
+        mojo::GetProxy(&wake_lock_service_));
+  }
+
+  if (keepScreenAwake) {
+    wake_lock_service_->RequestWakeLock();
+  } else {
+    wake_lock_service_->CancelWakeLock();
+  }
+}
+
+}  // namespace content
diff --git a/content/renderer/wake_lock/wake_lock_dispatcher.h b/content/renderer/wake_lock/wake_lock_dispatcher.h
new file mode 100644
index 0000000..e36a3e0
--- /dev/null
+++ b/content/renderer/wake_lock/wake_lock_dispatcher.h
@@ -0,0 +1,31 @@
+// Copyright 2015 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 CONTENT_RENDERER_WAKE_LOCK_WAKE_LOCK_DISPATCHER_H_
+#define CONTENT_RENDERER_WAKE_LOCK_WAKE_LOCK_DISPATCHER_H_
+
+#include "content/common/wake_lock_service.mojom.h"
+#include "content/public/renderer/render_frame_observer.h"
+#include "third_party/WebKit/public/platform/modules/wake_lock/WebWakeLockClient.h"
+
+namespace content {
+
+// WakeLockDispatcher sends wake lock messages to the browser process using the
+// Mojo WakeLockService.
+class WakeLockDispatcher : public RenderFrameObserver,
+                           public blink::WebWakeLockClient {
+ public:
+  explicit WakeLockDispatcher(RenderFrame* render_frame);
+  ~WakeLockDispatcher() override;
+
+ private:
+  // WebWakeLockClient implementation.
+  virtual void requestKeepScreenAwake(bool keepScreenAwake);
+
+  WakeLockServicePtr wake_lock_service_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_WAKE_LOCK_WAKE_LOCK_DISPATCHER_H_
diff --git a/content/test/data/page_with_input_field.html b/content/test/data/page_with_input_field.html
index 87426ac2..494456a 100644
--- a/content/test/data/page_with_input_field.html
+++ b/content/test/data/page_with_input_field.html
@@ -8,11 +8,6 @@
   inputField.focus();
 }
 
-function getInputFieldText() {
-  var inputField = document.getElementById("text-field");
-  return inputField.value;
-}
-
 function onInputFocus() {
   domAutomationController.setAutomationId(0);
   domAutomationController.send("input-focus");
diff --git a/content/test/gpu_memory_buffer_factory_test_template.h b/content/test/gpu_memory_buffer_factory_test_template.h
index 205dcc1..f0d90558 100644
--- a/content/test/gpu_memory_buffer_factory_test_template.h
+++ b/content/test/gpu_memory_buffer_factory_test_template.h
@@ -30,7 +30,7 @@
 
   for (auto format : gfx::GetBufferFormatsForTesting()) {
     gfx::BufferUsage usages[] = {
-        gfx::BufferUsage::GPU_READ, gfx::BufferUsage::GPU_READ_WRITE,
+        gfx::BufferUsage::GPU_READ, gfx::BufferUsage::SCANOUT,
         gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
         gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT};
     for (auto usage : usages) {
diff --git a/content/test/gpu_memory_buffer_impl_test_template.h b/content/test/gpu_memory_buffer_impl_test_template.h
index 9153d847..a91589f 100644
--- a/content/test/gpu_memory_buffer_impl_test_template.h
+++ b/content/test/gpu_memory_buffer_impl_test_template.h
@@ -46,7 +46,7 @@
 
   for (auto format : gfx::GetBufferFormatsForTesting()) {
     gfx::BufferUsage usages[] = {
-        gfx::BufferUsage::GPU_READ, gfx::BufferUsage::GPU_READ_WRITE,
+        gfx::BufferUsage::GPU_READ, gfx::BufferUsage::SCANOUT,
         gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
         gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT};
     for (auto usage : usages) {
diff --git a/gin/v8_isolate_memory_dump_provider.cc b/gin/v8_isolate_memory_dump_provider.cc
index ecbf5fff..79c7177a9 100644
--- a/gin/v8_isolate_memory_dump_provider.cc
+++ b/gin/v8_isolate_memory_dump_provider.cc
@@ -17,7 +17,7 @@
     IsolateHolder* isolate_holder)
     : isolate_holder_(isolate_holder) {
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this, base::ThreadTaskRunnerHandle::Get());
+      this, "V8Isolate", base::ThreadTaskRunnerHandle::Get());
 }
 
 V8IsolateMemoryDumpProvider::~V8IsolateMemoryDumpProvider() {
diff --git a/gpu/angle_end2end_tests_main.cc b/gpu/angle_end2end_tests_main.cc
index 008868c..272cf29 100644
--- a/gpu/angle_end2end_tests_main.cc
+++ b/gpu/angle_end2end_tests_main.cc
@@ -26,9 +26,12 @@
   testing::InitGoogleMock(&argc, argv);
   testing::AddGlobalTestEnvironment(new ANGLETestEnvironment());
   base::TestSuite test_suite(argc, argv);
-  int rt = base::LaunchUnitTestsSerially(
+  int rt = base::LaunchUnitTestsWithOptions(
       argc,
       argv,
+      1,  // Run tests serially.
+      0,  // Disable batching.
+      true,  // Use job objects.
       base::Bind(&RunHelper, base::Unretained(&test_suite)));
   return rt;
 }
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc
index 35805fe..01543b9 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -43,7 +43,7 @@
   // TODO(ericrk): Get this working in Android Webview. crbug.com/517156
   if (base::ThreadTaskRunnerHandle::IsSet()) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "gpu::CommandBufferHelper", base::ThreadTaskRunnerHandle::Get());
   }
 }
 
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index f0b8f8f..7c994d9 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -225,7 +225,7 @@
   // TODO(ericrk): Get this working in Android Webview. crbug.com/517156
   if (base::ThreadTaskRunnerHandle::IsSet()) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "GLES2Implementation", base::ThreadTaskRunnerHandle::Get());
   }
 
   return true;
diff --git a/gpu/command_buffer/client/mapped_memory.cc b/gpu/command_buffer/client/mapped_memory.cc
index d798ada..fcc9113 100644
--- a/gpu/command_buffer/client/mapped_memory.cc
+++ b/gpu/command_buffer/client/mapped_memory.cc
@@ -47,7 +47,7 @@
   // TODO(ericrk): Get this working in Android Webview. crbug.com/517156
   if (base::ThreadTaskRunnerHandle::IsSet()) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "gpu::MappedMemoryManager", base::ThreadTaskRunnerHandle::Get());
   }
 }
 
diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc
index 20806e2..50b03b50 100644
--- a/gpu/command_buffer/service/buffer_manager.cc
+++ b/gpu/command_buffer/service/buffer_manager.cc
@@ -40,7 +40,7 @@
   // so don't register a dump provider.
   if (memory_tracker_) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "gpu::BufferManager", base::ThreadTaskRunnerHandle::Get());
   }
 }
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index f90615a..1df0361 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -13186,6 +13186,8 @@
       return;
     }
   } else {
+    // TODO(dshwang): make GetLevelSize, ValidForTexture and ValidForTarget
+    // correct for GLImage also. crbug.com/549531
     if (!source_texture->GetLevelSize(source_texture->target(), 0,
                                       &source_width, &source_height, nullptr)) {
       LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
@@ -13193,6 +13195,13 @@
       return;
     }
 
+    if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0,
+                                         width, height, 1)) {
+      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
+                         "source texture bad dimensions.");
+      return;
+    }
+
     // Check that this type of texture is allowed.
     if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
                                            source_width, source_height, 1)) {
@@ -13206,12 +13215,6 @@
   GLenum source_internal_format = 0;
   source_texture->GetLevelType(source_texture->target(), 0, &source_type,
                                &source_internal_format);
-  if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0,
-                                       width, height, 1)) {
-    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
-                       "source texture bad dimensions.");
-    return;
-  }
 
   GLenum dest_type = 0;
   GLenum dest_internal_format = 0;
@@ -13515,6 +13518,13 @@
       return;
     }
 
+    if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0,
+                                         width, height, 1)) {
+      LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+                         "source texture bad dimensions.");
+      return;
+    }
+
     // Check that this type of texture is allowed.
     if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
                                            source_width, source_height, 1)) {
@@ -13528,12 +13538,6 @@
   GLenum source_internal_format = 0;
   source_texture->GetLevelType(source_texture->target(), 0, &source_type,
                                &source_internal_format);
-  if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0,
-                                       width, height, 1)) {
-    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
-                       "source texture bad dimensions.");
-    return;
-  }
 
   GLenum dest_type = 0;
   GLenum dest_internal_format = 0;
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index 5401a48..b3b1b12 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -769,7 +769,7 @@
       gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
           gfx::Size(width, height),
           gpu::ImageFactory::DefaultBufferFormatForImageFormat(internalformat),
-          gfx::BufferUsage::GPU_READ_WRITE));
+          gfx::BufferUsage::SCANOUT));
   if (!buffer)
     return -1;
 
diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc
index d9c82ae6..a8416f0 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.cc
+++ b/gpu/command_buffer/service/renderbuffer_manager.cc
@@ -61,7 +61,7 @@
   // so don't register a dump provider.
   if (memory_tracker_) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "gpu::RenderbufferManager", base::ThreadTaskRunnerHandle::Get());
   }
 }
 
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 9894abfd..33c6296 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -1415,7 +1415,7 @@
   // so don't register a dump provider.
   if (memory_tracker_) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "gpu::TextureManager", base::ThreadTaskRunnerHandle::Get());
   }
 
   return true;
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.cc b/gpu/command_buffer/service/transfer_buffer_manager.cc
index fa7c83c..b32b2dbb 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager.cc
+++ b/gpu/command_buffer/service/transfer_buffer_manager.cc
@@ -48,7 +48,8 @@
   // so don't register a dump provider.
   if (memory_tracker_) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        this, base::ThreadTaskRunnerHandle::Get());
+        this, "gpu::TransferBufferManager",
+        base::ThreadTaskRunnerHandle::Get());
   }
   return true;
 }
@@ -129,4 +130,3 @@
 }
 
 }  // namespace gpu
-
diff --git a/ios/chrome/browser/browser_state/browser_state_info_cache.cc b/ios/chrome/browser/browser_state/browser_state_info_cache.cc
index ceac087..e242c31d 100644
--- a/ios/chrome/browser/browser_state/browser_state_info_cache.cc
+++ b/ios/chrome/browser/browser_state/browser_state_info_cache.cc
@@ -4,6 +4,8 @@
 
 #include "ios/chrome/browser/browser_state/browser_state_info_cache.h"
 
+#include <algorithm>
+
 #include "base/i18n/case_conversion.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
@@ -16,7 +18,6 @@
 namespace {
 const char kGAIAIdKey[] = "gaia_id";
 const char kIsAuthErrorKey[] = "is_auth_error";
-const char kNameKey[] = "name";
 const char kUserNameKey[] = "user_name";
 }
 
@@ -31,9 +32,7 @@
        it.Advance()) {
     base::DictionaryValue* info = nullptr;
     cache->GetDictionaryWithoutPathExpansion(it.key(), &info);
-    base::string16 name;
-    info->GetString(kNameKey, &name);
-    sorted_keys_.insert(FindPositionForBrowserState(it.key(), name), it.key());
+    AddBrowserStateCacheKey(it.key());
   }
 }
 
@@ -41,7 +40,6 @@
 
 void BrowserStateInfoCache::AddBrowserState(
     const base::FilePath& browser_state_path,
-    const base::string16& name,
     const std::string& gaia_id,
     const base::string16& user_name) {
   std::string key = CacheKeyFromBrowserStatePath(browser_state_path);
@@ -49,12 +47,10 @@
   base::DictionaryValue* cache = update.Get();
 
   scoped_ptr<base::DictionaryValue> info(new base::DictionaryValue);
-  info->SetString(kNameKey, name);
   info->SetString(kGAIAIdKey, gaia_id);
   info->SetString(kUserNameKey, user_name);
   cache->SetWithoutPathExpansion(key, info.release());
-
-  sorted_keys_.insert(FindPositionForBrowserState(key, name), key);
+  AddBrowserStateCacheKey(key);
 
   FOR_EACH_OBSERVER(BrowserStateInfoCacheObserver, observer_list_,
                     OnBrowserStateAdded(browser_state_path));
@@ -78,8 +74,6 @@
     NOTREACHED();
     return;
   }
-  base::string16 name = GetNameOfBrowserStateAtIndex(browser_state_index);
-
   DictionaryPrefUpdate update(prefs_, ios::prefs::kBrowserStateInfoCache);
   base::DictionaryValue* cache = update.Get();
   std::string key = CacheKeyFromBrowserStatePath(browser_state_path);
@@ -87,7 +81,7 @@
   sorted_keys_.erase(std::find(sorted_keys_.begin(), sorted_keys_.end(), key));
 
   FOR_EACH_OBSERVER(BrowserStateInfoCacheObserver, observer_list_,
-                    OnBrowserStateWasRemoved(browser_state_path, name));
+                    OnBrowserStateWasRemoved(browser_state_path));
 }
 
 size_t BrowserStateInfoCache::GetNumberOfBrowserStates() const {
@@ -106,13 +100,6 @@
   return std::string::npos;
 }
 
-base::string16 BrowserStateInfoCache::GetNameOfBrowserStateAtIndex(
-    size_t index) const {
-  base::string16 name;
-  GetInfoForBrowserStateAtIndex(index)->GetString(kNameKey, &name);
-  return name;
-}
-
 base::string16 BrowserStateInfoCache::GetUserNameOfBrowserStateAtIndex(
     size_t index) const {
   base::string16 user_name;
@@ -214,22 +201,7 @@
   return base_name.MaybeAsASCII();
 }
 
-std::vector<std::string>::iterator
-BrowserStateInfoCache::FindPositionForBrowserState(
-    const std::string& search_key,
-    const base::string16& search_name) {
-  base::string16 search_name_l = base::i18n::ToLower(search_name);
-  for (size_t i = 0; i < GetNumberOfBrowserStates(); ++i) {
-    base::string16 name_l =
-        base::i18n::ToLower(GetNameOfBrowserStateAtIndex(i));
-    int name_compare = search_name_l.compare(name_l);
-    if (name_compare < 0)
-      return sorted_keys_.begin() + i;
-    if (name_compare == 0) {
-      int key_compare = search_key.compare(sorted_keys_[i]);
-      if (key_compare < 0)
-        return sorted_keys_.begin() + i;
-    }
-  }
-  return sorted_keys_.end();
+void BrowserStateInfoCache::AddBrowserStateCacheKey(const std::string& key) {
+  sorted_keys_.insert(
+      std::upper_bound(sorted_keys_.begin(), sorted_keys_.end(), key), key);
 }
diff --git a/ios/chrome/browser/browser_state/browser_state_info_cache.h b/ios/chrome/browser/browser_state/browser_state_info_cache.h
index 53fc47b..76228483 100644
--- a/ios/chrome/browser/browser_state/browser_state_info_cache.h
+++ b/ios/chrome/browser/browser_state/browser_state_info_cache.h
@@ -30,7 +30,6 @@
   virtual ~BrowserStateInfoCache();
 
   void AddBrowserState(const base::FilePath& browser_state_path,
-                       const base::string16& name,
                        const std::string& gaia_id,
                        const base::string16& user_name);
   void RemoveBrowserState(const base::FilePath& browser_state_path);
@@ -45,7 +44,6 @@
   // Gets and sets information related to browser states.
   size_t GetIndexOfBrowserStateWithPath(
       const base::FilePath& browser_state_path) const;
-  base::string16 GetNameOfBrowserStateAtIndex(size_t index) const;
   base::string16 GetUserNameOfBrowserStateAtIndex(size_t index) const;
   base::FilePath GetPathOfBrowserStateAtIndex(size_t index) const;
   std::string GetGAIAIdOfBrowserStateAtIndex(size_t index) const;
@@ -69,9 +67,7 @@
 
   std::string CacheKeyFromBrowserStatePath(
       const base::FilePath& browser_state_path) const;
-  std::vector<std::string>::iterator FindPositionForBrowserState(
-      const std::string& search_key,
-      const base::string16& search_name);
+  void AddBrowserStateCacheKey(const std::string& key);
 
   PrefService* prefs_;
   std::vector<std::string> sorted_keys_;
diff --git a/ios/chrome/browser/browser_state/browser_state_info_cache_observer.h b/ios/chrome/browser/browser_state/browser_state_info_cache_observer.h
index 9a77b858..2d8d91c0b 100644
--- a/ios/chrome/browser/browser_state/browser_state_info_cache_observer.h
+++ b/ios/chrome/browser/browser_state/browser_state_info_cache_observer.h
@@ -22,8 +22,7 @@
   virtual void OnBrowserStateAdded(const base::FilePath& path) = 0;
 
   // Called when a BrowserState has been removed.
-  virtual void OnBrowserStateWasRemoved(const base::FilePath& path,
-                                        const base::string16& name) = 0;
+  virtual void OnBrowserStateWasRemoved(const base::FilePath& path) = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(BrowserStateInfoCacheObserver);
diff --git a/ios/web/web_state/ui/wk_web_view_configuration_provider.mm b/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
index 030db07..cf776df 100644
--- a/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
+++ b/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
@@ -5,84 +5,14 @@
 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
 
 #import <Foundation/Foundation.h>
-#import <objc/runtime.h>
 #import <WebKit/WebKit.h>
 
 #include "base/ios/ios_util.h"
 #import "base/ios/weak_nsobject.h"
 #import "base/logging.h"
-#import "ios/web/alloc_with_zone_interceptor.h"
 #include "ios/web/public/browser_state.h"
 #import "ios/web/web_state/js/page_script_util.h"
 #import "ios/web/web_state/ui/crw_wk_script_message_router.h"
-#import "ios/web/web_state/web_view_internal_creation_util.h"
-
-#if !defined(NDEBUG)
-
-namespace {
-BOOL gAllowWKProcessPoolCreation = NO;
-
-// By default WKProcessPool creation is not allowed by embedder to prevent
-// issues with browsing data clearing. However some iOS system methods do create
-// WKProcessPool inside, which is perfectly fine and should be allowed. This
-// method whitelists given |klass| with given |selector|, so creation of
-// WKProcessPool is allowed inside that selector call. This function currently
-// supports Objective-C methods with up to 4 arguments and needs to be updated
-// if support for more arguments is required.
-void AllowWKProcessPoolCreation(Class klass, SEL selector) {
-  Method method = class_getInstanceMethod(klass, selector);
-  IMP originalImp = method_getImplementation(method);
-  IMP safeImp = imp_implementationWithBlock(
-      ^(id self, id arg1, id arg2, id arg3, id arg4) {
-        BOOL oldAllowWKProcessPoolCreation = gAllowWKProcessPoolCreation;
-        gAllowWKProcessPoolCreation = YES;
-        id result = originalImp(self, selector, arg1, arg2, arg3, arg4);
-        gAllowWKProcessPoolCreation = oldAllowWKProcessPoolCreation;
-        return result;
-      });
-
-  method_setImplementation(method, safeImp);
-}
-}
-
-@interface WKProcessPool (CRWAdditions)
-@end
-
-@implementation WKProcessPool (CRWAdditions)
-
-+ (void)load {
-  id (^allocator)(Class klass, NSZone* zone) = ^id(Class klass, NSZone* zone) {
-    if (gAllowWKProcessPoolCreation || web::IsWebViewAllocInitAllowed()) {
-      return NSAllocateObject(klass, 0, zone);
-    }
-    // You have hit this because you are trying to create a WKProcessPool
-    // directly or indirectly (f.e. by creating WKWebViewConfiguration
-    // manually). Please use GetWebViewConfiguration() to get
-    // WKWebViewConfiguration object.
-    NOTREACHED();
-    return nil;
-  };
-  web::AddAllocWithZoneMethod([WKProcessPool class], allocator);
-
-  if (!base::ios::IsRunningOnIOS9OrLater())
-    return;
-
-  // Make sure that WKWebsiteDataStore is allowed to create WKProcessPool for
-  // internal implementation purposes.
-  AllowWKProcessPoolCreation(
-      [WKWebsiteDataStore class],
-      @selector(fetchDataRecordsOfTypes:completionHandler:completionHandler:));
-  AllowWKProcessPoolCreation(
-      [WKWebsiteDataStore class],
-      @selector(removeDataOfTypes:forDataRecords:completionHandler:));
-  AllowWKProcessPoolCreation(
-      [WKWebsiteDataStore class],
-      @selector(removeDataOfTypes:modifiedSince:completionHandler:));
-}
-
-@end
-
-#endif  // !defined(NDEBUG)
 
 namespace web {
 
@@ -136,15 +66,6 @@
     // setJavaScriptCanOpenWindowsAutomatically is required to support popups.
     [[configuration_ preferences] setJavaScriptCanOpenWindowsAutomatically:YES];
     [[configuration_ userContentController] addUserScript:GetEarlyPageScript()];
-#if !defined(NDEBUG)
-    // Lazily load WKProcessPool. -[[WKProcessPool alloc] init] call is not
-    // allowed except when creating config object inside this class.
-    // Unmanaged creation of WKProcessPool may lead to issues with cookie
-    // clearing and Browsing Data Partitioning implementation.
-    gAllowWKProcessPoolCreation = YES;
-    CHECK([configuration_ processPool]);
-    gAllowWKProcessPoolCreation = NO;
-#endif  // !defined(NDEBUG)
   }
   // Prevent callers from changing the internals of configuration.
   return [[configuration_ copy] autorelease];
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc
index e5e51bb..a9386d37 100644
--- a/media/audio/mac/audio_low_latency_input_mac.cc
+++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -9,7 +9,9 @@
 #include "base/basictypes.h"
 #include "base/logging.h"
 #include "base/mac/mac_logging.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/metrics/sparse_histogram.h"
+#include "base/time/time.h"
 #include "media/audio/mac/audio_manager_mac.h"
 #include "media/base/audio_bus.h"
 #include "media/base/data_buffer.h"
@@ -23,6 +25,12 @@
 // The stream will be stopped as soon as this time limit is passed.
 const int kMaxErrorTimeoutInSeconds = 1;
 
+// A one-shot timer is created and started in Start() and it triggers
+// CheckInputStartupSuccess() after this amount of time. UMA stats marked
+// Media.Audio.InputStartupSuccessMac is then updated where true is added
+// if input callbacks have started, and false otherwise.
+const int kInputCallbackStartTimeoutInSeconds = 5;
+
 static std::ostream& operator<<(std::ostream& os,
                                 const AudioStreamBasicDescription& format) {
   os << "sample rate       : " << format.mSampleRate << std::endl
@@ -53,7 +61,8 @@
       number_of_channels_in_frame_(0),
       fifo_(input_params.channels(),
             number_of_frames_,
-            kNumberOfBlocksBufferInFifo) {
+            kNumberOfBlocksBufferInFifo),
+      input_callback_is_active_(false) {
   DCHECK(manager_);
 
   // Set up the desired (output) format specified by the client.
@@ -91,6 +100,7 @@
 
 // Obtain and open the AUHAL AudioOutputUnit for recording.
 bool AUAudioInputStream::Open() {
+  DCHECK(thread_checker_.CalledOnValidThread());
   // Verify that we are not already opened.
   if (audio_unit_)
     return false;
@@ -225,6 +235,7 @@
 }
 
 void AUAudioInputStream::Start(AudioInputCallback* callback) {
+  DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(callback);
   DLOG_IF(ERROR, !audio_unit_) << "Open() has not been called successfully";
   if (started_ || !audio_unit_)
@@ -250,26 +261,39 @@
   OSStatus result = AudioOutputUnitStart(audio_unit_);
   if (result == noErr) {
     started_ = true;
+    // For UMA stat purposes, start a one-shot timer which detects when input
+    // callbacks starts indicating if input audio recording works as intended.
+    // CheckInputStartupSuccess() will check if |input_callback_is_active_| is
+    // true when the timer expires. This timer delay is currently set to
+    // 5 seconds to avoid false alarms.
+    input_callback_timer_.reset(new base::OneShotTimer());
+    input_callback_timer_->Start(
+        FROM_HERE,
+        base::TimeDelta::FromSeconds(kInputCallbackStartTimeoutInSeconds), this,
+        &AUAudioInputStream::CheckInputStartupSuccess);
   }
   OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
       << "Failed to start acquiring data";
 }
 
 void AUAudioInputStream::Stop() {
+  DCHECK(thread_checker_.CalledOnValidThread());
   if (!started_)
     return;
   StopAgc();
+  input_callback_timer_.reset();
   OSStatus result = AudioOutputUnitStop(audio_unit_);
   DCHECK_EQ(result, noErr);
+  SetInputCallbackIsActive(false);
   started_ = false;
   sink_ = NULL;
   fifo_.Clear();
-
   OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
       << "Failed to stop acquiring data";
 }
 
 void AUAudioInputStream::Close() {
+  DCHECK(thread_checker_.CalledOnValidThread());
   // It is valid to call Close() before calling open or Start().
   // It is also valid to call Close() after Start() has been called.
   if (started_) {
@@ -372,7 +396,7 @@
 
 double AUAudioInputStream::GetVolume() {
   // Verify that we have a valid device.
-  if (input_device_id_ == kAudioObjectUnknown){
+  if (input_device_id_ == kAudioObjectUnknown) {
     NOTREACHED() << "Device ID is unknown";
     return 0.0;
   }
@@ -466,6 +490,14 @@
   if (!audio_input)
     return kAudioUnitErr_InvalidElement;
 
+  // Indicate that input callbacks have started on the internal AUHAL IO
+  // thread. The |input_callback_is_active_| member is read from the creating
+  // thread when a timer fires once and set to false in Stop() on the same
+  // thread. It means that this thread is the only writer of
+  // |input_callback_is_active_| once the tread starts and it should therefore
+  // be safe to modify.
+  audio_input->SetInputCallbackIsActive(true);
+
   // Update the |mDataByteSize| value in the audio_buffer_list() since
   // |number_of_frames| can be changed on the fly.
   // |mDataByteSize| needs to be exactly mapping to |number_of_frames|,
@@ -717,4 +749,30 @@
   return (result == noErr) ? is_settable : false;
 }
 
+void AUAudioInputStream::SetInputCallbackIsActive(bool enabled) {
+  base::subtle::Release_Store(&input_callback_is_active_, enabled);
+}
+
+bool AUAudioInputStream::GetInputCallbackIsActive() {
+  return (base::subtle::Acquire_Load(&input_callback_is_active_) != false);
+}
+
+void AUAudioInputStream::CheckInputStartupSuccess() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (started_) {
+    // Check if we have called Start() and input callbacks have actually
+    // started in time as they should. If that is not the case, we have a
+    // problem and the stream is considered dead.
+    const bool input_callback_is_active = GetInputCallbackIsActive();
+    UMA_HISTOGRAM_BOOLEAN("Media.Audio.InputStartupSuccessMac",
+                          input_callback_is_active);
+    DVLOG(1) << "input_callback_is_active: " << input_callback_is_active;
+
+    if (!input_callback_is_active) {
+      // TODO(henrika): perhaps we should close the stream here and trigger
+      // HandleError with as suitable error code.
+    }
+  }
+}
+
 }  // namespace media
diff --git a/media/audio/mac/audio_low_latency_input_mac.h b/media/audio/mac/audio_low_latency_input_mac.h
index abbac4b..e1d14b33 100644
--- a/media/audio/mac/audio_low_latency_input_mac.h
+++ b/media/audio/mac/audio_low_latency_input_mac.h
@@ -39,10 +39,13 @@
 #include <AudioUnit/AudioUnit.h>
 #include <CoreAudio/CoreAudio.h>
 
+#include "base/atomicops.h"
 #include "base/cancelable_callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
 #include "base/time/time.h"
+#include "base/timer/timer.h"
 #include "media/audio/agc_audio_stream.h"
 #include "media/audio/audio_io.h"
 #include "media/audio/audio_parameters.h"
@@ -114,8 +117,21 @@
   // channel.
   bool IsVolumeSettableOnChannel(int channel);
 
+  // Helper methods to set and get atomic |input_callback_is_active_|.
+  void SetInputCallbackIsActive(bool active);
+  bool GetInputCallbackIsActive();
+
+  // Checks if a stream was started successfully and the audio unit also starts
+  // to call InputProc() as it should. This method is called once when a timer
+  // expires 5 seconds after calling Start().
+  void CheckInputStartupSuccess();
+
+  // Verifies that Open(), Start(), Stop() and Close() are all called on the
+  // creating thread which is the main browser thread (CrBrowserMain) on Mac.
+  base::ThreadChecker thread_checker_;
+
   // Our creator, the audio manager needs to be notified when we close.
-  AudioManagerMac* manager_;
+  AudioManagerMac* const manager_;
 
   // Contains the desired number of audio frames in each callback.
   const size_t number_of_frames_;
@@ -133,7 +149,7 @@
   AudioUnit audio_unit_;
 
   // The UID refers to the current input audio device.
-  AudioDeviceID input_device_id_;
+  const AudioDeviceID input_device_id_;
 
   // Provides a mechanism for encapsulating one or more buffers of audio data.
   AudioBufferList audio_buffer_list_;
@@ -164,6 +180,15 @@
   // if length of error sequence is above a certain limit.
   base::TimeTicks last_success_time_;
 
+  // Is set to true on the internal AUHAL IO thread in the first input callback
+  // after Start() has bee called.
+  base::subtle::Atomic32 input_callback_is_active_;
+
+  // Timer which triggers CheckInputStartupSuccess() to verify that input
+  // callbacks have started as intended after a successful call to Start().
+  // This timer lives on the main browser thread.
+  scoped_ptr<base::OneShotTimer> input_callback_timer_;
+
   DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream);
 };
 
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 5be9452d..ff25e22 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -652,12 +652,12 @@
 
 bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture(
     blink::WebGraphicsContext3D* web_graphics_context,
-    unsigned int texture,
-    unsigned int internal_format,
-    unsigned int type,
-    bool premultiply_alpha,
-    bool flip_y) {
+    const CopyVideoTextureParams& params) {
   TRACE_EVENT0("media", "WebMediaPlayerImpl:copyVideoTextureToPlatformTexture");
+  DCHECK((params.copyType == CopyVideoTextureParams::FullCopy &&
+          !params.xoffset && !params.yoffset) ||
+         (params.copyType == CopyVideoTextureParams::SubCopy &&
+          !params.internalFormat && !params.type));
 
   scoped_refptr<VideoFrame> video_frame = GetCurrentFrameFromCompositor();
 
@@ -671,9 +671,15 @@
   gpu::gles2::GLES2Interface* gl =
       static_cast<gpu_blink::WebGraphicsContext3DImpl*>(web_graphics_context)
           ->GetGLInterface();
+  typedef SkCanvasVideoRenderer::CopyFrameSingleTextureParams CopyParams;
   SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
-      gl, video_frame.get(), texture, internal_format, type, premultiply_alpha,
-      flip_y);
+      gl, video_frame.get(),
+      CopyParams(params.copyType == CopyVideoTextureParams::FullCopy
+                     ? CopyParams::FullCopy
+                     : CopyParams::SubCopy,
+                 params.target, params.texture, params.internalFormat,
+                 params.type, params.level, params.xoffset, params.yoffset,
+                 params.premultiplyAlpha, params.flipY));
   return true;
 }
 
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index e839268d..497cb5da 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -138,11 +138,7 @@
 
   bool copyVideoTextureToPlatformTexture(
       blink::WebGraphicsContext3D* web_graphics_context,
-      unsigned int texture,
-      unsigned int internal_format,
-      unsigned int type,
-      bool premultiply_alpha,
-      bool flip_y) override;
+      const CopyVideoTextureParams& params) override;
 
   blink::WebAudioSourceProvider* audioSourceProvider() override;
 
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc
index fef32103..fc839141 100644
--- a/media/filters/vpx_video_decoder.cc
+++ b/media/filters/vpx_video_decoder.cc
@@ -342,7 +342,7 @@
   if (config.codec() == kCodecVP9) {
     memory_pool_ = new MemoryPool();
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-        memory_pool_.get(), task_runner_);
+        memory_pool_.get(), "VpxVideoDecoder", task_runner_);
     if (vpx_codec_set_frame_buffer_functions(vpx_codec_,
                                              &MemoryPool::GetVP9FrameBuffer,
                                              &MemoryPool::ReleaseVP9FrameBuffer,
diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc
index a382445..aa8d95e 100644
--- a/media/renderers/skcanvas_video_renderer.cc
+++ b/media/renderers/skcanvas_video_renderer.cc
@@ -162,8 +162,11 @@
     DCHECK(source_texture);
     gl->BindTexture(GL_TEXTURE_2D, source_texture);
     SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
-        gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, true,
-        false);
+        gl, video_frame,
+        SkCanvasVideoRenderer::CopyFrameSingleTextureParams(
+            SkCanvasVideoRenderer::CopyFrameSingleTextureParams::FullCopy,
+            GL_TEXTURE_2D, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0, 0,
+            true, false));
   } else {
     gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point);
     source_texture = gl->CreateAndConsumeTextureCHROMIUM(
@@ -539,11 +542,7 @@
 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
     gpu::gles2::GLES2Interface* gl,
     VideoFrame* video_frame,
-    unsigned int texture,
-    unsigned int internal_format,
-    unsigned int type,
-    bool premultiply_alpha,
-    bool flip_y) {
+    const CopyFrameSingleTextureParams& params) {
   DCHECK(video_frame);
   DCHECK(video_frame->HasTextures());
   DCHECK_EQ(1u, VideoFrame::NumPlanes(video_frame->format()));
@@ -564,9 +563,20 @@
   // value down to get the expected result.
   // "flip_y == true" means to reverse the video orientation while
   // "flip_y == false" means to keep the intrinsic orientation.
-  gl->CopyTextureCHROMIUM(GL_TEXTURE_2D, source_texture, texture,
-                          internal_format, type, flip_y, premultiply_alpha,
-                          false);
+  if (params.copy_type == CopyFrameSingleTextureParams::FullCopy) {
+    DCHECK(!params.xoffset && !params.yoffset);
+    gl->CopyTextureCHROMIUM(params.target, source_texture, params.texture,
+                            params.internal_format, params.type, params.flip_y,
+                            params.premultiply_alpha, false);
+  } else {
+    DCHECK_EQ(static_cast<unsigned int>(GL_FALSE), params.internal_format);
+    DCHECK_EQ(static_cast<unsigned int>(GL_FALSE), params.type);
+    gl->CopySubTextureCHROMIUM(params.target, source_texture, params.texture,
+                               params.xoffset, params.yoffset, 0, 0,
+                               video_frame->natural_size().width(),
+                               video_frame->natural_size().height(),
+                               params.flip_y, params.premultiply_alpha, false);
+  }
 
   gl->DeleteTextures(1, &source_texture);
   gl->Flush();
@@ -581,4 +591,26 @@
   last_timestamp_ = kNoTimestamp();
 }
 
+SkCanvasVideoRenderer::CopyFrameSingleTextureParams::
+    CopyFrameSingleTextureParams(CopyType copy_type,
+                                 unsigned target,
+                                 unsigned texture,
+                                 unsigned internal_format,
+                                 unsigned type,
+                                 int level,
+                                 int xoffset,
+                                 int yoffset,
+                                 bool premultiply_alpha,
+                                 bool flip_y)
+    : copy_type(copy_type),
+      target(target),
+      texture(texture),
+      internal_format(internal_format),
+      type(type),
+      level(level),
+      xoffset(xoffset),
+      yoffset(yoffset),
+      premultiply_alpha(premultiply_alpha),
+      flip_y(flip_y) {}
+
 }  // namespace media
diff --git a/media/renderers/skcanvas_video_renderer.h b/media/renderers/skcanvas_video_renderer.h
index 71e77ff..03de24a 100644
--- a/media/renderers/skcanvas_video_renderer.h
+++ b/media/renderers/skcanvas_video_renderer.h
@@ -65,14 +65,33 @@
   // Copy the contents of texture of |video_frame| to texture |texture|.
   // |level|, |internal_format|, |type| specify target texture |texture|.
   // The format of |video_frame| must be VideoFrame::NATIVE_TEXTURE.
+  struct MEDIA_EXPORT CopyFrameSingleTextureParams {
+    enum CopyType { FullCopy, SubCopy };
+    CopyFrameSingleTextureParams(CopyType copy_type,
+                                 unsigned target,
+                                 unsigned texture,
+                                 unsigned internal_format,
+                                 unsigned type,
+                                 int level,
+                                 int xoffset,
+                                 int yoffset,
+                                 bool premultiply_alpha,
+                                 bool flip_y);
+    CopyType copy_type;
+    unsigned int target;
+    unsigned int texture;
+    unsigned int internal_format;
+    unsigned int type;
+    int level;
+    int xoffset;
+    int yoffset;
+    bool premultiply_alpha;
+    bool flip_y;
+  };
   static void CopyVideoFrameSingleTextureToGLTexture(
       gpu::gles2::GLES2Interface* gl,
       VideoFrame* video_frame,
-      unsigned int texture,
-      unsigned int internal_format,
-      unsigned int type,
-      bool premultiply_alpha,
-      bool flip_y);
+      const CopyFrameSingleTextureParams& params);
 
  private:
   void ResetCache();
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc
index d1e3a3de..5f9543f 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -721,7 +721,7 @@
     : pool_impl_(
           new PoolImpl(media_task_runner, worker_task_runner, gpu_factories)) {
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      pool_impl_.get(), media_task_runner);
+      pool_impl_.get(), "GpuMemoryBufferVideoFramePool", media_task_runner);
 }
 
 GpuMemoryBufferVideoFramePool::~GpuMemoryBufferVideoFramePool() {
diff --git a/mojo/gles2/command_buffer_client_impl.cc b/mojo/gles2/command_buffer_client_impl.cc
index b3486874..f20c200 100644
--- a/mojo/gles2/command_buffer_client_impl.cc
+++ b/mojo/gles2/command_buffer_client_impl.cc
@@ -321,7 +321,7 @@
   scoped_ptr<gfx::GpuMemoryBuffer> buffer(mus::MojoGpuMemoryBufferImpl::Create(
       gfx::Size(static_cast<int>(width), static_cast<int>(height)),
       gpu::ImageFactory::DefaultBufferFormatForImageFormat(internalformat),
-      gfx::BufferUsage::GPU_READ_WRITE));
+      gfx::BufferUsage::SCANOUT));
   if (!buffer)
     return -1;
 
diff --git a/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java b/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
index 06ff933f..333c85c 100644
--- a/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
+++ b/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
@@ -394,8 +394,9 @@
 
     /**
      * Constructs a NetworkChangeNotifierAutoDetect. Should only be called on UI thread.
-     * @param alwaysWatchForChanges If true, always watch for network changes.
-     *    Otherwise, only watch if app is in foreground.
+     * @param policy The RegistrationPolicy which determines when this class should watch
+     *     for network changes (e.g. see (@link RegistrationPolicyAlwaysRegister} and
+     *     {@link RegistrationPolicyApplicationStatus}).
      */
     @SuppressLint("NewApi")
     public NetworkChangeNotifierAutoDetect(
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index e0c4100..8a8e742 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -1291,13 +1291,13 @@
   // reflect servers require a deprecated cipher rather than merely prefer
   // it. This, however, has no security benefit until the ciphers are actually
   // removed.
-  if (!server_ssl_config_.enable_deprecated_cipher_suites &&
+  if (!server_ssl_config_.deprecated_cipher_suites_enabled &&
       (error == ERR_SSL_VERSION_OR_CIPHER_MISMATCH ||
        error == ERR_CONNECTION_CLOSED || error == ERR_CONNECTION_RESET)) {
     net_log_.AddEvent(
         NetLog::TYPE_SSL_CIPHER_FALLBACK,
         base::Bind(&NetLogSSLCipherFallbackCallback, &request_->url, error));
-    server_ssl_config_.enable_deprecated_cipher_suites = true;
+    server_ssl_config_.deprecated_cipher_suites_enabled = true;
     ResetConnectionAndRequestForResend();
     return OK;
   }
@@ -1514,7 +1514,7 @@
   }
 
   UMA_HISTOGRAM_BOOLEAN("Net.ConnectionUsedSSLDeprecatedCipherFallback2",
-                        server_ssl_config_.enable_deprecated_cipher_suites);
+                        server_ssl_config_.deprecated_cipher_suites_enabled);
 
   if (server_ssl_config_.version_fallback) {
     // Record the error code which triggered the fallback and the state the
diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc
index 003933b7..492b89b4 100644
--- a/net/http/http_stream_factory.cc
+++ b/net/http/http_stream_factory.cc
@@ -13,6 +13,7 @@
 #include "net/base/host_port_pair.h"
 #include "net/base/port_util.h"
 #include "net/http/http_network_session.h"
+#include "net/quic/quic_protocol.h"
 #include "net/spdy/spdy_alt_svc_wire_format.h"
 #include "url/gurl.h"
 
@@ -54,6 +55,24 @@
         !IsPortValid(alternative_service_entry.port)) {
       continue;
     }
+    // Check if QUIC version is supported.
+    if (protocol == QUIC && !alternative_service_entry.version.empty()) {
+      bool match_found = false;
+      for (QuicVersion supported : session.params().quic_supported_versions) {
+        for (uint16 advertised : alternative_service_entry.version) {
+          if (supported == advertised) {
+            match_found = true;
+            break;
+          }
+        }
+        if (match_found) {
+          break;
+        }
+      }
+      if (!match_found) {
+        continue;
+      }
+    }
     AlternativeService alternative_service(protocol,
                                            alternative_service_entry.host,
                                            alternative_service_entry.port);
diff --git a/net/quic/quic_headers_stream_test.cc b/net/quic/quic_headers_stream_test.cc
index 98bf17b..9b93bbd 100644
--- a/net/quic/quic_headers_stream_test.cc
+++ b/net/quic/quic_headers_stream_test.cc
@@ -479,7 +479,7 @@
 }
 
 TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
-  SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR, "");
+  SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR);
   scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
   EXPECT_CALL(*connection_,
               SendConnectionCloseWithDetails(
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 378a6637..bc9f397 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
 #include "net/base/network_quality_estimator.h"
 #include "net/base/socket_performance_watcher.h"
 #include "net/base/test_completion_callback.h"
@@ -679,6 +680,64 @@
   SendRequestAndExpectQuicResponse("hello!");
 }
 
+TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceQuicSupportedVersion) {
+  std::string altsvc_header = base::StringPrintf(
+      "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", GetParam());
+  MockRead http_reads[] = {
+      MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
+      MockRead("hello world"),
+      MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+      MockRead(ASYNC, OK)};
+
+  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+                                     0);
+  socket_factory_.AddSocketDataProvider(&http_data);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+  MockQuicData mock_quic_data;
+  mock_quic_data.AddWrite(
+      ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
+                                    GetRequestHeaders("GET", "https", "/")));
+  mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+      1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
+  mock_quic_data.AddRead(
+      ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
+  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+  mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);  // No more data to read
+  mock_quic_data.AddRead(SYNCHRONOUS, 0);         // EOF
+
+  mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+
+  AddHangingNonAlternateProtocolSocketData();
+  CreateSessionWithNextProtos();
+
+  SendRequestAndExpectHttpResponse("hello world");
+  SendRequestAndExpectQuicResponse("hello!");
+}
+
+TEST_P(QuicNetworkTransactionTest,
+       DoNotUseAlternativeServiceQuicUnsupportedVersion) {
+  std::string altsvc_header = base::StringPrintf(
+      "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", GetParam() - 1);
+  MockRead http_reads[] = {
+      MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
+      MockRead("hello world"),
+      MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+      MockRead(ASYNC, OK)};
+
+  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+                                     0);
+  socket_factory_.AddSocketDataProvider(&http_data);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+  socket_factory_.AddSocketDataProvider(&http_data);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+  CreateSessionWithNextProtos();
+
+  SendRequestAndExpectHttpResponse("hello world");
+  SendRequestAndExpectHttpResponse("hello world");
+}
+
 // When multiple alternative services are advertised,
 // HttpStreamFactoryImpl::RequestStreamInternal() only passes the first one to
 // Job.  This is what the following test verifies.
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc
index 3066171..07072db 100644
--- a/net/socket/client_socket_pool_manager.cc
+++ b/net/socket/client_socket_pool_manager.cc
@@ -146,7 +146,7 @@
     }
     // Place sockets with and without deprecated ciphers into separate
     // connection groups.
-    if (ssl_config_for_origin.enable_deprecated_cipher_suites)
+    if (ssl_config_for_origin.deprecated_cipher_suites_enabled)
       prefix += "deprecatedciphers/";
     connection_group = prefix + connection_group;
   }
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 904a776..8fad0a0 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -2780,7 +2780,7 @@
     SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
   }
 
-  if (!ssl_config_.enable_deprecated_cipher_suites) {
+  if (!ssl_config_.rc4_enabled) {
     const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers();
     const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers();
     for (int i = 0; i < num_ciphers; i++) {
@@ -2906,7 +2906,7 @@
       NOTREACHED();
   }
   peer_id += "/";
-  if (ssl_config_.enable_deprecated_cipher_suites)
+  if (ssl_config_.deprecated_cipher_suites_enabled)
     peer_id += "deprecated";
 
   peer_id += "/";
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index d6e0aa2..29c59f7f 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -888,9 +888,10 @@
   if (ssl_config_.require_ecdhe)
     command.append(":!kRSA:!kDHE");
 
-  if (!ssl_config_.enable_deprecated_cipher_suites) {
+  if (!ssl_config_.rc4_enabled)
     command.append(":!RC4");
-  } else {
+
+  if (ssl_config_.deprecated_cipher_suites_enabled) {
     // Add TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 under a fallback. This is
     // believed to work around a bug in some out-of-date Microsoft IIS servers
     // which cause them to require the version downgrade
@@ -2053,7 +2054,7 @@
   }
 
   result.append("/");
-  if (ssl_config_.enable_deprecated_cipher_suites)
+  if (ssl_config_.deprecated_cipher_suites_enabled)
     result.append("deprecated");
 
   result.append("/");
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index d938674..06be299 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -2502,8 +2502,8 @@
             SSLConnectionStatusToVersion(ssl_info.connection_status));
 }
 
-// Test that RC4 is only enabled if enable_deprecated_cipher_suites is set.
-TEST_F(SSLClientSocketTest, DeprecatedRC4) {
+// Test that RC4 is only enabled if rc4_enabled is set.
+TEST_F(SSLClientSocketTest, RC4Enabled) {
   SpawnedTestServer::SSLOptions ssl_options;
   ssl_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_RC4;
   ASSERT_TRUE(StartTestServer(ssl_options));
@@ -2514,8 +2514,8 @@
   ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
   EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv);
 
-  // Enabling deprecated ciphers works fine.
-  ssl_config.enable_deprecated_cipher_suites = true;
+  // Enabling RC4 works fine.
+  ssl_config.rc4_enabled = true;
   ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
   EXPECT_EQ(OK, rv);
 }
@@ -2527,7 +2527,7 @@
   // Prepare a normal and deprecated SSL config.
   SSLConfig ssl_config;
   SSLConfig deprecated_ssl_config;
-  deprecated_ssl_config.enable_deprecated_cipher_suites = true;
+  deprecated_ssl_config.deprecated_cipher_suites_enabled = true;
 
   // Connect with deprecated ciphers enabled to warm the session cache cache.
   int rv;
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc
index eae2b503..fdd2653 100644
--- a/net/spdy/buffered_spdy_framer.cc
+++ b/net/spdy/buffered_spdy_framer.cc
@@ -343,9 +343,7 @@
 SpdyFrame* BufferedSpdyFramer::CreateRstStream(
     SpdyStreamId stream_id,
     SpdyRstStreamStatus status) const {
-  // RST_STREAM payloads are not part of any SPDY spec.
-  // SpdyFramer will accept them, but don't create them.
-  SpdyRstStreamIR rst_ir(stream_id, status, "");
+  SpdyRstStreamIR rst_ir(stream_id, status);
   return spdy_framer_.SerializeRstStream(rst_ir);
 }
 
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index beb20bc..c034311 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -953,9 +953,8 @@
       }
       break;
     case RST_STREAM:
-      // For SPDY versions < 4, the header has a fixed length.
-      // For SPDY version 4 and up, the RST_STREAM frame may include optional
-      // opaque data, so we only have a lower limit on the frame size.
+      // TODO(bnc): Enforce the length of the header, and change error to
+      // FRAME_SIZE_ERROR.
       if ((current_frame_length_ != GetRstStreamMinimumSize() &&
            protocol_version() <= SPDY3) ||
           (current_frame_length_ < GetRstStreamMinimumSize() &&
@@ -2442,9 +2441,6 @@
   // commented but left in place to simplify future patching.
   // Compute the output buffer size, taking opaque data into account.
   size_t expected_length = GetRstStreamMinimumSize();
-  if (protocol_version() > SPDY3) {
-    expected_length += rst_stream.description().size();
-  }
   SpdyFrameBuilder builder(expected_length, protocol_version());
 
   // Serialize the RST_STREAM frame.
@@ -2458,12 +2454,6 @@
   builder.WriteUInt32(SpdyConstants::SerializeRstStreamStatus(
       protocol_version(), rst_stream.status()));
 
-  // In HTTP2 and up, RST_STREAM frames may also specify opaque data.
-  if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) {
-    builder.WriteBytes(rst_stream.description().data(),
-                       rst_stream.description().size());
-  }
-
   DCHECK_EQ(expected_length, builder.length());
   return builder.take();
 }
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 5ad8a15..749d975 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -2433,12 +2433,10 @@
       0x00, 0x00, 0x00, 0x01,
     };
     const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x07, 0x03,
-      0x00, 0x00, 0x00, 0x00,
-      0x01, 0x00, 0x00, 0x00,
-      0x01, 0x52, 0x53, 0x54
+        0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00,
+        0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
     };
-    SpdyRstStreamIR rst_stream(1, RST_STREAM_PROTOCOL_ERROR, "RST");
+    SpdyRstStreamIR rst_stream(1, RST_STREAM_PROTOCOL_ERROR);
     scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
     if (IsHttp2()) {
       CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2461,9 +2459,7 @@
       0xff, 0x00, 0x00, 0x00,
       0x01,
     };
-    SpdyRstStreamIR rst_stream(0x7FFFFFFF,
-                               RST_STREAM_PROTOCOL_ERROR,
-                               "");
+    SpdyRstStreamIR rst_stream(0x7FFFFFFF, RST_STREAM_PROTOCOL_ERROR);
     scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
     if (IsHttp2()) {
       CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2486,9 +2482,7 @@
       0xff, 0x00, 0x00, 0x00,
       0x02,
     };
-    SpdyRstStreamIR rst_stream(0x7FFFFFFF,
-                               RST_STREAM_INTERNAL_ERROR,
-                               "");
+    SpdyRstStreamIR rst_stream(0x7FFFFFFF, RST_STREAM_INTERNAL_ERROR);
     scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
     if (IsHttp2()) {
       CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -5142,7 +5136,7 @@
     SpdyFramer framer(spdy_version_);
     framer.set_visitor(&visitor);
 
-    SpdyRstStreamIR rst_stream(13, RST_STREAM_CANCEL, "");
+    SpdyRstStreamIR rst_stream(13, RST_STREAM_CANCEL);
     scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
     SetFrameFlags(frame.get(), flags, spdy_version_);
 
diff --git a/net/spdy/spdy_protocol.cc b/net/spdy/spdy_protocol.cc
index 46b080f9..9eaf468a 100644
--- a/net/spdy/spdy_protocol.cc
+++ b/net/spdy/spdy_protocol.cc
@@ -776,10 +776,8 @@
 }
 
 SpdyRstStreamIR::SpdyRstStreamIR(SpdyStreamId stream_id,
-                                 SpdyRstStreamStatus status,
-                                 base::StringPiece description)
-    : SpdyFrameWithStreamIdIR(stream_id),
-      description_(description) {
+                                 SpdyRstStreamStatus status)
+    : SpdyFrameWithStreamIdIR(stream_id) {
   set_status(status);
 }
 
diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h
index c5d66c9..9abb396 100644
--- a/net/spdy/spdy_protocol.h
+++ b/net/spdy/spdy_protocol.h
@@ -723,8 +723,7 @@
 
 class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
  public:
-  SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status,
-                  base::StringPiece description);
+  SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status);
 
   ~SpdyRstStreamIR() override;
 
@@ -735,13 +734,10 @@
     status_ = status;
   }
 
-  base::StringPiece description() const { return description_; }
-
   void Visit(SpdyFrameVisitor* visitor) const override;
 
  private:
   SpdyRstStreamStatus status_;
-  base::StringPiece description_;
 
   DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR);
 };
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 186a02b..4cc450e 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -952,7 +952,7 @@
 SpdyFrame* SpdyTestUtil::ConstructSpdyRstStream(
     SpdyStreamId stream_id,
     SpdyRstStreamStatus status) const {
-  SpdyRstStreamIR rst_ir(stream_id, status, "");
+  SpdyRstStreamIR rst_ir(stream_id, status);
   return CreateFramer(false)->SerializeRstStream(rst_ir);
 }
 
diff --git a/net/ssl/ssl_config.cc b/net/ssl/ssl_config.cc
index 412bf00..e3ced671 100644
--- a/net/ssl/ssl_config.cc
+++ b/net/ssl/ssl_config.cc
@@ -24,7 +24,8 @@
       version_min(kDefaultSSLVersionMin),
       version_max(kDefaultSSLVersionMax),
       version_fallback_min(kDefaultSSLVersionFallbackMin),
-      enable_deprecated_cipher_suites(false),
+      deprecated_cipher_suites_enabled(false),
+      rc4_enabled(false),
       channel_id_enabled(true),
       false_start_enabled(true),
       signed_cert_timestamps_enabled(true),
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h
index cd83ea5d..25a66f7 100644
--- a/net/ssl/ssl_config.h
+++ b/net/ssl/ssl_config.h
@@ -109,8 +109,18 @@
   // disable TLS_ECDH_ECDSA_WITH_RC4_128_SHA, specify 0xC002.
   std::vector<uint16> disabled_cipher_suites;
 
-  // Enables deprecated cipher suites. Currently, RC4 is deprecated.
-  bool enable_deprecated_cipher_suites;
+  // Enables deprecated cipher suites. These cipher suites are selected under a
+  // fallback to distinguish servers which require them from servers which
+  // merely prefer them.
+  //
+  // NOTE: because they are under a fallback, connections are still vulnerable
+  // to them as far as downgrades are concerned, so this should only be used for
+  // measurement of ciphers not to be carried long-term. It is no fix for
+  // servers with bad configurations without full removal.
+  bool deprecated_cipher_suites_enabled;
+
+  // Enables RC4 cipher suites.
+  bool rc4_enabled;
 
   bool channel_id_enabled;   // True if TLS channel ID extension is enabled.
   bool false_start_enabled;  // True if we'll use TLS False Start.
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 59e885f..e782b88 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -7864,45 +7864,6 @@
   }
 }
 
-// Tests that servers which require a deprecated cipher suite still work.
-TEST_F(HTTPSRequestTest, CipherFallbackTest) {
-  TestNetLog net_log;
-  default_context_.set_net_log(&net_log);
-
-  SpawnedTestServer::SSLOptions ssl_options;
-  ssl_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_RC4;
-  SpawnedTestServer test_server(
-      SpawnedTestServer::TYPE_HTTPS, ssl_options,
-      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
-  ASSERT_TRUE(test_server.Start());
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> r(default_context_.CreateRequest(
-      test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
-  r->Start();
-  EXPECT_TRUE(r->is_pending());
-
-  base::RunLoop().Run();
-
-  EXPECT_EQ(1, d.response_started_count());
-  EXPECT_FALSE(d.received_data_before_response());
-  EXPECT_NE(0, d.bytes_received());
-  CheckSSLInfo(r->ssl_info());
-  EXPECT_EQ(test_server.host_port_pair().host(), r->GetSocketAddress().host());
-  EXPECT_EQ(test_server.host_port_pair().port(), r->GetSocketAddress().port());
-
-  // No version downgrade should have been necessary.
-  EXPECT_FALSE(r->ssl_info().connection_status &
-               SSL_CONNECTION_VERSION_FALLBACK);
-  EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_2,
-            SSLConnectionStatusToVersion(r->ssl_info().connection_status));
-
-  TestNetLogEntry::List entries;
-  net_log.GetEntries(&entries);
-  ExpectLogContainsSomewhere(entries, 0, NetLog::TYPE_SSL_CIPHER_FALLBACK,
-                             NetLog::PHASE_NONE);
-}
-
 // This tests that a load of www.google.com with a certificate error sets
 // the |certificate_errors_are_fatal| flag correctly. This flag will cause
 // the interstitial to be fatal.
diff --git a/skia/ext/bitmap_platform_device_cairo.cc b/skia/ext/bitmap_platform_device_cairo.cc
index 29066b3f..f52b430c6 100644
--- a/skia/ext/bitmap_platform_device_cairo.cc
+++ b/skia/ext/bitmap_platform_device_cairo.cc
@@ -136,14 +136,6 @@
   return device;
 }
 
-BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
-                                                           int height,
-                                                           bool is_opaque) {
-  // The Linux port always constructs initialized bitmaps, so there is no extra
-  // work to perform here.
-  return Create(width, height, is_opaque);
-}
-
 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                    bool is_opaque,
                                                    uint8_t* data) {
diff --git a/skia/ext/bitmap_platform_device_cairo.h b/skia/ext/bitmap_platform_device_cairo.h
index 96a1e17..96bc62a4 100644
--- a/skia/ext/bitmap_platform_device_cairo.h
+++ b/skia/ext/bitmap_platform_device_cairo.h
@@ -72,12 +72,6 @@
   // completely opaque and allows some optimizations.
   static BitmapPlatformDevice* Create(int width, int height, bool is_opaque);
 
-  // Performs the same construction as Create.
-  // Other ports require a separate construction routine because Create does not
-  // initialize the bitmap to 0.
-  static BitmapPlatformDevice* CreateAndClear(int width, int height,
-                                              bool is_opaque);
-
   // This doesn't take ownership of |data|. If |data| is NULL, the contents
   // of the device are initialized to 0.
   static BitmapPlatformDevice* Create(int width, int height, bool is_opaque,
diff --git a/skia/skia.gyp b/skia/skia.gyp
index b03c3b2..ce0aae1 100644
--- a/skia/skia.gyp
+++ b/skia/skia.gyp
@@ -13,6 +13,13 @@
         {
           'target_name': 'skia_library',
           'type': 'static_library',
+          # The optimize: 'max' scattered throughout are particularly
+          # important when compiled by MSVC 2013, which seems 
+          # to mis-link-time-compile code that's built with
+          # different optimization levels. http://crbug.com/543583
+          'variables': {
+            'optimize': 'max',
+          },
           'includes': [
             'skia_common.gypi',
             'skia_library.gypi',
@@ -29,6 +36,13 @@
       'targets': [
         {
           'target_name': 'skia',
+          # The optimize: 'max' scattered throughout are particularly
+          # important when compiled by MSVC 2013, which seems 
+          # to mis-link-time-compile code that's built with
+          # different optimization levels. http://crbug.com/543583
+          'variables': {
+            'optimize': 'max',
+          },
           'type': 'none',
           'dependencies': [
             'skia_library',
@@ -63,6 +77,13 @@
       'targets': [
         {
           'target_name': 'skia',
+          # The optimize: 'max' scattered throughout are particularly
+          # important when compiled by MSVC 2013, which seems 
+          # to mis-link-time-compile code that's built with
+          # different optimization levels. http://crbug.com/543583
+          'variables': {
+            'optimize': 'max',
+          },
           'type': 'shared_library',
           'includes': [
             # Include skia_common.gypi first since it contains filename
@@ -108,6 +129,13 @@
   'targets': [
     {
       'target_name': 'image_operations_bench',
+      # The optimize: 'max' scattered throughout are particularly
+      # important when compiled by MSVC 2013, which seems 
+      # to mis-link-time-compile code that's built with
+      # different optimization levels. http://crbug.com/543583
+      'variables': {
+        'optimize': 'max',
+      },
       'type': 'executable',
       'dependencies': [
         '../base/base.gyp:base',
@@ -123,6 +151,13 @@
     {
       'target_name': 'filter_fuzz_stub',
       'type': 'executable',
+      # The optimize: 'max' scattered throughout are particularly
+      # important when compiled by MSVC 2013, which seems 
+      # to mis-link-time-compile code that's built with
+      # different optimization levels. http://crbug.com/543583
+      'variables': {
+        'optimize': 'max',
+      },
       'dependencies': [
         '../base/base.gyp:base',
         '../base/base.gyp:test_support_base',
@@ -138,6 +173,13 @@
     {
       'target_name': 'skia_mojo',
       'type': 'static_library',
+      # The optimize: 'max' scattered throughout are particularly
+      # important when compiled by MSVC 2013, which seems 
+      # to mis-link-time-compile code that's built with
+      # different optimization levels. http://crbug.com/543583
+      'variables': {
+        'optimize': 'max',
+      },
       'dependencies': [
         'skia',
         '../base/base.gyp:base',
diff --git a/skia/skia_library_opts.gyp b/skia/skia_library_opts.gyp
index 35eec1b..85fdcb3 100644
--- a/skia/skia_library_opts.gyp
+++ b/skia/skia_library_opts.gyp
@@ -28,6 +28,13 @@
     {
       'target_name': 'skia_opts',
       'type': 'static_library',
+      # The optimize: 'max' scattered throughout are particularly
+      # important when compiled by MSVC 2013, which seems 
+      # to mis-link-time-compile code that's built with
+      # different optimization levels. http://crbug.com/543583
+      'variables': {
+        'optimize': 'max',
+      },
       'includes': [
         'skia_common.gypi',
         '../build/android/increase_size_for_speed.gypi',
@@ -102,6 +109,13 @@
     {
       'target_name': 'skia_opts_ssse3',
       'type': 'static_library',
+      # The optimize: 'max' scattered throughout are particularly
+      # important when compiled by MSVC 2013, which seems 
+      # to mis-link-time-compile code that's built with
+      # different optimization levels. http://crbug.com/543583
+      'variables': {
+        'optimize': 'max',
+      },
       'includes': [
         'skia_common.gypi',
         '../build/android/increase_size_for_speed.gypi',
@@ -139,6 +153,13 @@
     {
       'target_name': 'skia_opts_sse41',
       'type': 'static_library',
+      # The optimize: 'max' scattered throughout are particularly
+      # important when compiled by MSVC 2013, which seems 
+      # to mis-link-time-compile code that's built with
+      # different optimization levels. http://crbug.com/543583
+      'variables': {
+        'optimize': 'max',
+      },
       'includes': [
         'skia_common.gypi',
         '../build/android/increase_size_for_speed.gypi',
@@ -169,6 +190,13 @@
     {
       'target_name': 'skia_opts_none',
       'type': 'static_library',
+      # The optimize: 'max' scattered throughout are particularly
+      # important when compiled by MSVC 2013, which seems 
+      # to mis-link-time-compile code that's built with
+      # different optimization levels. http://crbug.com/543583
+      'variables': {
+        'optimize': 'max',
+      },
       'includes': [
         'skia_common.gypi',
         '../build/android/increase_size_for_speed.gypi',
diff --git a/sql/connection.cc b/sql/connection.cc
index 28beafc..a904632eb 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -355,7 +355,7 @@
       query_time_histogram_(NULL),
       clock_(new TimeSource()) {
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this);
+      this, "sql::Connection", nullptr);
 }
 
 Connection::~Connection() {
diff --git a/sync/android/java/src/org/chromium/sync/signin/AccountManagerDelegate.java b/sync/android/java/src/org/chromium/sync/signin/AccountManagerDelegate.java
index 60ecb57..b227f22 100644
--- a/sync/android/java/src/org/chromium/sync/signin/AccountManagerDelegate.java
+++ b/sync/android/java/src/org/chromium/sync/signin/AccountManagerDelegate.java
@@ -11,25 +11,19 @@
 import android.os.Bundle;
 import android.os.Handler;
 
+import org.chromium.base.Callback;
+
 /**
  * Wrapper around the Android account manager, to facilitate dependency injection during testing.
  */
 public interface AccountManagerDelegate {
     /**
-     * A callback class that can be used to allow asynchronous methods.
-     */
-    interface Callback<T> {
-        void gotResult(T value);
-    }
-
-    /**
      * Use the asynchronous getAccountsByType(String, Callback<Account[]>) instead.
      */
     @Deprecated
     Account[] getAccountsByType(String type);
 
-    // TODO(maxbogue): Remove full Callback path once AccountManagerDelegate.Callback is removed.
-    void getAccountsByType(String type, org.chromium.base.Callback<Account[]> callback);
+    void getAccountsByType(String type, Callback<Account[]> callback);
 
     AccountManagerFuture<Bundle> getAuthToken(Account account, String authTokenType,
             boolean notifyAuthFailure, AccountManagerCallback<Bundle> callback, Handler handler);
@@ -38,7 +32,5 @@
 
     AuthenticatorDescription[] getAuthenticatorTypes();
 
-    // TODO(maxbogue): Remove full Callback path once AccountManagerDelegate.Callback is removed.
-    void hasFeatures(
-            Account account, String[] features, org.chromium.base.Callback<Boolean> callback);
+    void hasFeatures(Account account, String[] features, Callback<Boolean> callback);
 }
diff --git a/sync/android/java/src/org/chromium/sync/signin/SystemAccountManagerDelegate.java b/sync/android/java/src/org/chromium/sync/signin/SystemAccountManagerDelegate.java
index 5865586f..75777dd8 100644
--- a/sync/android/java/src/org/chromium/sync/signin/SystemAccountManagerDelegate.java
+++ b/sync/android/java/src/org/chromium/sync/signin/SystemAccountManagerDelegate.java
@@ -18,6 +18,7 @@
 import android.os.StrictMode;
 import android.os.SystemClock;
 
+import org.chromium.base.Callback;
 import org.chromium.base.Log;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.library_loader.LibraryLoader;
@@ -53,10 +54,8 @@
         return accounts;
     }
 
-    // TODO(maxbogue): Remove full Callback path once AccountManagerDelegate.Callback is removed.
     @Override
-    public void getAccountsByType(
-            final String type, final org.chromium.base.Callback<Account[]> callback) {
+    public void getAccountsByType(final String type, final Callback<Account[]> callback) {
         new AsyncTask<Void, Void, Account[]>() {
             @Override
             protected Account[] doInBackground(Void... params) {
@@ -94,28 +93,13 @@
         return mAccountManager.getAuthenticatorTypes();
     }
 
-    // TODO(maxbogue): Remove full Callback path once AccountManagerDelegate.Callback is removed.
     @Override
-    public void hasFeatures(Account account, String[] features,
-            final org.chromium.base.Callback<Boolean> callback) {
-        hasFeatures(account, features, new Callback<Boolean>() {
-            @Override
-            public void gotResult(Boolean result) {
-                callback.onResult(result);
-            }
-        });
-    }
-
-    /**
-     * TODO(maxbogue): Remove once downstream override is removed.
-     */
-    @Deprecated
     public void hasFeatures(Account account, String[] features, final Callback<Boolean> callback) {
         if (!AccountManagerHelper.get(mApplicationContext).hasGetAccountsPermission()) {
             ThreadUtils.postOnUiThread(new Runnable() {
                 @Override
                 public void run() {
-                    callback.gotResult(false);
+                    callback.onResult(false);
                 }
             });
             return;
@@ -132,7 +116,7 @@
                 } catch (OperationCanceledException e) {
                     Log.e(TAG, "Checking features was cancelled. This should not happen.");
                 }
-                callback.gotResult(hasFeatures);
+                callback.onResult(hasFeatures);
             }
         }, null /* handler */);
     }
diff --git a/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java b/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
index 0420772..3b3fd39 100644
--- a/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
+++ b/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
@@ -26,6 +26,7 @@
 import android.os.Handler;
 import android.text.TextUtils;
 
+import org.chromium.base.Callback;
 import org.chromium.base.Log;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.sync.signin.AccountManagerDelegate;
@@ -136,10 +137,8 @@
         }
     }
 
-    // TODO(maxbogue): Remove full Callback path once AccountManagerDelegate.Callback is removed.
     @Override
-    public void getAccountsByType(
-            final String type, final org.chromium.base.Callback<Account[]> callback) {
+    public void getAccountsByType(final String type, final Callback<Account[]> callback) {
         new AsyncTask<Void, Void, Account[]>() {
             @Override
             protected Account[] doInBackground(Void... params) {
@@ -281,10 +280,9 @@
         return new AuthenticatorDescription[] { googleAuthenticator };
     }
 
-    // TODO(maxbogue): Remove full Callback path once AccountManagerDelegate.Callback is removed.
     @Override
-    public void hasFeatures(Account account, final String[] features,
-            final org.chromium.base.Callback<Boolean> callback) {
+    public void hasFeatures(
+            Account account, final String[] features, final Callback<Boolean> callback) {
         final AccountHolder accountHolder = getAccountHolder(account);
         accountHolder.addFeaturesCallback(new Runnable() {
             @Override
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 7b52738..d71c9f6 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1551,6 +1551,8 @@
 crbug.com/538717 [ Win Mac Linux ] http/tests/permissions/chromium/test-request-multiple-worker.html [ Failure Pass Timeout ]
 crbug.com/538717 [ Win Mac Linux ] http/tests/permissions/chromium/test-request-multiple-sharedworker.html [ Failure Pass Timeout ]
 
+crbug.com/549594 [ SnowLeopard ] svg/text/text-selection-ws-02-t.svg [ NeedsRebaseline ]
+
 crbug.com/541601 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-defaults.xhtml [ Failure ]
 
 crbug.com/543369 [ Linux ] fast/forms/select/popup-menu-appearance-tall.html [ Failure ]
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index 01d98f7..a4f5bc7 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -4254,7 +4254,7 @@
     case CSSValuePanY:
         return TouchActionPanY;
     case CSSValueManipulation:
-        return TouchActionPanX | TouchActionPanY | TouchActionPinchZoom;
+        return TouchActionManipulation;
     default:
         break;
     }
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 7fd5c90..af0cb90 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -712,13 +712,11 @@
 static PassRefPtrWillBeRawPtr<CSSValue> touchActionFlagsToCSSValue(TouchAction touchAction)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-    if (touchAction == TouchActionAuto)
+    if (touchAction == TouchActionAuto) {
         list->append(cssValuePool().createIdentifierValue(CSSValueAuto));
-    if (touchAction & TouchActionNone) {
-        ASSERT(touchAction == TouchActionNone);
+    } else if (touchAction == TouchActionNone) {
         list->append(cssValuePool().createIdentifierValue(CSSValueNone));
-    }
-    if (touchAction == (TouchActionPanX | TouchActionPanY | TouchActionPinchZoom)) {
+    } else if (touchAction == TouchActionManipulation) {
         list->append(cssValuePool().createIdentifierValue(CSSValueManipulation));
     } else {
         if ((touchAction & TouchActionPanX) == TouchActionPanX)
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
index 32565fb..55cec81 100644
--- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -77,7 +77,7 @@
 // Upper limit of m_listItems. According to the HTML standard, options larger
 // than this limit doesn't work well because |selectedIndex| IDL attribute is
 // signed.
-static const unsigned maxListItems = std::numeric_limits<int>::max();
+static const unsigned maxListItems = INT_MAX;
 
 HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form)
     : HTMLFormControlElementWithState(selectTag, document, form)
diff --git a/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp b/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
index fe517064..e481ed1 100644
--- a/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
@@ -206,13 +206,16 @@
     webMediaPlayer()->paint(canvas, destRect, paint ? paint->getAlpha() : 0xFF, mode);
 }
 
-bool HTMLVideoElement::copyVideoTextureToPlatformTexture(WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum type, bool premultiplyAlpha, bool flipY)
+bool HTMLVideoElement::copyVideoTextureToPlatformTexture(WebGraphicsContext3D* context, const WebMediaPlayer::CopyVideoTextureParams& params)
 {
     if (!webMediaPlayer())
         return false;
 
-    ASSERT(Extensions3DUtil::canUseCopyTextureCHROMIUM(GL_TEXTURE_2D, internalFormat, type, 0));
-    return webMediaPlayer()->copyVideoTextureToPlatformTexture(context, texture, internalFormat, type, premultiplyAlpha, flipY);
+    ASSERT(Extensions3DUtil::canUseCopyTextureCHROMIUM(params.target,
+        params.copyType == WebMediaPlayer::CopyVideoTextureParams::SubCopy ? GL_RGBA : params.internalFormat,
+        params.copyType == WebMediaPlayer::CopyVideoTextureParams::SubCopy ? GL_UNSIGNED_BYTE : params.type,
+        params.level));
+    return webMediaPlayer()->copyVideoTextureToPlatformTexture(context, params);
 }
 
 bool HTMLVideoElement::hasAvailableVideoFrame() const
diff --git a/third_party/WebKit/Source/core/html/HTMLVideoElement.h b/third_party/WebKit/Source/core/html/HTMLVideoElement.h
index 056e560..d2fc47ac 100644
--- a/third_party/WebKit/Source/core/html/HTMLVideoElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLVideoElement.h
@@ -69,7 +69,7 @@
     void paintCurrentFrame(SkCanvas*, const IntRect&, const SkPaint*) const;
 
     // Used by WebGL to do GPU-GPU textures copy if possible.
-    bool copyVideoTextureToPlatformTexture(WebGraphicsContext3D*, Platform3DObject texture, GLenum internalFormat, GLenum type, bool premultiplyAlpha, bool flipY);
+    bool copyVideoTextureToPlatformTexture(WebGraphicsContext3D*, const WebMediaPlayer::CopyVideoTextureParams&);
 
     bool shouldDisplayPosterImage() const { return displayMode() == Poster; }
 
diff --git a/third_party/WebKit/Source/core/input/TouchActionUtil.cpp b/third_party/WebKit/Source/core/input/TouchActionUtil.cpp
index 69eabf3c..8ef15dfd8 100644
--- a/third_party/WebKit/Source/core/input/TouchActionUtil.cpp
+++ b/third_party/WebKit/Source/core/input/TouchActionUtil.cpp
@@ -28,19 +28,6 @@
     return true;
 }
 
-static TouchAction intersectTouchAction(TouchAction action1, TouchAction action2)
-{
-    if (action1 == TouchActionNone || action2 == TouchActionNone)
-        return TouchActionNone;
-    if (action1 == TouchActionAuto)
-        return action2;
-    if (action2 == TouchActionAuto)
-        return action1;
-    if (!(action1 & action2))
-        return TouchActionNone;
-    return action1 & action2;
-}
-
 } // namespace
 
 TouchAction computeEffectiveTouchAction(const Node& node)
@@ -53,7 +40,7 @@
         if (LayoutObject* layoutObject = curNode->layoutObject()) {
             if (supportsTouchAction(*layoutObject)) {
                 TouchAction action = layoutObject->style()->touchAction();
-                effectiveTouchAction = intersectTouchAction(action, effectiveTouchAction);
+                effectiveTouchAction &= action;
                 if (effectiveTouchAction == TouchActionNone)
                     break;
             }
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index 70493d6..672b9410 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -705,9 +705,6 @@
 {
     ASSERT(element);
     ImageResource* cachedImage = getImageResource(element);
-    // Don't use cachedImage->imageForLayoutObject() here as that may return BitmapImages for cached SVG Images.
-    // Users of getImage() want access to the SVGImage, in order to figure out the filename extensions,
-    // which would be empty when asking the cached BitmapImages.
     return (cachedImage && !cachedImage->errorOccurred()) ?
         cachedImage->image() : nullptr;
 }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index 20aa6ac..14d6831 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -465,19 +465,22 @@
 
 static const size_t TouchActionBits = 6;
 enum TouchAction {
-    TouchActionAuto = 0x0,
-    TouchActionNone = 0x1,
-    TouchActionPanLeft = 0x2,
-    TouchActionPanRight = 0x4,
+    TouchActionNone = 0x0,
+    TouchActionPanLeft = 0x1,
+    TouchActionPanRight = 0x2,
     TouchActionPanX = TouchActionPanLeft | TouchActionPanRight,
-    TouchActionPanUp = 0x8,
-    TouchActionPanDown = 0x10,
+    TouchActionPanUp = 0x4,
+    TouchActionPanDown = 0x8,
     TouchActionPanY = TouchActionPanUp | TouchActionPanDown,
-    TouchActionPinchZoom = 0x20,
+    TouchActionPan = TouchActionPanX | TouchActionPanY,
+    TouchActionPinchZoom = 0x10,
+    TouchActionManipulation = TouchActionPan | TouchActionPinchZoom,
+    TouchActionDoubleTapZoom = 0x20,
+    TouchActionAuto = TouchActionManipulation | TouchActionDoubleTapZoom
 };
-inline TouchAction operator| (TouchAction a, TouchAction b) { return TouchAction(int(a) | int(b)); }
+inline TouchAction operator| (TouchAction a, TouchAction b) { return static_cast<TouchAction>(int(a) | int(b)); }
 inline TouchAction& operator|= (TouchAction& a, TouchAction b) { return a = a | b; }
-inline TouchAction operator& (TouchAction a, TouchAction b) { return TouchAction(int(a) & int(b)); }
+inline TouchAction operator& (TouchAction a, TouchAction b) { return static_cast<TouchAction>(int(a) & int(b)); }
 inline TouchAction& operator&= (TouchAction& a, TouchAction b) { return a = a & b; }
 
 enum EIsolation { IsolationAuto, IsolationIsolate };
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index bd0e611..5dcfc465 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -4390,7 +4390,7 @@
 
     if (!canvas->is3D()) {
         ImageBuffer* buffer = canvas->buffer();
-        if (!buffer->copyToPlatformTexture(webContext(), targetTexture, targetInternalformat, targetType,
+        if (!buffer->copyToPlatformTexture(webContext(), GL_TEXTURE_2D, targetTexture, targetInternalformat, targetType,
             targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
             ASSERT_NOT_REACHED();
         }
@@ -4422,6 +4422,51 @@
     }
 }
 
+bool WebGLRenderingContextBase::texImage2DVideoByGPU(TexImageFunctionType functionType, WebGLTexture* texture, GLenum target,
+    GLint level, GLenum internalformat, GLenum type, GLint xoffset, GLint yoffset, HTMLVideoElement* video)
+{
+    typedef WebMediaPlayer::CopyVideoTextureParams CopyParams;
+    if (video->copyVideoTextureToPlatformTexture(webContext(),
+        CopyParams(
+            functionType == NotTexSubImage2D ? CopyParams::FullCopy : CopyParams::SubCopy,
+            target, texture->object(), internalformat, type, level, xoffset,
+            yoffset, m_unpackPremultiplyAlpha, m_unpackFlipY))) {
+        if (functionType == NotTexSubImage2D)
+            texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, type);
+        return true;
+    }
+
+    // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU.
+    OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBufferSurface(IntSize(video->videoWidth(), video->videoHeight())));
+    if (surface->isValid()) {
+        OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(surface.release()));
+        if (imageBuffer) {
+            // The video element paints an RGBA frame into our surface here. By using an AcceleratedImageBufferSurface,
+            // we enable the WebMediaPlayer implementation to do any necessary color space conversion on the GPU (though it
+            // may still do a CPU conversion and upload the results).
+            video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr);
+
+            // This is a straight GPU-GPU copy, any necessary color space conversion was handled in the paintCurrentFrameInContext() call.
+            switch (functionType) {
+            case NotTexSubImage2D:
+                if (imageBuffer->copyToPlatformTexture(webContext(), target, texture->object(), internalformat, type,
+                    level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+                    texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, type);
+                    return true;
+                }
+                break;
+            case TexSubImage2D:
+                if (imageBuffer->copySubToPlatformTexture(webContext(), target, texture->object(), level,
+                    xoffset, yoffset, video->videoWidth(), video->videoHeight(), m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+                    return true;
+                }
+                break;
+            }
+        }
+    }
+    return false;
+}
+
 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
     GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
 {
@@ -4468,31 +4513,9 @@
     // Otherwise, it will fall back to the normal SW path.
     WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
     ASSERT(texture);
-    if (GL_TEXTURE_2D == target) {
-        if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level)
-            && video->copyVideoTextureToPlatformTexture(webContext(), texture->object(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
-            texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, type);
+    if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level)) {
+        if (texImage2DVideoByGPU(NotTexSubImage2D, texture, target, level, internalformat, type, 0, 0, video))
             return;
-        }
-
-        // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU.
-        OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBufferSurface(IntSize(video->videoWidth(), video->videoHeight())));
-        if (surface->isValid()) {
-            OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(surface.release()));
-            if (imageBuffer) {
-                // The video element paints an RGBA frame into our surface here. By using an AcceleratedImageBufferSurface,
-                // we enable the WebMediaPlayer implementation to do any necessary color space conversion on the GPU (though it
-                // may still do a CPU conversion and upload the results).
-                video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr);
-
-                // This is a straight GPU-GPU copy, any necessary color space conversion was handled in the paintCurrentFrameInContext() call.
-                if (imageBuffer->copyToPlatformTexture(webContext(), texture->object(), internalformat, type,
-                    level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
-                    texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, type);
-                    return;
-                }
-            }
-        }
     }
 
     // Normal pure SW path.
@@ -4708,6 +4731,16 @@
         || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, 0, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
         return;
 
+    // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
+    // Otherwise, it will fall back to the normal SW path.
+    WebGLTexture* texture = validateTextureBinding("texSubImage2D", target, true);
+    ASSERT(texture);
+    if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, GL_RGBA, type, level)) {
+        if (texImage2DVideoByGPU(TexSubImage2D, texture, target, level, GL_FALSE,
+            GL_FALSE, xoffset, yoffset, video))
+            return;
+    }
+
     RefPtr<Image> image = videoFrameToImage(video);
     if (!image)
         return;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
index a5fb75a..55ae7629 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -840,6 +840,9 @@
         GLenum internalformat, GLenum type, GLint xoffset, GLint yoffset, GLint zoffset, HTMLCanvasElement*);
     bool canUseTexImageCanvasByGPU(GLenum internalformat, GLenum type);
 
+    bool texImage2DVideoByGPU(TexImageFunctionType, WebGLTexture*, GLenum target, GLint level,
+        GLenum internalformat, GLenum type, GLint xoffset, GLint yoffset, HTMLVideoElement*);
+
     void handleTextureCompleteness(const char*, bool);
     void createFallbackBlackTextures1x1();
 
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index d9b40c8..a6066c87 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -119,6 +119,7 @@
 ForceOverlayFullscreenVideo
 OverlayScrollbars
 PagePopup status=stable
+PassPaintVisualRectToCompositor
 PathOpsSVGClipping status=stable
 PerformanceObserver status=experimental
 Permissions status=stable
diff --git a/third_party/WebKit/Source/platform/exported/Platform.cpp b/third_party/WebKit/Source/platform/exported/Platform.cpp
index 2b2ccb84..eb31fb4 100644
--- a/third_party/WebKit/Source/platform/exported/Platform.cpp
+++ b/third_party/WebKit/Source/platform/exported/Platform.cpp
@@ -49,7 +49,7 @@
 
     // TODO(ssid): remove this check after fixing crbug.com/486782.
     if (s_platform && s_platform->m_mainThread)
-        s_platform->registerMemoryDumpProvider(PartitionAllocMemoryDumpProvider::instance());
+        s_platform->registerMemoryDumpProvider(PartitionAllocMemoryDumpProvider::instance(), "PartitionAlloc");
 }
 
 void Platform::shutdown()
diff --git a/third_party/WebKit/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp b/third_party/WebKit/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp
index 1b5b9348..39418e35 100644
--- a/third_party/WebKit/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp
+++ b/third_party/WebKit/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp
@@ -137,16 +137,14 @@
 
 ots::TableAction BlinkOTSContext::GetTableAction(uint32_t tag)
 {
-#define TABLE_TAG(c1, c2, c3, c4) ((uint32_t)((((uint8_t)(c1)) << 24) | (((uint8_t)(c2)) << 16) | (((uint8_t)(c3)) << 8) | ((uint8_t)(c4))))
-
-    const uint32_t cbdtTag = TABLE_TAG('C', 'B', 'D', 'T');
-    const uint32_t cblcTag = TABLE_TAG('C', 'B', 'L', 'C');
-    const uint32_t colrTag = TABLE_TAG('C', 'O', 'L', 'R');
-    const uint32_t cpalTag = TABLE_TAG('C', 'P', 'A', 'L');
+    const uint32_t cbdtTag = OTS_TAG('C', 'B', 'D', 'T');
+    const uint32_t cblcTag = OTS_TAG('C', 'B', 'L', 'C');
+    const uint32_t colrTag = OTS_TAG('C', 'O', 'L', 'R');
+    const uint32_t cpalTag = OTS_TAG('C', 'P', 'A', 'L');
 #if HB_VERSION_ATLEAST(1, 0, 0)
-    const uint32_t gdefTag = TABLE_TAG('G', 'D', 'E', 'F');
-    const uint32_t gposTag = TABLE_TAG('G', 'P', 'O', 'S');
-    const uint32_t gsubTag = TABLE_TAG('G', 'S', 'U', 'B');
+    const uint32_t gdefTag = OTS_TAG('G', 'D', 'E', 'F');
+    const uint32_t gposTag = OTS_TAG('G', 'P', 'O', 'S');
+    const uint32_t gsubTag = OTS_TAG('G', 'S', 'U', 'B');
 #endif
 
     switch (tag) {
@@ -166,7 +164,6 @@
     default:
         return ots::TABLE_ACTION_DEFAULT;
     }
-#undef TABLE_TAG
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
index 51465ee0..042495b 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
@@ -178,9 +178,25 @@
     return m_surface->layer();
 }
 
-bool ImageBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY)
+bool ImageBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, GLenum target, Platform3DObject texture,
+    GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY)
 {
-    if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(GL_TEXTURE_2D, internalFormat, destType, level))
+    return copyToPlatformTextureInternal(true, context, target, texture, internalFormat,
+        destType, level, 0, 0, 0, 0, premultiplyAlpha, flipY);
+}
+
+bool ImageBuffer::copySubToPlatformTexture(WebGraphicsContext3D* context, GLenum target, Platform3DObject texture,
+    GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, bool premultiplyAlpha, bool flipY)
+{
+    return copyToPlatformTextureInternal(false, context, target, texture, GL_FALSE, GL_FALSE, level,
+        xoffset, yoffset, width, height, premultiplyAlpha, flipY);
+}
+
+bool ImageBuffer::copyToPlatformTextureInternal(bool isFullCopy, WebGraphicsContext3D* context, GLenum target,
+    Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, GLint xoffset, GLint yoffset,
+    GLsizei width, GLsizei height, bool premultiplyAlpha, bool flipY)
+{
+    if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalFormat, destType, level))
         return false;
 
     if (!isSurfaceValid())
@@ -219,9 +235,16 @@
     context->waitSyncPoint(mailbox->syncPoint);
     Platform3DObject sourceTexture = context->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox->name);
 
+    WGC3Dboolean glFlipY = flipY ? GL_FALSE : GL_TRUE;
+    WGC3Dboolean glPremultiplyAlpha = premultiplyAlpha ? GL_FALSE : GL_TRUE;
+
     // The canvas is stored in a premultiplied format, so unpremultiply if necessary.
     // The canvas is stored in an inverted position, so the flip semantics are reversed.
-    context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture, texture, internalFormat, destType, flipY ? GL_FALSE : GL_TRUE, GL_FALSE, premultiplyAlpha ? GL_FALSE : GL_TRUE);
+    if (isFullCopy) {
+        context->copyTextureCHROMIUM(target, sourceTexture, texture, internalFormat, destType, glFlipY, GL_FALSE, glPremultiplyAlpha);
+    } else {
+        context->copySubTextureCHROMIUM(target, sourceTexture, texture, xoffset, yoffset, 0, 0, width, height, glFlipY, GL_FALSE, glPremultiplyAlpha);
+    }
 
     context->deleteTexture(sourceTexture);
 
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
index d41b5b9..651e8c9 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
@@ -122,7 +122,9 @@
     // with textures that are RGB or RGBA format, UNSIGNED_BYTE type and level 0, as specified in
     // Extensions3D::canUseCopyTextureCHROMIUM().
     // Destroys the TEXTURE_2D binding for the active texture unit of the passed context
-    bool copyToPlatformTexture(WebGraphicsContext3D*, Platform3DObject, GLenum, GLenum, GLint, bool, bool);
+    bool copyToPlatformTexture(WebGraphicsContext3D*, GLenum, Platform3DObject, GLenum, GLenum, GLint, bool, bool);
+    bool copySubToPlatformTexture(WebGraphicsContext3D*, GLenum, Platform3DObject, GLint, GLint xoffset,
+        GLint yoffset, GLsizei width, GLsizei height, bool, bool);
 
     bool copyRenderingResultsFromDrawingBuffer(DrawingBuffer*, SourceDrawingBuffer);
 
@@ -148,6 +150,10 @@
         DrawnToAfterSnapshot,
     };
     mutable SnapshotState m_snapshotState;
+
+    bool copyToPlatformTextureInternal(bool isFullCopy, WebGraphicsContext3D*, GLenum, Platform3DObject, GLenum, GLenum,
+        GLint, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, bool, bool);
+
     OwnPtr<ImageBufferSurface> m_surface;
     ImageBufferClient* m_client;
 };
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.cpp b/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.cpp
index 950b8fa5..e63df142 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.cpp
@@ -83,9 +83,24 @@
 
 bool Extensions3DUtil::canUseCopyTextureCHROMIUM(GLenum destTarget, GLenum destFormat, GLenum destType, GLint level)
 {
-    // FIXME: restriction of (RGB || RGBA)/UNSIGNED_BYTE/(Level 0) should be lifted when
+    switch (destTarget) {
+    case GL_TEXTURE_2D:
+        break;
+    // TODO(dshwang): support cube map. crbug.com/517548
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        return false;
+    default:
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+    // TODO(dshwang): restriction of (RGB || RGBA)/UNSIGNED_BYTE/(Level 0) should be lifted when
     // WebGraphicsContext3D::copyTextureCHROMIUM(...) are fully functional.
-    if (destTarget == GL_TEXTURE_2D && (destFormat == GL_RGB || destFormat == GL_RGBA)
+    if ((destFormat == GL_RGB || destFormat == GL_RGBA)
         && destType == GL_UNSIGNED_BYTE
         && !level)
         return true;
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp
index c59fffa..9c7c30d 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.cpp
+++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -169,7 +169,7 @@
     GCInfoTable::init();
 
     if (Platform::current() && Platform::current()->currentThread())
-        Platform::current()->registerMemoryDumpProvider(BlinkGCMemoryDumpProvider::instance());
+        Platform::current()->registerMemoryDumpProvider(BlinkGCMemoryDumpProvider::instance(), "BlinkGC");
 }
 
 void Heap::shutdown()
diff --git a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
index 2519571..988bc1b 100644
--- a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
+++ b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
@@ -672,14 +672,17 @@
 STATIC_ASSERT_MATCHING_ENUM(WebCustomHandlersDeclined, NavigatorContentUtilsClient::CustomHandlersDeclined);
 
 STATIC_ASSERT_MATCHING_ENUM(WebTouchActionNone, TouchActionNone);
-STATIC_ASSERT_MATCHING_ENUM(WebTouchActionAuto, TouchActionAuto);
 STATIC_ASSERT_MATCHING_ENUM(WebTouchActionPanLeft, TouchActionPanLeft);
 STATIC_ASSERT_MATCHING_ENUM(WebTouchActionPanRight, TouchActionPanRight);
 STATIC_ASSERT_MATCHING_ENUM(WebTouchActionPanX, TouchActionPanX);
 STATIC_ASSERT_MATCHING_ENUM(WebTouchActionPanUp, TouchActionPanUp);
 STATIC_ASSERT_MATCHING_ENUM(WebTouchActionPanDown, TouchActionPanDown);
 STATIC_ASSERT_MATCHING_ENUM(WebTouchActionPanY, TouchActionPanY);
+STATIC_ASSERT_MATCHING_ENUM(WebTouchActionPan, TouchActionPan);
 STATIC_ASSERT_MATCHING_ENUM(WebTouchActionPinchZoom, TouchActionPinchZoom);
+STATIC_ASSERT_MATCHING_ENUM(WebTouchActionManipulation, TouchActionManipulation);
+STATIC_ASSERT_MATCHING_ENUM(WebTouchActionDoubleTapZoom, TouchActionDoubleTapZoom);
+STATIC_ASSERT_MATCHING_ENUM(WebTouchActionAuto, TouchActionAuto);
 
 STATIC_ASSERT_MATCHING_ENUM(WebSelection::NoSelection, NoSelection);
 STATIC_ASSERT_MATCHING_ENUM(WebSelection::CaretSelection, CaretSelection);
diff --git a/third_party/WebKit/Source/web/WebKit.cpp b/third_party/WebKit/Source/web/WebKit.cpp
index 0a908070..b05429d 100644
--- a/third_party/WebKit/Source/web/WebKit.cpp
+++ b/third_party/WebKit/Source/web/WebKit.cpp
@@ -123,7 +123,7 @@
         currentThread->addTaskObserver(s_endOfTaskRunner);
 
         // Register web cache dump provider for tracing.
-        platform->registerMemoryDumpProvider(WebCacheMemoryDumpProvider::instance());
+        platform->registerMemoryDumpProvider(WebCacheMemoryDumpProvider::instance(), "MemoryCache");
     }
 }
 
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index dde99a8e..6e6f742 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -2845,7 +2845,7 @@
         // zoom in if the user won't be able to zoom out. e.g if the textbox is within a
         // touch-action: none container the user can't zoom back out.
         TouchAction action = TouchActionUtil::computeEffectiveTouchAction(*element);
-        if (action != TouchActionAuto && !(action & TouchActionPinchZoom))
+        if (!(action & TouchActionPinchZoom))
             zoomInToLegibleScale = false;
     }
 
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index e4f7730..cdc1a5b 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -574,9 +574,10 @@
 
     // Registers a memory dump provider. The WebMemoryDumpProvider::onMemoryDump
     // method will be called on the same thread that called the
-    // registerMemoryDumpProvider() method.
+    // registerMemoryDumpProvider() method. |name| is used for debugging
+    // (duplicates are allowed) and must be a long-lived C string.
     // See crbug.com/458295 for design docs.
-    virtual void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*) { }
+    virtual void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*, const char* name) { }
 
     // Must be called on the thread that called registerMemoryDumpProvider().
     virtual void unregisterMemoryDumpProvider(blink::WebMemoryDumpProvider*) { }
diff --git a/third_party/WebKit/public/platform/WebMediaPlayer.h b/third_party/WebKit/public/platform/WebMediaPlayer.h
index 9670be7..cf26022 100644
--- a/third_party/WebKit/public/platform/WebMediaPlayer.h
+++ b/third_party/WebKit/public/platform/WebMediaPlayer.h
@@ -164,17 +164,32 @@
 
     virtual void paint(WebCanvas*, const WebRect&, unsigned char alpha, SkXfermode::Mode) = 0;
 
-    // TODO(dshwang): remove non-|target| version. crbug.com/349871
-    virtual bool copyVideoTextureToPlatformTexture(WebGraphicsContext3D*, unsigned texture, unsigned internalFormat, unsigned type, bool premultiplyAlpha, bool flipY) { return false; }
-
     // Do a GPU-GPU textures copy. If the copy is impossible or fails, it returns false.
-    virtual bool copyVideoTextureToPlatformTexture(WebGraphicsContext3D*, unsigned target,
-        unsigned texture, unsigned internalFormat, unsigned type, int level,
-        bool premultiplyAlpha, bool flipY) { return false; }
-    // Copy sub video frame texture to |texture|. If the copy is impossible or fails, it returns false.
-    virtual bool copyVideoSubTextureToPlatformTexture(WebGraphicsContext3D*, unsigned target,
-        unsigned texture, int level, int xoffset, int yoffset, bool premultiplyAlpha,
-        bool flipY) { return false; }
+    // Copy the video frame texture to full texture or sub texture depending on |copyType|.
+    // If FullCopy, |xoffset| and |yoffset| must be 0.
+    // If SubCopy, |internalFormat| and |type| must be GL_FALSE.
+    struct CopyVideoTextureParams {
+        enum CopyType { FullCopy, SubCopy };
+        CopyVideoTextureParams(CopyType copyType, unsigned target,
+            unsigned texture, unsigned internalFormat, unsigned type, int level,
+            int xoffset, int yoffset, bool premultiplyAlpha, bool flipY)
+            : copyType(copyType), target(target), texture(texture)
+            , internalFormat(internalFormat) , type(type), level(level)
+            , xoffset(xoffset), yoffset(yoffset)
+            , premultiplyAlpha(premultiplyAlpha), flipY(flipY)
+        { }
+        CopyType copyType;
+        unsigned target;
+        unsigned texture;
+        unsigned internalFormat;
+        unsigned type;
+        int level;
+        int xoffset;
+        int yoffset;
+        bool premultiplyAlpha;
+        bool flipY;
+    };
+    virtual bool copyVideoTextureToPlatformTexture(WebGraphicsContext3D*, const CopyVideoTextureParams&) = 0;
 
     virtual WebAudioSourceProvider* audioSourceProvider() { return nullptr; }
 
diff --git a/third_party/WebKit/public/web/WebTouchAction.h b/third_party/WebKit/public/web/WebTouchAction.h
index e9c3bc1..d1ee9cb 100644
--- a/third_party/WebKit/public/web/WebTouchAction.h
+++ b/third_party/WebKit/public/web/WebTouchAction.h
@@ -35,19 +35,22 @@
 
 // Flags for permitted touch actions, specified in http://w3c.github.io/pointerevents/#the-touch-action-css-property.
 enum WebTouchAction {
-    WebTouchActionAuto = 0x0,
-    WebTouchActionNone = 0x1,
-    WebTouchActionPanLeft = 0x2,
-    WebTouchActionPanRight = 0x4,
+    WebTouchActionNone = 0x0,
+    WebTouchActionPanLeft = 0x1,
+    WebTouchActionPanRight = 0x2,
     WebTouchActionPanX = WebTouchActionPanLeft | WebTouchActionPanRight,
-    WebTouchActionPanUp = 0x8,
-    WebTouchActionPanDown = 0x10,
+    WebTouchActionPanUp = 0x4,
+    WebTouchActionPanDown = 0x8,
     WebTouchActionPanY = WebTouchActionPanUp | WebTouchActionPanDown,
-    WebTouchActionPinchZoom = 0x20,
+    WebTouchActionPan = WebTouchActionPanX | WebTouchActionPanY,
+    WebTouchActionPinchZoom = 0x10,
+    WebTouchActionManipulation = WebTouchActionPan | WebTouchActionPinchZoom,
+    WebTouchActionDoubleTapZoom = 0x20,
+    WebTouchActionAuto = WebTouchActionManipulation | WebTouchActionDoubleTapZoom
 };
-inline WebTouchAction operator| (WebTouchAction a, WebTouchAction b) { return WebTouchAction(int(a) | int(b)); }
+inline WebTouchAction operator| (WebTouchAction a, WebTouchAction b) { return static_cast<WebTouchAction>(int(a) | int(b)); }
 inline WebTouchAction& operator|= (WebTouchAction& a, WebTouchAction b) { return a = a | b; }
-inline WebTouchAction operator& (WebTouchAction a, WebTouchAction b) { return WebTouchAction(int(a) & int(b)); }
+inline WebTouchAction operator& (WebTouchAction a, WebTouchAction b) { return static_cast<WebTouchAction>(int(a) & int(b)); }
 inline WebTouchAction& operator&= (WebTouchAction& a, WebTouchAction b) { return a = a & b; }
 
 
diff --git a/third_party/android_platform/README.chromium b/third_party/android_platform/README.chromium
index c795127..d0064a4 100644
--- a/third_party/android_platform/README.chromium
+++ b/third_party/android_platform/README.chromium
@@ -36,6 +36,8 @@
 Added debug logging and --verbose parameter.
 Used fast ELF symbolizer for symbols.py and tombstones
 Used multiprocessing to pre-process logcat before symbolizing it
+Added code address adjustment for the debuggerd output from pre-M Android
+    where relocations are packed.
 
 Android relocation packing tool details:
     Copy sources from AOSP bionic/tools/relocation_packer
diff --git a/third_party/android_platform/development/scripts/stack b/third_party/android_platform/development/scripts/stack
index 6c60c17..6901ad5 100755
--- a/third_party/android_platform/development/scripts/stack
+++ b/third_party/android_platform/development/scripts/stack
@@ -23,11 +23,15 @@
 import sys
 
 import stack_core
+import stack_libs
 import subprocess
 import symbol
 import sys
 
 DEFAULT_SYMROOT='/tmp/symbols'
+DEFAULT_APK_DIR='chrome_apk'
+# From: https://source.android.com/source/build-numbers.html
+_ANDROID_M_MAJOR_VERSION=6
 
 def PrintUsage():
   """Print usage and exit with error."""
@@ -44,6 +48,20 @@
   print "       If not specified, will look for the newest lib in out/Debug or"
   print "       out/Release"
   print
+  print "  --packed-relocation-adjustments"
+  print "  --no-packed-relocation-adjustments"
+  print "       turn packed relocation adjustment on and off (default is off)"
+  print "       If running on pre-M Android and the stack trace appears to"
+  print "       make no sense, try turning this feature on."
+  print
+  print "  --chrome-apk-dir=path"
+  print "       the path to the APK staging dir (can be absolute or relative"
+  print "       to src), such as =out/Debug/chrome_apk"
+  print "       If not specified, uses =|chrome-symbols-dir|/../chrome_apk"
+  print "       Parses libraries here to find data for adjusting debuggerd"
+  print "       tombstones where relocations are packed."
+  print "       Enable/disable with --[no-]packed-relocation-adjustments."
+  print
   print "  --symbols-zip=path"
   print "       the path to a symbols zip file, such as =dream-symbols-12345.zip"
   print
@@ -115,9 +133,12 @@
 def main(argv):
   try:
     options, arguments = getopt.getopt(argv, "",
-                                       ["more-info",
+                                       ["packed-relocation-adjustments",
+                                        "no-packed-relocation-adjustments",
+                                        "more-info",
                                         "less-info",
                                         "chrome-symbols-dir=",
+                                        "chrome-apk-dir=",
                                         "symbols-dir=",
                                         "symbols-zip=",
                                         "arch=",
@@ -128,6 +149,8 @@
 
   zip_arg = None
   more_info = False
+  chrome_apk_dir = None
+  packed_relocation_adjustments = "unknown"
   for option, value in options:
     if option == "--help":
       PrintUsage()
@@ -139,6 +162,12 @@
       symbol.ARCH = value
     elif option == "--chrome-symbols-dir":
       symbol.CHROME_SYMBOLS_DIR = os.path.join(symbol.CHROME_SRC, value)
+    elif option == "--chrome-apk-dir":
+      chrome_apk_dir = os.path.join(symbol.CHROME_SRC, value)
+    elif option == "--packed-relocation-adjustments":
+      packed_relocation_adjustments = True
+    elif option == "--no-packed-relocation-adjustments":
+      packed_relocation_adjustments = False
     elif option == "--more-info":
       more_info = True
     elif option == "--less-info":
@@ -146,6 +175,10 @@
     elif option == "--verbose":
       logging.basicConfig(level=logging.DEBUG)
 
+  if symbol.CHROME_SYMBOLS_DIR and not chrome_apk_dir:
+    chrome_apk_dir = os.path.join(symbol.CHROME_SYMBOLS_DIR,
+                                  '..', DEFAULT_APK_DIR)
+
   if len(arguments) > 1:
     PrintUsage()
 
@@ -153,7 +186,7 @@
     print "Reading native crash info from stdin"
     f = sys.stdin
   else:
-    print "Searching for native crashes in %s" % arguments[0]
+    print "Searching for native crashes in: " + os.path.realpath(arguments[0])
     f = open(arguments[0], "r")
 
   lines = f.readlines()
@@ -163,10 +196,40 @@
   if zip_arg:
     rootdir, symbol.SYMBOLS_DIR = UnzipSymbols(zip_arg)
 
-  print "Reading Android symbols from", symbol.SYMBOLS_DIR
+  if packed_relocation_adjustments == "unknown":
+    if chrome_apk_dir:
+      version = stack_libs.GetTargetAndroidVersionNumber(lines)
+      if version == None:
+        packed_relocation_adjustments = False
+        print ("Unknown Android release, "
+               + "consider --[no-]packed-relocation-adjustments options")
+      elif version >= _ANDROID_M_MAJOR_VERSION:
+        packed_relocation_adjustments = False
+      else:
+        packed_relocation_adjustments = True
+        print ("Pre-M Android release detected, "
+               + "added --packed-relocation-adjustments option")
+    else:
+      packed_relocation_adjustments = False
+
+  if packed_relocation_adjustments and not chrome_apk_dir:
+    packed_relocation_adjustments = False
+    print ("No APK directory given or defaulted, "
+           + "--packed-relocation-adjustments option ignored")
+
+  if packed_relocation_adjustments:
+    print ("Reading Chrome APK library data from: "
+           + os.path.normpath(chrome_apk_dir))
+    load_vaddrs = stack_libs.GetLoadVaddrs(chrome_apk_dir)
+  else:
+    load_vaddrs = {}
+
+  print ("Reading Android symbols from: "
+         + os.path.normpath(symbol.SYMBOLS_DIR))
   chrome_search_path = symbol.GetLibrarySearchPaths()
-  print "Searching for Chrome symbols from within", ':'.join(chrome_search_path)
-  stack_core.ConvertTrace(lines, more_info)
+  print ("Searching for Chrome symbols from within: "
+         + ':'.join((os.path.normpath(d) for d in chrome_search_path)))
+  stack_core.ConvertTrace(lines, load_vaddrs, more_info)
 
   if rootdir:
     # be a good citizen and clean up...os.rmdir and os.removedirs() don't work
diff --git a/third_party/android_platform/development/scripts/stack_core.py b/third_party/android_platform/development/scripts/stack_core.py
index 34309787..9ef2e30 100755
--- a/third_party/android_platform/development/scripts/stack_core.py
+++ b/third_party/android_platform/development/scripts/stack_core.py
@@ -32,6 +32,9 @@
 _DEFAULT_JOBS=8
 _CHUNK_SIZE = 1000
 
+_BASE_APK = 'base.apk'
+_LIBCHROME_SO = 'libchrome.so'
+
 _PROCESS_INFO_LINE = re.compile('(pid: [0-9]+, tid: [0-9]+.*)')
 _SIGNAL_LINE = re.compile('(signal [0-9]+ \(.*\).*)')
 _REGISTER_LINE = re.compile('(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})')
@@ -94,7 +97,8 @@
   print '  RELADDR   ' + 'FUNCTION'.ljust(maxlen) + '  FILE:LINE'
   for tl in trace_lines:
     (addr, symbol_with_offset, location) = tl
-    print '  %8s  %s  %s' % (addr, symbol_with_offset.ljust(maxlen), location)
+    normalized = os.path.normpath(location)
+    print '  %8s  %s  %s' % (addr, symbol_with_offset.ljust(maxlen), normalized)
   return
 
 
@@ -126,13 +130,13 @@
   print
   print '-----------------------------------------------------\n'
 
-def ConvertTrace(lines, more_info):
+def ConvertTrace(lines, load_vaddrs, more_info):
   """Convert strings containing native crash to a stack."""
   start = time.time()
 
   chunks = [lines[i: i+_CHUNK_SIZE] for i in xrange(0, len(lines), _CHUNK_SIZE)]
   pool = multiprocessing.Pool(processes=_DEFAULT_JOBS)
-  useful_log = itertools.chain(*pool.map(PreProcessLog, chunks))
+  useful_log = itertools.chain(*pool.map(PreProcessLog(load_vaddrs), chunks))
   pool.close()
   pool.join()
   end = time.time()
@@ -143,37 +147,76 @@
   logging.debug('Finished resolving symbols. Elapsed time: %.4fs',
                 (end - start))
 
+class PreProcessLog:
+  """Closure wrapper, for multiprocessing.Pool.map."""
+  def __init__(self, load_vaddrs):
+    """Bind load_vaddrs to the PreProcessLog closure.
+    Args:
+      load_vaddrs: LOAD segment min_vaddrs keyed on mapped executable
+    """
+    self._load_vaddrs = load_vaddrs;
 
-def PreProcessLog(lines):
-  """Preprocess the strings, only keep the useful ones.
-  Args:
-    lines: a list of byte strings read from logcat
+  def _AdjustAddress(self, address, lib):
+    """Add the vaddr of the library's first LOAD segment to address.
+    Args:
+      address: symbol address as a hexadecimal string
+      lib: path to loaded library
 
-  Returns:
-    A list of unicode strings related to native crash
-  """
-  useful_log = []
-  for ln in lines:
-    line = unicode(ln, errors='ignore')
-    if (_PROCESS_INFO_LINE.search(line)
-        or _SIGNAL_LINE.search(line)
-        or _REGISTER_LINE.search(line)
-        or _THREAD_LINE.search(line)
-        or _DALVIK_JNI_THREAD_LINE.search(line)
-        or _DALVIK_NATIVE_THREAD_LINE.search(line)
-        or _LOG_FATAL_LINE.search(line)
-        or _TRACE_LINE.match(line)
-        or _DEBUG_TRACE_LINE.match(line)):
-      useful_log.append(line)
-      continue
+    Returns:
+      address+load_vaddrs[key] if lib ends with /key, otherwise address
+    """
+    for key, offset in self._load_vaddrs.iteritems():
+      if lib.endswith('/' + key):
+        # Add offset to address, and return the result as a hexadecimal string
+        # with the same number of digits as the original. This allows the
+        # caller to make a direct textual substitution.
+        return ('%%0%dx' % len(address)) % (int(address, 16) + offset)
+    return address
 
-    if code_line.match(line):
-      # Code lines should be ignored. If this were excluded the 'code around'
-      # sections would trigger value_line matches.
-      continue
-    if _VALUE_LINE.match(line):
-      useful_log.append(line)
-  return useful_log
+  def __call__(self, lines):
+    """Preprocess the strings, only keep the useful ones.
+    Args:
+      lines: a list of byte strings read from logcat
+
+    Returns:
+      A list of unicode strings related to native crash
+    """
+    useful_log = []
+    for ln in lines:
+      line = unicode(ln, errors='ignore')
+      if (_PROCESS_INFO_LINE.search(line)
+          or _SIGNAL_LINE.search(line)
+          or _REGISTER_LINE.search(line)
+          or _THREAD_LINE.search(line)
+          or _DALVIK_JNI_THREAD_LINE.search(line)
+          or _DALVIK_NATIVE_THREAD_LINE.search(line)
+          or _LOG_FATAL_LINE.search(line)
+          or _DEBUG_TRACE_LINE.match(line)):
+        useful_log.append(line)
+        continue
+
+      match = _TRACE_LINE.match(line)
+      if match:
+        # If the trace line suggests a direct load from APK, replace the
+        # APK name with libchrome.so. Current load from APK supports only
+        # single library load, so it must be libchrome.so that was loaded
+        # in this way.
+        line = line.replace('/' + _BASE_APK, '/' + _LIBCHROME_SO)
+        # For trace lines specifically, the address may need to be adjusted
+        # to account for relocation packing. This is because debuggerd on
+        # pre-M platforms does not understand non-zero vaddr LOAD segments.
+        address, lib = match.group('address', 'lib')
+        adjusted_address = self._AdjustAddress(address, lib)
+        useful_log.append(line.replace(address, adjusted_address, 1))
+        continue
+
+      if code_line.match(line):
+        # Code lines should be ignored. If this were excluded the 'code around'
+        # sections would trigger value_line matches.
+        continue
+      if _VALUE_LINE.match(line):
+        useful_log.append(line)
+    return useful_log
 
 def ResolveCrashSymbol(lines, more_info):
   """Convert unicode strings which contains native crash to a stack
@@ -304,5 +347,3 @@
                             source_location))
 
   PrintOutput(trace_lines, value_lines, more_info)
-
-
diff --git a/third_party/android_platform/development/scripts/stack_libs.py b/third_party/android_platform/development/scripts/stack_libs.py
new file mode 100755
index 0000000..ee5a67e
--- /dev/null
+++ b/third_party/android_platform/development/scripts/stack_libs.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2015 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.
+
+
+"""Identifies address adjustments required for native crash dumps."""
+
+import glob
+import os.path
+import subprocess
+
+
+_BASE_APK = 'base.apk'
+_LIBCHROME_SO = 'libchrome.so'
+
+
+def GetTargetAndroidVersionNumber(lines):
+  """Return the Android major version number from the build fingerprint.
+
+  Args:
+    lines: Lines read from the tombstone file, before preprocessing.
+  Returns:
+    5, 6, etc, or None if not determinable (developer build?)
+  """
+  # For example, "Build fingerprint: 'Android/aosp_flo/flo:5.1.1/...'" is 5.
+  for line in lines:
+    if line.startswith('Build fingerprint: '):
+      fingerprint = line.split()[2]
+      version = fingerprint.split('/')[2].split(':')[1].split('.')[0]
+      try:
+        return int(version)
+      except ValueError:
+        return None
+  return None
+
+
+def _HasElfHeader(path):
+  """Return True if the file at the given path has an ELF magic header.
+
+  Minimal check only, for 'ELF' in bytes 1 to 3 of the file. Filters out
+  the zero-byte false-positives such as libchromeview.so returned by glob.
+
+  Args:
+    path: Path to file to check.
+  Returns:
+    True or False
+  """
+  with open(path) as stream:
+    elf_header = stream.read(4)
+    return len(elf_header) == 4 and elf_header[1:4] == 'ELF'
+
+
+def _ReadElfProgramHeaders(lib):
+  """Return an iterable of program headers, from 'readelf -l ...'.
+
+  Uses the platform readelf in all cases. This is somewhat lazy, but suffices
+  in practice because program headers in ELF files are architecture-agnostic.
+
+  Args:
+    lib: Library file to read.
+  Returns:
+    [readelf -l output line, ...]
+  """
+  string = subprocess.check_output(['readelf', '-l', lib])
+  return string.split('\n')
+
+
+def _FindMinLoadVaddr(lib):
+  """Return the minimum VirtAddr field of all library LOAD segments.
+
+  Args:
+    lib: Library file to read.
+  Returns:
+    Min VirtAddr field for all LOAD segments, or 0 if none found.
+  """
+  vaddrs = []
+  # Locate LOAD lines and find the smallest VirtAddr field, eg:
+  #   Type       Offset    VirtAddr   PhysAddr   FileSiz   MemSiz    Flg Align
+  #   LOAD       0x000000  0x001d6000 0x001d6000 0x20f63fc 0x20f63fc R E 0x1000
+  #   LOAD       0x20f6970 0x022cd970 0x022cd970 0x182df8  0x1b4490  RW  0x1000
+  # would return 0x1d6000. Ignores all non-LOAD lines.
+  for line in _ReadElfProgramHeaders(lib):
+    elements = line.split()
+    if elements and elements[0] == 'LOAD':
+      vaddrs.append(int(elements[2], 16))
+  if vaddrs:
+    return min(vaddrs)
+  return 0
+
+
+def GetLoadVaddrs(apk_dir):
+  """Return a dictionary of minimum VirtAddr fields for libraries in apk_dir.
+
+  The dictionary returned may be passed to stack_core.ConvertTrace(). In
+  pre-M Android releases the addresses printed by debuggerd into tombstones
+  do not take account of non-zero vaddrs. Here we collect this information,
+  so that we can use it later to correct such debuggerd tombstones.
+
+  Args:
+    apk_dir: Path to APK staging directory.
+  Returns:
+    {'libchrome.so': 12345, ...}
+  """
+  pathname = apk_dir + '/libs/*/*.so'
+  libs = [lib for lib in glob.glob(pathname) if _HasElfHeader(lib)]
+
+  load_vaddrs = {}
+  for lib in libs:
+    min_vaddr = _FindMinLoadVaddr(lib)
+    if min_vaddr:
+      # Store with the library basename as the key. This is because once on
+      # the device its path may not fully match its place in the APK staging
+      # directory
+      load_vaddrs[os.path.basename(lib)] = min_vaddr
+
+  # Direct load from APK causes debuggerd to tag trace lines as if from the
+  # file .../base.apk. So if we encounter a libchrome.so with packed
+  # relocations, replicate this as base.apk so that later adjustment code
+  # finds the appropriate adjustment.
+  if _LIBCHROME_SO in load_vaddrs:
+    load_vaddrs[_BASE_APK] = load_vaddrs[_LIBCHROME_SO]
+
+  return load_vaddrs
diff --git a/third_party/android_platform/development/scripts/symbol.py b/third_party/android_platform/development/scripts/symbol.py
index ead0e1ab..82fb1d7 100755
--- a/third_party/android_platform/development/scripts/symbol.py
+++ b/third_party/android_platform/development/scripts/symbol.py
@@ -148,7 +148,8 @@
     toolchain_info = (label, platform, target);
     if os.path.exists(ToolPath("addr2line", toolchain_info)):
       TOOLCHAIN_INFO = toolchain_info
-      print "Using toolchain from :" + ToolPath("", TOOLCHAIN_INFO)
+      print ("Using toolchain from: "
+             + os.path.normpath(ToolPath("", TOOLCHAIN_INFO)))
       return toolchain_info
 
   raise Exception("Could not find tool chain")
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index a9bcacab..5690d24 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -17416,6 +17416,14 @@
   </summary>
 </histogram>
 
+<histogram name="Media.Audio.InputStartupSuccessMac" enum="BooleanSuccess">
+  <owner>henrika@chromium.org</owner>
+  <summary>
+    Indicates if audio capturing did start after stream startup was requested.
+    Sampled once 5 seconds after a stream has been asked to start.
+  </summary>
+</histogram>
+
 <histogram name="Media.Audio.Render.FramesRequested" units="frames">
   <owner>tommi@chromium.org</owner>
   <summary>
@@ -57201,7 +57209,7 @@
   <int value="13" label="Enable Google Cloud Print proxy"/>
   <int value="14" label="Enable Safe Browsing"/>
   <int value="15" label="Enable reporting of usage and crash-related data"/>
-  <int value="16" label="Enable the password manager"/>
+  <int value="16" label="Enable saving passwords to the password manager"/>
   <int value="17" label="Allow users to show passwords in Password Manager"/>
   <int value="18" label="Enable AutoFill"/>
   <int value="19" label="Specify a list of disabled plugins"/>
@@ -57220,7 +57228,8 @@
   <int value="31" label="GSSAPI library name"/>
   <int value="32" label="Configure extension installation blacklist"/>
   <int value="33" label="Configure extension installation whitelist"/>
-  <int value="34" label="Configure the list of force-installed extensions"/>
+  <int value="34"
+      label="Configure the list of force-installed apps and extensions"/>
   <int value="35" label="Show Home button on toolbar"/>
   <int value="36" label="Disable Developer Tools"/>
   <int value="37" label="Action on startup"/>
@@ -57317,7 +57326,7 @@
       label="Enable reporting memory info (JS heap size) to page (deprecated)"/>
   <int value="116" label="Proxy settings"/>
   <int value="117" label="Disable Print Preview (deprecated)"/>
-  <int value="118" label="Disable SSL record splitting"/>
+  <int value="118" label="Disable TLS False Start"/>
   <int value="119" label="Report OS and firmware version"/>
   <int value="120" label="Report device activity times"/>
   <int value="121" label="Report device boot mode"/>
@@ -57543,7 +57552,7 @@
       label="Import autofill form data from default browser on first run"/>
   <int value="278" label="Extension management settings"/>
   <int value="279" label="Minimum SSL version enabled"/>
-  <int value="280" label="Minimum SSL version to fallback to"/>
+  <int value="280" label="Minimum TLS version to fallback to"/>
   <int value="281" label="Enable Touch to Search"/>
   <int value="282" label="Force Google SafeSearch"/>
   <int value="283" label="Force YouTube Safety Mode"/>
@@ -57575,13 +57584,17 @@
   <int value="300" label="Allow proceeding from the SSL warning page"/>
   <int value="301" label="Allows QUIC protocol"/>
   <int value="302" label="Key Permissions"/>
-  <int value="303" label="Welcome page on OS upgrade enabled"/>
+  <int value="303"
+      label="Enable showing the welcome page on the first browser launch
+             following OS upgrade."/>
   <int value="304" label="Use hardware acceleration when available"/>
-  <int value="305" label="Android Negotiate authenticator account type"/>
+  <int value="305" label="Account type for HTTP Negotiate authentication"/>
   <int value="306" label="Send system logs to the management server"/>
-  <int value="307" label="Enable Unified Desktop by Default"/>
-  <int value="308" label="Print Preview default printer selection policy"/>
-  <int value="309" label="Allow dinosaur easter egg game"/>
+  <int value="307"
+      label="Make Unified Desktop available and turn on by default."/>
+  <int value="308" label="Default printer selection rules"/>
+  <int value="309" label="Allow Dinosaur Easter Egg Game"/>
+  <int value="310" label="Whether RC4 cipher suites in TLS are enabled"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations" type="int">
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py
index 2a639284..ab1dacb 100644
--- a/tools/perf/benchmarks/smoothness.py
+++ b/tools/perf/benchmarks/smoothness.py
@@ -356,6 +356,7 @@
     return 'smoothness.gpu_rasterization.polymer'
 
 
+@benchmark.Disabled('reference')  # crbug.com/549429
 class SmoothnessToughScrollingCases(_Smoothness):
   page_set = page_sets.ToughScrollingCasesPageSet
 
diff --git a/ui/file_manager/externs/files_elements.js b/ui/file_manager/externs/files_elements.js
index 06a2653..757efacd 100644
--- a/ui/file_manager/externs/files_elements.js
+++ b/ui/file_manager/externs/files_elements.js
@@ -82,6 +82,9 @@
 /** @type {Object} */
 AudioPlayerElement.prototype.model;
 
+/** @type {boolean} */
+AudioPlayerElement.prototype.volumeSliderShown;
+
 AudioPlayerElement.prototype.onPageUnload = function() {};
 
 AudioPlayerElement.prototype.onAudioError = function() {};
diff --git a/ui/gfx/buffer_types.h b/ui/gfx/buffer_types.h
index 2c87905..04e9eaa 100644
--- a/ui/gfx/buffer_types.h
+++ b/ui/gfx/buffer_types.h
@@ -32,10 +32,12 @@
 // *_CPU_READ_WRITE_* can be mapped into the client's address space and accessed
 // by the CPU. *_CPU_READ_WRITE_PERSISTENT adds the additional condition that
 // successive Map() calls (with Unmap() calls between) will return a pointer to
-// the same memory contents.
+// the same memory contents. SCANOUT implies GPU_READ_WRITE.
+// TODO(reveman): Add GPU_READ_WRITE for use-cases where SCANOUT is not
+// required.
 enum class BufferUsage {
   GPU_READ,
-  GPU_READ_WRITE,
+  SCANOUT,
   GPU_READ_CPU_READ_WRITE,
   // TODO(reveman): Merge this with GPU_READ_CPU_READ_WRITE when SurfaceTexture
   // backed buffers are single buffered and support it.
diff --git a/ui/gl/gl_surface_ozone.cc b/ui/gl/gl_surface_ozone.cc
index eead3b2..c4b7642fa 100644
--- a/ui/gl/gl_surface_ozone.cc
+++ b/ui/gl/gl_surface_ozone.cc
@@ -570,7 +570,7 @@
             ->GetSurfaceFactoryOzone()
             ->CreateNativePixmap(widget_, GetSize(),
                                  gfx::BufferFormat::BGRA_8888,
-                                 gfx::BufferUsage::GPU_READ_WRITE);
+                                 gfx::BufferUsage::SCANOUT);
     if (!pixmap)
       return false;
     scoped_refptr<GLImageOzoneNativePixmap> image =
diff --git a/ui/ozone/demo/surfaceless_gl_renderer.cc b/ui/ozone/demo/surfaceless_gl_renderer.cc
index 4b3d555..60575d6 100644
--- a/ui/ozone/demo/surfaceless_gl_renderer.cc
+++ b/ui/ozone/demo/surfaceless_gl_renderer.cc
@@ -40,7 +40,7 @@
       OzonePlatform::GetInstance()
           ->GetSurfaceFactoryOzone()
           ->CreateNativePixmap(widget, size, gfx::BufferFormat::BGRX_8888,
-                               gfx::BufferUsage::GPU_READ_WRITE);
+                               gfx::BufferUsage::SCANOUT);
   scoped_refptr<gfx::GLImageOzoneNativePixmap> image(
       new gfx::GLImageOzoneNativePixmap(size, GL_RGB));
   if (!image->Initialize(pixmap.get(), gfx::BufferFormat::BGRX_8888)) {
diff --git a/ui/ozone/platform/drm/client_native_pixmap_factory_gbm.cc b/ui/ozone/platform/drm/client_native_pixmap_factory_gbm.cc
index d8c701c..7226665 100644
--- a/ui/ozone/platform/drm/client_native_pixmap_factory_gbm.cc
+++ b/ui/ozone/platform/drm/client_native_pixmap_factory_gbm.cc
@@ -48,7 +48,7 @@
                                 gfx::BufferUsage usage) const override {
     switch (usage) {
       case gfx::BufferUsage::GPU_READ:
-      case gfx::BufferUsage::GPU_READ_WRITE:
+      case gfx::BufferUsage::SCANOUT:
         return format == gfx::BufferFormat::RGBA_8888 ||
                format == gfx::BufferFormat::BGRA_8888 ||
                format == gfx::BufferFormat::BGRX_8888;
@@ -83,7 +83,7 @@
         NOTREACHED();
         return nullptr;
       case gfx::BufferUsage::GPU_READ:
-      case gfx::BufferUsage::GPU_READ_WRITE:
+      case gfx::BufferUsage::SCANOUT:
         return make_scoped_ptr<ClientNativePixmapGbm>(
             new ClientNativePixmapGbm);
     }
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc
index 19ecdfb..901dedb0 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread.cc
+++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -34,7 +34,7 @@
                                       const gfx::Size& size) override {
     scoped_refptr<GbmDevice> gbm(static_cast<GbmDevice*>(drm.get()));
     return GbmBuffer::CreateBuffer(gbm, format, size,
-                                   gfx::BufferUsage::GPU_READ_WRITE);
+                                   gfx::BufferUsage::SCANOUT);
   }
 
  protected:
diff --git a/ui/ozone/platform/drm/gpu/gbm_buffer.cc b/ui/ozone/platform/drm/gpu/gbm_buffer.cc
index b94164d..8c3c396 100644
--- a/ui/ozone/platform/drm/gpu/gbm_buffer.cc
+++ b/ui/ozone/platform/drm/gpu/gbm_buffer.cc
@@ -25,10 +25,7 @@
 GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm,
                      gbm_bo* bo,
                      gfx::BufferUsage usage)
-    : GbmBufferBase(gbm,
-                    bo,
-                    usage == gfx::BufferUsage::GPU_READ ||
-                        usage == gfx::BufferUsage::GPU_READ_WRITE),
+    : GbmBufferBase(gbm, bo, usage == gfx::BufferUsage::SCANOUT),
       usage_(usage) {}
 
 GbmBuffer::~GbmBuffer() {
@@ -44,12 +41,10 @@
     gfx::BufferUsage usage) {
   TRACE_EVENT2("drm", "GbmBuffer::CreateBuffer", "device",
                gbm->device_path().value(), "size", size.ToString());
-  bool with_cpu_access =
-      usage == gfx::BufferUsage::GPU_READ_CPU_READ_WRITE ||
-      usage == gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT;
+  bool use_scanout = (usage == gfx::BufferUsage::SCANOUT);
   unsigned flags = 0;
   // GBM_BO_USE_SCANOUT is the hint of x-tiling.
-  if (!with_cpu_access)
+  if (use_scanout)
     flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
   gbm_bo* bo = gbm_bo_create(gbm->device(), size.width(), size.height(),
                              GetFourCCFormatFromBufferFormat(format), flags);
@@ -57,7 +52,7 @@
     return nullptr;
 
   scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, usage));
-  if (!with_cpu_access && !buffer->GetFramebufferId())
+  if (use_scanout && !buffer->GetFramebufferId())
     return nullptr;
 
   return buffer;
@@ -145,8 +140,7 @@
     return false;
   }
 
-  DCHECK(buffer_->GetUsage() == gfx::BufferUsage::GPU_READ ||
-         buffer_->GetUsage() == gfx::BufferUsage::GPU_READ_WRITE);
+  DCHECK(buffer_->GetUsage() == gfx::BufferUsage::SCANOUT);
   surface_manager_->GetSurface(widget)->QueueOverlayPlane(OverlayPlane(
       buffer_, plane_z_order, plane_transform, display_bounds, crop_rect));
   return true;
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
index f140f82f..42be306c4 100644
--- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
+++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -110,8 +110,7 @@
 #if !defined(OS_CHROMEOS)
   // Support for memory mapping accelerated buffers requires some
   // CrOS-specific patches (using vgem).
-  DCHECK(gfx::BufferUsage::GPU_READ == usage ||
-         gfx::BufferUsage::GPU_READ_WRITE == usage);
+  DCHECK(gfx::BufferUsage::SCANOUT == usage);
 #endif
 
   scoped_refptr<GbmBuffer> buffer =