Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(330)

Side by Side Diff: chrome/browser/ui/views/apps/jumplist_updater_win.cc

Issue 158643002: Add option to install an ephemeral app to the Windows jump list (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added notimplemented Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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/views/apps/jumplist_updater_win.h"
6
7 #include <propvarutil.h>
8 #include <shobjidl.h>
9 #include <windows.h>
10 // This include needs to go out of order to prevent compilation errors because
tapted 2014/02/12 10:16:28 It's actually pretty common to always ensure <wind
11 // propidl.h does not check whether PID_FIRST_USABLE is already defined.
12 #include <propkey.h>
13
14 #include "base/command_line.h"
15 #include "base/path_service.h"
16 #include "base/win/scoped_comptr.h"
17 #include "base/win/scoped_propvariant.h"
18 #include "base/win/windows_version.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/common/chrome_constants.h"
21 #include "chrome/common/chrome_switches.h"
22
23 namespace {
24
25 void AddShellLink(base::win::ScopedComPtr<IObjectCollection> collection,
26 const std::wstring& application,
27 const std::wstring& switches,
28 const JumpListUpdater::ListItem& list_item) {
29 base::win::ScopedComPtr<IShellLink> link;
30 HRESULT result = link.CreateInstance(CLSID_ShellLink, NULL,
31 CLSCTX_INPROC_SERVER);
32 if (FAILED(result))
33 return;
34
35 // Set the application path to invoke for each link.
36 result = link->SetPath(application.c_str());
tapted 2014/02/12 10:16:28 ( would become SetPath(command_line.GetProgram().v
37 if (FAILED(result))
38 return;
39
40 // Set the command line args.
tapted 2014/02/12 10:16:28 And, e.g., I think this would be nicer if you coul
41 std::wstring arguments(switches);
42 if (!list_item.command_line_args.empty()) {
43 arguments.push_back(L' ');
44 arguments += list_item.command_line_args;
45 }
46 if (!arguments.empty()) {
47 result = link->SetArguments(arguments.c_str());
48 if (FAILED(result))
49 return;
50 }
51
52 // Set the icon. This can be allowed to fail.
53 if (!list_item.icon_path.empty())
54 link->SetIconLocation(list_item.icon_path.value().c_str(), 0);
tapted 2014/02/12 10:16:28 This could potentially use chrome.exe, and just pr
55
56 // Set the title. This must be added as a property.
57 base::win::ScopedComPtr<IPropertyStore> property_store;
58 result = link.QueryInterface(property_store.Receive());
59 if (FAILED(result))
60 return;
61
62 base::win::ScopedPropVariant property_title;
63 result = InitPropVariantFromString(list_item.title.c_str(),
tapted 2014/02/12 10:16:28 I'm a bit unfamiliar with this stuff, but can you
64 property_title.Receive());
65 if (FAILED(result))
66 return;
67
68 result = property_store->SetValue(PKEY_Title, property_title.get());
69 if (FAILED(result))
70 return;
71
72 result = property_store->Commit();
73 if (FAILED(result))
74 return;
75
76 // Add this IShellLink to the given collection.
77 collection->AddObject(link);
78 }
79
80 void AddTasks(base::win::ScopedComPtr<ICustomDestinationList> jumplist,
81 const std::wstring& application,
82 const std::wstring& switches,
83 const std::vector<JumpListUpdater::ListItem>& items) {
84 // Create a collection to store items for the "Tasks" category of the
85 // jump list.
86 base::win::ScopedComPtr<IObjectCollection> collection;
87 HRESULT result = collection.CreateInstance(CLSID_EnumerableObjectCollection,
88 NULL, CLSCTX_INPROC_SERVER);
89 if (FAILED(result))
90 return;
91
92 // Add list items.
93 for (std::vector<JumpListUpdater::ListItem>::const_iterator it =
94 items.begin(); it != items.end(); ++it) {
95 AddShellLink(collection, application, switches, *it);
96 }
97
98 // Cast to IObjectArray and update the jump list's "Tasks".
99 base::win::ScopedComPtr<IObjectArray> object_array;
100 result = collection.QueryInterface(object_array.Receive());
101 if (FAILED(result))
102 return;
103
104 jumplist->AddUserTasks(object_array);
105 }
106
107 } // namespace
108
109 // static
110 void JumpListUpdater::AppendArgs(const std::string& switch_string,
111 const base::string16& value,
112 base::string16* command_line_args) {
113 DCHECK(command_line_args);
114 CommandLine command_line(CommandLine::NO_PROGRAM);
115 if (value.empty())
116 command_line.AppendSwitch(switch_string);
117 else
118 command_line.AppendSwitchNative(switch_string, value);
119
120 if (!command_line_args->empty())
121 command_line_args->push_back(L' ');
122 *command_line_args += command_line.GetCommandLineString();
123 }
124
125 JumpListUpdater::JumpListUpdater(
126 Profile* profile,
127 const base::string16& app_user_model_id)
128 : profile_(profile),
129 app_user_model_id_(app_user_model_id) {
130 PathService::Get(base::FILE_EXE, &chrome_path_);
131
132 // Set up common command line switches.
133 base::FilePath user_data_dir = CommandLine::ForCurrentProcess()->
134 GetSwitchValuePath(switches::kUserDataDir);
tapted 2014/02/12 10:16:28 Do other things do it like this? It feels unreliab
135 if (!user_data_dir.empty())
tapted 2014/02/12 10:16:28 nit: curlies for multi-line if
136 AppendArgs(switches::kUserDataDir,
137 user_data_dir.value(),
138 &default_chrome_switches_);
139 }
140
141 JumpListUpdater::~JumpListUpdater() {}
142
143 void JumpListUpdater::Update(const std::vector<ListItem>& items) {
144 // Check all the preconditions for creating a jump list.
145 if (chrome_path_.empty())
146 return;
147
148 if (base::win::GetVersion() < base::win::VERSION_WIN7)
149 return;
150
151 // Create the jump list.
152 base::win::ScopedComPtr<ICustomDestinationList> jumplist;
153 HRESULT result = jumplist.CreateInstance(CLSID_DestinationList, NULL,
154 CLSCTX_INPROC_SERVER);
155 if (FAILED(result))
156 return;
157
158 // Associate the jump list with this application.
159 jumplist->SetAppID(app_user_model_id_.c_str());
160
161 // Start transaction to modify the jump list.
162 UINT max_slots; // unused
tapted 2014/02/12 10:16:28 nit: ` // Unused.` (with 2 spaces between code an
163 base::win::ScopedComPtr<IObjectArray> removed; // unused
164 result = jumplist->BeginList(&max_slots, __uuidof(*removed),
165 reinterpret_cast<void**>(&removed));
tapted 2014/02/12 10:16:28 would `removed.ReceiveVoid()` work here in place o
166 if (FAILED(result))
167 return;
168
169 // Add items to the predefined "Tasks" category.
170 AddTasks(jumplist,
171 chrome_path_.value(),
172 default_chrome_switches_,
173 items);
174
175 // Commit changes to the jump list.
176 jumplist->CommitList();
177 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698