blob: 6708bc5f604a51c4b660255468627e618d6ce267 [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package metrics
import (
"context"
"chromiumos/tast/common/testexec"
"chromiumos/tast/errors"
)
const (
metricsClientPath = "/usr/bin/metrics_client"
// metricsClientArg: "-c: return exit status 0 if user consents to stats,""
// "1 otherwise, in guest mode always return 1"
metricsClientArg = "-c"
// userConsents is the exit status if the user consents to stats.
userConsents = 0
// userDoesNotConsent is the exit status if the user does not consent to stats.
userDoesNotConsent = 1
)
// HasConsent checks if the system has metrics consent.
func HasConsent(ctx context.Context) (bool, error) {
// The C++ code reads the (possibly multiple) device policy files, and then
// falls back to previous files if the latest file isn't valid, and then falls
// back to enterprise enrollments and legacy consent files.
// Rather than try to reproduce all that in Go, call a C++ program that runs
// the exact same code that crash_reporter & crash_sender does.
err := testexec.CommandContext(ctx, metricsClientPath, metricsClientArg).Run()
code, ok := testexec.ExitCode(err)
if !ok {
return false, errors.Wrapf(err, "could not exec %s %s", metricsClientPath, metricsClientArg)
}
switch code {
case userConsents:
return true, nil
case userDoesNotConsent:
return false, nil
default:
return false, errors.Errorf("unexpected exit code from %s %s: %d", metricsClientPath, metricsClientArg, code)
}
}