1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file.
4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h"
6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <vector>
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/callback_forward.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/i18n/time_formatting.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/logging.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/task_runner_util.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/extension_util.h"
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/extensions/launch_util.h"
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/extension_constants.h"
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "extensions/browser/extension_system.h"
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "extensions/common/extension.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/manifest.h"
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/base/models/combobox_model.h"
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/base/text/bytes_formatting.h"
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/controls/combobox/combobox.h"
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/controls/label.h"
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/layout/layout_constants.h"
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/view.h"
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/widget/widget.h"
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// A model for a combobox selecting the launch options for a hosted app.
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Displays different options depending on the host OS.
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class LaunchOptionsComboboxModel : public ui::ComboboxModel {
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LaunchOptionsComboboxModel();
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~LaunchOptionsComboboxModel();
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  extensions::LaunchType GetLaunchTypeAtIndex(int index) const;
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int GetIndexForLaunchType(extensions::LaunchType launch_type) const;
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from ui::ComboboxModel:
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual int GetItemCount() const OVERRIDE;
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual base::string16 GetItemAt(int index) OVERRIDE;
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A list of the launch types available in the combobox, in order.
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<extensions::LaunchType> launch_types_;
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A list of the messages to display in the combobox, in order. The indexes in
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // this list correspond to the indexes in launch_types_.
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<base::string16> launch_type_messages_;
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LaunchOptionsComboboxModel::LaunchOptionsComboboxModel() {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (extensions::util::IsStreamlinedHostedAppsEnabled()) {
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Streamlined hosted apps can only toggle between LAUNCH_TYPE_WINDOW and
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // LAUNCH_TYPE_REGULAR.
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // TODO(sashab): Use a checkbox for this choice instead of combobox.
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_types_.push_back(extensions::LAUNCH_TYPE_REGULAR);
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_type_messages_.push_back(
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_TAB));
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Although LAUNCH_TYPE_WINDOW doesn't work on Mac, the streamlined hosted
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // apps flag isn't available on Mac, so we must be on a non-Mac OS.
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_types_.push_back(extensions::LAUNCH_TYPE_WINDOW);
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_type_messages_.push_back(
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_types_.push_back(extensions::LAUNCH_TYPE_REGULAR);
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_type_messages_.push_back(
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_REGULAR));
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_types_.push_back(extensions::LAUNCH_TYPE_PINNED);
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_type_messages_.push_back(
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_PINNED));
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_MACOSX)
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Mac does not support standalone web app browser windows or maximize.
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_types_.push_back(extensions::LAUNCH_TYPE_FULLSCREEN);
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_type_messages_.push_back(
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN));
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_types_.push_back(extensions::LAUNCH_TYPE_WINDOW);
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_type_messages_.push_back(
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Even though the launch type is Full Screen, it is more accurately
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // described as Maximized in non-Mac OSs.
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_types_.push_back(extensions::LAUNCH_TYPE_FULLSCREEN);
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_type_messages_.push_back(
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_MAXIMIZED));
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LaunchOptionsComboboxModel::~LaunchOptionsComboboxModel() {
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)extensions::LaunchType LaunchOptionsComboboxModel::GetLaunchTypeAtIndex(
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int index) const {
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return launch_types_[index];
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int LaunchOptionsComboboxModel::GetIndexForLaunchType(
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    extensions::LaunchType launch_type) const {
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (size_t i = 0; i < launch_types_.size(); i++) {
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (launch_types_[i] == launch_type) {
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return i;
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If the requested launch type is not available, just select the first one.
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LOG(WARNING) << "Unavailable launch type " << launch_type << " selected.";
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return 0;
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int LaunchOptionsComboboxModel::GetItemCount() const {
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return launch_types_.size();
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)base::string16 LaunchOptionsComboboxModel::GetItemAt(int index) {
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return launch_type_messages_[index];
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)AppInfoSummaryPanel::AppInfoSummaryPanel(Profile* profile,
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                         const extensions::Extension* app)
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : AppInfoPanel(profile, app),
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      description_heading_(NULL),
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      description_label_(NULL),
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      details_heading_(NULL),
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_title_(NULL),
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_value_(NULL),
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      version_title_(NULL),
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      version_value_(NULL),
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      installed_time_title_(NULL),
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      installed_time_value_(NULL),
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      last_run_time_title_(NULL),
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      last_run_time_value_(NULL),
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      launch_options_combobox_(NULL),
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      weak_ptr_factory_(this) {
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Create UI elements.
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CreateDescriptionControl();
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CreateDetailsControl();
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CreateLaunchOptionControl();
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Layout elements.
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SetLayoutManager(
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new views::BoxLayout(views::BoxLayout::kVertical,
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           0,
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           0,
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           views::kUnrelatedControlVerticalSpacing));
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LayoutDescriptionControl();
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LayoutDetailsControl();
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (launch_options_combobox_)
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    AddChildView(launch_options_combobox_);
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)AppInfoSummaryPanel::~AppInfoSummaryPanel() {
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Destroy view children before their models.
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RemoveAllChildViews(true);
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppInfoSummaryPanel::CreateDescriptionControl() {
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!app_->description().empty()) {
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const size_t kMaxLength = 400;
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::string16 text = base::UTF8ToUTF16(app_->description());
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (text.length() > kMaxLength) {
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      text = text.substr(0, kMaxLength);
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      text += base::ASCIIToUTF16(" ... ");
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    description_heading_ = CreateHeading(
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_DESCRIPTION_TITLE));
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    description_label_ = new views::Label(text);
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    description_label_->SetMultiLine(true);
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    description_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppInfoSummaryPanel::CreateDetailsControl() {
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The size doesn't make sense for component apps.
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (app_->location() != extensions::Manifest::COMPONENT) {
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_title_ = new views::Label(
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_SIZE_LABEL));
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_value_ = new views::Label(
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_SIZE_LOADING_LABEL));
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_value_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    StartCalculatingAppSize();
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The version doesn't make sense for bookmark apps.
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!app_->from_bookmark()) {
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Display 'Version: Built-in' for component apps.
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::string16 version_str = base::ASCIIToUTF16(app_->VersionString());
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (app_->location() == extensions::Manifest::COMPONENT)
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      version_str = l10n_util::GetStringUTF16(
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          IDS_APPLICATION_INFO_VERSION_BUILT_IN_LABEL);
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    version_title_ = new views::Label(
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_VERSION_LABEL));
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    version_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    version_value_ = new views::Label(version_str);
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    version_value_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The install date doesn't make sense for component apps.
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (app_->location() != extensions::Manifest::COMPONENT) {
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    installed_time_title_ = new views::Label(
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_INSTALLED_LABEL));
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    installed_time_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    installed_time_value_ =
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new views::Label(base::TimeFormatShortDate(GetInstalledTime()));
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    installed_time_value_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The last run time is currently incorrect for component and hosted apps,
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // since it is not updated when they are accessed outside of their shortcuts.
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(sashab): Update the run time for these correctly: crbug.com/398716
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (app_->location() != extensions::Manifest::COMPONENT &&
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !app_->is_hosted_app()) {
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    last_run_time_title_ = new views::Label(
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_LAST_RUN_LABEL));
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    last_run_time_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Display 'Never' if the app has never been run.
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::string16 last_run_value_str =
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_LAST_RUN_NEVER_LABEL);
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (GetLastLaunchedTime() != base::Time())
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      last_run_value_str = base::TimeFormatShortDate(GetLastLaunchedTime());
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    last_run_time_value_ = new views::Label(last_run_value_str);
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    last_run_time_value_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Only generate the heading if we have at least one field to display.
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (version_title_ || installed_time_title_ || last_run_time_title_) {
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    details_heading_ = CreateHeading(
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_DETAILS_TITLE));
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppInfoSummaryPanel::CreateLaunchOptionControl() {
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (CanSetLaunchType()) {
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_options_combobox_model_.reset(new LaunchOptionsComboboxModel());
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_options_combobox_ =
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        new views::Combobox(launch_options_combobox_model_.get());
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_options_combobox_->set_listener(this);
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    launch_options_combobox_->SetSelectedIndex(
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        launch_options_combobox_model_->GetIndexForLaunchType(GetLaunchType()));
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppInfoSummaryPanel::LayoutDescriptionControl() {
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (description_label_) {
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK(description_heading_);
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    views::View* vertical_stack = CreateVerticalStack();
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    vertical_stack->AddChildView(description_heading_);
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    vertical_stack->AddChildView(description_label_);
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    AddChildView(vertical_stack);
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppInfoSummaryPanel::LayoutDetailsControl() {
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (details_heading_) {
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    views::View* details_stack =
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        CreateVerticalStack(views::kRelatedControlSmallVerticalSpacing);
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (version_title_ && version_value_) {
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      details_stack->AddChildView(
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          CreateKeyValueField(version_title_, version_value_));
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (installed_time_title_ && installed_time_value_) {
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      details_stack->AddChildView(
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          CreateKeyValueField(installed_time_title_, installed_time_value_));
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (last_run_time_title_ && last_run_time_value_) {
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      details_stack->AddChildView(
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          CreateKeyValueField(last_run_time_title_, last_run_time_value_));
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (size_title_ && size_value_) {
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      details_stack->AddChildView(
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          CreateKeyValueField(size_title_, size_value_));
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    views::View* vertical_stack = CreateVerticalStack();
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    vertical_stack->AddChildView(details_heading_);
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    vertical_stack->AddChildView(details_stack);
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    AddChildView(vertical_stack);
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppInfoSummaryPanel::OnPerformAction(views::Combobox* combobox) {
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (combobox == launch_options_combobox_) {
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SetLaunchType(launch_options_combobox_model_->GetLaunchTypeAtIndex(
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        launch_options_combobox_->selected_index()));
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    NOTREACHED();
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppInfoSummaryPanel::StartCalculatingAppSize() {
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::PostTaskAndReplyWithResult(
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::BrowserThread::GetBlockingPool(),
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&base::ComputeDirectorySize, app_->path()),
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&AppInfoSummaryPanel::OnAppSizeCalculated, AsWeakPtr()));
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppInfoSummaryPanel::OnAppSizeCalculated(int64 app_size_in_bytes) {
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  size_value_->SetText(ui::FormatBytes(app_size_in_bytes));
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::Time AppInfoSummaryPanel::GetInstalledTime() const {
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return extensions::ExtensionPrefs::Get(profile_)->GetInstallTime(app_->id());
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::Time AppInfoSummaryPanel::GetLastLaunchedTime() const {
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return extensions::ExtensionPrefs::Get(profile_)
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ->GetLastLaunchTime(app_->id());
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)extensions::LaunchType AppInfoSummaryPanel::GetLaunchType() const {
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_),
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                   app_);
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppInfoSummaryPanel::SetLaunchType(
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    extensions::LaunchType launch_type) const {
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(CanSetLaunchType());
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ExtensionService* service =
347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->extension_service();
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  extensions::SetLaunchType(service, app_->id(), launch_type);
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool AppInfoSummaryPanel::CanSetLaunchType() const {
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // V2 apps don't have a launch type, and neither does the Chrome app.
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return app_->id() != extension_misc::kChromeAppId && !app_->is_platform_app();
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
355