| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" | 5 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <algorithm> |
| 8 #include <utility> |
| 8 | 9 |
| 10 #include "base/strings/string_split.h" |
| 9 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 10 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 11 #include "net/base/escape.h" | 13 #include "net/base/escape.h" |
| 14 #include "net/base/mime_util.h" |
| 12 #include "storage/browser/fileapi/file_system_url.h" | 15 #include "storage/browser/fileapi/file_system_url.h" |
| 13 #include "url/gurl.h" | 16 #include "url/gurl.h" |
| 14 | 17 |
| 15 namespace arc { | 18 namespace arc { |
| 16 | 19 |
| 20 namespace { |
| 21 |
| 22 struct MimeTypeToExtensions { |
| 23 const char* mime_type; |
| 24 const char* extensions; |
| 25 }; |
| 26 |
| 27 // The mapping from MIME types to file name extensions, taken from Android N. |
| 28 // See: frameworks/base/media/java/android/media/MediaFile.java |
| 29 constexpr MimeTypeToExtensions kAndroidMimeTypeMappings[] = { |
| 30 {"application/mspowerpoint", "ppt"}, |
| 31 {"application/msword", "doc"}, |
| 32 {"application/ogg", "ogg,oga"}, |
| 33 {"application/pdf", "pdf"}, |
| 34 {"application/vnd.apple.mpegurl", "m3u8"}, |
| 35 {"application/vnd.ms-excel", "xls"}, |
| 36 {"application/vnd.ms-wpl", "wpl"}, |
| 37 {"application/x-android-drm-fl", "fl"}, |
| 38 {"application/x-mpegurl", "m3u"}, |
| 39 {"application/zip", "zip"}, |
| 40 {"audio/aac", "aac"}, |
| 41 {"audio/aac-adts", "aac"}, |
| 42 {"audio/amr", "amr"}, |
| 43 {"audio/amr-wb", "awb"}, |
| 44 {"audio/flac", "flac"}, |
| 45 {"audio/imelody", "imy"}, |
| 46 {"audio/midi", "mid,midi,xmf,rtttl,rtx,ota,mxmf"}, |
| 47 {"audio/mp4", "m4a"}, |
| 48 {"audio/mpeg", "mp3,mpga"}, |
| 49 {"audio/mpegurl", "m3u8"}, |
| 50 {"audio/ogg", "ogg"}, |
| 51 {"audio/sp-midi", "smf"}, |
| 52 {"audio/x-matroska", "mka"}, |
| 53 {"audio/x-mpegurl", "m3u,m3u8"}, |
| 54 {"audio/x-ms-wma", "wma"}, |
| 55 {"audio/x-scpls", "pls"}, |
| 56 {"audio/x-wav", "wav"}, |
| 57 {"image/gif", "gif"}, |
| 58 {"image/jpeg", "jpg,jpeg"}, |
| 59 {"image/png", "png"}, |
| 60 {"image/vnd.wap.wbmp", "wbmp"}, |
| 61 {"image/webp", "webp"}, |
| 62 {"image/x-adobe-dng", "dng"}, |
| 63 {"image/x-canon-cr2", "cr2"}, |
| 64 {"image/x-fuji-raf", "raf"}, |
| 65 {"image/x-ms-bmp", "bmp"}, |
| 66 {"image/x-nikon-nef", "nef"}, |
| 67 {"image/x-nikon-nrw", "nrw"}, |
| 68 {"image/x-olympus-orf", "orf"}, |
| 69 {"image/x-panasonic-rw2", "rw2"}, |
| 70 {"image/x-pentax-pef", "pef"}, |
| 71 {"image/x-samsung-srw", "srw"}, |
| 72 {"image/x-sony-arw", "arw"}, |
| 73 {"text/html", "html,htm"}, |
| 74 {"text/plain", "txt"}, |
| 75 {"video/3gpp", "3gp,3gpp"}, |
| 76 {"video/3gpp2", "3g2,3gpp2"}, |
| 77 {"video/avi", "avi"}, |
| 78 {"video/mp2p", "mpg,mpeg"}, |
| 79 {"video/mp2ts", "ts"}, |
| 80 {"video/mp4", "mp4,m4v"}, |
| 81 {"video/mpeg", "mpg,mpeg"}, |
| 82 {"video/quicktime", "mov"}, |
| 83 {"video/webm", "webm"}, |
| 84 {"video/x-matroska", "mkv"}, |
| 85 {"video/x-ms-asf", "asf"}, |
| 86 {"video/x-ms-wmv", "wmv"}, |
| 87 }; |
| 88 |
| 89 constexpr char kApplicationOctetStreamMimeType[] = "application/octet-stream"; |
| 90 |
| 91 } // namespace |
| 92 |
| 17 // This is based on net/base/escape.cc: net::(anonymous namespace)::Escape. | 93 // This is based on net/base/escape.cc: net::(anonymous namespace)::Escape. |
| 18 // TODO(nya): Consider consolidating this function with EscapeFileSystemId() in | 94 // TODO(nya): Consider consolidating this function with EscapeFileSystemId() in |
| 19 // chrome/browser/chromeos/file_system_provider/mount_path_util.cc. | 95 // chrome/browser/chromeos/file_system_provider/mount_path_util.cc. |
| 20 // This version differs from the other one in the point that dots are not always | 96 // This version differs from the other one in the point that dots are not always |
| 21 // escaped because authorities often contain harmless dots. | 97 // escaped because authorities often contain harmless dots. |
| 22 std::string EscapePathComponent(const std::string& name) { | 98 std::string EscapePathComponent(const std::string& name) { |
| 23 std::string escaped; | 99 std::string escaped; |
| 24 // Escape dots only when they forms a special file name. | 100 // Escape dots only when they forms a special file name. |
| 25 if (name == "." || name == "..") { | 101 if (name == "." || name == "..") { |
| 26 base::ReplaceChars(name, ".", "%2E", &escaped); | 102 base::ReplaceChars(name, ".", "%2E", &escaped); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 } | 168 } |
| 93 | 169 |
| 94 GURL BuildDocumentUrl(const std::string& authority, | 170 GURL BuildDocumentUrl(const std::string& authority, |
| 95 const std::string& document_id) { | 171 const std::string& document_id) { |
| 96 return GURL(base::StringPrintf( | 172 return GURL(base::StringPrintf( |
| 97 "content://%s/document/%s", | 173 "content://%s/document/%s", |
| 98 net::EscapeQueryParamValue(authority, false /* use_plus */).c_str(), | 174 net::EscapeQueryParamValue(authority, false /* use_plus */).c_str(), |
| 99 net::EscapeQueryParamValue(document_id, false /* use_plus */).c_str())); | 175 net::EscapeQueryParamValue(document_id, false /* use_plus */).c_str())); |
| 100 } | 176 } |
| 101 | 177 |
| 178 std::vector<base::FilePath::StringType> GetExtensionsForArcMimeType( |
| 179 const std::string& mime_type) { |
| 180 // net::GetExtensionsForMimeType() returns unwanted extensions like |
| 181 // "exe,com,bin" for application/octet-stream. |
| 182 if (net::MatchesMimeType(kApplicationOctetStreamMimeType, mime_type)) |
| 183 return std::vector<base::FilePath::StringType>(); |
| 184 |
| 185 // Attempt net::GetExtensionsForMimeType(). |
| 186 { |
| 187 std::vector<base::FilePath::StringType> extensions; |
| 188 net::GetExtensionsForMimeType(mime_type, &extensions); |
| 189 if (!extensions.empty()) { |
| 190 base::FilePath::StringType preferred_extension; |
| 191 if (net::GetPreferredExtensionForMimeType(mime_type, |
| 192 &preferred_extension)) { |
| 193 auto iter = std::find(extensions.begin(), extensions.end(), |
| 194 preferred_extension); |
| 195 if (iter == extensions.end()) { |
| 196 // This is unlikely to happen, but there is no guarantee. |
| 197 extensions.insert(extensions.begin(), preferred_extension); |
| 198 } else { |
| 199 std::swap(extensions.front(), *iter); |
| 200 } |
| 201 } |
| 202 return extensions; |
| 203 } |
| 204 } |
| 205 |
| 206 // Fallback to our hard-coded list. |
| 207 for (const auto& entry : kAndroidMimeTypeMappings) { |
| 208 if (net::MatchesMimeType(entry.mime_type, mime_type)) { |
| 209 // We assume base::FilePath::StringType == std::string as this code is |
| 210 // built only on Chrome OS. |
| 211 return base::SplitString(entry.extensions, ",", base::TRIM_WHITESPACE, |
| 212 base::SPLIT_WANT_ALL); |
| 213 } |
| 214 } |
| 215 |
| 216 return std::vector<base::FilePath::StringType>(); |
| 217 } |
| 218 |
| 102 } // namespace arc | 219 } // namespace arc |
| OLD | NEW |