// Copyright 2022 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package chromemanagement provides access to the Chrome Management API.
//
// For product documentation, see: http://developers.google.com/chrome/management/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/chromemanagement/v1"
//   ...
//   ctx := context.Background()
//   chromemanagementService, err := chromemanagement.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   chromemanagementService, err := chromemanagement.NewService(ctx, option.WithScopes(chromemanagement.ChromeManagementTelemetryReadonlyScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   chromemanagementService, err := chromemanagement.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   chromemanagementService, err := chromemanagement.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package chromemanagement // import "google.golang.org/api/chromemanagement/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	internal "google.golang.org/api/internal"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint

const apiId = "chromemanagement:v1"
const apiName = "chromemanagement"
const apiVersion = "v1"
const basePath = "https://chromemanagement.googleapis.com/"
const mtlsBasePath = "https://chromemanagement.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See detailed information about apps installed on Chrome browsers and
	// devices managed by your organization
	ChromeManagementAppdetailsReadonlyScope = "https://www.googleapis.com/auth/chrome.management.appdetails.readonly"

	// See reports about devices and Chrome browsers managed within your
	// organization
	ChromeManagementReportsReadonlyScope = "https://www.googleapis.com/auth/chrome.management.reports.readonly"

	// See basic device and telemetry information collected from Chrome OS
	// devices or users managed within your organization
	ChromeManagementTelemetryReadonlyScope = "https://www.googleapis.com/auth/chrome.management.telemetry.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := internaloption.WithDefaultScopes(
		"https://www.googleapis.com/auth/chrome.management.appdetails.readonly",
		"https://www.googleapis.com/auth/chrome.management.reports.readonly",
		"https://www.googleapis.com/auth/chrome.management.telemetry.readonly",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Customers = NewCustomersService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Customers *CustomersService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewCustomersService(s *Service) *CustomersService {
	rs := &CustomersService{s: s}
	rs.Apps = NewCustomersAppsService(s)
	rs.Reports = NewCustomersReportsService(s)
	rs.Telemetry = NewCustomersTelemetryService(s)
	return rs
}

type CustomersService struct {
	s *Service

	Apps *CustomersAppsService

	Reports *CustomersReportsService

	Telemetry *CustomersTelemetryService
}

func NewCustomersAppsService(s *Service) *CustomersAppsService {
	rs := &CustomersAppsService{s: s}
	rs.Android = NewCustomersAppsAndroidService(s)
	rs.Chrome = NewCustomersAppsChromeService(s)
	rs.Web = NewCustomersAppsWebService(s)
	return rs
}

type CustomersAppsService struct {
	s *Service

	Android *CustomersAppsAndroidService

	Chrome *CustomersAppsChromeService

	Web *CustomersAppsWebService
}

func NewCustomersAppsAndroidService(s *Service) *CustomersAppsAndroidService {
	rs := &CustomersAppsAndroidService{s: s}
	return rs
}

type CustomersAppsAndroidService struct {
	s *Service
}

func NewCustomersAppsChromeService(s *Service) *CustomersAppsChromeService {
	rs := &CustomersAppsChromeService{s: s}
	return rs
}

type CustomersAppsChromeService struct {
	s *Service
}

func NewCustomersAppsWebService(s *Service) *CustomersAppsWebService {
	rs := &CustomersAppsWebService{s: s}
	return rs
}

type CustomersAppsWebService struct {
	s *Service
}

func NewCustomersReportsService(s *Service) *CustomersReportsService {
	rs := &CustomersReportsService{s: s}
	return rs
}

type CustomersReportsService struct {
	s *Service
}

func NewCustomersTelemetryService(s *Service) *CustomersTelemetryService {
	rs := &CustomersTelemetryService{s: s}
	rs.Devices = NewCustomersTelemetryDevicesService(s)
	return rs
}

type CustomersTelemetryService struct {
	s *Service

	Devices *CustomersTelemetryDevicesService
}

func NewCustomersTelemetryDevicesService(s *Service) *CustomersTelemetryDevicesService {
	rs := &CustomersTelemetryDevicesService{s: s}
	return rs
}

type CustomersTelemetryDevicesService struct {
	s *Service
}

// GoogleChromeManagementV1AndroidAppInfo: Android app information.
type GoogleChromeManagementV1AndroidAppInfo struct {
	// Permissions: Output only. Permissions requested by an Android app.
	Permissions []*GoogleChromeManagementV1AndroidAppPermission `json:"permissions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Permissions") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Permissions") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1AndroidAppInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1AndroidAppInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1AndroidAppPermission: Permission requested by
// an Android app.
type GoogleChromeManagementV1AndroidAppPermission struct {
	// Type: Output only. The type of the permission.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Type") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Type") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1AndroidAppPermission) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1AndroidAppPermission
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1AppDetails: Resource representing app
// details.
type GoogleChromeManagementV1AppDetails struct {
	// AndroidAppInfo: Output only. Android app information.
	AndroidAppInfo *GoogleChromeManagementV1AndroidAppInfo `json:"androidAppInfo,omitempty"`

	// AppId: Output only. Unique store identifier for the item. Examples:
	// "gmbmikajjgmnabiglmofipeabaddhgne" for the Save to Google Drive
	// Chrome extension, "com.google.android.apps.docs" for the Google Drive
	// Android app.
	AppId string `json:"appId,omitempty"`

	// ChromeAppInfo: Output only. Chrome Web Store app information.
	ChromeAppInfo *GoogleChromeManagementV1ChromeAppInfo `json:"chromeAppInfo,omitempty"`

	// Description: Output only. App's description.
	Description string `json:"description,omitempty"`

	// DetailUri: Output only. The uri for the detail page of the item.
	DetailUri string `json:"detailUri,omitempty"`

	// DisplayName: Output only. App's display name.
	DisplayName string `json:"displayName,omitempty"`

	// FirstPublishTime: Output only. First published time.
	FirstPublishTime string `json:"firstPublishTime,omitempty"`

	// HomepageUri: Output only. Home page or Website uri.
	HomepageUri string `json:"homepageUri,omitempty"`

	// IconUri: Output only. A link to an image that can be used as an icon
	// for the product.
	IconUri string `json:"iconUri,omitempty"`

	// IsPaidApp: Output only. Indicates if the app has to be paid for OR
	// has paid content.
	IsPaidApp bool `json:"isPaidApp,omitempty"`

	// LatestPublishTime: Output only. Latest published time.
	LatestPublishTime string `json:"latestPublishTime,omitempty"`

	// Name: Output only. Format:
	// name=customers/{customer_id}/apps/{chrome|android|web}/{app_id}@{versi
	// on}
	Name string `json:"name,omitempty"`

	// PrivacyPolicyUri: Output only. The URI pointing to the privacy policy
	// of the app, if it was provided by the developer. Version-specific
	// field that will only be set when the requested app version is found.
	PrivacyPolicyUri string `json:"privacyPolicyUri,omitempty"`

	// Publisher: Output only. The publisher of the item.
	Publisher string `json:"publisher,omitempty"`

	// ReviewNumber: Output only. Number of reviews received. Chrome Web
	// Store review information will always be for the latest version of an
	// app.
	ReviewNumber int64 `json:"reviewNumber,omitempty,string"`

	// ReviewRating: Output only. The rating of the app (on 5 stars). Chrome
	// Web Store review information will always be for the latest version of
	// an app.
	ReviewRating float64 `json:"reviewRating,omitempty"`

	// RevisionId: Output only. App version. A new revision is committed
	// whenever a new version of the app is published.
	RevisionId string `json:"revisionId,omitempty"`

	// ServiceError: Output only. Information about a partial service error
	// if applicable.
	ServiceError *GoogleRpcStatus `json:"serviceError,omitempty"`

	// Type: Output only. App type.
	//
	// Possible values:
	//   "APP_ITEM_TYPE_UNSPECIFIED" - App type unspecified.
	//   "CHROME" - Chrome app.
	//   "ANDROID" - ARC++ app.
	//   "WEB" - Web app.
	Type string `json:"type,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AndroidAppInfo") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AndroidAppInfo") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1AppDetails) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1AppDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleChromeManagementV1AppDetails) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleChromeManagementV1AppDetails
	var s1 struct {
		ReviewRating gensupport.JSONFloat64 `json:"reviewRating"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.ReviewRating = float64(s1.ReviewRating)
	return nil
}

// GoogleChromeManagementV1AudioStatusReport: Audio report.
type GoogleChromeManagementV1AudioStatusReport struct {
	// InputDevice: Output only. Active input device's name.
	InputDevice string `json:"inputDevice,omitempty"`

	// InputGain: Output only. Active input device's gain in [0, 100].
	InputGain int64 `json:"inputGain,omitempty"`

	// InputMute: Output only. Is active input device mute or not.
	InputMute bool `json:"inputMute,omitempty"`

	// OutputDevice: Output only. Active output device's name.
	OutputDevice string `json:"outputDevice,omitempty"`

	// OutputMute: Output only. Is active output device mute or not.
	OutputMute bool `json:"outputMute,omitempty"`

	// OutputVolume: Output only. Active output device's volume in [0, 100].
	OutputVolume int64 `json:"outputVolume,omitempty"`

	// ReportTime: Output only. Timestamp of when the sample was collected
	// on device.
	ReportTime string `json:"reportTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InputDevice") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InputDevice") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1AudioStatusReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1AudioStatusReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1BatteryInfo: Battery info
type GoogleChromeManagementV1BatteryInfo struct {
	// DesignCapacity: Output only. Design capacity (mAmpere-hours).
	DesignCapacity int64 `json:"designCapacity,omitempty,string"`

	// DesignMinVoltage: Output only. Designed minimum output voltage (mV)
	DesignMinVoltage int64 `json:"designMinVoltage,omitempty"`

	// ManufactureDate: Output only. The date the battery was manufactured.
	ManufactureDate *GoogleTypeDate `json:"manufactureDate,omitempty"`

	// Manufacturer: Output only. Battery manufacturer.
	Manufacturer string `json:"manufacturer,omitempty"`

	// SerialNumber: Output only. Battery serial number.
	SerialNumber string `json:"serialNumber,omitempty"`

	// Technology: Output only. Technology of the battery. Example: Li-ion
	Technology string `json:"technology,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DesignCapacity") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DesignCapacity") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1BatteryInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1BatteryInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1BatterySampleReport: Sampling data for
// battery.
type GoogleChromeManagementV1BatterySampleReport struct {
	// ChargeRate: Output only. Battery charge percentage.
	ChargeRate int64 `json:"chargeRate,omitempty"`

	// Current: Output only. Battery current (mA).
	Current int64 `json:"current,omitempty,string"`

	// DischargeRate: Output only. The battery discharge rate measured in
	// mW. Positive if the battery is being discharged, negative if it's
	// being charged.
	DischargeRate int64 `json:"dischargeRate,omitempty"`

	// RemainingCapacity: Output only. Battery remaining capacity
	// (mAmpere-hours).
	RemainingCapacity int64 `json:"remainingCapacity,omitempty,string"`

	// ReportTime: Output only. Timestamp of when the sample was collected
	// on device
	ReportTime string `json:"reportTime,omitempty"`

	// Status: Output only. Battery status read from sysfs. Example:
	// Discharging
	Status string `json:"status,omitempty"`

	// Temperature: Output only. Temperature in Celsius degrees.
	Temperature int64 `json:"temperature,omitempty"`

	// Voltage: Output only. Battery voltage (millivolt).
	Voltage int64 `json:"voltage,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "ChargeRate") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChargeRate") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1BatterySampleReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1BatterySampleReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1BatteryStatusReport: Status data for battery.
type GoogleChromeManagementV1BatteryStatusReport struct {
	// BatteryHealth: Output only. Battery health.
	//
	// Possible values:
	//   "BATTERY_HEALTH_UNSPECIFIED" - Health unknown.
	//   "BATTERY_HEALTH_NORMAL" - Battery is healthy.
	//   "BATTERY_REPLACE_SOON" - Battery is moderately unhealthy and should
	// be replaced soon.
	//   "BATTERY_REPLACE_NOW" - Battery is unhealthy and should be
	// replaced.
	BatteryHealth string `json:"batteryHealth,omitempty"`

	// CycleCount: Output only. Cycle count.
	CycleCount int64 `json:"cycleCount,omitempty"`

	// FullChargeCapacity: Output only. Full charge capacity
	// (mAmpere-hours).
	FullChargeCapacity int64 `json:"fullChargeCapacity,omitempty,string"`

	// ReportTime: Output only. Timestamp of when the sample was collected
	// on device
	ReportTime string `json:"reportTime,omitempty"`

	// Sample: Output only. Sampling data for the battery sorted in a
	// decreasing order of report_time.
	Sample []*GoogleChromeManagementV1BatterySampleReport `json:"sample,omitempty"`

	// SerialNumber: Output only. Battery serial number.
	SerialNumber string `json:"serialNumber,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BatteryHealth") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BatteryHealth") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1BatteryStatusReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1BatteryStatusReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1BrowserVersion: Describes a browser version
// and its install count.
type GoogleChromeManagementV1BrowserVersion struct {
	// Channel: Output only. The release channel of the installed browser.
	//
	// Possible values:
	//   "RELEASE_CHANNEL_UNSPECIFIED" - No release channel specified.
	//   "CANARY" - Canary release channel.
	//   "DEV" - Dev release channel.
	//   "BETA" - Beta release channel.
	//   "STABLE" - Stable release channel.
	Channel string `json:"channel,omitempty"`

	// Count: Output only. Count grouped by device_system and major version
	Count int64 `json:"count,omitempty,string"`

	// DeviceOsVersion: Output only. Version of the system-specified
	// operating system.
	DeviceOsVersion string `json:"deviceOsVersion,omitempty"`

	// System: Output only. The device operating system.
	//
	// Possible values:
	//   "DEVICE_SYSTEM_UNSPECIFIED" - No operating system specified.
	//   "SYSTEM_OTHER" - Other operating system.
	//   "SYSTEM_ANDROID" - Android operating system.
	//   "SYSTEM_IOS" - Apple iOS operating system.
	//   "SYSTEM_CROS" - ChromeOS operating system.
	//   "SYSTEM_WINDOWS" - Microsoft Windows operating system.
	//   "SYSTEM_MAC" - Apple macOS operating system.
	//   "SYSTEM_LINUX" - Linux operating system.
	System string `json:"system,omitempty"`

	// Version: Output only. The full version of the installed browser.
	Version string `json:"version,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Channel") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Channel") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1BrowserVersion) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1BrowserVersion
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1ChromeAppInfo: Chrome Web Store app
// information.
type GoogleChromeManagementV1ChromeAppInfo struct {
	// GoogleOwned: Output only. Whether the app or extension is built and
	// maintained by Google. Version-specific field that will only be set
	// when the requested app version is found.
	GoogleOwned bool `json:"googleOwned,omitempty"`

	// IsCwsHosted: Output only. Whether the app or extension is in a
	// published state in the Chrome Web Store.
	IsCwsHosted bool `json:"isCwsHosted,omitempty"`

	// IsKioskOnly: Output only. Whether the app is only for Kiosk mode on
	// ChromeOS devices
	IsKioskOnly bool `json:"isKioskOnly,omitempty"`

	// IsTheme: Output only. Whether the app or extension is a theme.
	IsTheme bool `json:"isTheme,omitempty"`

	// KioskEnabled: Output only. Whether this app is enabled for Kiosk mode
	// on ChromeOS devices
	KioskEnabled bool `json:"kioskEnabled,omitempty"`

	// MinUserCount: Output only. The minimum number of users using this
	// app.
	MinUserCount int64 `json:"minUserCount,omitempty"`

	// Permissions: Output only. Every custom permission requested by the
	// app. Version-specific field that will only be set when the requested
	// app version is found.
	Permissions []*GoogleChromeManagementV1ChromeAppPermission `json:"permissions,omitempty"`

	// SiteAccess: Output only. Every permission giving access to domains or
	// broad host patterns. ( e.g. www.google.com). This includes the
	// matches from content scripts as well as hosts in the permissions node
	// of the manifest. Version-specific field that will only be set when
	// the requested app version is found.
	SiteAccess []*GoogleChromeManagementV1ChromeAppSiteAccess `json:"siteAccess,omitempty"`

	// SupportEnabled: Output only. The app developer has enabled support
	// for their app. Version-specific field that will only be set when the
	// requested app version is found.
	SupportEnabled bool `json:"supportEnabled,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GoogleOwned") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GoogleOwned") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1ChromeAppInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1ChromeAppInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1ChromeAppPermission: Permission requested by
// a Chrome app or extension.
type GoogleChromeManagementV1ChromeAppPermission struct {
	// AccessUserData: Output only. If available, whether this permissions
	// grants the app/extension access to user data.
	AccessUserData bool `json:"accessUserData,omitempty"`

	// DocumentationUri: Output only. If available, a URI to a page that has
	// documentation for the current permission.
	DocumentationUri string `json:"documentationUri,omitempty"`

	// Type: Output only. The type of the permission.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccessUserData") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AccessUserData") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1ChromeAppPermission) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1ChromeAppPermission
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1ChromeAppRequest: Details of an app
// installation request.
type GoogleChromeManagementV1ChromeAppRequest struct {
	// AppDetails: Output only. Format:
	// app_details=customers/{customer_id}/apps/chrome/{app_id}
	AppDetails string `json:"appDetails,omitempty"`

	// AppId: Output only. Unique store identifier for the app. Example:
	// "gmbmikajjgmnabiglmofipeabaddhgne" for the Save to Google Drive
	// Chrome extension.
	AppId string `json:"appId,omitempty"`

	// DetailUri: Output only. The uri for the detail page of the item.
	DetailUri string `json:"detailUri,omitempty"`

	// DisplayName: Output only. App's display name.
	DisplayName string `json:"displayName,omitempty"`

	// IconUri: Output only. A link to an image that can be used as an icon
	// for the product.
	IconUri string `json:"iconUri,omitempty"`

	// LatestRequestTime: Output only. The timestamp of the most recently
	// made request for this app.
	LatestRequestTime string `json:"latestRequestTime,omitempty"`

	// RequestCount: Output only. Total count of requests for this app.
	RequestCount int64 `json:"requestCount,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "AppDetails") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AppDetails") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1ChromeAppRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1ChromeAppRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1ChromeAppSiteAccess: Represent one host
// permission.
type GoogleChromeManagementV1ChromeAppSiteAccess struct {
	// HostMatch: Output only. This can contain very specific hosts, or
	// patterns like "*.com" for instance.
	HostMatch string `json:"hostMatch,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HostMatch") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HostMatch") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1ChromeAppSiteAccess) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1ChromeAppSiteAccess
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1CountChromeAppRequestsResponse: Response
// containing summary of requested app installations.
type GoogleChromeManagementV1CountChromeAppRequestsResponse struct {
	// NextPageToken: Token to specify the next page in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// RequestedApps: Count of requested apps matching request.
	RequestedApps []*GoogleChromeManagementV1ChromeAppRequest `json:"requestedApps,omitempty"`

	// TotalSize: Total number of matching app requests.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1CountChromeAppRequestsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1CountChromeAppRequestsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1CountChromeVersionsResponse: Response
// containing requested browser versions details and counts.
type GoogleChromeManagementV1CountChromeVersionsResponse struct {
	// BrowserVersions: List of all browser versions and their install
	// counts.
	BrowserVersions []*GoogleChromeManagementV1BrowserVersion `json:"browserVersions,omitempty"`

	// NextPageToken: Token to specify the next page of the request.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalSize: Total number browser versions matching request.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "BrowserVersions") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BrowserVersions") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1CountChromeVersionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1CountChromeVersionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1CountInstalledAppsResponse: Response
// containing details of queried installed apps.
type GoogleChromeManagementV1CountInstalledAppsResponse struct {
	// InstalledApps: List of installed apps matching request.
	InstalledApps []*GoogleChromeManagementV1InstalledApp `json:"installedApps,omitempty"`

	// NextPageToken: Token to specify the next page of the request.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalSize: Total number of installed apps matching request.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "InstalledApps") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InstalledApps") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1CountInstalledAppsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1CountInstalledAppsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1CpuInfo: CPU specs for a CPU.
type GoogleChromeManagementV1CpuInfo struct {
	// Architecture: Output only. The CPU architecture.
	//
	// Possible values:
	//   "ARCHITECTURE_UNSPECIFIED" - Architecture unknown.
	//   "X64" - x64 architecture
	Architecture string `json:"architecture,omitempty"`

	// MaxClockSpeed: Output only. The max CPU clock speed in kHz.
	MaxClockSpeed int64 `json:"maxClockSpeed,omitempty"`

	// Model: Output only. The CPU model name. Example: Intel(R) Core(TM)
	// i5-8250U CPU @ 1.60GHz
	Model string `json:"model,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Architecture") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Architecture") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1CpuInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1CpuInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1CpuStatusReport: Contains samples of the cpu
// status reports.
type GoogleChromeManagementV1CpuStatusReport struct {
	// CpuTemperatureInfo: Output only. CPU temperature sample info per CPU
	// core in Celsius
	CpuTemperatureInfo []*GoogleChromeManagementV1CpuTemperatureInfo `json:"cpuTemperatureInfo,omitempty"`

	// CpuUtilizationPct: Output only. Sample of CPU utilization (0-100
	// percent).
	CpuUtilizationPct int64 `json:"cpuUtilizationPct,omitempty"`

	// ReportTime: Output only. The timestamp in milliseconds representing
	// time at which this report was sampled.
	ReportTime string `json:"reportTime,omitempty"`

	// SampleFrequency: Output only. Frequency the report is sampled.
	SampleFrequency string `json:"sampleFrequency,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CpuTemperatureInfo")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CpuTemperatureInfo") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1CpuStatusReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1CpuStatusReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1CpuTemperatureInfo: CPU temperature of a
// device. Sampled per CPU core in Celsius
type GoogleChromeManagementV1CpuTemperatureInfo struct {
	// Label: Output only. CPU label. Example: Core 0
	Label string `json:"label,omitempty"`

	// TemperatureCelsius: Output only. CPU temperature in Celsius.
	TemperatureCelsius int64 `json:"temperatureCelsius,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Label") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Label") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1CpuTemperatureInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1CpuTemperatureInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1Device: Describes a device reporting Chrome
// browser information.
type GoogleChromeManagementV1Device struct {
	// DeviceId: Output only. The ID of the device that reported this Chrome
	// browser information.
	DeviceId string `json:"deviceId,omitempty"`

	// Machine: Output only. The name of the machine within its local
	// network.
	Machine string `json:"machine,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeviceId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DeviceId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1Device) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1Device
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1DiskInfo: Status of the single storage
// device.
type GoogleChromeManagementV1DiskInfo struct {
	// BytesReadThisSession: Output only. Number of bytes read since last
	// boot.
	BytesReadThisSession int64 `json:"bytesReadThisSession,omitempty,string"`

	// BytesWrittenThisSession: Output only. Number of bytes written since
	// last boot.
	BytesWrittenThisSession int64 `json:"bytesWrittenThisSession,omitempty,string"`

	// DiscardTimeThisSession: Output only. Time spent discarding since last
	// boot. Discarding is writing to clear blocks which are no longer in
	// use. Supported on kernels 4.18+.
	DiscardTimeThisSession string `json:"discardTimeThisSession,omitempty"`

	// Health: Output only. Disk health.
	Health string `json:"health,omitempty"`

	// IoTimeThisSession: Output only. Counts the time the disk and queue
	// were busy, so unlike the fields above, parallel requests are not
	// counted multiple times.
	IoTimeThisSession string `json:"ioTimeThisSession,omitempty"`

	// Manufacturer: Output only. Disk manufacturer.
	Manufacturer string `json:"manufacturer,omitempty"`

	// Model: Output only. Disk model.
	Model string `json:"model,omitempty"`

	// ReadTimeThisSession: Output only. Time spent reading from disk since
	// last boot.
	ReadTimeThisSession string `json:"readTimeThisSession,omitempty"`

	// SerialNumber: Output only. Disk serial number.
	SerialNumber string `json:"serialNumber,omitempty"`

	// SizeBytes: Output only. Disk size.
	SizeBytes int64 `json:"sizeBytes,omitempty,string"`

	// Type: Output only. Disk type: eMMC / NVMe / ATA / SCSI.
	Type string `json:"type,omitempty"`

	// VolumeIds: Output only. Disk volumes.
	VolumeIds []string `json:"volumeIds,omitempty"`

	// WriteTimeThisSession: Output only. Time spent writing to disk since
	// last boot.
	WriteTimeThisSession string `json:"writeTimeThisSession,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "BytesReadThisSession") to unconditionally include in API requests.
	// By default, fields with empty or default values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BytesReadThisSession") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1DiskInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1DiskInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1DisplayInfo: Information for a display.
type GoogleChromeManagementV1DisplayInfo struct {
	// DeviceId: Output only. Represents the graphics card device id.
	DeviceId int64 `json:"deviceId,omitempty,string"`

	// IsInternal: Output only. Indicates if display is internal or not.
	IsInternal bool `json:"isInternal,omitempty"`

	// RefreshRate: Output only. Refresh rate in Hz.
	RefreshRate int64 `json:"refreshRate,omitempty"`

	// ResolutionHeight: Output only. Resolution height in pixels.
	ResolutionHeight int64 `json:"resolutionHeight,omitempty"`

	// ResolutionWidth: Output only. Resolution width in pixels.
	ResolutionWidth int64 `json:"resolutionWidth,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeviceId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DeviceId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1DisplayInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1DisplayInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1FindInstalledAppDevicesResponse: Response
// containing a list of devices with queried app installed.
type GoogleChromeManagementV1FindInstalledAppDevicesResponse struct {
	// Devices: A list of devices which have the app installed. Sorted in
	// ascending alphabetical order on the Device.machine field.
	Devices []*GoogleChromeManagementV1Device `json:"devices,omitempty"`

	// NextPageToken: Token to specify the next page of the request.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalSize: Total number of devices matching request.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Devices") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Devices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1FindInstalledAppDevicesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1FindInstalledAppDevicesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1GraphicsAdapterInfo: Information of a
// graphics adapter (GPU).
type GoogleChromeManagementV1GraphicsAdapterInfo struct {
	// Adapter: Output only. Adapter name. Example: Mesa DRI Intel(R) UHD
	// Graphics 620 (Kabylake GT2).
	Adapter string `json:"adapter,omitempty"`

	// DeviceId: Output only. Represents the graphics card device id.
	DeviceId int64 `json:"deviceId,omitempty,string"`

	// DriverVersion: Output only. Version of the GPU driver.
	DriverVersion string `json:"driverVersion,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Adapter") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Adapter") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1GraphicsAdapterInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1GraphicsAdapterInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1GraphicsInfo: Information of the graphics
// subsystem.
type GoogleChromeManagementV1GraphicsInfo struct {
	// AdapterInfo: Output only. Information about the graphics adapter
	// (GPU).
	AdapterInfo *GoogleChromeManagementV1GraphicsAdapterInfo `json:"adapterInfo,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdapterInfo") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AdapterInfo") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1GraphicsInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1GraphicsInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1GraphicsStatusReport: Information of the
// graphics subsystem.
type GoogleChromeManagementV1GraphicsStatusReport struct {
	// Displays: Output only. Information about the displays for the device.
	Displays []*GoogleChromeManagementV1DisplayInfo `json:"displays,omitempty"`

	// ReportTime: Output only. Time at which the graphics data was
	// reported.
	ReportTime string `json:"reportTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Displays") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Displays") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1GraphicsStatusReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1GraphicsStatusReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1InstalledApp: Describes an installed app.
type GoogleChromeManagementV1InstalledApp struct {
	// AppId: Output only. Unique identifier of the app. For Chrome apps and
	// extensions, the 32-character id (e.g.
	// ehoadneljpdggcbbknedodolkkjodefl). For Android apps, the package name
	// (e.g. com.evernote).
	AppId string `json:"appId,omitempty"`

	// AppInstallType: Output only. How the app was installed.
	//
	// Possible values:
	//   "APP_INSTALL_TYPE_UNSPECIFIED" - Application install type not
	// specified.
	//   "MULTIPLE" - Multiple app install types.
	//   "NORMAL" - Normal app install type.
	//   "ADMIN" - Administrator app install type.
	//   "DEVELOPMENT" - Development app install type.
	//   "SIDELOAD" - Sideloaded app install type.
	//   "OTHER" - Other app install type.
	AppInstallType string `json:"appInstallType,omitempty"`

	// AppSource: Output only. Source of the installed app.
	//
	// Possible values:
	//   "APP_SOURCE_UNSPECIFIED" - Application source not specified.
	//   "CHROME_WEBSTORE" - Generally for extensions and Chrome apps.
	//   "PLAY_STORE" - Play Store app.
	AppSource string `json:"appSource,omitempty"`

	// AppType: Output only. Type of the app.
	//
	// Possible values:
	//   "APP_TYPE_UNSPECIFIED" - App type not specified.
	//   "EXTENSION" - Chrome extension.
	//   "APP" - Chrome app.
	//   "THEME" - Chrome theme.
	//   "HOSTED_APP" - Chrome hosted app.
	//   "ANDROID_APP" - ARC++ app.
	AppType string `json:"appType,omitempty"`

	// BrowserDeviceCount: Output only. Count of browser devices with this
	// app installed.
	BrowserDeviceCount int64 `json:"browserDeviceCount,omitempty,string"`

	// Description: Output only. Description of the installed app.
	Description string `json:"description,omitempty"`

	// Disabled: Output only. Whether the app is disabled.
	Disabled bool `json:"disabled,omitempty"`

	// DisplayName: Output only. Name of the installed app.
	DisplayName string `json:"displayName,omitempty"`

	// HomepageUri: Output only. Homepage uri of the installed app.
	HomepageUri string `json:"homepageUri,omitempty"`

	// OsUserCount: Output only. Count of ChromeOS users with this app
	// installed.
	OsUserCount int64 `json:"osUserCount,omitempty,string"`

	// Permissions: Output only. Permissions of the installed app.
	Permissions []string `json:"permissions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AppId") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1InstalledApp) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1InstalledApp
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleChromeManagementV1ListTelemetryDevicesResponse struct {
	// Devices: Telemetry devices returned in the response.
	Devices []*GoogleChromeManagementV1TelemetryDevice `json:"devices,omitempty"`

	// NextPageToken: Token to specify next page in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Devices") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Devices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1ListTelemetryDevicesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1ListTelemetryDevicesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1MemoryInfo: Memory information of a device.
type GoogleChromeManagementV1MemoryInfo struct {
	// AvailableRamBytes: Output only. Amount of available RAM in bytes.
	AvailableRamBytes int64 `json:"availableRamBytes,omitempty,string"`

	// TotalRamBytes: Output only. Total RAM in bytes.
	TotalRamBytes int64 `json:"totalRamBytes,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "AvailableRamBytes")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AvailableRamBytes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1MemoryInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1MemoryInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1MemoryStatusReport: Contains samples of
// memory status reports.
type GoogleChromeManagementV1MemoryStatusReport struct {
	// PageFaults: Output only. Number of page faults during this collection
	PageFaults int64 `json:"pageFaults,omitempty"`

	// ReportTime: Output only. The timestamp in milliseconds representing
	// time at which this report was sampled.
	ReportTime string `json:"reportTime,omitempty"`

	// SampleFrequency: Output only. Frequency the report is sampled.
	SampleFrequency string `json:"sampleFrequency,omitempty"`

	// SystemRamFreeBytes: Output only. Amount of free RAM in bytes
	// (unreliable due to Garbage Collection).
	SystemRamFreeBytes int64 `json:"systemRamFreeBytes,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "PageFaults") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PageFaults") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1MemoryStatusReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1MemoryStatusReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1NetworkStatusReport: State of
// visible/configured networks.
type GoogleChromeManagementV1NetworkStatusReport struct {
	// GatewayIpAddress: Output only. Gateway IP address.
	GatewayIpAddress string `json:"gatewayIpAddress,omitempty"`

	// LanIpAddress: Output only. LAN IP address.
	LanIpAddress string `json:"lanIpAddress,omitempty"`

	// ReportTime: Output only. Time at which the network state was
	// reported.
	ReportTime string `json:"reportTime,omitempty"`

	// SampleFrequency: Output only. Frequency the report is sampled.
	SampleFrequency string `json:"sampleFrequency,omitempty"`

	// SignalStrengthDbm: Output only. Signal strength for wireless networks
	// measured in decibels.
	SignalStrengthDbm int64 `json:"signalStrengthDbm,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GatewayIpAddress") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GatewayIpAddress") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1NetworkStatusReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1NetworkStatusReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1OsUpdateStatus: Contains information
// regarding the current OS update status.
type GoogleChromeManagementV1OsUpdateStatus struct {
	// LastRebootTime: Output only. Timestamp of the last reboot.
	LastRebootTime string `json:"lastRebootTime,omitempty"`

	// LastUpdateCheckTime: Output only. Timestamp of the last update check.
	LastUpdateCheckTime string `json:"lastUpdateCheckTime,omitempty"`

	// LastUpdateTime: Output only. Timestamp of the last successful update.
	LastUpdateTime string `json:"lastUpdateTime,omitempty"`

	// NewPlatformVersion: Output only. New platform version of the os image
	// being downloaded and applied. It is only set when update status is
	// OS_IMAGE_DOWNLOAD_IN_PROGRESS or OS_UPDATE_NEED_REBOOT. Note this
	// could be a dummy "0.0.0.0" for OS_UPDATE_NEED_REBOOT status for some
	// edge cases, e.g. update engine is restarted without a reboot.
	NewPlatformVersion string `json:"newPlatformVersion,omitempty"`

	// NewRequestedPlatformVersion: Output only. New requested platform
	// version from the pending updated kiosk app.
	NewRequestedPlatformVersion string `json:"newRequestedPlatformVersion,omitempty"`

	// UpdateState: Output only. Current state of the os update.
	//
	// Possible values:
	//   "UPDATE_STATE_UNSPECIFIED" - State unspecified.
	//   "OS_IMAGE_DOWNLOAD_NOT_STARTED" - OS has not started downloading.
	//   "OS_IMAGE_DOWNLOAD_IN_PROGRESS" - OS has started download on
	// device.
	//   "OS_UPDATE_NEED_REBOOT" - Device needs reboot to finish upload.
	UpdateState string `json:"updateState,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LastRebootTime") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LastRebootTime") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1OsUpdateStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1OsUpdateStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1StorageInfo: Status data for storage.
type GoogleChromeManagementV1StorageInfo struct {
	// AvailableDiskBytes: The available space for user data storage in the
	// device in bytes.
	AvailableDiskBytes int64 `json:"availableDiskBytes,omitempty,string"`

	// TotalDiskBytes: The total space for user data storage in the device
	// in bytes.
	TotalDiskBytes int64 `json:"totalDiskBytes,omitempty,string"`

	// Volume: Information for disk volumes
	Volume []*GoogleChromeManagementV1StorageInfoDiskVolume `json:"volume,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AvailableDiskBytes")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AvailableDiskBytes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1StorageInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1StorageInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1StorageInfoDiskVolume: Information for disk
// volumes
type GoogleChromeManagementV1StorageInfoDiskVolume struct {
	// StorageFreeBytes: Free storage space in bytes.
	StorageFreeBytes int64 `json:"storageFreeBytes,omitempty,string"`

	// StorageTotalBytes: Total storage space in bytes.
	StorageTotalBytes int64 `json:"storageTotalBytes,omitempty,string"`

	// VolumeId: Disk volume id.
	VolumeId string `json:"volumeId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "StorageFreeBytes") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "StorageFreeBytes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1StorageInfoDiskVolume) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1StorageInfoDiskVolume
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1StorageStatusReport: Status data for storage.
type GoogleChromeManagementV1StorageStatusReport struct {
	// Disk: Output only. Reports on disk.
	Disk []*GoogleChromeManagementV1DiskInfo `json:"disk,omitempty"`

	// ReportTime: Output only. Timestamp of when the sample was collected
	// on device
	ReportTime string `json:"reportTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Disk") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Disk") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1StorageStatusReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1StorageStatusReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleChromeManagementV1TelemetryDevice: Telemetry data collected
// from a managed device.
type GoogleChromeManagementV1TelemetryDevice struct {
	// AudioStatusReport: Output only. Audio reports collected periodically
	// sorted in a decreasing order of report_time.
	AudioStatusReport []*GoogleChromeManagementV1AudioStatusReport `json:"audioStatusReport,omitempty"`

	// BatteryInfo: Output only. Information on battery specs for the
	// device.
	BatteryInfo []*GoogleChromeManagementV1BatteryInfo `json:"batteryInfo,omitempty"`

	// BatteryStatusReport: Output only. Battery reports collected
	// periodically.
	BatteryStatusReport []*GoogleChromeManagementV1BatteryStatusReport `json:"batteryStatusReport,omitempty"`

	// CpuInfo: Output only. Information regarding CPU specs for the device.
	CpuInfo []*GoogleChromeManagementV1CpuInfo `json:"cpuInfo,omitempty"`

	// CpuStatusReport: Output only. CPU status reports collected
	// periodically sorted in a decreasing order of report_time.
	CpuStatusReport []*GoogleChromeManagementV1CpuStatusReport `json:"cpuStatusReport,omitempty"`

	// Customer: Output only. Google Workspace Customer whose enterprise
	// enrolled the device.
	Customer string `json:"customer,omitempty"`

	// DeviceId: Output only. The unique Directory API ID of the device.
	// This value is the same as the Admin Console's Directory API ID in the
	// ChromeOS Devices tab
	DeviceId string `json:"deviceId,omitempty"`

	// GraphicsInfo: Output only. Contains information regarding Graphic
	// peripherals for the device.
	GraphicsInfo *GoogleChromeManagementV1GraphicsInfo `json:"graphicsInfo,omitempty"`

	// GraphicsStatusReport: Output only. Graphics reports collected
	// periodically.
	GraphicsStatusReport []*GoogleChromeManagementV1GraphicsStatusReport `json:"graphicsStatusReport,omitempty"`

	// MemoryInfo: Output only. Information regarding memory specs for the
	// device.
	MemoryInfo *GoogleChromeManagementV1MemoryInfo `json:"memoryInfo,omitempty"`

	// MemoryStatusReport: Output only. Memory status reports collected
	// periodically sorted decreasing by report_time.
	MemoryStatusReport []*GoogleChromeManagementV1MemoryStatusReport `json:"memoryStatusReport,omitempty"`

	// Name: Output only. Resource name of the device.
	Name string `json:"name,omitempty"`

	// NetworkStatusReport: Output only. Network specs collected
	// periodically.
	NetworkStatusReport []*GoogleChromeManagementV1NetworkStatusReport `json:"networkStatusReport,omitempty"`

	// OrgUnitId: Output only. Organization unit ID of the device.
	OrgUnitId string `json:"orgUnitId,omitempty"`

	// OsUpdateStatus: Output only. Contains relevant information regarding
	// ChromeOS update status.
	OsUpdateStatus []*GoogleChromeManagementV1OsUpdateStatus `json:"osUpdateStatus,omitempty"`

	// SerialNumber: Output only. Device serial number. This value is the
	// same as the Admin Console's Serial Number in the ChromeOS Devices
	// tab.
	SerialNumber string `json:"serialNumber,omitempty"`

	// StorageInfo: Output only. Information of storage specs for the
	// device.
	StorageInfo *GoogleChromeManagementV1StorageInfo `json:"storageInfo,omitempty"`

	// StorageStatusReport: Output only. Storage reports collected
	// periodically.
	StorageStatusReport []*GoogleChromeManagementV1StorageStatusReport `json:"storageStatusReport,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AudioStatusReport")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AudioStatusReport") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleChromeManagementV1TelemetryDevice) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleChromeManagementV1TelemetryDevice
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleRpcStatus: The `Status` type defines a logical error model that
// is suitable for different programming environments, including REST
// APIs and RPC APIs. It is used by gRPC (https://github.com/grpc). Each
// `Status` message contains three pieces of data: error code, error
// message, and error details. You can find out more about this error
// model and how to work with it in the API Design Guide
// (https://cloud.google.com/apis/design/errors).
type GoogleRpcStatus struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details. There is a
	// common set of message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any user-facing error message should be localized and sent
	// in the google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleRpcStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleRpcStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleTypeDate: Represents a whole or partial calendar date, such as
// a birthday. The time of day and time zone are either specified
// elsewhere or are insignificant. The date is relative to the Gregorian
// Calendar. This can represent one of the following: * A full date,
// with non-zero year, month, and day values. * A month and day, with a
// zero year (for example, an anniversary). * A year on its own, with a
// zero month and a zero day. * A year and month, with a zero day (for
// example, a credit card expiration date). Related types: *
// google.type.TimeOfDay * google.type.DateTime *
// google.protobuf.Timestamp
type GoogleTypeDate struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and
	// month, or 0 to specify a year by itself or a year and month where the
	// day isn't significant.
	Day int64 `json:"day,omitempty"`

	// Month: Month of a year. Must be from 1 to 12, or 0 to specify a year
	// without a month and day.
	Month int64 `json:"month,omitempty"`

	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a
	// date without a year.
	Year int64 `json:"year,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Day") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Day") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleTypeDate) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypeDate
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "chromemanagement.customers.apps.countChromeAppRequests":

type CustomersAppsCountChromeAppRequestsCall struct {
	s            *Service
	customer     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// CountChromeAppRequests: Generate summary of app installation
// requests.
//
// - customer: Customer id or "my_customer" to use the customer
//   associated to the account making the request.
func (r *CustomersAppsService) CountChromeAppRequests(customer string) *CustomersAppsCountChromeAppRequestsCall {
	c := &CustomersAppsCountChromeAppRequestsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customer = customer
	return c
}

// OrderBy sets the optional parameter "orderBy": Field used to order
// results. Supported fields: * request_count * latest_request_time
func (c *CustomersAppsCountChromeAppRequestsCall) OrderBy(orderBy string) *CustomersAppsCountChromeAppRequestsCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// OrgUnitId sets the optional parameter "orgUnitId": The ID of the
// organizational unit.
func (c *CustomersAppsCountChromeAppRequestsCall) OrgUnitId(orgUnitId string) *CustomersAppsCountChromeAppRequestsCall {
	c.urlParams_.Set("orgUnitId", orgUnitId)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// results to return. Maximum and default are 50, anything above will be
// coerced to 50.
func (c *CustomersAppsCountChromeAppRequestsCall) PageSize(pageSize int64) *CustomersAppsCountChromeAppRequestsCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to specify
// the page of the request to be returned.
func (c *CustomersAppsCountChromeAppRequestsCall) PageToken(pageToken string) *CustomersAppsCountChromeAppRequestsCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersAppsCountChromeAppRequestsCall) Fields(s ...googleapi.Field) *CustomersAppsCountChromeAppRequestsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersAppsCountChromeAppRequestsCall) IfNoneMatch(entityTag string) *CustomersAppsCountChromeAppRequestsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersAppsCountChromeAppRequestsCall) Context(ctx context.Context) *CustomersAppsCountChromeAppRequestsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersAppsCountChromeAppRequestsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersAppsCountChromeAppRequestsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+customer}/apps:countChromeAppRequests")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"customer": c.customer,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.apps.countChromeAppRequests" call.
// Exactly one of
// *GoogleChromeManagementV1CountChromeAppRequestsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleChromeManagementV1CountChromeAppRequestsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CustomersAppsCountChromeAppRequestsCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1CountChromeAppRequestsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1CountChromeAppRequestsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generate summary of app installation requests.",
	//   "flatPath": "v1/customers/{customersId}/apps:countChromeAppRequests",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.apps.countChromeAppRequests",
	//   "parameterOrder": [
	//     "customer"
	//   ],
	//   "parameters": {
	//     "customer": {
	//       "description": "Required. Customer id or \"my_customer\" to use the customer associated to the account making the request.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field used to order results. Supported fields: * request_count * latest_request_time",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orgUnitId": {
	//       "description": "The ID of the organizational unit.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of results to return. Maximum and default are 50, anything above will be coerced to 50.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to specify the page of the request to be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+customer}/apps:countChromeAppRequests",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1CountChromeAppRequestsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.appdetails.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CustomersAppsCountChromeAppRequestsCall) Pages(ctx context.Context, f func(*GoogleChromeManagementV1CountChromeAppRequestsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "chromemanagement.customers.apps.android.get":

type CustomersAppsAndroidGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get a specific app for a customer by its resource name.
//
// - name: The app for which details are being queried. Examples:
//   "customers/my_customer/apps/chrome/gmbmikajjgmnabiglmofipeabaddhgne@
//   2.1.2" for the Save to Google Drive Chrome extension version 2.1.2,
//   "customers/my_customer/apps/android/com.google.android.apps.docs"
//   for the Google Drive Android app's latest version.
func (r *CustomersAppsAndroidService) Get(name string) *CustomersAppsAndroidGetCall {
	c := &CustomersAppsAndroidGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersAppsAndroidGetCall) Fields(s ...googleapi.Field) *CustomersAppsAndroidGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersAppsAndroidGetCall) IfNoneMatch(entityTag string) *CustomersAppsAndroidGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersAppsAndroidGetCall) Context(ctx context.Context) *CustomersAppsAndroidGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersAppsAndroidGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersAppsAndroidGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.apps.android.get" call.
// Exactly one of *GoogleChromeManagementV1AppDetails or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleChromeManagementV1AppDetails.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CustomersAppsAndroidGetCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1AppDetails, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1AppDetails{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get a specific app for a customer by its resource name.",
	//   "flatPath": "v1/customers/{customersId}/apps/android/{androidId}",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.apps.android.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The app for which details are being queried. Examples: \"customers/my_customer/apps/chrome/gmbmikajjgmnabiglmofipeabaddhgne@2.1.2\" for the Save to Google Drive Chrome extension version 2.1.2, \"customers/my_customer/apps/android/com.google.android.apps.docs\" for the Google Drive Android app's latest version.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+/apps/android/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1AppDetails"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.appdetails.readonly"
	//   ]
	// }

}

// method id "chromemanagement.customers.apps.chrome.get":

type CustomersAppsChromeGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get a specific app for a customer by its resource name.
//
// - name: The app for which details are being queried. Examples:
//   "customers/my_customer/apps/chrome/gmbmikajjgmnabiglmofipeabaddhgne@
//   2.1.2" for the Save to Google Drive Chrome extension version 2.1.2,
//   "customers/my_customer/apps/android/com.google.android.apps.docs"
//   for the Google Drive Android app's latest version.
func (r *CustomersAppsChromeService) Get(name string) *CustomersAppsChromeGetCall {
	c := &CustomersAppsChromeGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersAppsChromeGetCall) Fields(s ...googleapi.Field) *CustomersAppsChromeGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersAppsChromeGetCall) IfNoneMatch(entityTag string) *CustomersAppsChromeGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersAppsChromeGetCall) Context(ctx context.Context) *CustomersAppsChromeGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersAppsChromeGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersAppsChromeGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.apps.chrome.get" call.
// Exactly one of *GoogleChromeManagementV1AppDetails or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleChromeManagementV1AppDetails.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CustomersAppsChromeGetCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1AppDetails, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1AppDetails{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get a specific app for a customer by its resource name.",
	//   "flatPath": "v1/customers/{customersId}/apps/chrome/{chromeId}",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.apps.chrome.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The app for which details are being queried. Examples: \"customers/my_customer/apps/chrome/gmbmikajjgmnabiglmofipeabaddhgne@2.1.2\" for the Save to Google Drive Chrome extension version 2.1.2, \"customers/my_customer/apps/android/com.google.android.apps.docs\" for the Google Drive Android app's latest version.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+/apps/chrome/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1AppDetails"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.appdetails.readonly"
	//   ]
	// }

}

// method id "chromemanagement.customers.apps.web.get":

type CustomersAppsWebGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get a specific app for a customer by its resource name.
//
// - name: The app for which details are being queried. Examples:
//   "customers/my_customer/apps/chrome/gmbmikajjgmnabiglmofipeabaddhgne@
//   2.1.2" for the Save to Google Drive Chrome extension version 2.1.2,
//   "customers/my_customer/apps/android/com.google.android.apps.docs"
//   for the Google Drive Android app's latest version.
func (r *CustomersAppsWebService) Get(name string) *CustomersAppsWebGetCall {
	c := &CustomersAppsWebGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersAppsWebGetCall) Fields(s ...googleapi.Field) *CustomersAppsWebGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersAppsWebGetCall) IfNoneMatch(entityTag string) *CustomersAppsWebGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersAppsWebGetCall) Context(ctx context.Context) *CustomersAppsWebGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersAppsWebGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersAppsWebGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.apps.web.get" call.
// Exactly one of *GoogleChromeManagementV1AppDetails or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleChromeManagementV1AppDetails.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CustomersAppsWebGetCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1AppDetails, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1AppDetails{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get a specific app for a customer by its resource name.",
	//   "flatPath": "v1/customers/{customersId}/apps/web/{webId}",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.apps.web.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The app for which details are being queried. Examples: \"customers/my_customer/apps/chrome/gmbmikajjgmnabiglmofipeabaddhgne@2.1.2\" for the Save to Google Drive Chrome extension version 2.1.2, \"customers/my_customer/apps/android/com.google.android.apps.docs\" for the Google Drive Android app's latest version.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+/apps/web/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1AppDetails"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.appdetails.readonly"
	//   ]
	// }

}

// method id "chromemanagement.customers.reports.countChromeVersions":

type CustomersReportsCountChromeVersionsCall struct {
	s            *Service
	customer     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// CountChromeVersions: Generate report of installed Chrome versions.
//
// - customer: Customer id or "my_customer" to use the customer
//   associated to the account making the request.
func (r *CustomersReportsService) CountChromeVersions(customer string) *CustomersReportsCountChromeVersionsCall {
	c := &CustomersReportsCountChromeVersionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customer = customer
	return c
}

// Filter sets the optional parameter "filter": Query string to filter
// results, AND-separated fields in EBNF syntax. Note: OR operations are
// not supported in this filter. Supported filter fields: *
// last_active_date
func (c *CustomersReportsCountChromeVersionsCall) Filter(filter string) *CustomersReportsCountChromeVersionsCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrgUnitId sets the optional parameter "orgUnitId": The ID of the
// organizational unit.
func (c *CustomersReportsCountChromeVersionsCall) OrgUnitId(orgUnitId string) *CustomersReportsCountChromeVersionsCall {
	c.urlParams_.Set("orgUnitId", orgUnitId)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// results to return. Maximum and default are 100.
func (c *CustomersReportsCountChromeVersionsCall) PageSize(pageSize int64) *CustomersReportsCountChromeVersionsCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to specify
// the page of the request to be returned.
func (c *CustomersReportsCountChromeVersionsCall) PageToken(pageToken string) *CustomersReportsCountChromeVersionsCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersReportsCountChromeVersionsCall) Fields(s ...googleapi.Field) *CustomersReportsCountChromeVersionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersReportsCountChromeVersionsCall) IfNoneMatch(entityTag string) *CustomersReportsCountChromeVersionsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersReportsCountChromeVersionsCall) Context(ctx context.Context) *CustomersReportsCountChromeVersionsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersReportsCountChromeVersionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersReportsCountChromeVersionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+customer}/reports:countChromeVersions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"customer": c.customer,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.reports.countChromeVersions" call.
// Exactly one of *GoogleChromeManagementV1CountChromeVersionsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleChromeManagementV1CountChromeVersionsResponse.ServerResponse.He
// ader or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CustomersReportsCountChromeVersionsCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1CountChromeVersionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1CountChromeVersionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generate report of installed Chrome versions.",
	//   "flatPath": "v1/customers/{customersId}/reports:countChromeVersions",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.reports.countChromeVersions",
	//   "parameterOrder": [
	//     "customer"
	//   ],
	//   "parameters": {
	//     "customer": {
	//       "description": "Required. Customer id or \"my_customer\" to use the customer associated to the account making the request.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Query string to filter results, AND-separated fields in EBNF syntax. Note: OR operations are not supported in this filter. Supported filter fields: * last_active_date",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orgUnitId": {
	//       "description": "The ID of the organizational unit.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of results to return. Maximum and default are 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to specify the page of the request to be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+customer}/reports:countChromeVersions",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1CountChromeVersionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.reports.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CustomersReportsCountChromeVersionsCall) Pages(ctx context.Context, f func(*GoogleChromeManagementV1CountChromeVersionsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "chromemanagement.customers.reports.countInstalledApps":

type CustomersReportsCountInstalledAppsCall struct {
	s            *Service
	customer     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// CountInstalledApps: Generate report of app installations.
//
// - customer: Customer id or "my_customer" to use the customer
//   associated to the account making the request.
func (r *CustomersReportsService) CountInstalledApps(customer string) *CustomersReportsCountInstalledAppsCall {
	c := &CustomersReportsCountInstalledAppsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customer = customer
	return c
}

// Filter sets the optional parameter "filter": Query string to filter
// results, AND-separated fields in EBNF syntax. Note: OR operations are
// not supported in this filter. Supported filter fields: * app_name *
// app_type * install_type * number_of_permissions * total_install_count
// * latest_profile_active_date * permission_name
func (c *CustomersReportsCountInstalledAppsCall) Filter(filter string) *CustomersReportsCountInstalledAppsCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field used to order
// results. Supported order by fields: * app_name * app_type *
// install_type * number_of_permissions * total_install_count
func (c *CustomersReportsCountInstalledAppsCall) OrderBy(orderBy string) *CustomersReportsCountInstalledAppsCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// OrgUnitId sets the optional parameter "orgUnitId": The ID of the
// organizational unit.
func (c *CustomersReportsCountInstalledAppsCall) OrgUnitId(orgUnitId string) *CustomersReportsCountInstalledAppsCall {
	c.urlParams_.Set("orgUnitId", orgUnitId)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// results to return. Maximum and default are 100.
func (c *CustomersReportsCountInstalledAppsCall) PageSize(pageSize int64) *CustomersReportsCountInstalledAppsCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to specify
// the page of the request to be returned.
func (c *CustomersReportsCountInstalledAppsCall) PageToken(pageToken string) *CustomersReportsCountInstalledAppsCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersReportsCountInstalledAppsCall) Fields(s ...googleapi.Field) *CustomersReportsCountInstalledAppsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersReportsCountInstalledAppsCall) IfNoneMatch(entityTag string) *CustomersReportsCountInstalledAppsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersReportsCountInstalledAppsCall) Context(ctx context.Context) *CustomersReportsCountInstalledAppsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersReportsCountInstalledAppsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersReportsCountInstalledAppsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+customer}/reports:countInstalledApps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"customer": c.customer,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.reports.countInstalledApps" call.
// Exactly one of *GoogleChromeManagementV1CountInstalledAppsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleChromeManagementV1CountInstalledAppsResponse.ServerResponse.Hea
// der or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CustomersReportsCountInstalledAppsCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1CountInstalledAppsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1CountInstalledAppsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generate report of app installations.",
	//   "flatPath": "v1/customers/{customersId}/reports:countInstalledApps",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.reports.countInstalledApps",
	//   "parameterOrder": [
	//     "customer"
	//   ],
	//   "parameters": {
	//     "customer": {
	//       "description": "Required. Customer id or \"my_customer\" to use the customer associated to the account making the request.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Query string to filter results, AND-separated fields in EBNF syntax. Note: OR operations are not supported in this filter. Supported filter fields: * app_name * app_type * install_type * number_of_permissions * total_install_count * latest_profile_active_date * permission_name",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field used to order results. Supported order by fields: * app_name * app_type * install_type * number_of_permissions * total_install_count",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orgUnitId": {
	//       "description": "The ID of the organizational unit.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of results to return. Maximum and default are 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to specify the page of the request to be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+customer}/reports:countInstalledApps",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1CountInstalledAppsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.reports.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CustomersReportsCountInstalledAppsCall) Pages(ctx context.Context, f func(*GoogleChromeManagementV1CountInstalledAppsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "chromemanagement.customers.reports.findInstalledAppDevices":

type CustomersReportsFindInstalledAppDevicesCall struct {
	s            *Service
	customer     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// FindInstalledAppDevices: Generate report of devices that have a
// specified app installed.
//
// - customer: Customer id or "my_customer" to use the customer
//   associated to the account making the request.
func (r *CustomersReportsService) FindInstalledAppDevices(customer string) *CustomersReportsFindInstalledAppDevicesCall {
	c := &CustomersReportsFindInstalledAppDevicesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customer = customer
	return c
}

// AppId sets the optional parameter "appId": Unique identifier of the
// app. For Chrome apps and extensions, the 32-character id (e.g.
// ehoadneljpdggcbbknedodolkkjodefl). For Android apps, the package name
// (e.g. com.evernote).
func (c *CustomersReportsFindInstalledAppDevicesCall) AppId(appId string) *CustomersReportsFindInstalledAppDevicesCall {
	c.urlParams_.Set("appId", appId)
	return c
}

// AppType sets the optional parameter "appType": Type of the app.
//
// Possible values:
//   "APP_TYPE_UNSPECIFIED" - App type not specified.
//   "EXTENSION" - Chrome extension.
//   "APP" - Chrome app.
//   "THEME" - Chrome theme.
//   "HOSTED_APP" - Chrome hosted app.
//   "ANDROID_APP" - ARC++ app.
func (c *CustomersReportsFindInstalledAppDevicesCall) AppType(appType string) *CustomersReportsFindInstalledAppDevicesCall {
	c.urlParams_.Set("appType", appType)
	return c
}

// Filter sets the optional parameter "filter": Query string to filter
// results, AND-separated fields in EBNF syntax. Note: OR operations are
// not supported in this filter. Supported filter fields: *
// last_active_date
func (c *CustomersReportsFindInstalledAppDevicesCall) Filter(filter string) *CustomersReportsFindInstalledAppDevicesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field used to order
// results. Supported order by fields: * machine * device_id
func (c *CustomersReportsFindInstalledAppDevicesCall) OrderBy(orderBy string) *CustomersReportsFindInstalledAppDevicesCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// OrgUnitId sets the optional parameter "orgUnitId": The ID of the
// organizational unit.
func (c *CustomersReportsFindInstalledAppDevicesCall) OrgUnitId(orgUnitId string) *CustomersReportsFindInstalledAppDevicesCall {
	c.urlParams_.Set("orgUnitId", orgUnitId)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// results to return. Maximum and default are 100.
func (c *CustomersReportsFindInstalledAppDevicesCall) PageSize(pageSize int64) *CustomersReportsFindInstalledAppDevicesCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to specify
// the page of the request to be returned.
func (c *CustomersReportsFindInstalledAppDevicesCall) PageToken(pageToken string) *CustomersReportsFindInstalledAppDevicesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersReportsFindInstalledAppDevicesCall) Fields(s ...googleapi.Field) *CustomersReportsFindInstalledAppDevicesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersReportsFindInstalledAppDevicesCall) IfNoneMatch(entityTag string) *CustomersReportsFindInstalledAppDevicesCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersReportsFindInstalledAppDevicesCall) Context(ctx context.Context) *CustomersReportsFindInstalledAppDevicesCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersReportsFindInstalledAppDevicesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersReportsFindInstalledAppDevicesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+customer}/reports:findInstalledAppDevices")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"customer": c.customer,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.reports.findInstalledAppDevices" call.
// Exactly one of
// *GoogleChromeManagementV1FindInstalledAppDevicesResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleChromeManagementV1FindInstalledAppDevicesResponse.ServerRespons
// e.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CustomersReportsFindInstalledAppDevicesCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1FindInstalledAppDevicesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1FindInstalledAppDevicesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generate report of devices that have a specified app installed.",
	//   "flatPath": "v1/customers/{customersId}/reports:findInstalledAppDevices",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.reports.findInstalledAppDevices",
	//   "parameterOrder": [
	//     "customer"
	//   ],
	//   "parameters": {
	//     "appId": {
	//       "description": "Unique identifier of the app. For Chrome apps and extensions, the 32-character id (e.g. ehoadneljpdggcbbknedodolkkjodefl). For Android apps, the package name (e.g. com.evernote).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "appType": {
	//       "description": "Type of the app.",
	//       "enum": [
	//         "APP_TYPE_UNSPECIFIED",
	//         "EXTENSION",
	//         "APP",
	//         "THEME",
	//         "HOSTED_APP",
	//         "ANDROID_APP"
	//       ],
	//       "enumDescriptions": [
	//         "App type not specified.",
	//         "Chrome extension.",
	//         "Chrome app.",
	//         "Chrome theme.",
	//         "Chrome hosted app.",
	//         "ARC++ app."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "customer": {
	//       "description": "Required. Customer id or \"my_customer\" to use the customer associated to the account making the request.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Query string to filter results, AND-separated fields in EBNF syntax. Note: OR operations are not supported in this filter. Supported filter fields: * last_active_date",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field used to order results. Supported order by fields: * machine * device_id",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orgUnitId": {
	//       "description": "The ID of the organizational unit.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of results to return. Maximum and default are 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to specify the page of the request to be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+customer}/reports:findInstalledAppDevices",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1FindInstalledAppDevicesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.reports.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CustomersReportsFindInstalledAppDevicesCall) Pages(ctx context.Context, f func(*GoogleChromeManagementV1FindInstalledAppDevicesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "chromemanagement.customers.telemetry.devices.get":

type CustomersTelemetryDevicesGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get telemetry device.
//
// - name: Name of the `TelemetryDevice` to return.
func (r *CustomersTelemetryDevicesService) Get(name string) *CustomersTelemetryDevicesGetCall {
	c := &CustomersTelemetryDevicesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersTelemetryDevicesGetCall) Fields(s ...googleapi.Field) *CustomersTelemetryDevicesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersTelemetryDevicesGetCall) IfNoneMatch(entityTag string) *CustomersTelemetryDevicesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersTelemetryDevicesGetCall) Context(ctx context.Context) *CustomersTelemetryDevicesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersTelemetryDevicesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersTelemetryDevicesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.telemetry.devices.get" call.
// Exactly one of *GoogleChromeManagementV1TelemetryDevice or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleChromeManagementV1TelemetryDevice.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CustomersTelemetryDevicesGetCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1TelemetryDevice, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1TelemetryDevice{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get telemetry device.",
	//   "flatPath": "v1/customers/{customersId}/telemetry/devices/{devicesId}",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.telemetry.devices.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the `TelemetryDevice` to return.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+/telemetry/devices/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1TelemetryDevice"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.telemetry.readonly"
	//   ]
	// }

}

// method id "chromemanagement.customers.telemetry.devices.list":

type CustomersTelemetryDevicesListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List all telemetry devices.
//
// - parent: Customer id or "my_customer" to use the customer associated
//   to the account making the request.
func (r *CustomersTelemetryDevicesService) List(parent string) *CustomersTelemetryDevicesListCall {
	c := &CustomersTelemetryDevicesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Only include resources
// that match the filter. Supported filter fields: - org_unit_id -
// serial_number - device_id
func (c *CustomersTelemetryDevicesListCall) Filter(filter string) *CustomersTelemetryDevicesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// results to return. Default value is 100. Maximum value is 200.
func (c *CustomersTelemetryDevicesListCall) PageSize(pageSize int64) *CustomersTelemetryDevicesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to specify
// next page in the list.
func (c *CustomersTelemetryDevicesListCall) PageToken(pageToken string) *CustomersTelemetryDevicesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": Required. Read mask
// to specify which fields to return.
func (c *CustomersTelemetryDevicesListCall) ReadMask(readMask string) *CustomersTelemetryDevicesListCall {
	c.urlParams_.Set("readMask", readMask)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomersTelemetryDevicesListCall) Fields(s ...googleapi.Field) *CustomersTelemetryDevicesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CustomersTelemetryDevicesListCall) IfNoneMatch(entityTag string) *CustomersTelemetryDevicesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CustomersTelemetryDevicesListCall) Context(ctx context.Context) *CustomersTelemetryDevicesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomersTelemetryDevicesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomersTelemetryDevicesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/telemetry/devices")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "chromemanagement.customers.telemetry.devices.list" call.
// Exactly one of *GoogleChromeManagementV1ListTelemetryDevicesResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleChromeManagementV1ListTelemetryDevicesResponse.ServerResponse.H
// eader or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CustomersTelemetryDevicesListCall) Do(opts ...googleapi.CallOption) (*GoogleChromeManagementV1ListTelemetryDevicesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleChromeManagementV1ListTelemetryDevicesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List all telemetry devices.",
	//   "flatPath": "v1/customers/{customersId}/telemetry/devices",
	//   "httpMethod": "GET",
	//   "id": "chromemanagement.customers.telemetry.devices.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Optional. Only include resources that match the filter. Supported filter fields: - org_unit_id - serial_number - device_id ",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of results to return. Default value is 100. Maximum value is 200.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to specify next page in the list.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Customer id or \"my_customer\" to use the customer associated to the account making the request.",
	//       "location": "path",
	//       "pattern": "^customers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "Required. Read mask to specify which fields to return.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/telemetry/devices",
	//   "response": {
	//     "$ref": "GoogleChromeManagementV1ListTelemetryDevicesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/chrome.management.telemetry.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CustomersTelemetryDevicesListCall) Pages(ctx context.Context, f func(*GoogleChromeManagementV1ListTelemetryDevicesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}
