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