Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / browser_window_state.cc
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.
4
5 #include "chrome/browser/ui/browser_window_state.h"
6
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"
19
20 namespace chrome {
21 namespace {
22
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;
30
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;
38
39   *ret_num1 = num1;
40   *ret_num2 = num2;
41   return true;
42 }
43
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) {}
50
51   virtual ~WindowPlacementPrefUpdate() {}
52
53   virtual 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);
59     }
60     return this_app_dict;
61   }
62
63  private:
64   const std::string window_name_;
65
66   DISALLOW_COPY_AND_ASSIGN(WindowPlacementPrefUpdate);
67 };
68
69 }  // namespace
70
71 std::string GetWindowName(const Browser* browser) {
72   if (browser->app_name().empty()) {
73     return browser->is_type_popup() ?
74         prefs::kBrowserWindowPlacementPopup : prefs::kBrowserWindowPlacement;
75   }
76   return browser->app_name();
77 }
78
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()));
87   }
88   return scoped_ptr<DictionaryPrefUpdate>(
89       new WindowPlacementPrefUpdate(prefs, window_name));
90 }
91
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());
98
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;
106 }
107
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());
113 }
114
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);
126 }
127
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);
140
141   const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
142   bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
143   bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
144   if (record_mode || playback_mode) {
145     // In playback/record mode we always fix the size of the browser and
146     // move it to (0,0).  The reason for this is two reasons:  First we want
147     // resize/moves in the playback to still work, and Second we want
148     // playbacks to work (as much as possible) on machines w/ different
149     // screen sizes.
150     *bounds = gfx::Rect(0, 0, 800, 600);
151   }
152
153   // The following options override playback/record.
154   if (parsed_command_line.HasSwitch(switches::kWindowSize)) {
155     std::string str =
156         parsed_command_line.GetSwitchValueASCII(switches::kWindowSize);
157     int width, height;
158     if (ParseCommaSeparatedIntegers(str, &width, &height))
159       bounds->set_size(gfx::Size(width, height));
160   }
161   if (parsed_command_line.HasSwitch(switches::kWindowPosition)) {
162     std::string str =
163         parsed_command_line.GetSwitchValueASCII(switches::kWindowPosition);
164     int x, y;
165     if (ParseCommaSeparatedIntegers(str, &x, &y))
166       bounds->set_origin(gfx::Point(x, y));
167   }
168 }
169
170 }  // namespace chrome