Commit f1319807 authored by Trent Apted's avatar Trent Apted Committed by Commit Bot

When enabled, open chrome://media-app rather than Gallery.

Principally, this ensures that the Camera App opens the correct "camera
roll" app, depending on whether the "Media App" SWA is enabled. It
does this by intercepting the request to executeTask with the Gallery
app, but allows the Gallery app to still open RAW image file types.

No effect when chrome://flags#media-app is not enabled.

Except for RAW files, we will hide the Gallery as a file handler
option in the files app in a follow-up so that users are not
confused why selecting it also results in the Media App being
launched.

Bug: 1030935, b/153387960
Change-Id: Ibe63455e8dd247769fabd123edb4925b8bae3739
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2143417
Commit-Queue: Trent Apted <tapted@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759170}
parent 1fb4dd0e
...@@ -12,12 +12,17 @@ ...@@ -12,12 +12,17 @@
#include <vector> #include <vector>
#include "base/bind.h" #include "base/bind.h"
#include "base/feature_list.h"
#include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend.h" #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/common/extensions/api/file_manager_private.h" #include "chrome/common/extensions/api/file_manager_private.h"
#include "chrome/common/extensions/api/file_manager_private_internal.h" #include "chrome/common/extensions/api/file_manager_private_internal.h"
#include "chromeos/constants/chromeos_features.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/file_handlers/directory_util.h" #include "extensions/browser/api/file_handlers/directory_util.h"
#include "extensions/browser/api/file_handlers/mime_util.h" #include "extensions/browser/api/file_handlers/mime_util.h"
...@@ -65,6 +70,56 @@ std::set<std::string> GetUniqueMimeTypes( ...@@ -65,6 +70,56 @@ std::set<std::string> GetUniqueMimeTypes(
return mime_types; return mime_types;
} }
// Returns whether |url| is a RAW image file according to its extension. Note
// that since none of the extensions of interest are "known" mime types (per
// net/mime_util.cc), it's enough to simply check the extension rather than
// using MimeTypeCollector. TODO(crbug/1030935): Remove this.
bool IsRawImage(const FileSystemURL& url) {
constexpr const char* kRawExtensions[] = {".arw", ".cr2", ".dng", ".nef",
".nrw", ".orf", ".raf", ".rw2"};
return base::Contains(kRawExtensions, url.path().Extension());
}
// Intercepts usage of executeTask(..) that wants to invoke the old "Gallery"
// chrome app. If the media app is enabled, substitute it.
// TODO(crbug/1030935): Remove this when the gallery app is properly removed and
// the camera app has a new API (not fileManagerPrivate) to invoke its
// "Camera Roll" viewer.
void MaybeAdjustTaskForGalleryAppRemoval(
file_manager::file_tasks::TaskDescriptor* task,
const std::vector<FileSystemURL>& urls,
Profile* profile) {
if (!base::FeatureList::IsEnabled(chromeos::features::kMediaApp))
return;
if (task->app_id != file_manager::kGalleryAppId)
return;
DCHECK_EQ(task->task_type, file_manager::file_tasks::TASK_TYPE_FILE_HANDLER);
// Filter out any request with a RAW image type of a kind that the Gallery
// is known to register as a handler. Although from a product perspective, the
// Gallery should be entirely hidden, we still direct RAW images to Gallery
// until chrome://media-app supports them.
if (std::find_if(urls.begin(), urls.end(), &IsRawImage) != urls.end())
return;
auto* provider = web_app::WebAppProvider::Get(profile);
DCHECK(provider);
base::Optional<web_app::AppId> optional_app_id =
provider->system_web_app_manager().GetAppIdForSystemApp(
web_app::SystemAppType::MEDIA);
DCHECK(optional_app_id);
// Even if the flag is enabled, app installation can sometimes fail. Don't
// crash in that case. See https://crbug.com/1024042.
if (!optional_app_id)
return;
task->task_type = file_manager::file_tasks::TASK_TYPE_WEB_APP;
task->app_id = *optional_app_id;
}
} // namespace } // namespace
FileManagerPrivateInternalExecuteTaskFunction:: FileManagerPrivateInternalExecuteTaskFunction::
...@@ -103,6 +158,9 @@ FileManagerPrivateInternalExecuteTaskFunction::Run() { ...@@ -103,6 +158,9 @@ FileManagerPrivateInternalExecuteTaskFunction::Run() {
urls.push_back(url); urls.push_back(url);
} }
MaybeAdjustTaskForGalleryAppRemoval(&task, urls,
chrome_details_.GetProfile());
const bool result = file_manager::file_tasks::ExecuteFileTask( const bool result = file_manager::file_tasks::ExecuteFileTask(
chrome_details_.GetProfile(), source_url(), task, urls, chrome_details_.GetProfile(), source_url(), task, urls,
base::BindOnce( base::BindOnce(
......
{
// chrome-extension://pkplfbidichfdicaijlchgnapepdginl
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtDfX9dHNh948bt00YhZBm3P6E5QLaOt+v8kXVtibQfiPtOD2FTScB/f0wX/EQWVO7BkaSOsRkTPcPIgocyMPYr2FLgqGLFlYT9nQpKJZUFNF5oJ5rG6Nv7ppf4zEB3j6da1IBRTz2yOZ+6O1TMZxol/V62/QcqrJeggsHTEPGLdr9Ua4b1Ka0xKJnJngZljsbw93FI1o+P9dAh5BS6wTPiZI/vmJVjvMTkSTnaZ3n9Go2t7A0XLcSxLcVyuLAd2mAvSN0mIviOukdM66wr7llif71nKuUt+4qvlr/r9HfwzN6pA4jkwhtS1UD+3CmB+wsHwsnohNcuu4FIQ6rgq/7QIDAQAB",
"name": "chrome.fileManagerPrivate tests",
"version": "0.1",
"manifest_version": 2,
"description": "Tests of chrome.fileManagerPrivate.* component extension methods",
"app": {
"background": {
"scripts": ["test.js"]
}
},
"permissions": [
"fileManagerPrivate",
{
"fileSystem": ["requestFileSystem"]
}
]
}
// Copyright 2020 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.
/**
* Runs tests to verify that file browser tasks for natively supported file
* types are handled by the appropriate default-installed system app.
*/
const kTestPng = 'test_dir/test_file.png';
const kTestRawImage = 'test_dir/test_file.arw';
/**
* Finds the `volumeType` volume then resolves the provided `path` as an Entry.
*/
function getFileEntry(volumeType, path) {
return new Promise(resolve => {
chrome.fileManagerPrivate.getVolumeMetadataList(list => {
const volume = list.find(v => v.volumeType === volumeType);
chrome.test.assertTrue(!!volume, `${volumeType} volume not found.`);
chrome.fileSystem.requestFileSystem({volumeId: volume.volumeId}, fs => {
fs.root.getFile(
path, {},
entry => {
resolve(entry);
},
fileError => {
chrome.test.fail(
`Unable to getFile "${path}": ${fileError.message}`);
});
});
});
});
}
/**
* A method the camera app uses to open its "camera roll". Instrumented for
* testing. See chromeos/camera/src/js/browser_proxy/browser_proxy.js.
*/
function openGallery(entry) {
// "nlkncpkkdoccmpiclbokaimcnedabhhm" is the Gallery component chrome app's
// extension ID. This task id is hard-coded in the Camera component app.
const id = 'nlkncpkkdoccmpiclbokaimcnedabhhm|app|open';
function taskCallback(taskResult) {
chrome.test.assertEq(
chrome.fileManagerPrivate.TaskResult.MESSAGE_SENT, taskResult);
chrome.test.succeed();
}
chrome.fileManagerPrivate.executeTask(id, [entry], taskCallback);
}
function testPngOpensGallery() {
getFileEntry('testing', kTestPng).then(openGallery);
}
function testRawOpensGallery() {
getFileEntry('testing', kTestRawImage).then(openGallery);
}
// Handle the case where JSTestStarter has already injected a test to run.
if (self.testNameToRun) {
chrome.test.runTests([self[testNameToRun]]);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment