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// Component updates can be either differential updates or full updates.
6// Full updates come in CRX format; differential updates come in CRX-style
7// archives, but have a different magic number. They contain "commands.json", a
8// list of commands for the patcher to follow. The patcher uses these commands,
9// the other files in the archive, and the files from the existing installation
10// of the component to create the contents of a full update, which is then
11// installed normally.
12// Component updates are specified by the 'codebasediff' attribute of an
13// updatecheck response:
14//   <updatecheck codebase="http://example.com/extension_1.2.3.4.crx"
15//                hash="12345" size="9854" status="ok" version="1.2.3.4"
16//                prodversionmin="2.0.143.0"
17//                codebasediff="http://example.com/diff_1.2.3.4.crx"
18//                hashdiff="123" sizediff="101"
19//                fp="1.123" />
20// The component updater will attempt a differential update if it is available
21// and allowed to, and fall back to a full update if it fails.
22//
23// After installation (diff or full), the component updater records "fp", the
24// fingerprint of the installed files, to later identify the existing files to
25// the server so that a proper differential update can be provided next cycle.
26
27#ifndef COMPONENTS_COMPONENT_UPDATER_COMPONENT_PATCHER_H_
28#define COMPONENTS_COMPONENT_UPDATER_COMPONENT_PATCHER_H_
29
30#include "base/callback_forward.h"
31#include "base/macros.h"
32#include "base/memory/ref_counted.h"
33#include "base/memory/scoped_ptr.h"
34#include "base/values.h"
35#include "components/component_updater/component_unpacker.h"
36
37namespace base {
38class FilePath;
39}
40
41namespace component_updater {
42
43class ComponentInstaller;
44class DeltaUpdateOp;
45class OutOfProcessPatcher;
46
47// The type of a patch file.
48enum PatchType {
49  kPatchTypeUnknown,
50  kPatchTypeCourgette,
51  kPatchTypeBsdiff,
52};
53
54// Encapsulates a task for applying a differential update to a component.
55class ComponentPatcher : public base::RefCountedThreadSafe<ComponentPatcher> {
56 public:
57  // Takes an unpacked differential CRX (|input_dir|) and a component installer,
58  // and sets up the class to create a new (non-differential) unpacked CRX.
59  // If |in_process| is true, patching will be done completely within the
60  // existing process. Otherwise, some steps of patching may be done
61  // out-of-process.
62  ComponentPatcher(const base::FilePath& input_dir,
63                   const base::FilePath& unpack_dir,
64                   ComponentInstaller* installer,
65                   scoped_refptr<OutOfProcessPatcher> out_of_process_patcher,
66                   scoped_refptr<base::SequencedTaskRunner> task_runner);
67
68  // Starts patching files. This member function returns immediately, after
69  // posting a task to do the patching. When patching has been completed,
70  // |callback| will be called with the error codes if any error codes were
71  // encountered.
72  void Start(const ComponentUnpacker::Callback& callback);
73
74 private:
75  friend class base::RefCountedThreadSafe<ComponentPatcher>;
76
77  virtual ~ComponentPatcher();
78
79  void StartPatching();
80
81  void PatchNextFile();
82
83  void DonePatchingFile(ComponentUnpacker::Error error, int extended_error);
84
85  void DonePatching(ComponentUnpacker::Error error, int extended_error);
86
87  const base::FilePath input_dir_;
88  const base::FilePath unpack_dir_;
89  ComponentInstaller* const installer_;
90  scoped_refptr<OutOfProcessPatcher> out_of_process_patcher_;
91  ComponentUnpacker::Callback callback_;
92  scoped_ptr<base::ListValue> commands_;
93  base::ValueVector::const_iterator next_command_;
94  scoped_refptr<DeltaUpdateOp> current_operation_;
95  scoped_refptr<base::SequencedTaskRunner> task_runner_;
96
97  DISALLOW_COPY_AND_ASSIGN(ComponentPatcher);
98};
99
100}  // namespace component_updater
101
102#endif  // COMPONENTS_COMPONENT_UPDATER_COMPONENT_PATCHER_H_
103