Commit cdf40b4b authored by ben's avatar ben Committed by Commit bot

Enforce capability spec renderer <--> browser.

This implements:

- allows the content embedder to merge a manifest into the base ones provided by content, allowing it to add to the list of interfaces exposed to the renderer.
- adds such an overlay to chrome/browser

So.. from now on if you add an interface to either the browser/renderer, you'll need to list it in the manifest. I wonder how we should broadcast this. Also as a separate step we should require these manifests get security review.

R=rockot@chromium.org,tsepez@chromium.org

Committed: https://crrev.com/4ea17059bf78553528f3ffb4a9de84a447622fd3
Committed: https://crrev.com/807a926c9ca02ac8ae1b52e82537834ef78fb9ba
Committed: https://crrev.com/91c25a3cedc4fadcb8c84e91cc59a8f90411058a
Review-Url: https://codereview.chromium.org/2259903002
Cr-Original-Original-Original-Commit-Position: refs/heads/master@{#418282}
Cr-Original-Original-Commit-Position: refs/heads/master@{#418398}
Cr-Original-Commit-Position: refs/heads/master@{#418582}
Cr-Commit-Position: refs/heads/master@{#418691}
parent bf9fe707
......@@ -581,6 +581,7 @@
<include name="IDR_IME_WINDOW_CLOSE_C" file="resources\input_ime\ime_window_close_click.png" type="BINDATA" />
<include name="IDR_IME_WINDOW_CLOSE_H" file="resources\input_ime\ime_window_close_hover.png" type="BINDATA" />
</if>
<include name="IDR_CONTENT_BROWSER_MANIFEST_OVERLAY" file="content_browser_manifest_overlay.json" type="BINDATA" />
</includes>
</release>
</grit>
......@@ -14,6 +14,7 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/scoped_file.h"
#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
......@@ -106,6 +107,7 @@
#include "chrome/common/render_messages.h"
#include "chrome/common/secure_origin_whitelist.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/browser_resources.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/installer/util/google_update_settings.h"
#include "chromeos/chromeos_constants.h"
......@@ -162,6 +164,7 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/mojo_shell_connection.h"
#include "content/public/common/sandbox_type.h"
#include "content/public/common/service_names.h"
#include "content/public/common/url_utils.h"
#include "content/public/common/web_preferences.h"
#include "device/usb/public/interfaces/chooser_service.mojom.h"
......@@ -2964,6 +2967,21 @@ void ChromeContentBrowserClient::RegisterOutOfProcessMojoApplications(
#endif
}
std::unique_ptr<base::Value>
ChromeContentBrowserClient::GetServiceManifestOverlay(
const std::string& name) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
int id = -1;
if (name == content::kBrowserMojoApplicationName)
id = IDR_CONTENT_BROWSER_MANIFEST_OVERLAY;
if (id == -1)
return nullptr;
base::StringPiece manifest_contents =
rb.GetRawDataResourceForScale(id, ui::ScaleFactor::SCALE_FACTOR_NONE);
return base::JSONReader::Read(manifest_contents);
}
void ChromeContentBrowserClient::OpenURL(
content::BrowserContext* browser_context,
const content::OpenURLParams& params,
......
......@@ -299,6 +299,8 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
StaticMojoApplicationMap* apps) override;
void RegisterOutOfProcessMojoApplications(
OutOfProcessMojoApplicationMap* apps) override;
std::unique_ptr<base::Value> GetServiceManifestOverlay(
const std::string& name) override;
void OpenURL(content::BrowserContext* browser_context,
const content::OpenURLParams& params,
const base::Callback<void(content::WebContents*)>& callback)
......
{
"name": "exe:content_browser",
"capabilities": {
"provided": {
"web": [
"autofill::mojom::AutofillDriver",
"autofill::mojom::PasswordManagerDriver",
"extensions::StashService",
"metrics::mojom::LeakDetector",
"startup_metric_utils::mojom::StartupMetricHost",
"translate::mojom::ContentTranslateDriver"
]
}
}
}
......@@ -875,6 +875,8 @@ source_set("browser") {
"mime_registry_impl.h",
"mojo/interface_registrar_android.cc",
"mojo/interface_registrar_android.h",
"mojo/merge_dictionary.cc",
"mojo/merge_dictionary.h",
"mojo/mojo_shell_context.cc",
"mojo/mojo_shell_context.h",
"net/browser_online_state_observer.cc",
......
......@@ -26,13 +26,13 @@
#include "content/browser/push_messaging/push_messaging_router.h"
#include "content/browser/storage_partition_impl_map.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/mojo/constants.h"
#include "content/public/browser/blob_handle.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/site_instance.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/mojo_shell_connection.h"
#include "content/public/common/service_names.h"
#include "net/cookies/cookie_store.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/channel_id_store.h"
......
......@@ -38,7 +38,6 @@
#include "content/common/establish_channel_params.h"
#include "content/common/gpu_host_messages.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/common/mojo/constants.h"
#include "content/common/mojo/mojo_child_connection.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.h"
......@@ -55,6 +54,7 @@
#include "content/public/common/result_codes.h"
#include "content/public/common/sandbox_type.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_names.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/ipc/service/switches.h"
......
// Copyright 2016 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 "content/browser/mojo/merge_dictionary.h"
namespace content {
void MergeDictionary(base::DictionaryValue* target,
const base::DictionaryValue* source) {
for (base::DictionaryValue::Iterator it(*source); !it.IsAtEnd();
it.Advance()) {
const base::Value* merge_value = &it.value();
// Check whether we have to merge dictionaries.
if (merge_value->IsType(base::Value::TYPE_DICTIONARY)) {
base::DictionaryValue* sub_dict;
if (target->GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
MergeDictionary(
sub_dict,
static_cast<const base::DictionaryValue*>(merge_value));
continue;
}
}
if (merge_value->IsType(base::Value::TYPE_LIST)) {
const base::ListValue* merge_list = nullptr;
if (merge_value->GetAsList(&merge_list)) {
base::ListValue* target_list = nullptr;
CHECK(target->GetListWithoutPathExpansion(it.key(), &target_list));
if (target_list) {
for (size_t i = 0; i < merge_list->GetSize(); ++i) {
std::string value;
CHECK(merge_list->GetString(i, &value));
target_list->AppendString(value);
}
}
}
} else {
// All other cases: Make a copy and hook it up.
target->SetWithoutPathExpansion(it.key(), merge_value->DeepCopy());
}
}
}
} // namespace content
// Copyright 2016 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.
#ifndef CONTENT_BROWSER_MOJO_MERGE_DICTIONARY_H_
#define CONTENT_BROWSER_MOJO_MERGE_DICTIONARY_H_
#include "base/values.h"
#include "content/common/content_export.h"
namespace content {
// Similar to base::DictionaryValue::MergeDictionary(), except concatenates
// ListValue contents.
// This is explicitly not part of base::DictionaryValue at brettw's request.
void CONTENT_EXPORT MergeDictionary(base::DictionaryValue* target,
const base::DictionaryValue* source);
} // namespace content
#endif // CONTENT_BROWSER_MOJO_MERGE_DICTIONARY_H_
// Copyright 2016 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 "base/memory/ptr_util.h"
#include "content/browser/mojo/merge_dictionary.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
using MergeDictionaryTest = testing::Test;
TEST(MergeDictionaryTest, Merge) {
// |source| & |target| have three properties, "string", "list" and
// "dictionary", which are then merged.
base::DictionaryValue target;
target.SetString("string", "Hello, ");
std::unique_ptr<base::DictionaryValue> dict_value_original(
base::MakeUnique<base::DictionaryValue>());
dict_value_original->SetString("key1", "original");
dict_value_original->SetString("key3", "original");
target.Set("dictionary", std::move(dict_value_original));
std::unique_ptr<base::ListValue> list(base::MakeUnique<base::ListValue>());
list->AppendString("A");
list->AppendString("B");
target.Set("list", std::move(list));
base::DictionaryValue source;
source.SetString("string", "World!");
std::unique_ptr<base::DictionaryValue> dict_value_replacement(
base::MakeUnique<base::DictionaryValue>());
dict_value_replacement->SetString("key1", "new");
dict_value_replacement->SetString("key2", "new");
source.Set("dictionary", std::move(dict_value_replacement));
list = base::MakeUnique<base::ListValue>();
list->AppendString("C");
source.Set("list", std::move(list));
MergeDictionary(&target, &source);
// Simple string value should have been clobbered.
std::string out_string;
EXPECT_TRUE(target.GetString("string", &out_string));
EXPECT_EQ(out_string, "World!");
// Dictionary should have been merged, with key1 being clobbered, key2 added
// and key3 preserved.
base::DictionaryValue* out_dictionary = nullptr;
EXPECT_TRUE(target.GetDictionary("dictionary", &out_dictionary));
EXPECT_EQ(3u, out_dictionary->size());
std::string value1, value2, value3;
EXPECT_TRUE(out_dictionary->GetString("key1", &value1));
EXPECT_TRUE(out_dictionary->GetString("key2", &value2));
EXPECT_TRUE(out_dictionary->GetString("key3", &value3));
EXPECT_EQ(value1, "new");
EXPECT_EQ(value2, "new");
EXPECT_EQ(value3, "original");
// List should have been merged, with the items from source appended to the
// items from target.
base::ListValue* out_list = nullptr;
EXPECT_TRUE(target.GetList("list", &out_list));
EXPECT_EQ(3u, out_list->GetSize());
std::string a, b, c;
EXPECT_TRUE(out_list->GetString(0, &a));
EXPECT_TRUE(out_list->GetString(1, &b));
EXPECT_TRUE(out_list->GetString(2, &c));
EXPECT_EQ("A", a);
EXPECT_EQ("B", b);
EXPECT_EQ("C", c);
}
} // namespace content
......@@ -9,12 +9,13 @@
#include <utility>
#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/common/mojo/constants.h"
#include "content/browser/mojo/merge_dictionary.h"
#include "content/common/mojo/mojo_shell_connection_impl.h"
#include "content/grit/content_resources.h"
#include "content/public/browser/browser_thread.h"
......@@ -23,6 +24,7 @@
#include "content/public/browser/utility_process_host_client.h"
#include "content/public/common/content_client.h"
#include "content/public/common/mojo_shell_connection.h"
#include "content/public/common/service_names.h"
#include "mojo/edk/embedder/embedder.h"
#include "services/catalog/catalog.h"
#include "services/catalog/manifest_provider.h"
......@@ -126,15 +128,28 @@ class BuiltinManifestProvider : public catalog::ManifestProvider {
private:
// catalog::ManifestProvider:
bool GetApplicationManifest(const base::StringPiece& name,
std::string* manifest_contents) override {
auto manifest_it = manifests_->find(name.as_string());
if (manifest_it != manifests_->end()) {
*manifest_contents = manifest_it->second;
DCHECK(!manifest_contents->empty());
return true;
std::unique_ptr<base::Value> GetManifest(const std::string& name) override {
auto manifest_it = manifests_->find(name);
std::unique_ptr<base::Value> manifest_root;
if (manifest_it != manifests_->end())
manifest_root = base::JSONReader::Read(manifest_it->second);
base::DictionaryValue* manifest_dictionary = nullptr;
if (manifest_root && !manifest_root->GetAsDictionary(&manifest_dictionary))
return nullptr;
std::unique_ptr<base::Value> overlay_root =
GetContentClient()->browser()->GetServiceManifestOverlay(name);
if (overlay_root) {
if (!manifest_root) {
manifest_root = std::move(overlay_root);
} else {
base::DictionaryValue* overlay_dictionary = nullptr;
if (overlay_root->GetAsDictionary(&overlay_dictionary))
MergeDictionary(manifest_dictionary, overlay_dictionary);
}
}
return false;
return manifest_root;
}
std::unique_ptr<ContentBrowserClient::MojoApplicationManifestMap> manifests_;
......
......@@ -23,7 +23,6 @@
#include "content/common/child_process_host_impl.h"
#include "content/common/child_process_messages.h"
#include "content/common/content_switches_internal.h"
#include "content/common/mojo/constants.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
......@@ -32,6 +31,7 @@
#include "content/public/common/process_type.h"
#include "content/public/common/sandbox_type.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_names.h"
#include "ipc/ipc_switches.h"
#include "mojo/edk/embedder/embedder.h"
#include "net/base/network_change_notifier.h"
......
......@@ -130,7 +130,6 @@
#include "content/common/frame_messages.h"
#include "content/common/gpu_host_messages.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/common/mojo/constants.h"
#include "content/common/mojo/mojo_child_connection.h"
#include "content/common/mojo/mojo_shell_connection_impl.h"
#include "content/common/render_process_messages.h"
......@@ -160,6 +159,7 @@
#include "content/public/common/resource_type.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_names.h"
#include "content/public/common/url_constants.h"
#include "device/battery/battery_monitor_impl.h"
#include "gpu/GLES2/gl2extchromium.h"
......
......@@ -26,7 +26,6 @@
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/common/mojo/constants.h"
#include "content/common/mojo/mojo_child_connection.h"
#include "content/common/utility_messages.h"
#include "content/public/browser/browser_thread.h"
......@@ -38,6 +37,7 @@
#include "content/public/common/process_type.h"
#include "content/public/common/sandbox_type.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_names.h"
#include "ipc/ipc_switches.h"
#include "mojo/edk/embedder/embedder.h"
#include "services/shell/public/cpp/connection.h"
......
......@@ -51,11 +51,11 @@
#include "content/child/thread_safe_sender.h"
#include "content/common/child_process_messages.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/common/mojo/constants.h"
#include "content/public/common/connection_filter.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/mojo_channel_switches.h"
#include "content/public/common/mojo_shell_connection.h"
#include "content/public/common/service_names.h"
#include "ipc/attachment_broker.h"
#include "ipc/attachment_broker_unprivileged.h"
#include "ipc/ipc_channel_mojo.h"
......
......@@ -216,8 +216,6 @@ source_set("common") {
"media/video_capture_messages.h",
"memory_messages.h",
"message_port_messages.h",
"mojo/constants.cc",
"mojo/constants.h",
"mojo/embedded_application_runner.cc",
"mojo/embedded_application_runner.h",
"mojo/mojo_shell_connection_impl.cc",
......
......@@ -18,11 +18,11 @@
#include "content/child/thread_safe_sender.h"
#include "content/common/establish_channel_params.h"
#include "content/common/gpu_host_messages.h"
#include "content/common/mojo/constants.h"
#include "content/gpu/gpu_service_factory.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/mojo_shell_connection.h"
#include "content/public/common/service_names.h"
#include "content/public/gpu/content_gpu_client.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/sync_point_manager.h"
......
per-file *.json=set noparent
per-file *.json=file://ipc/SECURITY_OWNERS
......@@ -6,7 +6,27 @@
"capabilities": {
// Remove this once http://crbug.com/632818 is fixed.
"provided": {
"all_interfaces": [ "*" ]
"all_interfaces": [ "*" ],
"web": [
"blink::mojom::BackgroundSyncService",
"blink::mojom::BroadcastChannelProvider",
"blink::mojom::BudgetService",
"blink::mojom::MimeRegistry",
"blink::mojom::NotificationService",
"blink::mojom::OffscreenCanvasFrameReceiver",
"blink::mojom::OffscreenCanvasSurface",
"blink::mojom::PermissionService",
"blink::mojom::WebSocket",
"content::mojom::LayoutTestBluetoothFakeAdapterSetter",
"content::mojom::StoragePartitionService",
"content::mojom::URLLoaderFactory",
"device::BatteryMonitor",
"device::mojom::LightSensor",
"device::mojom::MotionSensor",
"device::mojom::OrientationSensor",
"media::mojom::ImageCapture",
"memory_coordinator::mojom::MemoryCoordinatorHandle"
]
},
"required": {
"*": { "classes": [ "app" ] },
......@@ -15,7 +35,7 @@
// processes.
"exe:content_gpu": { "classes": [ "all_interfaces" ] },
"exe:content_plugin": { "classes": [ "all_interfaces" ] },
"exe:content_renderer": { "classes": [ "all_interfaces" ] },
"exe:content_renderer": { "classes": [ "browser" ] },
"exe:content_utility": { "classes": [ "all_interfaces" ] },
"mojo:shell": {
......
......@@ -4,12 +4,20 @@
"display_name": "Content Renderer",
"capabilities": {
"provided": {
"all_interfaces": [ "*" ]
"all_interfaces": [ "*" ],
"browser": [
"content::mojom::EmbeddedWorkerSetup",
"content::mojom::FrameFactory",
"content::mojom::TestMojoService",
"IPC::mojom::ChannelBootstrap",
"mojom::ResourceUsageReporter",
"web_cache::mojom::WebCache"
]
},
"required": {
// Remove this once http://crbug.com/632818 is fixed.
"exe:content_browser": {
"classes": [ "all_interfaces" ]
"classes": [ "web" ]
},
"mojo:ui": {
"interfaces": [
......
......@@ -428,4 +428,10 @@ ContentBrowserClient::OverrideCreateExternalVideoSurfaceContainer(
}
#endif
std::unique_ptr<base::Value> ContentBrowserClient::GetServiceManifestOverlay(
const std::string& name) {
return nullptr;
}
} // namespace content
......@@ -717,6 +717,13 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual void RegisterMojoApplicationManifests(
MojoApplicationManifestMap* manifests) {}
// Allow the embedder to provide a dictionary loaded from a JSON file
// resembling a service manifest whose capabilities section will be merged
// with content's own for |name|. Additional entries will be appended to their
// respective sections.
virtual std::unique_ptr<base::Value> GetServiceManifestOverlay(
const std::string& name);
// Allows to override the visibility state of a RenderFrameHost.
// |visibility_state| should not be null. It will only be set if needed.
virtual void OverridePageVisibilityState(
......
......@@ -196,6 +196,8 @@ source_set("common_sources") {
"screen_orientation_values.h",
"security_style.h",
"send_zygote_child_ping_linux.h",
"service_names.cc",
"service_names.h",
"speech_recognition_error.h",
"speech_recognition_grammar.h",
"speech_recognition_result.cc",
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/common/mojo/constants.h"
#include "content/public/common/service_names.h"
namespace content {
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_COMMON_MOJO_CONSTANTS_H_
#define CONTENT_COMMON_MOJO_CONSTANTS_H_
#ifndef CONTENT_PUBLIC_COMMON_SERVICE_NAMES_H_
#define CONTENT_PUBLIC_COMMON_SERVICE_NAMES_H_
#include "content/common/content_export.h"
......@@ -17,4 +17,4 @@ extern const char CONTENT_EXPORT kUtilityMojoApplicationName[];
} // namespace content
#endif // CONTENT_COMMON_MOJO_CONSTANTS_H_
#endif // CONTENT_PUBLIC_COMMON_SERVICE_NAMES_H_
......@@ -19,7 +19,6 @@
#include "cc/output/buffer_to_texture_target_map.h"
#include "content/app/mojo/mojo_init.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/common/mojo/constants.h"
#include "content/common/mojo/mojo_child_connection.h"
#include "content/common/resource_messages.h"
#include "content/public/browser/browser_thread.h"
......@@ -27,6 +26,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/mojo_shell_connection.h"
#include "content/public/common/service_names.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_content_client_initializer.h"
......
......@@ -1095,6 +1095,7 @@ test("content_unittests") {
"../browser/media/session/audio_focus_manager_unittest.cc",
"../browser/media/session/media_session_controller_unittest.cc",
"../browser/media/session/media_session_uma_helper_unittest.cc",
"../browser/mojo/merge_dictionary_unittest.cc",
"../browser/net/quota_policy_cookie_store_unittest.cc",
"../browser/notification_service_impl_unittest.cc",
"../browser/notifications/notification_database_data_unittest.cc",
......
......@@ -7,7 +7,9 @@
#include <string>
#include "base/strings/string_piece.h"
namespace base {
class Value;
}
namespace catalog {
......@@ -20,8 +22,7 @@ class ManifestProvider {
// Retrieves the raw contents of the manifest for application named |name|.
// Returns true if |name| is known and |*manifest_contents| is populated.
// returns false otherwise.
virtual bool GetApplicationManifest(const base::StringPiece& name,
std::string* manifest_contents) = 0;
virtual std::unique_ptr<base::Value> GetManifest(const std::string& name) = 0;
};
} // namespace catalog
......
......@@ -178,25 +178,24 @@ void Reader::CreateEntryForName(
const std::string& mojo_name,
EntryCache* cache,
const CreateEntryForNameCallback& entry_created_callback) {
std::string manifest_contents;
if (manifest_provider_ &&
manifest_provider_->GetApplicationManifest(mojo_name,
&manifest_contents)) {
if (manifest_provider_) {
std::unique_ptr<base::Value> manifest_root =
base::JSONReader::Read(manifest_contents);
base::PostTaskAndReplyWithResult(
file_task_runner_.get(), FROM_HERE,
base::Bind(&ProcessManifest, base::Passed(&manifest_root),
system_package_dir_),
base::Bind(&Reader::OnReadManifest, weak_factory_.GetWeakPtr(), cache,
entry_created_callback));
} else {
base::PostTaskAndReplyWithResult(
file_task_runner_.get(), FROM_HERE,
base::Bind(&ReadManifest, system_package_dir_, mojo_name),
base::Bind(&Reader::OnReadManifest, weak_factory_.GetWeakPtr(), cache,
entry_created_callback));
manifest_provider_->GetManifest(mojo_name);
if (manifest_root) {
base::PostTaskAndReplyWithResult(
file_task_runner_.get(), FROM_HERE,
base::Bind(&ProcessManifest, base::Passed(&manifest_root),
system_package_dir_),
base::Bind(&Reader::OnReadManifest, weak_factory_.GetWeakPtr(), cache,
entry_created_callback));
return;
}
}
base::PostTaskAndReplyWithResult(
file_task_runner_.get(), FROM_HERE,
base::Bind(&ReadManifest, system_package_dir_, mojo_name),
base::Bind(&Reader::OnReadManifest, weak_factory_.GetWeakPtr(), cache,
entry_created_callback));
}
Reader::Reader(ManifestProvider* manifest_provider)
......
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