1// Copyright 2013 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/media_galleries/fileapi/supported_audio_video_checker.h"
6
7#include <set>
8#include <vector>
9
10#include "base/bind.h"
11#include "base/callback.h"
12#include "base/lazy_instance.h"
13#include "base/location.h"
14#include "base/logging.h"
15#include "base/stl_util.h"
16#include "chrome/browser/media_galleries/fileapi/safe_audio_video_checker.h"
17#include "content/public/browser/browser_thread.h"
18#include "net/base/mime_util.h"
19
20namespace {
21
22class SupportedAudioVideoExtensions {
23 public:
24  SupportedAudioVideoExtensions() {
25    std::vector<base::FilePath::StringType> extensions;
26    net::GetExtensionsForMimeType("audio/*", &extensions);
27    net::GetExtensionsForMimeType("video/*", &extensions);
28    for (size_t i = 0; i < extensions.size(); ++i) {
29      std::string mime_type;
30      if (net::GetWellKnownMimeTypeFromExtension(extensions[i], &mime_type) &&
31          net::IsSupportedMimeType(mime_type)) {
32        audio_video_extensions_.insert(
33            base::FilePath::kExtensionSeparator + extensions[i]);
34      }
35    }
36  };
37
38  bool HasSupportedAudioVideoExtension(const base::FilePath& file) {
39    return ContainsKey(audio_video_extensions_, file.Extension());
40  }
41
42 private:
43  std::set<base::FilePath::StringType> audio_video_extensions_;
44
45  DISALLOW_COPY_AND_ASSIGN(SupportedAudioVideoExtensions);
46};
47
48base::LazyInstance<SupportedAudioVideoExtensions> g_audio_video_extensions =
49    LAZY_INSTANCE_INITIALIZER;
50
51base::File OpenOnFileThread(const base::FilePath& path) {
52  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
53  return base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
54}
55
56}  // namespace
57
58SupportedAudioVideoChecker::~SupportedAudioVideoChecker() {}
59
60// static
61bool SupportedAudioVideoChecker::SupportsFileType(const base::FilePath& path) {
62  return g_audio_video_extensions.Get().HasSupportedAudioVideoExtension(path);
63}
64
65void SupportedAudioVideoChecker::StartPreWriteValidation(
66    const storage::CopyOrMoveFileValidator::ResultCallback& result_callback) {
67  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
68  DCHECK(callback_.is_null());
69  callback_ = result_callback;
70
71  content::BrowserThread::PostTaskAndReplyWithResult(
72      content::BrowserThread::FILE,
73      FROM_HERE,
74      base::Bind(&OpenOnFileThread, path_),
75      base::Bind(&SupportedAudioVideoChecker::OnFileOpen,
76                 weak_factory_.GetWeakPtr()));
77}
78
79SupportedAudioVideoChecker::SupportedAudioVideoChecker(
80    const base::FilePath& path)
81    : path_(path),
82      weak_factory_(this) {
83}
84
85void SupportedAudioVideoChecker::OnFileOpen(base::File file) {
86  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
87  if (!file.IsValid()) {
88    callback_.Run(base::File::FILE_ERROR_SECURITY);
89    return;
90  }
91
92  safe_checker_ = new SafeAudioVideoChecker(file.Pass(), callback_);
93  safe_checker_->Start();
94}
95