summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/webstore_install_helper.cc
blob: 55fefbe48cb882f93d9f5f9e386a82b0d5633bc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright (c) 2012 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 "chrome/browser/extensions/webstore_install_helper.h"

#include "base/bind.h"
#include "base/values.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "components/safe_json/safe_json_parser.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request.h"

using content::BrowserThread;

namespace {

const char kImageDecodeError[] = "Image decode failed";

}  // namespace

namespace extensions {

WebstoreInstallHelper::WebstoreInstallHelper(
    Delegate* delegate,
    const std::string& id,
    const std::string& manifest,
    const GURL& icon_url,
    net::URLRequestContextGetter* context_getter)
    : delegate_(delegate),
      id_(id),
      manifest_(manifest),
      icon_url_(icon_url),
      context_getter_(context_getter),
      icon_decode_complete_(false),
      manifest_parse_complete_(false),
      parse_error_(Delegate::UNKNOWN_ERROR) {
}

WebstoreInstallHelper::~WebstoreInstallHelper() {}

void WebstoreInstallHelper::Start() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  safe_json::SafeJsonParser::Parse(
      manifest_, base::Bind(&WebstoreInstallHelper::OnJSONParseSucceeded, this),
      base::Bind(&WebstoreInstallHelper::OnJSONParseFailed, this));

  if (icon_url_.is_empty()) {
    icon_decode_complete_ = true;
  } else {
    // No existing |icon_fetcher_| to avoid unbalanced AddRef().
    CHECK(!icon_fetcher_.get());
    AddRef();  // Balanced in OnFetchComplete().
    icon_fetcher_.reset(new chrome::BitmapFetcher(icon_url_, this));
    icon_fetcher_->Init(
        context_getter_, std::string(),
        net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
        net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES);
    icon_fetcher_->Start();
  }
}

void WebstoreInstallHelper::OnFetchComplete(const GURL& url,
                                            const SkBitmap* image) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // OnFetchComplete should only be called as icon_fetcher_ delegate to avoid
  // unbalanced Release().
  CHECK(icon_fetcher_.get());

  if (image)
    icon_ = *image;
  icon_decode_complete_ = true;
  if (icon_.empty()) {
    error_ = kImageDecodeError;
    parse_error_ = Delegate::ICON_ERROR;
  }
  icon_fetcher_.reset();

  ReportResultsIfComplete();
  Release();  // Balanced in Start().
}

void WebstoreInstallHelper::OnJSONParseSucceeded(
    scoped_ptr<base::Value> result) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  manifest_parse_complete_ = true;
  const base::DictionaryValue* value;
  if (result->GetAsDictionary(&value))
    parsed_manifest_.reset(value->DeepCopy());
  else
    parse_error_ = Delegate::MANIFEST_ERROR;

  ReportResultsIfComplete();
}

void WebstoreInstallHelper::OnJSONParseFailed(
    const std::string& error_message) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  manifest_parse_complete_ = true;
  error_ = error_message;
  parse_error_ = Delegate::MANIFEST_ERROR;
  ReportResultsIfComplete();
}

void WebstoreInstallHelper::ReportResultsIfComplete() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (!icon_decode_complete_ || !manifest_parse_complete_)
    return;

  if (error_.empty() && parsed_manifest_)
    delegate_->OnWebstoreParseSuccess(id_, icon_, parsed_manifest_.release());
  else
    delegate_->OnWebstoreParseFailure(id_, parse_error_, error_);
}

}  // namespace extensions