1 // Copyright 2014 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 "mojo/tools/package_manager/package_manager_application.h" 6 7 #include "base/files/file_util.h" 8 #include "mojo/tools/package_manager/manifest.h" 9 #include "mojo/tools/package_manager/unpacker.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/stl_util.h" 12 #include "mojo/public/cpp/application/application_impl.h" 13 14 namespace mojo { 15 16 namespace { 17 18 const base::FilePath::CharType kManifestFileName[] = 19 FILE_PATH_LITERAL("manifest.json"); 20 21 } // namespace 22 23 PackageManagerApplication::PendingLoad::PendingLoad() { 24 } 25 26 PackageManagerApplication::PendingLoad::~PendingLoad() { 27 } 28 29 PackageManagerApplication::PackageManagerApplication() { 30 } 31 32 PackageManagerApplication::~PackageManagerApplication() { 33 STLDeleteContainerPairSecondPointers(pending_.begin(), pending_.end()); 34 } 35 36 void PackageManagerApplication::Initialize(ApplicationImpl* app) { 37 app->ConnectToService("mojo:mojo_network_service", &network_service_); 38 39 printf("Enter URL> "); 40 char buf[1024]; 41 if (scanf("%1023s", buf) != 1) { 42 printf("No input, exiting\n"); 43 base::MessageLoop::current()->Quit(); 44 return; 45 } 46 GURL url(buf); 47 if (!url.is_valid()) { 48 printf("Invalid URL\n"); 49 base::MessageLoop::current()->Quit(); 50 return; 51 } 52 53 StartLoad(url); 54 } 55 56 void PackageManagerApplication::StartLoad(const GURL& url) { 57 if (completed_.find(url) != completed_.end() || 58 pending_.find(url) != pending_.end()) 59 return; // Already loaded or are loading this one. 60 61 PendingLoad* load = new PendingLoad; 62 load->fetcher.reset(new mojo::PackageFetcher( 63 network_service_.get(), this, url)); 64 pending_[url] = load; 65 } 66 67 void PackageManagerApplication::LoadDeps(const Manifest& manifest) { 68 for (size_t i = 0; i < manifest.deps().size(); i++) 69 StartLoad(manifest.deps()[i]); 70 } 71 72 void PackageManagerApplication::PendingLoadComplete(const GURL& url) { 73 pending_.erase(pending_.find(url)); 74 completed_.insert(url); 75 if (pending_.empty()) 76 base::MessageLoop::current()->Quit(); 77 } 78 79 void PackageManagerApplication::FetchSucceeded( 80 const GURL& url, 81 const base::FilePath& name) { 82 Unpacker unpacker; 83 if (!unpacker.Unpack(name)) { 84 base::DeleteFile(name, false); 85 printf("Failed to unpack\n"); 86 PendingLoadComplete(url); 87 return; 88 } 89 // The downloaded .zip file is no longer necessary. 90 base::DeleteFile(name, false); 91 92 // Load the manifest. 93 base::FilePath manifest_path = unpacker.dir().Append(kManifestFileName); 94 Manifest manifest; 95 std::string err_msg; 96 if (!manifest.ParseFromFile(manifest_path, &err_msg)) { 97 printf("%s\n", err_msg.c_str()); 98 PendingLoadComplete(url); 99 return; 100 } 101 102 // Enqueue loads for any deps. 103 LoadDeps(manifest); 104 105 printf("Loaded %s\n", url.spec().c_str()); 106 PendingLoadComplete(url); 107 } 108 109 void PackageManagerApplication::FetchFailed(const GURL& url) { 110 PendingLoadComplete(url); 111 } 112 113 } // namespace mojo 114