File: device_description_service.h

package info (click to toggle)
chromium 139.0.7258.127-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,096 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (177 lines) | stat: -rw-r--r-- 7,325 bytes parent folder | download | duplicates (7)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DEVICE_DESCRIPTION_SERVICE_H_
#define CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DEVICE_DESCRIPTION_SERVICE_H_

#include <memory>
#include <string>

#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
#include "chrome/browser/media/router/discovery/dial/parsed_dial_device_description.h"
#include "chrome/browser/media/router/discovery/dial/safe_dial_device_description_parser.h"

namespace media_router {

class DeviceDescriptionFetcher;
class SafeDialDeviceDescriptionParser;

// This class fetches and parses device description XML for DIAL devices. Actual
// parsing happens in a separate utility process via SafeDeviceDescriptionParser
// (instead of in this class).
// This class is not sequence safe.
class DeviceDescriptionService {
 public:
  // Represents cached device description data parsed from device description
  // XML.
  struct CacheEntry {
    CacheEntry();
    CacheEntry(const CacheEntry& other);
    ~CacheEntry();

    // The expiration time from the cache.
    base::Time expire_time;

    // The device description version number (non-negative).
    int32_t config_id;

    // Parsed device description data from XML.
    ParsedDialDeviceDescription description_data;
  };

  // Called if parsing device description XML in utility process succeeds, and
  // all fields are valid.
  // |device_data|: The device to look up.
  // |description_data|: Device description data from device description XML.
  using DeviceDescriptionParseSuccessCallback = base::RepeatingCallback<void(
      const DialDeviceData& device_data,
      const ParsedDialDeviceDescription& description_data)>;

  // Called if parsing device description XML in utility process fails, or some
  // parsed fields are missing or invalid.
  using DeviceDescriptionParseErrorCallback =
      base::RepeatingCallback<void(const DialDeviceData& device_data,
                                   const std::string& error_message)>;

  DeviceDescriptionService(
      const DeviceDescriptionParseSuccessCallback& success_cb,
      const DeviceDescriptionParseErrorCallback& error_cb);

  DeviceDescriptionService(const DeviceDescriptionService&) = delete;
  DeviceDescriptionService& operator=(const DeviceDescriptionService&) = delete;

  virtual ~DeviceDescriptionService();

  // For each device in |devices|, if there is a valid cache entry for it, call
  // |success_cb_| with cached device description; otherwise start fetching
  // device description XML and parsing XML in utility process. Call
  // |success_cb_| if both fetching and parsing succeeds; otherwise call
  // |error_cb_|.
  virtual void GetDeviceDescriptions(
      const std::vector<DialDeviceData>& devices);

 protected:
  // Parses the device description data in |description_data| and invokes
  // OnParsedDeviceDescription() when done, passing |device_data| along.
  // Made visible so it can be overwritten in tests.
  virtual void ParseDeviceDescription(
      const DialDeviceData& device_data,
      const DialDeviceDescriptionData& description_data);

  // Overridden by unit tests.
  virtual std::unique_ptr<DeviceDescriptionFetcher> CreateFetcher(
      const DialDeviceData& device_data,
      base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb,
      base::OnceCallback<void(const std::string&)> error_cb);

 private:
  friend class DeviceDescriptionServiceTest;
  friend class TestDeviceDescriptionService;
  FRIEND_TEST_ALL_PREFIXES(DeviceDescriptionServiceTest,
                           TestGetDeviceDescriptionRemoveOutDatedFetchers);
  FRIEND_TEST_ALL_PREFIXES(DeviceDescriptionServiceTest,
                           TestGetDeviceDescriptionFetchURL);
  FRIEND_TEST_ALL_PREFIXES(DeviceDescriptionServiceTest,
                           TestGetDeviceDescriptionFetchURLError);
  FRIEND_TEST_ALL_PREFIXES(DeviceDescriptionServiceTest,
                           TestCleanUpCacheEntries);
  FRIEND_TEST_ALL_PREFIXES(DeviceDescriptionServiceTest,
                           TestSafeParserProperlyCreated);

  // Checks the cache for a valid device description. If the entry is found but
  // is expired, it is removed from the cache. Returns cached entry of
  // parsed device description. Returns nullptr if cache entry does not exist or
  // is not valid.
  // |device_data|: The device to look up.
  const CacheEntry* CheckAndUpdateCache(const DialDeviceData& device_data);

  // Issues a HTTP GET request for the device description. No-op if there is
  // already a pending request.
  // |device_data|: The device to look up.
  void FetchDeviceDescription(const DialDeviceData& device_data);

  // Invoked when HTTP GET request finishes.
  // |device_data|: Device data initiating the HTTP request.
  // |description_data|: Response from HTTP request.
  void OnDeviceDescriptionFetchComplete(
      const DialDeviceData& device_data,
      const DialDeviceDescriptionData& description_data);

  // Invoked when HTTP GET request fails.
  // |device_data|: Device data initiating the HTTP request.
  // |error_message|: Error message from HTTP request.
  void OnDeviceDescriptionFetchError(const DialDeviceData& device_data,
                                     const std::string& error_message);

  // Invoked when SafeDialDeviceDescriptionParser finishes parsing device
  // description XML.
  // |device_data|: Device data initiating XML parsing in utility process.
  // |device_description|: Parsed device description from utility process,
  // empty if parsing failed.
  // |parsing_error|: error encountered while parsing DIAL device description.
  void OnParsedDeviceDescription(
      const DialDeviceData& device_data,
      const ParsedDialDeviceDescription& device_description,
      SafeDialDeviceDescriptionParser::ParsingResult parsing_result);

  // Remove expired cache entries from |description_map_|.
  void CleanUpCacheEntries();

  // Used by unit tests.
  virtual base::Time GetNow();

  // Map of current device description fetches in progress, keyed by device
  // label.
  std::map<std::string, std::unique_ptr<DeviceDescriptionFetcher>>
      device_description_fetcher_map_;

  // The number of device description still pending to be parsed.
  uint32_t pending_device_count_ = 0U;

  // Map of current cached device descriptions, keyed by device label.
  std::map<std::string, CacheEntry> description_cache_;

  // See comments for DeviceDescriptionParseSuccessCallback.
  DeviceDescriptionParseSuccessCallback success_cb_;

  // See comments for DeviceDescriptionParseErrorCallback.
  DeviceDescriptionParseErrorCallback error_cb_;

  // Timer for clean up expired cache entries.
  std::unique_ptr<base::RepeatingTimer> clean_up_timer_;

  // Safe DIAL parser. Does the parsing in a utility process.
  SafeDialDeviceDescriptionParser device_description_parser_;

  SEQUENCE_CHECKER(sequence_checker_);
};

}  // namespace media_router

#endif  // CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DEVICE_DESCRIPTION_SERVICE_H_