| Index: win8/metro_driver/file_picker_ash.cc
 | 
| diff --git a/win8/metro_driver/file_picker_ash.cc b/win8/metro_driver/file_picker_ash.cc
 | 
| deleted file mode 100644
 | 
| index 31e699d0ed11909a4145493e1acfb5bc793c0ddf..0000000000000000000000000000000000000000
 | 
| --- a/win8/metro_driver/file_picker_ash.cc
 | 
| +++ /dev/null
 | 
| @@ -1,619 +0,0 @@
 | 
| -// Copyright (c) 2013 The Chromium Authors. All rights reserved.
 | 
| -// Use of this source code is governed by a BSD-style license that can be
 | 
| -// found in the LICENSE file.
 | 
| -
 | 
| -#include <stddef.h>
 | 
| -#include <stdint.h>
 | 
| -
 | 
| -#include "stdafx.h"
 | 
| -#include "win8/metro_driver/file_picker_ash.h"
 | 
| -
 | 
| -#include "base/bind.h"
 | 
| -#include "base/logging.h"
 | 
| -#include "base/message_loop/message_loop.h"
 | 
| -#include "base/strings/string_split.h"
 | 
| -#include "base/strings/string_util.h"
 | 
| -#include "base/synchronization/waitable_event.h"
 | 
| -#include "base/win/scoped_comptr.h"
 | 
| -#include "ui/metro_viewer/metro_viewer_messages.h"
 | 
| -#include "win8/metro_driver/chrome_app_view_ash.h"
 | 
| -#include "win8/metro_driver/winrt_utils.h"
 | 
| -
 | 
| -namespace {
 | 
| -
 | 
| -typedef winfoundtn::Collections::IVector<HSTRING> StringVectorItf;
 | 
| -
 | 
| -// TODO(siggi): Complete this implementation and move it to a common place.
 | 
| -class StringVectorImpl : public mswr::RuntimeClass<StringVectorItf> {
 | 
| - public:
 | 
| -  ~StringVectorImpl() override {
 | 
| -    std::for_each(strings_.begin(), strings_.end(), ::WindowsDeleteString);
 | 
| -  }
 | 
| -
 | 
| -  HRESULT RuntimeClassInitialize(const std::vector<base::string16>& list) {
 | 
| -    for (size_t i = 0; i < list.size(); ++i)
 | 
| -      strings_.push_back(MakeHString(list[i]));
 | 
| -
 | 
| -    return S_OK;
 | 
| -  }
 | 
| -
 | 
| -  // IVector<HSTRING> implementation.
 | 
| -  STDMETHOD(GetAt)(unsigned index, HSTRING* item) override {
 | 
| -    if (index >= strings_.size())
 | 
| -      return E_INVALIDARG;
 | 
| -
 | 
| -    return ::WindowsDuplicateString(strings_[index], item);
 | 
| -  }
 | 
| -  STDMETHOD(get_Size)(unsigned* size) override {
 | 
| -    if (strings_.size() > UINT_MAX)
 | 
| -      return E_UNEXPECTED;
 | 
| -    *size = static_cast<unsigned>(strings_.size());
 | 
| -    return S_OK;
 | 
| -  }
 | 
| -  STDMETHOD(GetView)(
 | 
| -      winfoundtn::Collections::IVectorView<HSTRING>** view) override {
 | 
| -    return E_NOTIMPL;
 | 
| -  }
 | 
| -  STDMETHOD(IndexOf)(HSTRING value, unsigned* index, boolean* found) override {
 | 
| -    return E_NOTIMPL;
 | 
| -  }
 | 
| -
 | 
| -  // write methods
 | 
| -  STDMETHOD(SetAt)(unsigned index, HSTRING item) override { return E_NOTIMPL; }
 | 
| -  STDMETHOD(InsertAt)(unsigned index, HSTRING item) override {
 | 
| -    return E_NOTIMPL;
 | 
| -  }
 | 
| -  STDMETHOD(RemoveAt)(unsigned index) override { return E_NOTIMPL; }
 | 
| -  STDMETHOD(Append)(HSTRING item) override { return E_NOTIMPL; }
 | 
| -  STDMETHOD(RemoveAtEnd)() override { return E_NOTIMPL; }
 | 
| -  STDMETHOD(Clear)() override { return E_NOTIMPL; }
 | 
| -
 | 
| - private:
 | 
| -  std::vector<HSTRING> strings_;
 | 
| -};
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
| -FilePickerSessionBase::~FilePickerSessionBase() {
 | 
| -}
 | 
| -
 | 
| -bool FilePickerSessionBase::Run() {
 | 
| -  if (!DoFilePicker())
 | 
| -    return false;
 | 
| -  return success_;
 | 
| -}
 | 
| -
 | 
| -FilePickerSessionBase::FilePickerSessionBase(ChromeAppViewAsh* app_view,
 | 
| -                                             const base::string16& title,
 | 
| -                                             const base::string16& filter,
 | 
| -                                             const base::FilePath& default_path)
 | 
| -    : success_(false),
 | 
| -      title_(title),
 | 
| -      filter_(filter),
 | 
| -      default_path_(default_path),
 | 
| -      app_view_(app_view) {
 | 
| -}
 | 
| -
 | 
| -bool FilePickerSessionBase::DoFilePicker() {
 | 
| -  // The file picker will fail if spawned from a snapped application,
 | 
| -  // so let's attempt to unsnap first if we're in that state.
 | 
| -  HRESULT hr = ChromeAppViewAsh::Unsnap();
 | 
| -  if (FAILED(hr)) {
 | 
| -    LOG(ERROR) << "Failed to unsnap for file picker, error 0x" << hr;
 | 
| -    return false;
 | 
| -  }
 | 
| -  hr = StartFilePicker();
 | 
| -  if (FAILED(hr)) {
 | 
| -    LOG(ERROR) << "Failed to start file picker, error 0x"
 | 
| -               << std::hex << hr;
 | 
| -    return false;
 | 
| -  }
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -OpenFilePickerSession::OpenFilePickerSession(
 | 
| -    ChromeAppViewAsh* app_view,
 | 
| -    const base::string16& title,
 | 
| -    const base::string16& filter,
 | 
| -    const base::FilePath& default_path,
 | 
| -    bool allow_multi_select)
 | 
| -    : FilePickerSessionBase(app_view, title, filter, default_path),
 | 
| -      allow_multi_select_(allow_multi_select) {
 | 
| -}
 | 
| -
 | 
| -OpenFilePickerSession::~OpenFilePickerSession() {
 | 
| -}
 | 
| -
 | 
| -HRESULT OpenFilePickerSession::SinglePickerDone(SingleFileAsyncOp* async,
 | 
| -                                                AsyncStatus status) {
 | 
| -  if (status == Completed) {
 | 
| -    mswr::ComPtr<winstorage::IStorageFile> file;
 | 
| -    HRESULT hr = async->GetResults(file.GetAddressOf());
 | 
| -
 | 
| -    if (file) {
 | 
| -      mswr::ComPtr<winstorage::IStorageItem> storage_item;
 | 
| -      if (SUCCEEDED(hr))
 | 
| -        hr = file.As(&storage_item);
 | 
| -
 | 
| -      mswrw::HString file_path;
 | 
| -      if (SUCCEEDED(hr))
 | 
| -        hr = storage_item->get_Path(file_path.GetAddressOf());
 | 
| -
 | 
| -      if (SUCCEEDED(hr)) {
 | 
| -        UINT32 path_len = 0;
 | 
| -        const wchar_t* path_str =
 | 
| -            ::WindowsGetStringRawBuffer(file_path.Get(), &path_len);
 | 
| -
 | 
| -        result_ = path_str;
 | 
| -        success_ = true;
 | 
| -      }
 | 
| -    } else {
 | 
| -      LOG(ERROR) << "NULL IStorageItem";
 | 
| -    }
 | 
| -  } else {
 | 
| -    LOG(ERROR) << "Unexpected async status " << static_cast<int>(status);
 | 
| -  }
 | 
| -  app_view_->OnOpenFileCompleted(this, success_);
 | 
| -  return S_OK;
 | 
| -}
 | 
| -
 | 
| -HRESULT OpenFilePickerSession::MultiPickerDone(MultiFileAsyncOp* async,
 | 
| -                                               AsyncStatus status) {
 | 
| -  if (status == Completed) {
 | 
| -    mswr::ComPtr<StorageFileVectorCollection> files;
 | 
| -    HRESULT hr = async->GetResults(files.GetAddressOf());
 | 
| -
 | 
| -    if (files) {
 | 
| -      base::string16 result;
 | 
| -      if (SUCCEEDED(hr))
 | 
| -        hr = ComposeMultiFileResult(files.Get(), &result);
 | 
| -
 | 
| -      if (SUCCEEDED(hr)) {
 | 
| -        success_ = true;
 | 
| -        // The code below has been copied from the
 | 
| -        // SelectFileDialogImpl::RunOpenMultiFileDialog function in
 | 
| -        // select_file_dialog_win.cc.
 | 
| -        // TODO(ananta)
 | 
| -        // Consolidate this into a common place.
 | 
| -        const wchar_t* selection = result.c_str();
 | 
| -        std::vector<base::FilePath> files;
 | 
| -
 | 
| -        while (*selection) {  // Empty string indicates end of list.
 | 
| -          files.push_back(base::FilePath(selection));
 | 
| -          // Skip over filename and null-terminator.
 | 
| -          selection += files.back().value().length() + 1;
 | 
| -        }
 | 
| -        if (files.empty()) {
 | 
| -          success_ = false;
 | 
| -        } else if (files.size() == 1) {
 | 
| -          // When there is one file, it contains the path and filename.
 | 
| -          filenames_ = files;
 | 
| -        } else if (files.size() > 1) {
 | 
| -          // Otherwise, the first string is the path, and the remainder are
 | 
| -          // filenames.
 | 
| -          std::vector<base::FilePath>::iterator path = files.begin();
 | 
| -          for (std::vector<base::FilePath>::iterator file = path + 1;
 | 
| -               file != files.end(); ++file) {
 | 
| -            filenames_.push_back(path->Append(*file));
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    } else {
 | 
| -      LOG(ERROR) << "NULL StorageFileVectorCollection";
 | 
| -    }
 | 
| -  } else {
 | 
| -    LOG(ERROR) << "Unexpected async status " << static_cast<int>(status);
 | 
| -  }
 | 
| -  app_view_->OnOpenFileCompleted(this, success_);
 | 
| -  return S_OK;
 | 
| -}
 | 
| -
 | 
| -HRESULT OpenFilePickerSession::StartFilePicker() {
 | 
| -  mswrw::HStringReference class_name(
 | 
| -      RuntimeClass_Windows_Storage_Pickers_FileOpenPicker);
 | 
| -
 | 
| -  // Create the file picker.
 | 
| -  mswr::ComPtr<winstorage::Pickers::IFileOpenPicker> picker;
 | 
| -  HRESULT hr = ::Windows::Foundation::ActivateInstance(
 | 
| -      class_name.Get(), picker.GetAddressOf());
 | 
| -  CheckHR(hr);
 | 
| -
 | 
| -  // Set the file type filter
 | 
| -  mswr::ComPtr<winfoundtn::Collections::IVector<HSTRING>> filter;
 | 
| -  hr = picker->get_FileTypeFilter(filter.GetAddressOf());
 | 
| -  if (FAILED(hr))
 | 
| -    return hr;
 | 
| -
 | 
| -  if (filter_.empty()) {
 | 
| -    hr = filter->Append(mswrw::HStringReference(L"*").Get());
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -  } else {
 | 
| -    // The filter is a concatenation of zero terminated string pairs,
 | 
| -    // where each pair is {description, extension}. The concatenation ends
 | 
| -    // with a zero length string - e.g. a double zero terminator.
 | 
| -    const wchar_t* walk = filter_.c_str();
 | 
| -    while (*walk != L'\0') {
 | 
| -      // Walk past the description.
 | 
| -      walk += wcslen(walk) + 1;
 | 
| -
 | 
| -      // We should have an extension, but bail on malformed filters.
 | 
| -      if (*walk == L'\0')
 | 
| -        break;
 | 
| -
 | 
| -      // There can be a single extension, or a list of semicolon-separated ones.
 | 
| -      std::vector<base::string16> extensions_win32_style = base::SplitString(
 | 
| -          walk, L";", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 | 
| -
 | 
| -      // Metro wants suffixes only, not patterns.
 | 
| -      mswrw::HString extension;
 | 
| -      for (size_t i = 0; i < extensions_win32_style.size(); ++i) {
 | 
| -        if (extensions_win32_style[i] == L"*.*") {
 | 
| -          // The wildcard filter is "*" for Metro. The string "*.*" produces
 | 
| -          // an "invalid parameter" error.
 | 
| -          hr = extension.Set(L"*");
 | 
| -        } else {
 | 
| -          // Metro wants suffixes only, not patterns.
 | 
| -          base::string16 ext =
 | 
| -              base::FilePath(extensions_win32_style[i]).Extension();
 | 
| -          if ((ext.size() < 2) ||
 | 
| -              (ext.find_first_of(L"*?") != base::string16::npos)) {
 | 
| -            continue;
 | 
| -          }
 | 
| -          hr = extension.Set(ext.c_str());
 | 
| -        }
 | 
| -        if (SUCCEEDED(hr))
 | 
| -          hr = filter->Append(extension.Get());
 | 
| -        if (FAILED(hr))
 | 
| -          return hr;
 | 
| -      }
 | 
| -
 | 
| -      // Walk past the extension.
 | 
| -      walk += wcslen(walk) + 1;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  // Spin up a single or multi picker as appropriate.
 | 
| -  if (allow_multi_select_) {
 | 
| -    mswr::ComPtr<MultiFileAsyncOp> completion;
 | 
| -    hr = picker->PickMultipleFilesAsync(&completion);
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -
 | 
| -    // Create the callback method.
 | 
| -    typedef winfoundtn::IAsyncOperationCompletedHandler<
 | 
| -        StorageFileVectorCollection*> HandlerDoneType;
 | 
| -    mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>(
 | 
| -        this, &OpenFilePickerSession::MultiPickerDone));
 | 
| -    DCHECK(handler.Get() != NULL);
 | 
| -    hr = completion->put_Completed(handler.Get());
 | 
| -
 | 
| -    return hr;
 | 
| -  } else {
 | 
| -    mswr::ComPtr<SingleFileAsyncOp> completion;
 | 
| -    hr = picker->PickSingleFileAsync(&completion);
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -
 | 
| -    // Create the callback method.
 | 
| -    typedef winfoundtn::IAsyncOperationCompletedHandler<
 | 
| -        winstorage::StorageFile*> HandlerDoneType;
 | 
| -    mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>(
 | 
| -        this, &OpenFilePickerSession::SinglePickerDone));
 | 
| -    DCHECK(handler.Get() != NULL);
 | 
| -    hr = completion->put_Completed(handler.Get());
 | 
| -
 | 
| -    return hr;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -HRESULT OpenFilePickerSession::ComposeMultiFileResult(
 | 
| -    StorageFileVectorCollection* files, base::string16* result) {
 | 
| -  DCHECK(files != NULL);
 | 
| -  DCHECK(result != NULL);
 | 
| -
 | 
| -  // Empty the output string.
 | 
| -  result->clear();
 | 
| -
 | 
| -  unsigned int num_files = 0;
 | 
| -  HRESULT hr = files->get_Size(&num_files);
 | 
| -  if (FAILED(hr))
 | 
| -    return hr;
 | 
| -
 | 
| -  // Make sure we return an error on an empty collection.
 | 
| -  if (num_files == 0) {
 | 
| -    DLOG(ERROR) << "Empty collection on input.";
 | 
| -    return E_UNEXPECTED;
 | 
| -  }
 | 
| -
 | 
| -  // This stores the base path that should be the parent of all the files.
 | 
| -  base::FilePath base_path;
 | 
| -
 | 
| -  // Iterate through the collection and append the file paths to the result.
 | 
| -  for (unsigned int i = 0; i < num_files; ++i) {
 | 
| -    mswr::ComPtr<winstorage::IStorageFile> file;
 | 
| -    hr = files->GetAt(i, file.GetAddressOf());
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -
 | 
| -    mswr::ComPtr<winstorage::IStorageItem> storage_item;
 | 
| -    hr = file.As(&storage_item);
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -
 | 
| -    mswrw::HString file_path_str;
 | 
| -    hr = storage_item->get_Path(file_path_str.GetAddressOf());
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -
 | 
| -    base::FilePath file_path(MakeStdWString(file_path_str.Get()));
 | 
| -    if (base_path.empty()) {
 | 
| -      DCHECK(result->empty());
 | 
| -      base_path = file_path.DirName();
 | 
| -
 | 
| -      // Append the path, including the terminating zero.
 | 
| -      // We do this only for the first file.
 | 
| -      result->append(base_path.value().c_str(), base_path.value().size() + 1);
 | 
| -    }
 | 
| -    DCHECK(!result->empty());
 | 
| -    DCHECK(!base_path.empty());
 | 
| -    DCHECK(base_path == file_path.DirName());
 | 
| -
 | 
| -    // Append the base name, including the terminating zero.
 | 
| -    base::FilePath base_name = file_path.BaseName();
 | 
| -    result->append(base_name.value().c_str(), base_name.value().size() + 1);
 | 
| -  }
 | 
| -
 | 
| -  DCHECK(!result->empty());
 | 
| -
 | 
| -  return S_OK;
 | 
| -}
 | 
| -
 | 
| -SaveFilePickerSession::SaveFilePickerSession(
 | 
| -    ChromeAppViewAsh* app_view,
 | 
| -    const MetroViewerHostMsg_SaveAsDialogParams& params)
 | 
| -    : FilePickerSessionBase(app_view,
 | 
| -                            params.title,
 | 
| -                            params.filter,
 | 
| -                            params.suggested_name),
 | 
| -      filter_index_(params.filter_index) {
 | 
| -}
 | 
| -
 | 
| -int SaveFilePickerSession::filter_index() const {
 | 
| -  // TODO(ananta)
 | 
| -  // Add support for returning the correct filter index. This does not work in
 | 
| -  // regular Chrome metro on trunk as well.
 | 
| -  // BUG: https://code.google.com/p/chromium/issues/detail?id=172704
 | 
| -  return filter_index_;
 | 
| -}
 | 
| -
 | 
| -HRESULT SaveFilePickerSession::StartFilePicker() {
 | 
| -  mswrw::HStringReference class_name(
 | 
| -      RuntimeClass_Windows_Storage_Pickers_FileSavePicker);
 | 
| -
 | 
| -  // Create the file picker.
 | 
| -  mswr::ComPtr<winstorage::Pickers::IFileSavePicker> picker;
 | 
| -  HRESULT hr = ::Windows::Foundation::ActivateInstance(
 | 
| -      class_name.Get(), picker.GetAddressOf());
 | 
| -  CheckHR(hr);
 | 
| -
 | 
| -  typedef winfoundtn::Collections::IMap<HSTRING, StringVectorItf*>
 | 
| -      StringVectorMap;
 | 
| -  mswr::ComPtr<StringVectorMap> choices;
 | 
| -  hr = picker->get_FileTypeChoices(choices.GetAddressOf());
 | 
| -  if (FAILED(hr))
 | 
| -    return hr;
 | 
| -
 | 
| -  if (!filter_.empty()) {
 | 
| -    // The filter is a concatenation of zero terminated string pairs,
 | 
| -    // where each pair is {description, extension list}. The concatenation ends
 | 
| -    // with a zero length string - e.g. a double zero terminator.
 | 
| -    const wchar_t* walk = filter_.c_str();
 | 
| -    while (*walk != L'\0') {
 | 
| -      mswrw::HString description;
 | 
| -      hr = description.Set(walk);
 | 
| -      if (FAILED(hr))
 | 
| -        return hr;
 | 
| -
 | 
| -      // Walk past the description.
 | 
| -      walk += wcslen(walk) + 1;
 | 
| -
 | 
| -      // We should have an extension, but bail on malformed filters.
 | 
| -      if (*walk == L'\0')
 | 
| -        break;
 | 
| -
 | 
| -      // There can be a single extension, or a list of semicolon-separated ones.
 | 
| -      std::vector<base::string16> extensions_win32_style = base::SplitString(
 | 
| -          walk, L";", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 | 
| -
 | 
| -      // Metro wants suffixes only, not patterns.  Also, metro does not support
 | 
| -      // the all files ("*") pattern in the save picker.
 | 
| -      std::vector<base::string16> extensions;
 | 
| -      for (size_t i = 0; i < extensions_win32_style.size(); ++i) {
 | 
| -        base::string16 ext =
 | 
| -            base::FilePath(extensions_win32_style[i]).Extension();
 | 
| -        if ((ext.size() < 2) ||
 | 
| -            (ext.find_first_of(L"*?") != base::string16::npos))
 | 
| -          continue;
 | 
| -        extensions.push_back(ext);
 | 
| -      }
 | 
| -
 | 
| -      if (!extensions.empty()) {
 | 
| -        // Convert to a Metro collection class.
 | 
| -        mswr::ComPtr<StringVectorItf> list;
 | 
| -        hr = mswr::MakeAndInitialize<StringVectorImpl>(
 | 
| -            list.GetAddressOf(), extensions);
 | 
| -        if (FAILED(hr))
 | 
| -          return hr;
 | 
| -
 | 
| -        // Finally set the filter.
 | 
| -        boolean replaced = FALSE;
 | 
| -        hr = choices->Insert(description.Get(), list.Get(), &replaced);
 | 
| -        if (FAILED(hr))
 | 
| -          return hr;
 | 
| -        DCHECK_EQ(FALSE, replaced);
 | 
| -      }
 | 
| -
 | 
| -      // Walk past the extension(s).
 | 
| -      walk += wcslen(walk) + 1;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  // The save picker requires at least one choice.  Callers are strongly advised
 | 
| -  // to provide sensible choices.  If none were given, fallback to .dat.
 | 
| -  uint32_t num_choices = 0;
 | 
| -  hr = choices->get_Size(&num_choices);
 | 
| -  if (FAILED(hr))
 | 
| -    return hr;
 | 
| -
 | 
| -  if (num_choices == 0) {
 | 
| -    mswrw::HString description;
 | 
| -    // TODO(grt): Get a properly translated string.  This can't be done from
 | 
| -    // within metro_driver.  Consider preprocessing the filter list in Chrome
 | 
| -    // land to ensure it has this entry if all others are patterns.  In that
 | 
| -    // case, this whole block of code can be removed.
 | 
| -    hr = description.Set(L"Data File");
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -
 | 
| -    mswr::ComPtr<StringVectorItf> list;
 | 
| -    hr = mswr::MakeAndInitialize<StringVectorImpl>(
 | 
| -        list.GetAddressOf(), std::vector<base::string16>(1, L".dat"));
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -
 | 
| -    boolean replaced = FALSE;
 | 
| -    hr = choices->Insert(description.Get(), list.Get(), &replaced);
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -    DCHECK_EQ(FALSE, replaced);
 | 
| -  }
 | 
| -
 | 
| -  if (!default_path_.empty()) {
 | 
| -    base::string16 file_part = default_path_.BaseName().value();
 | 
| -    // If the suggested_name is a root directory, then don't set it as the
 | 
| -    // suggested name.
 | 
| -    if (file_part.size() == 1 && file_part[0] == L'\\')
 | 
| -      file_part.clear();
 | 
| -    hr = picker->put_SuggestedFileName(
 | 
| -        mswrw::HStringReference(file_part.c_str()).Get());
 | 
| -    if (FAILED(hr))
 | 
| -      return hr;
 | 
| -  }
 | 
| -
 | 
| -  mswr::ComPtr<SaveFileAsyncOp> completion;
 | 
| -  hr = picker->PickSaveFileAsync(&completion);
 | 
| -  if (FAILED(hr))
 | 
| -    return hr;
 | 
| -
 | 
| -  // Create the callback method.
 | 
| -  typedef winfoundtn::IAsyncOperationCompletedHandler<
 | 
| -      winstorage::StorageFile*> HandlerDoneType;
 | 
| -  mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>(
 | 
| -      this, &SaveFilePickerSession::FilePickerDone));
 | 
| -  DCHECK(handler.Get() != NULL);
 | 
| -  hr = completion->put_Completed(handler.Get());
 | 
| -
 | 
| -  return hr;
 | 
| -}
 | 
| -
 | 
| -HRESULT SaveFilePickerSession::FilePickerDone(SaveFileAsyncOp* async,
 | 
| -                                              AsyncStatus status) {
 | 
| -  if (status == Completed) {
 | 
| -    mswr::ComPtr<winstorage::IStorageFile> file;
 | 
| -    HRESULT hr = async->GetResults(file.GetAddressOf());
 | 
| -
 | 
| -    if (file) {
 | 
| -      mswr::ComPtr<winstorage::IStorageItem> storage_item;
 | 
| -      if (SUCCEEDED(hr))
 | 
| -        hr = file.As(&storage_item);
 | 
| -
 | 
| -      mswrw::HString file_path;
 | 
| -      if (SUCCEEDED(hr))
 | 
| -        hr = storage_item->get_Path(file_path.GetAddressOf());
 | 
| -
 | 
| -      if (SUCCEEDED(hr)) {
 | 
| -        base::string16 path_str = MakeStdWString(file_path.Get());
 | 
| -        result_ = path_str;
 | 
| -        success_ = true;
 | 
| -      }
 | 
| -    } else {
 | 
| -      LOG(ERROR) << "NULL IStorageItem";
 | 
| -    }
 | 
| -  } else {
 | 
| -    LOG(ERROR) << "Unexpected async status " << static_cast<int>(status);
 | 
| -  }
 | 
| -  app_view_->OnSaveFileCompleted(this, success_);
 | 
| -  return S_OK;
 | 
| -}
 | 
| -
 | 
| -FolderPickerSession::FolderPickerSession(ChromeAppViewAsh* app_view,
 | 
| -                                         const base::string16& title)
 | 
| -    : FilePickerSessionBase(app_view, title, L"", base::FilePath()) {
 | 
| -}
 | 
| -
 | 
| -HRESULT FolderPickerSession::StartFilePicker() {
 | 
| -  mswrw::HStringReference class_name(
 | 
| -      RuntimeClass_Windows_Storage_Pickers_FolderPicker);
 | 
| -
 | 
| -  // Create the folder picker.
 | 
| -  mswr::ComPtr<winstorage::Pickers::IFolderPicker> picker;
 | 
| -  HRESULT hr = ::Windows::Foundation::ActivateInstance(
 | 
| -      class_name.Get(), picker.GetAddressOf());
 | 
| -  CheckHR(hr);
 | 
| -
 | 
| -  // Set the file type filter
 | 
| -  mswr::ComPtr<winfoundtn::Collections::IVector<HSTRING>> filter;
 | 
| -  hr = picker->get_FileTypeFilter(filter.GetAddressOf());
 | 
| -  if (FAILED(hr))
 | 
| -    return hr;
 | 
| -
 | 
| -  hr = filter->Append(mswrw::HStringReference(L"*").Get());
 | 
| -  if (FAILED(hr))
 | 
| -    return hr;
 | 
| -
 | 
| -  mswr::ComPtr<FolderPickerAsyncOp> completion;
 | 
| -  hr = picker->PickSingleFolderAsync(&completion);
 | 
| -  if (FAILED(hr))
 | 
| -    return hr;
 | 
| -
 | 
| -  // Create the callback method.
 | 
| -  typedef winfoundtn::IAsyncOperationCompletedHandler<
 | 
| -      winstorage::StorageFolder*> HandlerDoneType;
 | 
| -  mswr::ComPtr<HandlerDoneType> handler(mswr::Callback<HandlerDoneType>(
 | 
| -      this, &FolderPickerSession::FolderPickerDone));
 | 
| -  DCHECK(handler.Get() != NULL);
 | 
| -  hr = completion->put_Completed(handler.Get());
 | 
| -  return hr;
 | 
| -}
 | 
| -
 | 
| -HRESULT FolderPickerSession::FolderPickerDone(FolderPickerAsyncOp* async,
 | 
| -                                              AsyncStatus status) {
 | 
| -  if (status == Completed) {
 | 
| -    mswr::ComPtr<winstorage::IStorageFolder> folder;
 | 
| -    HRESULT hr = async->GetResults(folder.GetAddressOf());
 | 
| -
 | 
| -    if (folder) {
 | 
| -      mswr::ComPtr<winstorage::IStorageItem> storage_item;
 | 
| -      if (SUCCEEDED(hr))
 | 
| -        hr = folder.As(&storage_item);
 | 
| -
 | 
| -      mswrw::HString file_path;
 | 
| -      if (SUCCEEDED(hr))
 | 
| -        hr = storage_item->get_Path(file_path.GetAddressOf());
 | 
| -
 | 
| -      if (SUCCEEDED(hr)) {
 | 
| -        base::string16 path_str = MakeStdWString(file_path.Get());
 | 
| -        result_ = path_str;
 | 
| -        success_ = true;
 | 
| -      }
 | 
| -    } else {
 | 
| -      LOG(ERROR) << "NULL IStorageItem";
 | 
| -    }
 | 
| -  } else {
 | 
| -    LOG(ERROR) << "Unexpected async status " << static_cast<int>(status);
 | 
| -  }
 | 
| -  app_view_->OnFolderPickerCompleted(this, success_);
 | 
| -  return S_OK;
 | 
| -}
 | 
| -
 | 
| 
 |