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"
23 // Parse two comma-separated integers from str. Return true on success.
24 bool ParseCommaSeparatedIntegers(const std::string
& str
,
27 size_t num1_size
= str
.find_first_of(',');
28 if (num1_size
== std::string::npos
)
31 size_t num2_pos
= num1_size
+ 1;
32 size_t num2_size
= str
.size() - num2_pos
;
35 if (!base::StringToInt(str
.substr(0, num1_size
), &num1
) ||
36 !base::StringToInt(str
.substr(num2_pos
, num2_size
), &num2
))
44 class WindowPlacementPrefUpdate
: public DictionaryPrefUpdate
{
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
);
64 const std::string window_name_
;
66 DISALLOW_COPY_AND_ASSIGN(WindowPlacementPrefUpdate
);
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
,
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
,
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
);
103 const base::DictionaryValue
* to_return
= NULL
;
104 app_windows
->GetDictionary(window_name
, &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());
125 session_service
->SetWindowBounds(browser
->session_id(), bounds
, show_state
);
128 void GetSavedWindowBoundsAndShowState(const Browser
* browser
,
130 ui::WindowShowState
* show_state
) {
134 *bounds
= browser
->override_bounds();
135 WindowSizer::GetBrowserWindowBoundsAndShowState(browser
->app_name(),
141 const base::CommandLine
& parsed_command_line
=
142 *base::CommandLine::ForCurrentProcess();
144 if (parsed_command_line
.HasSwitch(switches::kWindowSize
)) {
146 parsed_command_line
.GetSwitchValueASCII(switches::kWindowSize
);
148 if (ParseCommaSeparatedIntegers(str
, &width
, &height
))
149 bounds
->set_size(gfx::Size(width
, height
));
151 if (parsed_command_line
.HasSwitch(switches::kWindowPosition
)) {
153 parsed_command_line
.GetSwitchValueASCII(switches::kWindowPosition
);
155 if (ParseCommaSeparatedIntegers(str
, &x
, &y
))
156 bounds
->set_origin(gfx::Point(x
, y
));
160 } // namespace chrome