| OLD | NEW |
| (Empty) |
| 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 "stdafx.h" | |
| 6 #include "secondary_tile.h" | |
| 7 | |
| 8 #include <windows.ui.startscreen.h> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/strings/utf_string_conversions.h" | |
| 13 #include "url/gurl.h" | |
| 14 #include "win8/metro_driver/chrome_app_view.h" | |
| 15 #include "win8/metro_driver/winrt_utils.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 using base::win::MetroPinUmaResultCallback; | |
| 20 | |
| 21 // Callback for asynchronous pin requests. | |
| 22 class TileRequestCompleter { | |
| 23 public: | |
| 24 enum PinType { | |
| 25 PIN, | |
| 26 UNPIN | |
| 27 }; | |
| 28 TileRequestCompleter(PinType type, const MetroPinUmaResultCallback& callback) | |
| 29 : type_(type), callback_(callback) {} | |
| 30 | |
| 31 void Complete(mswr::ComPtr<winfoundtn::IAsyncOperation<bool>>& completion); | |
| 32 | |
| 33 private: | |
| 34 // Callback that responds to user input on the pin request pop-up. This will | |
| 35 // run |callback_|, then delete |this| before returning. | |
| 36 HRESULT Respond(winfoundtn::IAsyncOperation<bool>* async, | |
| 37 AsyncStatus status); | |
| 38 | |
| 39 PinType type_; | |
| 40 MetroPinUmaResultCallback callback_; | |
| 41 }; | |
| 42 | |
| 43 void TileRequestCompleter::Complete( | |
| 44 mswr::ComPtr<winfoundtn::IAsyncOperation<bool>>& completion) { | |
| 45 typedef winfoundtn::IAsyncOperationCompletedHandler<bool> RequestDoneType; | |
| 46 mswr::ComPtr<RequestDoneType> handler(mswr::Callback<RequestDoneType>( | |
| 47 this, &TileRequestCompleter::Respond)); | |
| 48 DCHECK(handler.Get() != NULL); | |
| 49 HRESULT hr = completion->put_Completed(handler.Get()); | |
| 50 CheckHR(hr, "Failed to put_Completed"); | |
| 51 } | |
| 52 | |
| 53 HRESULT TileRequestCompleter::Respond(winfoundtn::IAsyncOperation<bool>* async, | |
| 54 AsyncStatus status) { | |
| 55 base::win::MetroSecondaryTilePinUmaResult pin_state = | |
| 56 base::win::METRO_PIN_STATE_NONE; | |
| 57 | |
| 58 if (status == Completed) { | |
| 59 unsigned char result; | |
| 60 CheckHR(async->GetResults(&result)); | |
| 61 LOG(INFO) << __FUNCTION__ << " result " << static_cast<int>(result); | |
| 62 switch (result) { | |
| 63 case 0: | |
| 64 pin_state = type_ == PIN ? | |
| 65 base::win::METRO_PIN_RESULT_CANCEL : | |
| 66 base::win::METRO_UNPIN_RESULT_CANCEL; | |
| 67 break; | |
| 68 case 1: | |
| 69 pin_state = type_ == PIN ? | |
| 70 base::win::METRO_PIN_RESULT_OK : | |
| 71 base::win::METRO_UNPIN_RESULT_OK; | |
| 72 break; | |
| 73 default: | |
| 74 pin_state = type_ == PIN ? | |
| 75 base::win::METRO_PIN_RESULT_OTHER : | |
| 76 base::win::METRO_UNPIN_RESULT_OTHER; | |
| 77 break; | |
| 78 } | |
| 79 } else { | |
| 80 LOG(ERROR) << __FUNCTION__ << " Unexpected async status " | |
| 81 << static_cast<int>(status); | |
| 82 pin_state = type_ == PIN ? | |
| 83 base::win::METRO_PIN_RESULT_ERROR : | |
| 84 base::win::METRO_UNPIN_RESULT_ERROR; | |
| 85 } | |
| 86 callback_.Run(pin_state); | |
| 87 | |
| 88 delete this; | |
| 89 return S_OK; | |
| 90 } | |
| 91 | |
| 92 void DeleteTileFromStartScreen(const base::string16& tile_id, | |
| 93 const MetroPinUmaResultCallback& callback) { | |
| 94 DVLOG(1) << __FUNCTION__; | |
| 95 mswr::ComPtr<winui::StartScreen::ISecondaryTileFactory> tile_factory; | |
| 96 HRESULT hr = winrt_utils::CreateActivationFactory( | |
| 97 RuntimeClass_Windows_UI_StartScreen_SecondaryTile, | |
| 98 tile_factory.GetAddressOf()); | |
| 99 CheckHR(hr, "Failed to create instance of ISecondaryTileFactory"); | |
| 100 | |
| 101 mswrw::HString id; | |
| 102 id.Attach(MakeHString(tile_id)); | |
| 103 | |
| 104 mswr::ComPtr<winui::StartScreen::ISecondaryTile> tile; | |
| 105 hr = tile_factory->CreateWithId(id.Get(), tile.GetAddressOf()); | |
| 106 CheckHR(hr, "Failed to create tile"); | |
| 107 | |
| 108 mswr::ComPtr<winfoundtn::IAsyncOperation<bool>> completion; | |
| 109 hr = tile->RequestDeleteAsync(completion.GetAddressOf()); | |
| 110 CheckHR(hr, "RequestDeleteAsync failed"); | |
| 111 | |
| 112 if (FAILED(hr)) { | |
| 113 callback.Run(base::win::METRO_UNPIN_REQUEST_SHOW_ERROR); | |
| 114 return; | |
| 115 } | |
| 116 | |
| 117 // Deleted in TileRequestCompleter::Respond when the async operation | |
| 118 // completes. | |
| 119 TileRequestCompleter* completer = | |
| 120 new TileRequestCompleter(TileRequestCompleter::UNPIN, callback); | |
| 121 completer->Complete(completion); | |
| 122 } | |
| 123 | |
| 124 void CreateTileOnStartScreen(const base::string16& tile_id, | |
| 125 const base::string16& title_str, | |
| 126 const base::string16& url_str, | |
| 127 const base::FilePath& logo_path, | |
| 128 const MetroPinUmaResultCallback& callback) { | |
| 129 VLOG(1) << __FUNCTION__; | |
| 130 | |
| 131 mswr::ComPtr<winui::StartScreen::ISecondaryTileFactory> tile_factory; | |
| 132 HRESULT hr = winrt_utils::CreateActivationFactory( | |
| 133 RuntimeClass_Windows_UI_StartScreen_SecondaryTile, | |
| 134 tile_factory.GetAddressOf()); | |
| 135 CheckHR(hr, "Failed to create instance of ISecondaryTileFactory"); | |
| 136 | |
| 137 winui::StartScreen::TileOptions options = | |
| 138 winui::StartScreen::TileOptions_ShowNameOnLogo; | |
| 139 mswrw::HString title; | |
| 140 title.Attach(MakeHString(title_str)); | |
| 141 | |
| 142 mswrw::HString id; | |
| 143 id.Attach(MakeHString(tile_id)); | |
| 144 | |
| 145 mswrw::HString args; | |
| 146 // The url is just passed into the tile agruments as is. Metro and desktop | |
| 147 // chrome will see the arguments as command line parameters. | |
| 148 // A GURL is used to ensure any spaces are properly escaped. | |
| 149 GURL url(url_str); | |
| 150 args.Attach(MakeHString(base::UTF8ToUTF16(url.spec()))); | |
| 151 | |
| 152 mswr::ComPtr<winfoundtn::IUriRuntimeClassFactory> uri_factory; | |
| 153 hr = winrt_utils::CreateActivationFactory( | |
| 154 RuntimeClass_Windows_Foundation_Uri, | |
| 155 uri_factory.GetAddressOf()); | |
| 156 CheckHR(hr, "Failed to create URIFactory"); | |
| 157 | |
| 158 mswrw::HString logo_url; | |
| 159 logo_url.Attach( | |
| 160 MakeHString(base::string16(L"file:///").append(logo_path.value()))); | |
| 161 mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; | |
| 162 hr = uri_factory->CreateUri(logo_url.Get(), &uri); | |
| 163 CheckHR(hr, "Failed to create URI"); | |
| 164 | |
| 165 mswr::ComPtr<winui::StartScreen::ISecondaryTile> tile; | |
| 166 hr = tile_factory->CreateTile(id.Get(), | |
| 167 title.Get(), | |
| 168 title.Get(), | |
| 169 args.Get(), | |
| 170 options, | |
| 171 uri.Get(), | |
| 172 tile.GetAddressOf()); | |
| 173 CheckHR(hr, "Failed to create tile"); | |
| 174 | |
| 175 hr = tile->put_ForegroundText(winui::StartScreen::ForegroundText_Light); | |
| 176 CheckHR(hr, "Failed to change foreground text color"); | |
| 177 | |
| 178 mswr::ComPtr<winfoundtn::IAsyncOperation<bool>> completion; | |
| 179 hr = tile->RequestCreateAsync(completion.GetAddressOf()); | |
| 180 CheckHR(hr, "RequestCreateAsync failed"); | |
| 181 | |
| 182 if (FAILED(hr)) { | |
| 183 callback.Run(base::win::METRO_PIN_REQUEST_SHOW_ERROR); | |
| 184 return; | |
| 185 } | |
| 186 | |
| 187 // Deleted in TileRequestCompleter::Respond when the async operation | |
| 188 // completes. | |
| 189 TileRequestCompleter* completer = | |
| 190 new TileRequestCompleter(TileRequestCompleter::PIN, callback); | |
| 191 completer->Complete(completion); | |
| 192 } | |
| 193 | |
| 194 } // namespace | |
| 195 | |
| 196 BOOL MetroIsPinnedToStartScreen(const base::string16& tile_id) { | |
| 197 mswr::ComPtr<winui::StartScreen::ISecondaryTileStatics> tile_statics; | |
| 198 HRESULT hr = winrt_utils::CreateActivationFactory( | |
| 199 RuntimeClass_Windows_UI_StartScreen_SecondaryTile, | |
| 200 tile_statics.GetAddressOf()); | |
| 201 CheckHR(hr, "Failed to create instance of ISecondaryTileStatics"); | |
| 202 | |
| 203 boolean exists; | |
| 204 hr = tile_statics->Exists(MakeHString(tile_id), &exists); | |
| 205 CheckHR(hr, "ISecondaryTileStatics.Exists failed"); | |
| 206 return exists; | |
| 207 } | |
| 208 | |
| 209 void MetroUnPinFromStartScreen(const base::string16& tile_id, | |
| 210 const MetroPinUmaResultCallback& callback) { | |
| 211 globals.appview_msg_loop->PostTask( | |
| 212 FROM_HERE, base::Bind(&DeleteTileFromStartScreen, | |
| 213 tile_id, | |
| 214 callback)); | |
| 215 } | |
| 216 | |
| 217 void MetroPinToStartScreen(const base::string16& tile_id, | |
| 218 const base::string16& title, | |
| 219 const base::string16& url, | |
| 220 const base::FilePath& logo_path, | |
| 221 const MetroPinUmaResultCallback& callback) { | |
| 222 globals.appview_msg_loop->PostTask( | |
| 223 FROM_HERE, base::Bind(&CreateTileOnStartScreen, | |
| 224 tile_id, | |
| 225 title, | |
| 226 url, | |
| 227 logo_path, | |
| 228 callback)); | |
| 229 } | |
| OLD | NEW |