summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/external_pref_loader.h
blob: d951db8709b6c763aafdd3021c9ba7f9bef35342 (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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// 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.

#ifndef CHROME_BROWSER_EXTENSIONS_EXTERNAL_PREF_LOADER_H_
#define CHROME_BROWSER_EXTENSIONS_EXTERNAL_PREF_LOADER_H_

#include <string>

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/scoped_observer.h"
#include "base/values.h"
#include "chrome/browser/extensions/external_loader.h"
#include "chrome/browser/prefs/pref_service_syncable_observer.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_observer.h"

class PrefServiceSyncable;
class Profile;

namespace extensions {

// A specialization of the ExternalLoader that uses a json file to
// look up which external extensions are registered.
// Instances of this class are expected to be created and destroyed on the UI
// thread and they are expecting public method calls from the UI thread.
class ExternalPrefLoader : public ExternalLoader,
                           public PrefServiceSyncableObserver,
                           public ProfileSyncServiceObserver {
 public:
  enum Options {
    NONE = 0,

    // Ensure that only root can force an external install by checking
    // that all components of the path to external extensions files are
    // owned by root and not writable by any non-root user.
    ENSURE_PATH_CONTROLLED_BY_ADMIN = 1 << 0,

    // Delay external preference load. It delays default apps installation
    // to not overload the system on first time user login.
    DELAY_LOAD_UNTIL_PRIORITY_SYNC = 1 << 1,
  };

  // |base_path_id| is the directory containing the external_extensions.json
  // file or the standalone extension manifest files. Relative file paths to
  // extension files are resolved relative to this path. |profile| is used to
  // wait priority sync if DELAY_LOAD_UNTIL_PRIORITY_SYNC set.
  ExternalPrefLoader(int base_path_id, Options options, Profile* profile);

  const base::FilePath GetBaseCrxFilePath() override;

 protected:
  ~ExternalPrefLoader() override;

  void StartLoading() override;
  bool IsOptionSet(Options option) {
    return (options_ & option) != 0;
  }

  // The resource id of the base path with the information about the json
  // file containing which extensions to load.
  const int base_path_id_;

  const Options options_;

 private:
  friend class base::RefCountedThreadSafe<ExternalLoader>;

  // PrefServiceSyncableObserver:
  void OnIsSyncingChanged() override;

  // ProfileSyncServiceObserver
  void OnStateChanged() override;

  // If priority sync ready posts LoadOnFileThread and return true.
  bool PostLoadIfPrioritySyncReady();

  // Post LoadOnFileThread and stop observing for sync service states.
  void PostLoadAndRemoveObservers();

  // Actually searches for and loads candidate standalone extension preference
  // files in the path corresponding to |base_path_id|.
  // Must be called on the file thread.
  void LoadOnFileThread();

  // Extracts the information contained in an external_extension.json file
  // regarding which extensions to install. |prefs| will be modified to
  // receive the extracted extension information.
  // Must be called from the File thread.
  void ReadExternalExtensionPrefFile(base::DictionaryValue* prefs);

  // Extracts the information contained in standalone external extension
  // json files (<extension id>.json) regarding what external extensions
  // to install. |prefs| will be modified to receive the extracted extension
  // information.
  // Must be called from the File thread.
  void ReadStandaloneExtensionPrefFiles(base::DictionaryValue* prefs);

  // The path (coresponding to |base_path_id_| containing the json files
  // describing which extensions to load.
  base::FilePath base_path_;

  // Profile that loads these external prefs.
  // Needed for waiting for waiting priority sync.
  Profile* profile_;

  // Used for registering observer for PrefServiceSyncable.
  ScopedObserver<PrefServiceSyncable, PrefServiceSyncableObserver>
      syncable_pref_observer_;

  DISALLOW_COPY_AND_ASSIGN(ExternalPrefLoader);
};

// A simplified version of ExternalPrefLoader that loads the dictionary
// from json data specified in a string.
class ExternalTestingLoader : public ExternalLoader {
 public:
  ExternalTestingLoader(const std::string& json_data,
                        const base::FilePath& fake_base_path);

  const base::FilePath GetBaseCrxFilePath() override;

 protected:
  void StartLoading() override;

 private:
  friend class base::RefCountedThreadSafe<ExternalLoader>;

  ~ExternalTestingLoader() override;

  base::FilePath fake_base_path_;
  scoped_ptr<base::DictionaryValue> testing_prefs_;

  DISALLOW_COPY_AND_ASSIGN(ExternalTestingLoader);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_EXTERNAL_PREF_LOADER_H_