Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / browser_window_state.cc
blobc59e7fd899572739308add9f59368998f387a74e
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/browser_window_state.h"
7 #include "base/command_line.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/prefs/scoped_user_pref_update.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "chrome/browser/defaults.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sessions/session_service.h"
14 #include "chrome/browser/sessions/session_service_factory.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/window_sizer/window_sizer.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h"
20 namespace chrome {
21 namespace {
23 // Parse two comma-separated integers from str. Return true on success.
24 bool ParseCommaSeparatedIntegers(const std::string& str,
25 int* ret_num1,
26 int* ret_num2) {
27 size_t num1_size = str.find_first_of(',');
28 if (num1_size == std::string::npos)
29 return false;
31 size_t num2_pos = num1_size + 1;
32 size_t num2_size = str.size() - num2_pos;
33 int num1 = 0;
34 int num2 = 0;
35 if (!base::StringToInt(str.substr(0, num1_size), &num1) ||
36 !base::StringToInt(str.substr(num2_pos, num2_size), &num2))
37 return false;
39 *ret_num1 = num1;
40 *ret_num2 = num2;
41 return true;
44 class WindowPlacementPrefUpdate : public DictionaryPrefUpdate {
45 public:
46 WindowPlacementPrefUpdate(PrefService* service,
47 const std::string& window_name)
48 : DictionaryPrefUpdate(service, prefs::kAppWindowPlacement),
49 window_name_(window_name) {}
51 ~WindowPlacementPrefUpdate() override {}
53 base::DictionaryValue* Get() override {
54 base::DictionaryValue* all_apps_dict = DictionaryPrefUpdate::Get();
55 base::DictionaryValue* this_app_dict = NULL;
56 if (!all_apps_dict->GetDictionary(window_name_, &this_app_dict)) {
57 this_app_dict = new base::DictionaryValue;
58 all_apps_dict->Set(window_name_, this_app_dict);
60 return this_app_dict;
63 private:
64 const std::string window_name_;
66 DISALLOW_COPY_AND_ASSIGN(WindowPlacementPrefUpdate);
69 } // namespace
71 std::string GetWindowName(const Browser* browser) {
72 if (browser->app_name().empty()) {
73 return browser->is_type_popup() ?
74 prefs::kBrowserWindowPlacementPopup : prefs::kBrowserWindowPlacement;
76 return browser->app_name();
79 scoped_ptr<DictionaryPrefUpdate> GetWindowPlacementDictionaryReadWrite(
80 const std::string& window_name,
81 PrefService* prefs) {
82 DCHECK(!window_name.empty());
83 // A normal DictionaryPrefUpdate will suffice for non-app windows.
84 if (prefs->FindPreference(window_name.c_str())) {
85 return make_scoped_ptr(
86 new DictionaryPrefUpdate(prefs, window_name.c_str()));
88 return scoped_ptr<DictionaryPrefUpdate>(
89 new WindowPlacementPrefUpdate(prefs, window_name));
92 const base::DictionaryValue* GetWindowPlacementDictionaryReadOnly(
93 const std::string& window_name,
94 PrefService* prefs) {
95 DCHECK(!window_name.empty());
96 if (prefs->FindPreference(window_name.c_str()))
97 return prefs->GetDictionary(window_name.c_str());
99 const base::DictionaryValue* app_windows =
100 prefs->GetDictionary(prefs::kAppWindowPlacement);
101 if (!app_windows)
102 return NULL;
103 const base::DictionaryValue* to_return = NULL;
104 app_windows->GetDictionary(window_name, &to_return);
105 return to_return;
108 bool ShouldSaveWindowPlacement(const Browser* browser) {
109 // Only save the window placement of popups if the window is from a trusted
110 // source (v1 app, devtools, or system window).
111 return (browser->type() == Browser::TYPE_TABBED) ||
112 ((browser->type() == Browser::TYPE_POPUP) && browser->is_trusted_source());
115 void SaveWindowPlacement(const Browser* browser,
116 const gfx::Rect& bounds,
117 ui::WindowShowState show_state) {
118 // Save to the session storage service, used when reloading a past session.
119 // Note that we don't want to be the ones who cause lazy initialization of
120 // the session service. This function gets called during initial window
121 // showing, and we don't want to bring in the session service this early.
122 SessionService* session_service =
123 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
124 if (session_service)
125 session_service->SetWindowBounds(browser->session_id(), bounds, show_state);
128 void GetSavedWindowBoundsAndShowState(const Browser* browser,
129 gfx::Rect* bounds,
130 ui::WindowShowState* show_state) {
131 DCHECK(browser);
132 DCHECK(bounds);
133 DCHECK(show_state);
134 *bounds = browser->override_bounds();
135 WindowSizer::GetBrowserWindowBoundsAndShowState(browser->app_name(),
136 *bounds,
137 browser,
138 bounds,
139 show_state);
141 const base::CommandLine& parsed_command_line =
142 *base::CommandLine::ForCurrentProcess();
144 if (parsed_command_line.HasSwitch(switches::kWindowSize)) {
145 std::string str =
146 parsed_command_line.GetSwitchValueASCII(switches::kWindowSize);
147 int width, height;
148 if (ParseCommaSeparatedIntegers(str, &width, &height))
149 bounds->set_size(gfx::Size(width, height));
151 if (parsed_command_line.HasSwitch(switches::kWindowPosition)) {
152 std::string str =
153 parsed_command_line.GetSwitchValueASCII(switches::kWindowPosition);
154 int x, y;
155 if (ParseCommaSeparatedIntegers(str, &x, &y))
156 bounds->set_origin(gfx::Point(x, y));
160 } // namespace chrome