Commit 2906a8df authored by Leonid Baraz's avatar Leonid Baraz Committed by Chromium LUCI CQ

Make both request and response base::Value

Rid cloud_policy_client.h of dependences on EncryptedRecord and related stuff.

Bug: 1078512
Change-Id: I45345388e738727d1593d49cfb4042a1d80e63c2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2580560
Commit-Queue: Leonid Baraz <lbaraz@chromium.org>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Reviewed-by: default avatarZach Trudo <zatrudo@google.com>
Cr-Commit-Position: refs/heads/master@{#835756}
parent 6f155766
......@@ -6,6 +6,7 @@
#include <utility>
#include "base/base64.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/containers/queue.h"
......@@ -17,6 +18,7 @@
#include "base/task_runner.h"
#include "base/values.h"
#include "chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h"
#include "chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.h"
#include "chrome/browser/policy/messaging_layer/util/status.h"
#include "chrome/browser/policy/messaging_layer/util/status_macros.h"
#include "chrome/browser/policy/messaging_layer/util/statusor.h"
......@@ -111,19 +113,31 @@ void RecordHandlerImpl::ReportUploader::OnStart() {
void RecordHandlerImpl::ReportUploader::StartUpload(
const EncryptedRecord& encrypted_record) {
auto cb = base::BindOnce(&RecordHandlerImpl::ReportUploader::OnUploadComplete,
base::Unretained(this));
auto response_cb =
base::BindOnce(&RecordHandlerImpl::ReportUploader::OnUploadComplete,
base::Unretained(this));
auto request_result = UploadEncryptedReportingRequestBuilder()
.AddRecord(encrypted_record)
.Build();
if (!request_result.has_value()) {
std::move(response_cb).Run(base::nullopt);
return;
}
base::Value request = std::move(request_result.value());
base::PostTask(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(
[](policy::CloudPolicyClient* client, const EncryptedRecord& record,
base::OnceCallback<void(base::Optional<base::Value>)> cb) {
[](policy::CloudPolicyClient* client, base::Value request,
base::OnceCallback<void(base::Optional<base::Value>)>
response_cb) {
client->UploadEncryptedReport(
record,
std::move(request),
reporting::GetContext(ProfileManager::GetPrimaryUserProfile()),
std::move(cb));
std::move(response_cb));
},
client_, encrypted_record, std::move(cb)));
client_, std::move(request), std::move(response_cb)));
}
void RecordHandlerImpl::ReportUploader::OnUploadComplete(
......@@ -167,17 +181,22 @@ void RecordHandlerImpl::ReportUploader::HandleSuccessfulUpload() {
const base::Value* last_succeed_uploaded_record =
last_response_.FindDictKey("lastSucceedUploadedRecord");
if (last_succeed_uploaded_record != nullptr) {
SequencingInformation seq_info;
// Note: Fields below are 'int', should be converted into 'uint64_t'.
const auto sequencing_id =
last_succeed_uploaded_record->FindIntKey("sequencingId");
const auto generation_id =
last_succeed_uploaded_record->FindIntKey("generationId");
const std::string* sequencing_id_str =
last_succeed_uploaded_record->FindStringKey("sequencingId");
const std::string* generation_id_str =
last_succeed_uploaded_record->FindStringKey("generationId");
const auto priority = last_succeed_uploaded_record->FindIntKey("priority");
if (sequencing_id.has_value() && generation_id.has_value() &&
uint64_t sequencing_id = 0;
uint64_t generation_id = 0;
if (sequencing_id_str &&
base::StringToUint64(*sequencing_id_str, &sequencing_id) &&
generation_id_str &&
base::StringToUint64(*generation_id_str, &generation_id) &&
priority.has_value() && Priority_IsValid(priority.value())) {
seq_info.set_sequencing_id(sequencing_id.value());
seq_info.set_generation_id(generation_id.value());
SequencingInformation seq_info;
seq_info.set_sequencing_id(sequencing_id);
seq_info.set_generation_id(generation_id);
seq_info.set_priority(Priority(priority.value()));
highest_sequencing_information_ = std::move(seq_info);
}
......
......@@ -82,18 +82,22 @@ class TestCompletionResponder {
};
// Helper function composes JSON represented as base::Value from Sequencing
// information.
// information in request.
base::Value ValueFromSucceededSequencingInfo(
const SequencingInformation& sequencing_information) {
base::Value sequencing_info(base::Value::Type::DICTIONARY);
sequencing_info.SetIntKey("sequencingId",
sequencing_information.sequencing_id());
sequencing_info.SetIntKey("generationId",
sequencing_information.generation_id());
sequencing_info.SetIntKey("priority", sequencing_information.priority());
base::Value result(base::Value::Type::DICTIONARY);
result.SetPath("lastSucceedUploadedRecord", std::move(sequencing_info));
return result;
const base::Optional<base::Value> request) {
EXPECT_TRUE(request.has_value());
EXPECT_TRUE(request.value().is_dict());
const base::Value* const encrypted_record_list =
request.value().FindListKey("encryptedRecord");
EXPECT_TRUE(encrypted_record_list != nullptr);
EXPECT_FALSE(encrypted_record_list->GetList().empty());
const base::Value* seq_info =
encrypted_record_list->GetList().rbegin()->FindDictKey(
"sequencingInformation");
EXPECT_TRUE(seq_info != nullptr);
base::Value response(base::Value::Type::DICTIONARY);
response.SetPath("lastSucceedUploadedRecord", seq_info->Clone());
return response;
}
class RecordHandlerImplTest : public testing::Test {
......@@ -111,13 +115,13 @@ class RecordHandlerImplTest : public testing::Test {
std::unique_ptr<policy::MockCloudPolicyClient> client_;
};
std::unique_ptr<std::vector<EncryptedRecord>> RecordListBuilder(
uint64_t number_of_test_records,
std::unique_ptr<std::vector<EncryptedRecord>> BuildTestRecordsVector(
size_t number_of_test_records,
uint64_t generation_id) {
std::unique_ptr<std::vector<EncryptedRecord>> test_records =
std::make_unique<std::vector<EncryptedRecord>>();
for (uint64_t i = 0; i < number_of_test_records; i++) {
test_records->reserve(number_of_test_records);
for (size_t i = 0; i < number_of_test_records; i++) {
EncryptedRecord encrypted_record;
encrypted_record.set_encrypted_wrapped_record(
base::StrCat({"Record Number ", base::NumberToString(i)}));
......@@ -132,19 +136,19 @@ std::unique_ptr<std::vector<EncryptedRecord>> RecordListBuilder(
}
TEST_F(RecordHandlerImplTest, ForwardsRecordsToCloudPolicyClient) {
uint64_t kNumTestRecords = 10;
uint64_t kGenerationId = 1234;
auto test_records = RecordListBuilder(kNumTestRecords, kGenerationId);
constexpr size_t kNumTestRecords = 10;
constexpr uint64_t kGenerationId = 1234;
auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId);
TestCallbackWaiterWithCounter client_waiter{kNumTestRecords};
EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _))
.Times(kNumTestRecords)
.WillRepeatedly(WithArgs<0, 2>(
Invoke([&client_waiter](
const ::reporting::EncryptedRecord& record,
base::Value request,
policy::CloudPolicyClient::ResponseCallback callback) {
std::move(callback).Run(ValueFromSucceededSequencingInfo(
record.sequencing_information()));
std::move(callback).Run(
ValueFromSucceededSequencingInfo(std::move(request)));
client_waiter.Signal();
})));
......@@ -170,7 +174,7 @@ TEST_F(RecordHandlerImplTest, ReportsEarlyFailure) {
uint64_t kNumSuccessfulUploads = 5;
uint64_t kNumTestRecords = 10;
uint64_t kGenerationId = 1234;
auto test_records = RecordListBuilder(kNumTestRecords, kGenerationId);
auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId);
// Wait kNumSuccessfulUploads times + 1 for the failure.
TestCallbackWaiterWithCounter client_waiter{kNumSuccessfulUploads + 1};
......@@ -178,12 +182,12 @@ TEST_F(RecordHandlerImplTest, ReportsEarlyFailure) {
::testing::InSequence seq;
EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _))
.Times(kNumSuccessfulUploads)
.WillRepeatedly(WithArgs<0, 2>(Invoke(
[&client_waiter](
const ::reporting::EncryptedRecord& record,
base::OnceCallback<void(base::Optional<base::Value>)> callback) {
std::move(callback).Run(ValueFromSucceededSequencingInfo(
record.sequencing_information()));
.WillRepeatedly(WithArgs<0, 2>(
Invoke([&client_waiter](
base::Value request,
policy::CloudPolicyClient::ResponseCallback callback) {
std::move(callback).Run(
ValueFromSucceededSequencingInfo(std::move(request)));
client_waiter.Signal();
})));
EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _))
......
......@@ -120,18 +120,22 @@ class TestCallbackWaiterWithCounter : public TestCallbackWaiter {
};
// Helper function composes JSON represented as base::Value from Sequencing
// information.
// information in request.
base::Value ValueFromSucceededSequencingInfo(
const SequencingInformation& sequencing_information) {
base::Value sequencing_info(base::Value::Type::DICTIONARY);
sequencing_info.SetIntKey("sequencingId",
sequencing_information.sequencing_id());
sequencing_info.SetIntKey("generationId",
sequencing_information.generation_id());
sequencing_info.SetIntKey("priority", sequencing_information.priority());
base::Value result(base::Value::Type::DICTIONARY);
result.SetPath("lastSucceedUploadedRecord", std::move(sequencing_info));
return result;
const base::Optional<base::Value> request) {
EXPECT_TRUE(request.has_value());
EXPECT_TRUE(request.value().is_dict());
const base::Value* const encrypted_record_list =
request.value().FindListKey("encryptedRecord");
EXPECT_TRUE(encrypted_record_list != nullptr);
EXPECT_FALSE(encrypted_record_list->GetList().empty());
const base::Value* seq_info =
encrypted_record_list->GetList().rbegin()->FindDictKey(
"sequencingInformation");
EXPECT_TRUE(seq_info != nullptr);
base::Value response(base::Value::Type::DICTIONARY);
response.SetPath("lastSucceedUploadedRecord", seq_info->Clone());
return response;
}
class UploadClientTest : public ::testing::Test {
......@@ -211,10 +215,10 @@ TEST_F(UploadClientTest, CreateUploadClientAndUploadRecords) {
EXPECT_CALL(*client, UploadEncryptedReport(_, _, _))
.WillRepeatedly(WithArgs<0, 2>(Invoke(
[&waiter](const ::reporting::EncryptedRecord& record,
policy::CloudPolicyClient::ResponseCallback callback) {
std::move(callback).Run(ValueFromSucceededSequencingInfo(
record.sequencing_information()));
[&waiter](base::Value request,
policy::CloudPolicyClient::ResponseCallback response_cb) {
std::move(response_cb)
.Run(ValueFromSucceededSequencingInfo(std::move(request)));
base::ThreadPool::PostTask(
FROM_HERE, {base::TaskPriority::BEST_EFFORT},
base::BindOnce(&TestCallbackWaiterWithCounter::Signal,
......
......@@ -607,7 +607,7 @@ void CloudPolicyClient::UploadSecurityEventReport(
}
void CloudPolicyClient::UploadEncryptedReport(
const ::reporting::EncryptedRecord& record,
base::Value merging_payload,
base::Optional<base::Value> context,
ResponseCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......@@ -619,11 +619,9 @@ void CloudPolicyClient::UploadEncryptedReport(
std::unique_ptr<EncryptedReportingJobConfiguration> config =
std::make_unique<EncryptedReportingJobConfiguration>(
this, service()->configuration()->GetEncryptedReportingServerUrl(),
std::move(merging_payload),
base::BindOnce(&CloudPolicyClient::OnEncryptedReportUploadCompleted,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
if (!config->AddEncryptedRecord(record)) {
return;
}
if (context.has_value()) {
config->UpdateContext(context.value());
}
......
......@@ -28,7 +28,6 @@
#include "components/policy/core/common/remote_commands/remote_command_job.h"
#include "components/policy/policy_export.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "components/policy/proto/record.pb.h"
namespace content {
class BrowserContext;
......@@ -79,7 +78,7 @@ class POLICY_EXPORT CloudPolicyClient {
using DeviceDMTokenCallback = base::RepeatingCallback<std::string(
const std::vector<std::string>& user_affiliation_ids)>;
// A callback that processes response value received from the server,
// Callback that processes response value received from the server,
// or nullopt, if there was a failure.
using ResponseCallback =
base::OnceCallback<void(base::Optional<base::Value>)>;
......@@ -319,10 +318,10 @@ class POLICY_EXPORT CloudPolicyClient {
base::Value report,
StatusCallback callback);
// Uploads a report containing an EncryptedRecord. The client must be in a
// registered state. The |callback| will be called when the operation
// completes.
virtual void UploadEncryptedReport(const ::reporting::EncryptedRecord& record,
// Uploads a report containing |merging_payload| (merged into the default
// payload of the job). The client must be in a registered state. The
// |callback| will be called when the operation completes.
virtual void UploadEncryptedReport(base::Value merging_payload,
base::Optional<base::Value> context,
ResponseCallback callback);
......
......@@ -11,6 +11,7 @@
#include <memory>
#include <set>
#include "base/base64.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
......@@ -18,6 +19,7 @@
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "base/values.h"
......@@ -114,6 +116,52 @@ MATCHER_P(MatchProto, expected, "matches protobuf") {
return arg.SerializePartialAsString() == expected.SerializePartialAsString();
}
base::Value ConvertEncryptedRecordToValue(
const ::reporting::EncryptedRecord& record) {
base::Value record_request(base::Value::Type::DICTIONARY);
if (record.has_encrypted_wrapped_record()) {
base::Value encrypted_wrapped_record(base::Value::Type::DICTIONARY);
std::string base64_encode;
base::Base64Encode(record.encrypted_wrapped_record(), &base64_encode);
record_request.SetStringKey("encryptedWrappedRecord", base64_encode);
}
if (record.has_encryption_info()) {
base::Value encryption_info(base::Value::Type::DICTIONARY);
if (record.encryption_info().has_encryption_key()) {
std::string base64_encode;
base::Base64Encode(record.encryption_info().encryption_key(),
&base64_encode);
encryption_info.SetStringKey("encryptionKey", base64_encode);
}
if (record.encryption_info().has_public_key_id()) {
encryption_info.SetStringKey(
"publicKeyId",
base::NumberToString(record.encryption_info().public_key_id()));
}
record_request.SetPath("encryptionInfo", std::move(encryption_info));
}
if (record.has_sequencing_information()) {
base::Value sequencing_information(base::Value::Type::DICTIONARY);
if (record.sequencing_information().has_sequencing_id()) {
sequencing_information.SetStringKey(
"sequencingId", base::NumberToString(
record.sequencing_information().sequencing_id()));
}
if (record.sequencing_information().has_generation_id()) {
sequencing_information.SetStringKey(
"generationId", base::NumberToString(
record.sequencing_information().generation_id()));
}
if (record.sequencing_information().has_priority()) {
sequencing_information.SetIntKey(
"priority", record.sequencing_information().priority());
}
record_request.SetPath("sequencingInformation",
std::move(sequencing_information));
}
return record_request;
}
// A mock class to allow us to set expectations on upload callbacks.
class MockStatusCallbackObserver {
public:
......@@ -443,7 +491,8 @@ class CloudPolicyClientTest : public testing::Test {
CloudPolicyClient::ResponseCallback response_callback =
base::BindOnce(&MockResponseCallbackObserver::OnResponseReceived,
base::Unretained(&response_callback_observer_));
client_->UploadEncryptedReport(record, std::move(context),
client_->UploadEncryptedReport(ConvertEncryptedRecordToValue(record),
std::move(context),
std::move(response_callback));
base::RunLoop().RunUntilIdle();
}
......@@ -1582,53 +1631,6 @@ TEST_F(CloudPolicyClientTest, UploadEncryptedReport) {
EXPECT_EQ(client_->status(), DM_STATUS_SUCCESS);
}
TEST_F(CloudPolicyClientTest, DenyPoorlyFormedEncryptedRecords) {
RegisterClient();
// Create empty record
::reporting::EncryptedRecord record;
EXPECT_CALL(response_callback_observer_, OnResponseReceived(Not(HasValue())))
.Times(1);
AttemptUploadEncryptedWaitUntilIdle(record);
// Add encrypted_wrapped_record without sequencing information.
record.set_encrypted_wrapped_record("Enterprise");
EXPECT_CALL(response_callback_observer_, OnResponseReceived(Not(HasValue())))
.Times(1);
AttemptUploadEncryptedWaitUntilIdle(record);
// Incorrectly set sequencing information by only setting sequencing id.
auto* sequencing_information = record.mutable_sequencing_information();
sequencing_information->set_sequencing_id(1701);
EXPECT_CALL(response_callback_observer_, OnResponseReceived(Not(HasValue())))
.Times(1);
AttemptUploadEncryptedWaitUntilIdle(record);
// Finish correctly setting sequencing information but incorrectly set
// encryption info.
sequencing_information->set_generation_id(12345678);
sequencing_information->set_priority(::reporting::IMMEDIATE);
auto* encryption_info = record.mutable_encryption_info();
encryption_info->set_encryption_key("Key");
EXPECT_CALL(response_callback_observer_, OnResponseReceived(Not(HasValue())))
.Times(1);
AttemptUploadEncryptedWaitUntilIdle(record);
// Finish correctly setting encryption info - expect complete call.
encryption_info->set_public_key_id(1234);
EXPECT_CALL(response_callback_observer_, OnResponseReceived(HasValue()))
.Times(1);
ExpectAndCaptureJSONJob(/*response=*/"{}");
AttemptUploadEncryptedWaitUntilIdle(record);
}
TEST_F(CloudPolicyClientTest, UploadAppInstallReport) {
RegisterClient();
......
......@@ -12,16 +12,14 @@
#include "base/macros.h"
#include "base/optional.h"
#include "base/values.h"
#include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/reporting_job_configuration_base.h"
#include "components/policy/policy_export.h"
#include "components/policy/proto/record.pb.h"
#include "components/policy/proto/record_constants.pb.h"
namespace policy {
class CloudPolicyClient;
// EncryptedReportingJobConfiguration configures a payload for the Encrypted
// server endpoint. A JSON version of the payload looks like this:
// {
......@@ -37,8 +35,8 @@ class CloudPolicyClient;
// "generationId": 123456789,
// "priority": 1
// }
// },
// {
// },
// {
// "encryptedWrappedRecord": "EncryptedMessage",
// "encryptionInfo" : {
// "encryptionKey": "EncryptedMessage",
......@@ -49,8 +47,8 @@ class CloudPolicyClient;
// "generationId": 123456789,
// "priority": 1
// }
// }
// },
// }
// ],
// "device": {
// "client_id": "abcdef1234",
// "dmToken": "abcdef1234",
......@@ -65,19 +63,17 @@ class CloudPolicyClient;
// "userAgent": "abcdef1234"
// }
// }
// "device" and "browser" are populated by the base class,
// the rest needs to be provided as |merging_payload|.
class POLICY_EXPORT EncryptedReportingJobConfiguration
: public ReportingJobConfigurationBase {
public:
EncryptedReportingJobConfiguration(CloudPolicyClient* client,
const std::string& server_url,
UploadCompleteCallback callback);
base::Value merging_payload,
UploadCompleteCallback complete_cb);
~EncryptedReportingJobConfiguration() override;
// Adds a record to the request.
// returns true if record was successfully added to the payload, otherwise
// returns false.
bool AddEncryptedRecord(const ::reporting::EncryptedRecord& record);
// |context| is a base::Value item as generated by |reporting::GetContext|.
// |context| will be stored and applied to the payload on the proceeding
// |GetPayload| call. |context| mostly fills out the profile dictionary, but
......@@ -85,85 +81,15 @@ class POLICY_EXPORT EncryptedReportingJobConfiguration
// reporting::GetContext for specifics).
void UpdateContext(base::Value& context);
static std::string GetEncryptedRecordListKey();
static std::string GetEncryptedWrappedRecordPath();
protected:
void UpdatePayloadBeforeGetInternal() override;
std::string GetUmaString() const override;
private:
// Builds a |base::Value| dictionary from a |reporting::EncryptedRecord|
// proto.
class POLICY_EXPORT EncryptedRecordDictionaryBuilder {
public:
EncryptedRecordDictionaryBuilder() = delete;
static base::Optional<base::Value> ConvertEncryptedRecordProtoToValue(
const ::reporting::EncryptedRecord& record);
// Path for EncryptedWrappedRecord
static std::string GetEncryptedWrappedRecordPath();
// Paths for SequencingInformation
static std::string GetSequencingInformationSequencingIdPath();
static std::string GetSequencingInformationGenerationIdPath();
static std::string GetSequencingInformationPriorityPath();
// Paths for EncryptionInfo
static std::string GetEncryptionInfoEncryptionKeyPath();
static std::string GetEncryptionInfoPublicKeyIdPath();
private:
static const char kEncryptedWrappedRecord_[];
static const char kSequencingInformationKey_[];
static const char kEncryptionInfoKey_[];
};
// Builds a |base::Value| dictionary from a |reporting::SequencingInformation|
// proto.
class SequencingInformationDictionaryBuilder {
public:
SequencingInformationDictionaryBuilder() = delete;
static base::Optional<base::Value> ConvertSequencingInformationProtoToValue(
const ::reporting::SequencingInformation& sequencing_information);
static std::string GetSequencingIdPath();
static std::string GetGenerationIdPath();
static std::string GetPriorityPath();
private:
static const char kSequencingId_[];
static const char kGenerationId_[];
static const char kPriority_[];
};
// Builds a |base::Value| dictionary from a |reporting::EncryptionInfo| proto.
class EncryptionInfoDictionaryBuilder {
public:
EncryptionInfoDictionaryBuilder() = delete;
static base::Optional<base::Value> ConvertEncryptionInfoProtoToValue(
const ::reporting::EncryptionInfo& encryption_info);
static std::string GetEncryptionKeyPath();
static std::string GetPublicKeyIdPath();
private:
static const char kEncryptionKey_[];
static const char kPublicKeyId_[];
};
friend class EncryptedReportingJobConfigurationTest;
void AddEncryptedRecordListToPayload();
std::set<std::string> GetTopLevelKeyAllowList();
static const char kEncryptedRecordListKey_[];
static const char kDeviceKey_[];
static const char kBrowserKey_[];
};
} // namespace policy
......
......@@ -52,8 +52,8 @@ void MockCloudPolicyClient::SetStatus(DeviceManagementStatus status) {
status_ = status;
}
MockCloudPolicyClientObserver::MockCloudPolicyClientObserver() {}
MockCloudPolicyClientObserver::MockCloudPolicyClientObserver() = default;
MockCloudPolicyClientObserver::~MockCloudPolicyClientObserver() {}
MockCloudPolicyClientObserver::~MockCloudPolicyClientObserver() = default;
} // namespace policy
......@@ -111,7 +111,7 @@ class MockCloudPolicyClient : public CloudPolicyClient {
StatusCallback&));
MOCK_METHOD3(UploadEncryptedReport,
void(const ::reporting::EncryptedRecord&,
void(base::Value,
base::Optional<base::Value>,
ResponseCallback));
......@@ -159,26 +159,25 @@ class MockCloudPolicyClient : public CloudPolicyClient {
const enterprise_management::PolicyFetchResponse& policy);
// Inject invalidation version.
void SetFetchedInvalidationVersion(
int64_t fetched_invalidation_version);
void SetFetchedInvalidationVersion(int64_t fetched_invalidation_version);
// Sets the status field.
void SetStatus(DeviceManagementStatus status);
// Make the notification helpers public.
using CloudPolicyClient::NotifyClientError;
using CloudPolicyClient::NotifyPolicyFetched;
using CloudPolicyClient::NotifyRegistrationStateChanged;
using CloudPolicyClient::NotifyClientError;
using CloudPolicyClient::dm_token_;
using CloudPolicyClient::client_id_;
using CloudPolicyClient::dm_token_;
using CloudPolicyClient::fetched_invalidation_version_;
using CloudPolicyClient::invalidation_payload_;
using CloudPolicyClient::invalidation_version_;
using CloudPolicyClient::last_policy_timestamp_;
using CloudPolicyClient::public_key_version_;
using CloudPolicyClient::public_key_version_valid_;
using CloudPolicyClient::types_to_fetch_;
using CloudPolicyClient::invalidation_version_;
using CloudPolicyClient::invalidation_payload_;
using CloudPolicyClient::fetched_invalidation_version_;
private:
DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyClient);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment