11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/tools/package_manager/package_manager_application.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/tools/package_manager/manifest.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/tools/package_manager/unpacker.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/message_loop/message_loop.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/stl_util.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/public/cpp/application/application_impl.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace mojo {
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst base::FilePath::CharType kManifestFileName[] =
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FILE_PATH_LITERAL("manifest.json");
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPackageManagerApplication::PendingLoad::PendingLoad() {
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPackageManagerApplication::PendingLoad::~PendingLoad() {
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPackageManagerApplication::PackageManagerApplication() {
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPackageManagerApplication::~PackageManagerApplication() {
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  STLDeleteContainerPairSecondPointers(pending_.begin(), pending_.end());
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageManagerApplication::Initialize(ApplicationImpl* app) {
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  app->ConnectToService("mojo:mojo_network_service", &network_service_);
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  printf("Enter URL> ");
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  char buf[1024];
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (scanf("%1023s", buf) != 1) {
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    printf("No input, exiting\n");
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::MessageLoop::current()->Quit();
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL url(buf);
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!url.is_valid()) {
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    printf("Invalid URL\n");
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::MessageLoop::current()->Quit();
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StartLoad(url);
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageManagerApplication::StartLoad(const GURL& url) {
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (completed_.find(url) != completed_.end() ||
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pending_.find(url) != pending_.end())
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;  // Already loaded or are loading this one.
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PendingLoad* load = new PendingLoad;
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load->fetcher.reset(new mojo::PackageFetcher(
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      network_service_.get(), this, url));
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_[url] = load;
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageManagerApplication::LoadDeps(const Manifest& manifest) {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < manifest.deps().size(); i++)
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    StartLoad(manifest.deps()[i]);
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageManagerApplication::PendingLoadComplete(const GURL& url) {
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_.erase(pending_.find(url));
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  completed_.insert(url);
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (pending_.empty())
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::MessageLoop::current()->Quit();
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageManagerApplication::FetchSucceeded(
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& url,
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::FilePath& name) {
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Unpacker unpacker;
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!unpacker.Unpack(name)) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::DeleteFile(name, false);
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    printf("Failed to unpack\n");
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    PendingLoadComplete(url);
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The downloaded .zip file is no longer necessary.
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::DeleteFile(name, false);
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Load the manifest.
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::FilePath manifest_path = unpacker.dir().Append(kManifestFileName);
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Manifest manifest;
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string err_msg;
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!manifest.ParseFromFile(manifest_path, &err_msg)) {
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    printf("%s\n", err_msg.c_str());
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    PendingLoadComplete(url);
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Enqueue loads for any deps.
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  LoadDeps(manifest);
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  printf("Loaded %s\n", url.spec().c_str());
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PendingLoadComplete(url);
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageManagerApplication::FetchFailed(const GURL& url) {
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PendingLoadComplete(url);
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace mojo
114