// Copyright 2020 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 androidmanagement provides access to the Android Management API.
//
// For product documentation, see: https://developers.google.com/android/management
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/androidmanagement/v1"
//   ...
//   ctx := context.Background()
//   androidmanagementService, err := androidmanagement.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
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   androidmanagementService, err := androidmanagement.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, ...)
//   androidmanagementService, err := androidmanagement.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package androidmanagement // import "google.golang.org/api/androidmanagement/v1"

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

	googleapi "google.golang.org/api/googleapi"
	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 = "androidmanagement:v1"
const apiName = "androidmanagement"
const apiVersion = "v1"
const basePath = "https://androidmanagement.googleapis.com/"
const mtlsBasePath = "https://androidmanagement.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// Manage Android devices and apps for your customers
	AndroidmanagementScope = "https://www.googleapis.com/auth/androidmanagement"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/androidmanagement",
	)
	// 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.Enterprises = NewEnterprisesService(s)
	s.SignupUrls = NewSignupUrlsService(s)
	return s, nil
}

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

	Enterprises *EnterprisesService

	SignupUrls *SignupUrlsService
}

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

func NewEnterprisesService(s *Service) *EnterprisesService {
	rs := &EnterprisesService{s: s}
	rs.Applications = NewEnterprisesApplicationsService(s)
	rs.Devices = NewEnterprisesDevicesService(s)
	rs.EnrollmentTokens = NewEnterprisesEnrollmentTokensService(s)
	rs.Policies = NewEnterprisesPoliciesService(s)
	rs.WebApps = NewEnterprisesWebAppsService(s)
	rs.WebTokens = NewEnterprisesWebTokensService(s)
	return rs
}

type EnterprisesService struct {
	s *Service

	Applications *EnterprisesApplicationsService

	Devices *EnterprisesDevicesService

	EnrollmentTokens *EnterprisesEnrollmentTokensService

	Policies *EnterprisesPoliciesService

	WebApps *EnterprisesWebAppsService

	WebTokens *EnterprisesWebTokensService
}

func NewEnterprisesApplicationsService(s *Service) *EnterprisesApplicationsService {
	rs := &EnterprisesApplicationsService{s: s}
	return rs
}

type EnterprisesApplicationsService struct {
	s *Service
}

func NewEnterprisesDevicesService(s *Service) *EnterprisesDevicesService {
	rs := &EnterprisesDevicesService{s: s}
	rs.Operations = NewEnterprisesDevicesOperationsService(s)
	return rs
}

type EnterprisesDevicesService struct {
	s *Service

	Operations *EnterprisesDevicesOperationsService
}

func NewEnterprisesDevicesOperationsService(s *Service) *EnterprisesDevicesOperationsService {
	rs := &EnterprisesDevicesOperationsService{s: s}
	return rs
}

type EnterprisesDevicesOperationsService struct {
	s *Service
}

func NewEnterprisesEnrollmentTokensService(s *Service) *EnterprisesEnrollmentTokensService {
	rs := &EnterprisesEnrollmentTokensService{s: s}
	return rs
}

type EnterprisesEnrollmentTokensService struct {
	s *Service
}

func NewEnterprisesPoliciesService(s *Service) *EnterprisesPoliciesService {
	rs := &EnterprisesPoliciesService{s: s}
	return rs
}

type EnterprisesPoliciesService struct {
	s *Service
}

func NewEnterprisesWebAppsService(s *Service) *EnterprisesWebAppsService {
	rs := &EnterprisesWebAppsService{s: s}
	return rs
}

type EnterprisesWebAppsService struct {
	s *Service
}

func NewEnterprisesWebTokensService(s *Service) *EnterprisesWebTokensService {
	rs := &EnterprisesWebTokensService{s: s}
	return rs
}

type EnterprisesWebTokensService struct {
	s *Service
}

func NewSignupUrlsService(s *Service) *SignupUrlsService {
	rs := &SignupUrlsService{s: s}
	return rs
}

type SignupUrlsService struct {
	s *Service
}

// AdvancedSecurityOverrides: Security policies set to the most secure
// values by default. To maintain the security posture of a device, we
// don't recommend overriding any of the default values.
type AdvancedSecurityOverrides struct {
	// UntrustedAppsPolicy: The policy for untrusted apps (apps from unknown
	// sources) enforced on the device. Replaces
	// install_unknown_sources_allowed (deprecated).
	//
	// Possible values:
	//   "UNTRUSTED_APPS_POLICY_UNSPECIFIED" - Unspecified. Defaults to
	// DISALLOW_INSTALL.
	//   "DISALLOW_INSTALL" - Default. Disallow untrusted app installs on
	// entire device.
	//   "ALLOW_INSTALL_IN_PERSONAL_PROFILE_ONLY" - For devices with work
	// profiles, allow untrusted app installs in the device's personal
	// profile only.
	//   "ALLOW_INSTALL_DEVICE_WIDE" - Allow untrusted app installs on
	// entire device.
	UntrustedAppsPolicy string `json:"untrustedAppsPolicy,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UntrustedAppsPolicy")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "UntrustedAppsPolicy") 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 *AdvancedSecurityOverrides) MarshalJSON() ([]byte, error) {
	type NoMethod AdvancedSecurityOverrides
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AlwaysOnVpnPackage: Configuration for an always-on VPN connection.
type AlwaysOnVpnPackage struct {
	// LockdownEnabled: Disallows networking when the VPN is not connected.
	LockdownEnabled bool `json:"lockdownEnabled,omitempty"`

	// PackageName: The package name of the VPN app.
	PackageName string `json:"packageName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LockdownEnabled") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "LockdownEnabled") 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 *AlwaysOnVpnPackage) MarshalJSON() ([]byte, error) {
	type NoMethod AlwaysOnVpnPackage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApiLevelCondition: A compliance rule condition which is satisfied if
// the Android Framework API level on the device doesn't meet a minimum
// requirement. There can only be one rule with this type of condition
// per policy.
type ApiLevelCondition struct {
	// MinApiLevel: The minimum desired Android Framework API level. If the
	// device doesn't meet the minimum requirement, this condition is
	// satisfied. Must be greater than zero.
	MinApiLevel int64 `json:"minApiLevel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MinApiLevel") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "MinApiLevel") 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 *ApiLevelCondition) MarshalJSON() ([]byte, error) {
	type NoMethod ApiLevelCondition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AppTrackInfo: Id to name association of a app track.
type AppTrackInfo struct {
	// TrackAlias: The track name associated with the trackId, set in the
	// Play Console. The name is modifiable from Play Console.
	TrackAlias string `json:"trackAlias,omitempty"`

	// TrackId: The unmodifiable unique track identifier, taken from the
	// releaseTrackId in the URL of the Play Console page that displays the
	// app’s track information.
	TrackId string `json:"trackId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TrackAlias") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "TrackAlias") 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 *AppTrackInfo) MarshalJSON() ([]byte, error) {
	type NoMethod AppTrackInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Application: Information about an app.
type Application struct {
	// AppTracks: Application tracks visible to the enterprise.
	AppTracks []*AppTrackInfo `json:"appTracks,omitempty"`

	// ManagedProperties: The set of managed properties available to be
	// pre-configured for the app.
	ManagedProperties []*ManagedProperty `json:"managedProperties,omitempty"`

	// Name: The name of the app in the form
	// enterprises/{enterpriseId}/applications/{package_name}.
	Name string `json:"name,omitempty"`

	// Permissions: The permissions required by the app.
	Permissions []*ApplicationPermission `json:"permissions,omitempty"`

	// Title: The title of the app. Localized.
	Title string `json:"title,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AppTracks") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "AppTracks") 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 *Application) MarshalJSON() ([]byte, error) {
	type NoMethod Application
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApplicationEvent: An app-related event.
type ApplicationEvent struct {
	// CreateTime: The creation time of the event.
	CreateTime string `json:"createTime,omitempty"`

	// EventType: App event type.
	//
	// Possible values:
	//   "APPLICATION_EVENT_TYPE_UNSPECIFIED" - This value is disallowed.
	//   "INSTALLED" - The app was installed.
	//   "CHANGED" - The app was changed, for example, a component was
	// enabled or disabled.
	//   "DATA_CLEARED" - The app data was cleared.
	//   "REMOVED" - The app was removed.
	//   "REPLACED" - A new version of the app has been installed, replacing
	// the old version.
	//   "RESTARTED" - The app was restarted.
	//   "PINNED" - The app was pinned to the foreground.
	//   "UNPINNED" - The app was unpinned.
	EventType string `json:"eventType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateTime") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "CreateTime") 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 *ApplicationEvent) MarshalJSON() ([]byte, error) {
	type NoMethod ApplicationEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApplicationPermission: A permission required by the app.
type ApplicationPermission struct {
	// Description: A longer description of the permission, providing more
	// detail on what it affects. Localized.
	Description string `json:"description,omitempty"`

	// Name: The name of the permission. Localized.
	Name string `json:"name,omitempty"`

	// PermissionId: An opaque string uniquely identifying the permission.
	// Not localized.
	PermissionId string `json:"permissionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Description") 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 *ApplicationPermission) MarshalJSON() ([]byte, error) {
	type NoMethod ApplicationPermission
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApplicationPolicy: Policy for an individual app.
type ApplicationPolicy struct {
	// AccessibleTrackIds: List of the app’s track IDs that a device
	// belonging to the enterprise can access. If the list contains multiple
	// track IDs, devices receive the latest version among all accessible
	// tracks. If the list contains no track IDs, devices only have access
	// to the app’s production track. More details about each track are
	// available in AppTrackInfo.
	AccessibleTrackIds []string `json:"accessibleTrackIds,omitempty"`

	// ConnectedWorkAndPersonalApp: Controls whether the app can communicate
	// with itself across a device’s work and personal profiles, subject
	// to user consent.
	//
	// Possible values:
	//   "CONNECTED_WORK_AND_PERSONAL_APP_UNSPECIFIED" - Unspecified.
	// Defaults to CONNECTED_WORK_AND_PERSONAL_APPS_DISALLOWED.
	//   "CONNECTED_WORK_AND_PERSONAL_APP_DISALLOWED" - Default. Prevents
	// the app from communicating cross-profile.
	//   "CONNECTED_WORK_AND_PERSONAL_APP_ALLOWED" - Allows the app to
	// communicate across profiles after receiving user consent.
	ConnectedWorkAndPersonalApp string `json:"connectedWorkAndPersonalApp,omitempty"`

	// DefaultPermissionPolicy: The default policy for all permissions
	// requested by the app. If specified, this overrides the policy-level
	// default_permission_policy which applies to all apps. It does not
	// override the permission_grants which applies to all apps.
	//
	// Possible values:
	//   "PERMISSION_POLICY_UNSPECIFIED" - Policy not specified. If no
	// policy is specified for a permission at any level, then the PROMPT
	// behavior is used by default.
	//   "PROMPT" - Prompt the user to grant a permission.
	//   "GRANT" - Automatically grant a permission.
	//   "DENY" - Automatically deny a permission.
	DefaultPermissionPolicy string `json:"defaultPermissionPolicy,omitempty"`

	// DelegatedScopes: The scopes delegated to the app from Android Device
	// Policy.
	//
	// Possible values:
	//   "DELEGATED_SCOPE_UNSPECIFIED" - No delegation scope specified.
	//   "CERT_INSTALL" - Grants access to certificate installation and
	// management.
	//   "MANAGED_CONFIGURATIONS" - Grants access to managed configurations
	// management.
	//   "BLOCK_UNINSTALL" - Grants access to blocking uninstallation.
	//   "PERMISSION_GRANT" - Grants access to permission policy and
	// permission grant state.
	//   "PACKAGE_ACCESS" - Grants access to package access state.
	//   "ENABLE_SYSTEM_APP" - Grants access for enabling system apps.
	DelegatedScopes []string `json:"delegatedScopes,omitempty"`

	// Disabled: Whether the app is disabled. When disabled, the app data is
	// still preserved.
	Disabled bool `json:"disabled,omitempty"`

	// InstallType: The type of installation to perform.
	//
	// Possible values:
	//   "INSTALL_TYPE_UNSPECIFIED" - Unspecified. Defaults to AVAILABLE.
	//   "PREINSTALLED" - The app is automatically installed and can be
	// removed by the user.
	//   "FORCE_INSTALLED" - The app is automatically installed and can't be
	// removed by the user.
	//   "BLOCKED" - The app is blocked and can't be installed. If the app
	// was installed under a previous policy, it will be uninstalled.
	//   "AVAILABLE" - The app is available to install.
	//   "REQUIRED_FOR_SETUP" - The app is automatically installed and can't
	// be removed by the user and will prevent setup from completion until
	// installation is complete.
	//   "KIOSK" - The app is automatically installed in kiosk mode: it's
	// set as the preferred home intent and whitelisted for lock task mode.
	// Device setup won't complete until the app is installed. After
	// installation, users won't be able to remove the app. You can only set
	// this installType for one app per policy. When this is present in the
	// policy, status bar will be automatically disabled.
	InstallType string `json:"installType,omitempty"`

	// LockTaskAllowed: Whether the app is allowed to lock itself in
	// full-screen mode. DEPRECATED. Use InstallType KIOSK or
	// kioskCustomLauncherEnabled to to configure a dedicated device.
	LockTaskAllowed bool `json:"lockTaskAllowed,omitempty"`

	// ManagedConfiguration: Managed configuration applied to the app. The
	// format for the configuration is dictated by the ManagedProperty
	// values supported by the app. Each field name in the managed
	// configuration must match the key field of the ManagedProperty. The
	// field value must be compatible with the type of the ManagedProperty:
	// *type* *JSON value* BOOL true or false STRING string INTEGER number
	// CHOICE string MULTISELECT array of strings HIDDEN string BUNDLE_ARRAY
	// array of objects
	ManagedConfiguration googleapi.RawMessage `json:"managedConfiguration,omitempty"`

	// ManagedConfigurationTemplate: The managed configurations template for
	// the app, saved from the managed configurations iframe. This field is
	// ignored if managed_configuration is set.
	ManagedConfigurationTemplate *ManagedConfigurationTemplate `json:"managedConfigurationTemplate,omitempty"`

	// MinimumVersionCode: The minimum version of the app that runs on the
	// device. If set, the device attempts to update the app to at least
	// this version code. If the app is not up-to-date, the device will
	// contain a NonComplianceDetail with non_compliance_reason set to
	// APP_NOT_UPDATED. The app must already be published to Google Play
	// with a version code greater than or equal to this value. At most 20
	// apps may specify a minimum version code per policy.
	MinimumVersionCode int64 `json:"minimumVersionCode,omitempty"`

	// PackageName: The package name of the app. For example,
	// com.google.android.youtube for the YouTube app.
	PackageName string `json:"packageName,omitempty"`

	// PermissionGrants: Explicit permission grants or denials for the app.
	// These values override the default_permission_policy and
	// permission_grants which apply to all apps.
	PermissionGrants []*PermissionGrant `json:"permissionGrants,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccessibleTrackIds")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "AccessibleTrackIds") 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 *ApplicationPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod ApplicationPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApplicationReport: Information reported about an installed app.
type ApplicationReport struct {
	// ApplicationSource: The source of the package.
	//
	// Possible values:
	//   "APPLICATION_SOURCE_UNSPECIFIED" - The app was sideloaded from an
	// unspecified source.
	//   "SYSTEM_APP_FACTORY_VERSION" - This is a system app from the
	// device's factory image.
	//   "SYSTEM_APP_UPDATED_VERSION" - This is an updated system app.
	//   "INSTALLED_FROM_PLAY_STORE" - The app was installed from the Google
	// Play Store.
	ApplicationSource string `json:"applicationSource,omitempty"`

	// DisplayName: The display name of the app.
	DisplayName string `json:"displayName,omitempty"`

	// Events: List of app events. The most recent 20 events are stored in
	// the list.
	Events []*ApplicationEvent `json:"events,omitempty"`

	// InstallerPackageName: The package name of the app that installed this
	// app.
	InstallerPackageName string `json:"installerPackageName,omitempty"`

	// KeyedAppStates: List of keyed app states reported by the app.
	KeyedAppStates []*KeyedAppState `json:"keyedAppStates,omitempty"`

	// PackageName: Package name of the app.
	PackageName string `json:"packageName,omitempty"`

	// PackageSha256Hash: The SHA-256 hash of the app's APK file, which can
	// be used to verify the app hasn't been modified. Each byte of the hash
	// value is represented as a two-digit hexadecimal number.
	PackageSha256Hash string `json:"packageSha256Hash,omitempty"`

	// SigningKeyCertFingerprints: The SHA-1 hash of each
	// android.content.pm.Signature
	// (https://developer.android.com/reference/android/content/pm/Signature.
	// html) associated with the app package. Each byte of each hash value
	// is represented as a two-digit hexadecimal number.
	SigningKeyCertFingerprints []string `json:"signingKeyCertFingerprints,omitempty"`

	// State: Application state.
	//
	// Possible values:
	//   "APPLICATION_STATE_UNSPECIFIED" - App state is unspecified
	//   "REMOVED" - App was removed from the device
	//   "INSTALLED" - App is installed on the device
	State string `json:"state,omitempty"`

	// VersionCode: The app version code, which can be used to determine
	// whether one version is more recent than another.
	VersionCode int64 `json:"versionCode,omitempty"`

	// VersionName: The app version as displayed to the user.
	VersionName string `json:"versionName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApplicationSource")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "ApplicationSource") 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 *ApplicationReport) MarshalJSON() ([]byte, error) {
	type NoMethod ApplicationReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApplicationReportingSettings: Settings controlling the behavior of
// application reports.
type ApplicationReportingSettings struct {
	// IncludeRemovedApps: Whether removed apps are included in application
	// reports.
	IncludeRemovedApps bool `json:"includeRemovedApps,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IncludeRemovedApps")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "IncludeRemovedApps") 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 *ApplicationReportingSettings) MarshalJSON() ([]byte, error) {
	type NoMethod ApplicationReportingSettings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BlockAction: An action to block access to apps and data on a fully
// managed device or in a work profile. This action also triggers a
// device or work profile to displays a user-facing notification with
// information (where possible) on how to correct the compliance issue.
// Note: wipeAction must also be specified.
type BlockAction struct {
	// BlockAfterDays: Number of days the policy is non-compliant before the
	// device or work profile is blocked. To block access immediately, set
	// to 0. blockAfterDays must be less than wipeAfterDays.
	BlockAfterDays int64 `json:"blockAfterDays,omitempty"`

	// BlockScope: Specifies the scope of this BlockAction. Only applicable
	// to devices that are company-owned.
	//
	// Possible values:
	//   "BLOCK_SCOPE_UNSPECIFIED" - Unspecified. Defaults to
	// BLOCK_SCOPE_WORK_PROFILE.
	//   "BLOCK_SCOPE_WORK_PROFILE" - Block action is only applied to apps
	// in the work profile. Apps in the personal profile are unaffected.
	//   "BLOCK_SCOPE_DEVICE" - Block action is applied to the entire
	// device, including apps in the personal profile.
	BlockScope string `json:"blockScope,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BlockAfterDays") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "BlockAfterDays") 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 *BlockAction) MarshalJSON() ([]byte, error) {
	type NoMethod BlockAction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ChoosePrivateKeyRule: A rule for automatically choosing a private key
// and certificate to authenticate the device to a server.
type ChoosePrivateKeyRule struct {
	// PackageNames: The package names for which outgoing requests are
	// subject to this rule. If no package names are specified, then the
	// rule applies to all packages. For each package name listed, the rule
	// applies to that package and all other packages that shared the same
	// Android UID. The SHA256 hash of the signing key signatures of each
	// package_name will be verified against those provided by Play
	PackageNames []string `json:"packageNames,omitempty"`

	// PrivateKeyAlias: The alias of the private key to be used.
	PrivateKeyAlias string `json:"privateKeyAlias,omitempty"`

	// UrlPattern: The URL pattern to match against the URL of the outgoing
	// request. The pattern may contain asterisk (*) wildcards. Any URL is
	// matched if unspecified.
	UrlPattern string `json:"urlPattern,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PackageNames") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "PackageNames") 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 *ChoosePrivateKeyRule) MarshalJSON() ([]byte, error) {
	type NoMethod ChoosePrivateKeyRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Command: A command.
type Command struct {
	// CreateTime: The timestamp at which the command was created. The
	// timestamp is automatically generated by the server.
	CreateTime string `json:"createTime,omitempty"`

	// Duration: The duration for which the command is valid. The command
	// will expire if not executed by the device during this time. The
	// default duration if unspecified is ten minutes. There is no maximum
	// duration.
	Duration string `json:"duration,omitempty"`

	// ErrorCode: If the command failed, an error code explaining the
	// failure. This is not set when the command is cancelled by the caller.
	//
	// Possible values:
	//   "COMMAND_ERROR_CODE_UNSPECIFIED" - There was no error.
	//   "UNKNOWN" - An unknown error occurred.
	//   "API_LEVEL" - The API level of the device does not support this
	// command.
	//   "MANAGEMENT_MODE" - The management mode (profile owner, device
	// owner, etc.) does not support the command.
	//   "INVALID_VALUE" - The command has an invalid parameter value.
	//   "UNSUPPORTED" - The device doesn't support the command. Updating
	// Android Device Policy to the latest version may resolve the issue.
	ErrorCode string `json:"errorCode,omitempty"`

	// NewPassword: For commands of type RESET_PASSWORD, optionally
	// specifies the new password.
	NewPassword string `json:"newPassword,omitempty"`

	// ResetPasswordFlags: For commands of type RESET_PASSWORD, optionally
	// specifies flags.
	//
	// Possible values:
	//   "RESET_PASSWORD_FLAG_UNSPECIFIED" - This value is ignored.
	//   "REQUIRE_ENTRY" - Don't allow other admins to change the password
	// again until the user has entered it.
	//   "DO_NOT_ASK_CREDENTIALS_ON_BOOT" - Don't ask for user credentials
	// on device boot.
	//   "LOCK_NOW" - Lock the device after password reset.
	ResetPasswordFlags []string `json:"resetPasswordFlags,omitempty"`

	// Type: The type of the command.
	//
	// Possible values:
	//   "COMMAND_TYPE_UNSPECIFIED" - This value is disallowed.
	//   "LOCK" - Lock the device, as if the lock screen timeout had
	// expired.
	//   "RESET_PASSWORD" - Reset the user's password.
	//   "REBOOT" - Reboot the device. Only supported on API level 24+.
	Type string `json:"type,omitempty"`

	// UserName: The resource name of the user that owns the device in the
	// form enterprises/{enterpriseId}/users/{userId}. This is automatically
	// generated by the server based on the device the command is sent to.
	UserName string `json:"userName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateTime") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "CreateTime") 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 *Command) MarshalJSON() ([]byte, error) {
	type NoMethod Command
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ComplianceRule: A rule declaring which mitigating actions to take
// when a device is not compliant with its policy. For every rule, there
// is always an implicit mitigating action to set policy_compliant to
// false for the Device resource, and display a message on the device
// indicating that the device is not compliant with its policy. Other
// mitigating actions may optionally be taken as well, depending on the
// field values in the rule.
type ComplianceRule struct {
	// ApiLevelCondition: A condition which is satisfied if the Android
	// Framework API level on the device doesn't meet a minimum requirement.
	ApiLevelCondition *ApiLevelCondition `json:"apiLevelCondition,omitempty"`

	// DisableApps: If set to true, the rule includes a mitigating action to
	// disable apps so that the device is effectively disabled, but app data
	// is preserved. If the device is running an app in locked task mode,
	// the app will be closed and a UI showing the reason for non-compliance
	// will be displayed.
	DisableApps bool `json:"disableApps,omitempty"`

	// NonComplianceDetailCondition: A condition which is satisfied if there
	// exists any matching NonComplianceDetail for the device.
	NonComplianceDetailCondition *NonComplianceDetailCondition `json:"nonComplianceDetailCondition,omitempty"`

	// PackageNamesToDisable: If set, the rule includes a mitigating action
	// to disable apps specified in the list, but app data is preserved.
	PackageNamesToDisable []string `json:"packageNamesToDisable,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApiLevelCondition")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "ApiLevelCondition") 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 *ComplianceRule) MarshalJSON() ([]byte, error) {
	type NoMethod ComplianceRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Date: Represents a whole or partial calendar date, e.g. a birthday.
// The time of day and time zone are either specified elsewhere or are
// not significant. The date is relative to the Proleptic Gregorian
// Calendar. This can represent: A full date, with non-zero year, month
// and day values A month and day value, with a zero year, e.g. an
// anniversary A year on its own, with zero month and day values A year
// and month value, with a zero day, e.g. a credit card expiration
// dateRelated types are google.type.TimeOfDay and
// google.protobuf.Timestamp.
type Date struct {
	// Day: Day of month. Must be from 1 to 31 and valid for the year and
	// month, or 0 if specifying a year by itself or a year and month where
	// the day is not significant.
	Day int64 `json:"day,omitempty"`

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

	// Year: Year of date. Must be from 1 to 9999, or 0 if specifying 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 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 *Date) MarshalJSON() ([]byte, error) {
	type NoMethod Date
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Device: A device owned by an enterprise. Unless otherwise noted, all
// fields are read-only and can't be modified by
// enterprises.devices.patch.
type Device struct {
	// ApiLevel: The API level of the Android platform version running on
	// the device.
	ApiLevel int64 `json:"apiLevel,omitempty"`

	// ApplicationReports: Reports for apps installed on the device. This
	// information is only available when application_reports_enabled is
	// true in the device's policy.
	ApplicationReports []*ApplicationReport `json:"applicationReports,omitempty"`

	// AppliedPolicyName: The name of the policy currently applied to the
	// device.
	AppliedPolicyName string `json:"appliedPolicyName,omitempty"`

	// AppliedPolicyVersion: The version of the policy currently applied to
	// the device.
	AppliedPolicyVersion int64 `json:"appliedPolicyVersion,omitempty,string"`

	// AppliedState: The state currently applied to the device.
	//
	// Possible values:
	//   "DEVICE_STATE_UNSPECIFIED" - This value is disallowed.
	//   "ACTIVE" - The device is active.
	//   "DISABLED" - The device is disabled.
	//   "DELETED" - The device was deleted. This state will never be
	// returned by an API call, but is used in the final status report
	// published to Cloud Pub/Sub when the device acknowledges the deletion.
	//   "PROVISIONING" - The device is being provisioned. Newly enrolled
	// devices are in this state until they have a policy applied.
	AppliedState string `json:"appliedState,omitempty"`

	// DeviceSettings: Device settings information. This information is only
	// available if deviceSettingsEnabled is true in the device's policy.
	DeviceSettings *DeviceSettings `json:"deviceSettings,omitempty"`

	// DisabledReason: If the device state is DISABLED, an optional message
	// that is displayed on the device indicating the reason the device is
	// disabled. This field can be modified by a patch request.
	DisabledReason *UserFacingMessage `json:"disabledReason,omitempty"`

	// Displays: Detailed information about displays on the device. This
	// information is only available if displayInfoEnabled is true in the
	// device's policy.
	Displays []*Display `json:"displays,omitempty"`

	// EnrollmentTime: The time of device enrollment.
	EnrollmentTime string `json:"enrollmentTime,omitempty"`

	// EnrollmentTokenData: If the device was enrolled with an enrollment
	// token with additional data provided, this field contains that data.
	EnrollmentTokenData string `json:"enrollmentTokenData,omitempty"`

	// EnrollmentTokenName: If the device was enrolled with an enrollment
	// token, this field contains the name of the token.
	EnrollmentTokenName string `json:"enrollmentTokenName,omitempty"`

	// HardwareInfo: Detailed information about the device hardware.
	HardwareInfo *HardwareInfo `json:"hardwareInfo,omitempty"`

	// HardwareStatusSamples: Hardware status samples in chronological
	// order. This information is only available if hardwareStatusEnabled is
	// true in the device's policy.
	HardwareStatusSamples []*HardwareStatus `json:"hardwareStatusSamples,omitempty"`

	// LastPolicyComplianceReportTime: Deprecated.
	LastPolicyComplianceReportTime string `json:"lastPolicyComplianceReportTime,omitempty"`

	// LastPolicySyncTime: The last time the device fetched its policy.
	LastPolicySyncTime string `json:"lastPolicySyncTime,omitempty"`

	// LastStatusReportTime: The last time the device sent a status report.
	LastStatusReportTime string `json:"lastStatusReportTime,omitempty"`

	// ManagementMode: The type of management mode Android Device Policy
	// takes on the device. This influences which policy settings are
	// supported.
	//
	// Possible values:
	//   "MANAGEMENT_MODE_UNSPECIFIED" - This value is disallowed.
	//   "DEVICE_OWNER" - Device owner. Android Device Policy has full
	// control over the device.
	//   "PROFILE_OWNER" - Profile owner. Android Device Policy has control
	// over a managed profile on the device.
	ManagementMode string `json:"managementMode,omitempty"`

	// MemoryEvents: Events related to memory and storage measurements in
	// chronological order. This information is only available if
	// memoryInfoEnabled is true in the device's policy.
	MemoryEvents []*MemoryEvent `json:"memoryEvents,omitempty"`

	// MemoryInfo: Memory information. This information is only available if
	// memoryInfoEnabled is true in the device's policy.
	MemoryInfo *MemoryInfo `json:"memoryInfo,omitempty"`

	// Name: The name of the device in the form
	// enterprises/{enterpriseId}/devices/{deviceId}.
	Name string `json:"name,omitempty"`

	// NetworkInfo: Device network information. This information is only
	// available if networkInfoEnabled is true in the device's policy.
	NetworkInfo *NetworkInfo `json:"networkInfo,omitempty"`

	// NonComplianceDetails: Details about policy settings that the device
	// is not compliant with.
	NonComplianceDetails []*NonComplianceDetail `json:"nonComplianceDetails,omitempty"`

	// Ownership: Ownership of the managed device.
	//
	// Possible values:
	//   "OWNERSHIP_UNSPECIFIED" - Ownership is unspecified.
	//   "COMPANY_OWNED" - Device is company-owned.
	//   "PERSONALLY_OWNED" - Device is personally-owned.
	Ownership string `json:"ownership,omitempty"`

	// PolicyCompliant: Whether the device is compliant with its policy.
	PolicyCompliant bool `json:"policyCompliant,omitempty"`

	// PolicyName: The name of the policy applied to the device, in the form
	// enterprises/{enterpriseId}/policies/{policyId}. If not specified, the
	// policy_name for the device's user is applied. This field can be
	// modified by a patch request. You can specify only the policyId when
	// calling enterprises.devices.patch, as long as the policyId doesn’t
	// contain any slashes. The rest of the policy name is inferred.
	PolicyName string `json:"policyName,omitempty"`

	// PowerManagementEvents: Power management events on the device in
	// chronological order. This information is only available if
	// powerManagementEventsEnabled is true in the device's policy.
	PowerManagementEvents []*PowerManagementEvent `json:"powerManagementEvents,omitempty"`

	// PreviousDeviceNames: If the same physical device has been enrolled
	// multiple times, this field contains its previous device names. The
	// serial number is used as the unique identifier to determine if the
	// same physical device has enrolled previously. The names are in
	// chronological order.
	PreviousDeviceNames []string `json:"previousDeviceNames,omitempty"`

	// SecurityPosture: Device's security posture value that reflects how
	// secure the device is.
	SecurityPosture *SecurityPosture `json:"securityPosture,omitempty"`

	// SoftwareInfo: Detailed information about the device software. This
	// information is only available if softwareInfoEnabled is true in the
	// device's policy.
	SoftwareInfo *SoftwareInfo `json:"softwareInfo,omitempty"`

	// State: The state to be applied to the device. This field can be
	// modified by a patch request. Note that when calling
	// enterprises.devices.patch, ACTIVE and DISABLED are the only allowable
	// values. To enter the device into a DELETED state, call
	// enterprises.devices.delete.
	//
	// Possible values:
	//   "DEVICE_STATE_UNSPECIFIED" - This value is disallowed.
	//   "ACTIVE" - The device is active.
	//   "DISABLED" - The device is disabled.
	//   "DELETED" - The device was deleted. This state will never be
	// returned by an API call, but is used in the final status report
	// published to Cloud Pub/Sub when the device acknowledges the deletion.
	//   "PROVISIONING" - The device is being provisioned. Newly enrolled
	// devices are in this state until they have a policy applied.
	State string `json:"state,omitempty"`

	// SystemProperties: Map of selected system properties name and value
	// related to the device. This information is only available if
	// systemPropertiesEnabled is true in the device's policy.
	SystemProperties map[string]string `json:"systemProperties,omitempty"`

	// User: The user who owns the device.
	User *User `json:"user,omitempty"`

	// UserName: The resource name of the user that owns this device in the
	// form enterprises/{enterpriseId}/users/{userId}.
	UserName string `json:"userName,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ApiLevel") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "ApiLevel") 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 *Device) MarshalJSON() ([]byte, error) {
	type NoMethod Device
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceSettings: Information about security related device settings on
// device.
type DeviceSettings struct {
	// AdbEnabled: Whether ADB
	// (https://developer.android.com/studio/command-line/adb.html) is
	// enabled on the device.
	AdbEnabled bool `json:"adbEnabled,omitempty"`

	// DevelopmentSettingsEnabled: Whether developer mode is enabled on the
	// device.
	DevelopmentSettingsEnabled bool `json:"developmentSettingsEnabled,omitempty"`

	// EncryptionStatus: Encryption status from DevicePolicyManager.
	//
	// Possible values:
	//   "ENCRYPTION_STATUS_UNSPECIFIED" - Unspecified. No device should
	// have this type.
	//   "UNSUPPORTED" - Encryption is not supported by the device.
	//   "INACTIVE" - Encryption is supported by the device, but is not
	// currently active.
	//   "ACTIVATING" - Encryption is not currently active, but is currently
	// being activated.
	//   "ACTIVE" - Encryption is active.
	//   "ACTIVE_DEFAULT_KEY" - Encryption is active, but an encryption key
	// is not set by the user.
	//   "ACTIVE_PER_USER" - Encryption is active, and the encryption key is
	// tied to the user profile.
	EncryptionStatus string `json:"encryptionStatus,omitempty"`

	// IsDeviceSecure: Whether the device is secured with PIN/password.
	IsDeviceSecure bool `json:"isDeviceSecure,omitempty"`

	// IsEncrypted: Whether the storage encryption is enabled.
	IsEncrypted bool `json:"isEncrypted,omitempty"`

	// UnknownSourcesEnabled: Whether installing apps from unknown sources
	// is enabled.
	UnknownSourcesEnabled bool `json:"unknownSourcesEnabled,omitempty"`

	// VerifyAppsEnabled: Whether Verify Apps (Google Play Protect
	// (https://support.google.com/googleplay/answer/2812853)) is enabled on
	// the device.
	VerifyAppsEnabled bool `json:"verifyAppsEnabled,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdbEnabled") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "AdbEnabled") 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 *DeviceSettings) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceSettings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Display: Device display information.
type Display struct {
	// Density: Display density expressed as dots-per-inch.
	Density int64 `json:"density,omitempty"`

	// DisplayId: Unique display id.
	DisplayId int64 `json:"displayId,omitempty"`

	// Height: Display height in pixels.
	Height int64 `json:"height,omitempty"`

	// Name: Name of the display.
	Name string `json:"name,omitempty"`

	// RefreshRate: Refresh rate of the display in frames per second.
	RefreshRate int64 `json:"refreshRate,omitempty"`

	// State: State of the display.
	//
	// Possible values:
	//   "DISPLAY_STATE_UNSPECIFIED" - This value is disallowed.
	//   "OFF" - Display is off.
	//   "ON" - Display is on.
	//   "DOZE" - Display is dozing in a low power state
	//   "SUSPENDED" - Display is dozing in a suspended low power state.
	State string `json:"state,omitempty"`

	// Width: Display width in pixels.
	Width int64 `json:"width,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Density") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Density") 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 *Display) MarshalJSON() ([]byte, error) {
	type NoMethod Display
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Empty: A generic empty message that you can re-use to avoid defining
// duplicated empty messages in your APIs. A typical example is to use
// it as the request or the response type of an API method. For
// instance: service Foo { rpc Bar(google.protobuf.Empty) returns
// (google.protobuf.Empty); } The JSON representation for Empty is empty
// JSON object {}.
type Empty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// EnrollmentToken: An enrollment token.
type EnrollmentToken struct {
	// AdditionalData: Optional, arbitrary data associated with the
	// enrollment token. This could contain, for example, the ID of an org
	// unit the device is assigned to after enrollment. After a device
	// enrolls with the token, this data will be exposed in the
	// enrollment_token_data field of the Device resource. The data must be
	// 1024 characters or less; otherwise, the creation request will fail.
	AdditionalData string `json:"additionalData,omitempty"`

	// AllowPersonalUsage: Controls whether personal usage is allowed on a
	// device provisioned with this enrollment token.For company-owned
	// devices: Enabling personal usage allows the user to set up a work
	// profile on the device. Disabling personal usage requires the user
	// provision the device as a fully managed device.For personally-owned
	// devices: Enabling personal usage allows the user to set up a work
	// profile on the device. Disabling personal usage will prevent the
	// device from provisioning. Personal usage cannot be disabled on
	// personally-owned device.
	//
	// Possible values:
	//   "ALLOW_PERSONAL_USAGE_UNSPECIFIED" - Personal usage restriction is
	// not specified
	//   "PERSONAL_USAGE_ALLOWED" - Personal usage is allowed
	//   "PERSONAL_USAGE_DISALLOWED" - Personal usage is disallowed
	AllowPersonalUsage string `json:"allowPersonalUsage,omitempty"`

	// Duration: The length of time the enrollment token is valid, ranging
	// from 1 minute to 30 days. If not specified, the default duration is 1
	// hour.
	Duration string `json:"duration,omitempty"`

	// ExpirationTimestamp: The expiration time of the token. This is a
	// read-only field generated by the server.
	ExpirationTimestamp string `json:"expirationTimestamp,omitempty"`

	// Name: The name of the enrollment token, which is generated by the
	// server during creation, in the form
	// enterprises/{enterpriseId}/enrollmentTokens/{enrollmentTokenId}.
	Name string `json:"name,omitempty"`

	// OneTimeOnly: Whether the enrollment token is for one time use only.
	// If the flag is set to true, only one device can use it for
	// registration.
	OneTimeOnly bool `json:"oneTimeOnly,omitempty"`

	// PolicyName: The name of the policy initially applied to the enrolled
	// device, in the form enterprises/{enterpriseId}/policies/{policyId}.
	// If not specified, the policy_name for the device’s user is applied.
	// If user_name is also not specified,
	// enterprises/{enterpriseId}/policies/default is applied by default.
	// When updating this field, you can specify only the policyId as long
	// as the policyId doesn’t contain any slashes. The rest of the policy
	// name will be inferred.
	PolicyName string `json:"policyName,omitempty"`

	// QrCode: A JSON string whose UTF-8 representation can be used to
	// generate a QR code to enroll a device with this enrollment token. To
	// enroll a device using NFC, the NFC record must contain a serialized
	// java.util.Properties representation of the properties in the JSON.
	QrCode string `json:"qrCode,omitempty"`

	// User: The user associated with this enrollment token. If it's
	// specified when the enrollment token is created and the user does not
	// exist, the user will be created. This field must not contain
	// personally identifiable information. Only the account_identifier
	// field needs to be set.
	User *User `json:"user,omitempty"`

	// Value: The token value that's passed to the device and authorizes the
	// device to enroll. This is a read-only field generated by the server.
	Value string `json:"value,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AdditionalData") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "AdditionalData") 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 *EnrollmentToken) MarshalJSON() ([]byte, error) {
	type NoMethod EnrollmentToken
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Enterprise: The configuration applied to an enterprise.
type Enterprise struct {
	// AppAutoApprovalEnabled: Deprecated and unused.
	AppAutoApprovalEnabled bool `json:"appAutoApprovalEnabled,omitempty"`

	// EnabledNotificationTypes: The types of Google Pub/Sub notifications
	// enabled for the enterprise.
	//
	// Possible values:
	//   "NOTIFICATION_TYPE_UNSPECIFIED" - This value is ignored.
	//   "ENROLLMENT" - A notification sent when a device enrolls.
	//   "COMPLIANCE_REPORT" - Deprecated.
	//   "STATUS_REPORT" - A notification sent when a device issues a status
	// report.
	//   "COMMAND" - A notification sent when a device command has
	// completed.
	EnabledNotificationTypes []string `json:"enabledNotificationTypes,omitempty"`

	// EnterpriseDisplayName: The name of the enterprise displayed to users.
	EnterpriseDisplayName string `json:"enterpriseDisplayName,omitempty"`

	// Logo: An image displayed as a logo during device provisioning.
	// Supported types are: image/bmp, image/gif, image/x-ico, image/jpeg,
	// image/png, image/webp, image/vnd.wap.wbmp, image/x-adobe-dng.
	Logo *ExternalData `json:"logo,omitempty"`

	// Name: The name of the enterprise which is generated by the server
	// during creation, in the form enterprises/{enterpriseId}.
	Name string `json:"name,omitempty"`

	// PrimaryColor: A color in RGB format that indicates the predominant
	// color to display in the device management app UI. The color
	// components are stored as follows: (red << 16) | (green << 8) | blue,
	// where the value of each component is between 0 and 255, inclusive.
	PrimaryColor int64 `json:"primaryColor,omitempty"`

	// PubsubTopic: The topic that Cloud Pub/Sub notifications are published
	// to, in the form projects/{project}/topics/{topic}. This field is only
	// required if Pub/Sub notifications are enabled.
	PubsubTopic string `json:"pubsubTopic,omitempty"`

	// SigninDetails: Sign-in details of the enterprise.
	SigninDetails []*SigninDetail `json:"signinDetails,omitempty"`

	// TermsAndConditions: Terms and conditions that must be accepted when
	// provisioning a device for this enterprise. A page of terms is
	// generated for each value in this list.
	TermsAndConditions []*TermsAndConditions `json:"termsAndConditions,omitempty"`

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

	// ForceSendFields is a list of field names (e.g.
	// "AppAutoApprovalEnabled") to unconditionally include in API requests.
	// By default, fields with empty 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. "AppAutoApprovalEnabled")
	// 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 *Enterprise) MarshalJSON() ([]byte, error) {
	type NoMethod Enterprise
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExternalData: Data hosted at an external location. The data is to be
// downloaded by Android Device Policy and verified against the hash.
type ExternalData struct {
	// Sha256Hash: The base-64 encoded SHA-256 hash of the content hosted at
	// url. If the content doesn't match this hash, Android Device Policy
	// won't use the data.
	Sha256Hash string `json:"sha256Hash,omitempty"`

	// Url: The absolute URL to the data, which must use either the http or
	// https scheme. Android Device Policy doesn't provide any credentials
	// in the GET request, so the URL must be publicly accessible. Including
	// a long, random component in the URL may be used to prevent attackers
	// from discovering the URL.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Sha256Hash") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Sha256Hash") 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 *ExternalData) MarshalJSON() ([]byte, error) {
	type NoMethod ExternalData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FreezePeriod: A system freeze period. When a device’s clock is
// within the freeze period, all incoming system updates (including
// security patches) are blocked and won’t be installed. When a device
// is outside the freeze period, normal update behavior applies. Leap
// years are ignored in freeze period calculations, in particular: * If
// Feb. 29th is set as the start or end date of a freeze period, the
// freeze period will start or end on Feb. 28th instead. * When a
// device’s system clock reads Feb. 29th, it’s treated as Feb. 28th.
// * When calculating the number of days in a freeze period or the time
// between two freeze periods, Feb. 29th is ignored and not counted as a
// day.
type FreezePeriod struct {
	// EndDate: The end date (inclusive) of the freeze period. Must be no
	// later than 90 days from the start date. If the end date is earlier
	// than the start date, the freeze period is considered wrapping
	// year-end. Note: year must not be set. For example, {"month":
	// 1,"date": 30}.
	EndDate *Date `json:"endDate,omitempty"`

	// StartDate: The start date (inclusive) of the freeze period. Note:
	// year must not be set. For example, {"month": 1,"date": 30}.
	StartDate *Date `json:"startDate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndDate") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "EndDate") 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 *FreezePeriod) MarshalJSON() ([]byte, error) {
	type NoMethod FreezePeriod
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HardwareInfo: Information about device hardware. The fields related
// to temperature thresholds are only available if hardwareStatusEnabled
// is true in the device's policy.
type HardwareInfo struct {
	// BatteryShutdownTemperatures: Battery shutdown temperature thresholds
	// in Celsius for each battery on the device.
	BatteryShutdownTemperatures []float64 `json:"batteryShutdownTemperatures,omitempty"`

	// BatteryThrottlingTemperatures: Battery throttling temperature
	// thresholds in Celsius for each battery on the device.
	BatteryThrottlingTemperatures []float64 `json:"batteryThrottlingTemperatures,omitempty"`

	// Brand: Brand of the device. For example, Google.
	Brand string `json:"brand,omitempty"`

	// CpuShutdownTemperatures: CPU shutdown temperature thresholds in
	// Celsius for each CPU on the device.
	CpuShutdownTemperatures []float64 `json:"cpuShutdownTemperatures,omitempty"`

	// CpuThrottlingTemperatures: CPU throttling temperature thresholds in
	// Celsius for each CPU on the device.
	CpuThrottlingTemperatures []float64 `json:"cpuThrottlingTemperatures,omitempty"`

	// DeviceBasebandVersion: Baseband version. For example,
	// MDM9625_104662.22.05.34p.
	DeviceBasebandVersion string `json:"deviceBasebandVersion,omitempty"`

	// GpuShutdownTemperatures: GPU shutdown temperature thresholds in
	// Celsius for each GPU on the device.
	GpuShutdownTemperatures []float64 `json:"gpuShutdownTemperatures,omitempty"`

	// GpuThrottlingTemperatures: GPU throttling temperature thresholds in
	// Celsius for each GPU on the device.
	GpuThrottlingTemperatures []float64 `json:"gpuThrottlingTemperatures,omitempty"`

	// Hardware: Name of the hardware. For example, Angler.
	Hardware string `json:"hardware,omitempty"`

	// Manufacturer: Manufacturer. For example, Motorola.
	Manufacturer string `json:"manufacturer,omitempty"`

	// Model: The model of the device. For example, Asus Nexus 7.
	Model string `json:"model,omitempty"`

	// SerialNumber: The device serial number.
	SerialNumber string `json:"serialNumber,omitempty"`

	// SkinShutdownTemperatures: Device skin shutdown temperature thresholds
	// in Celsius.
	SkinShutdownTemperatures []float64 `json:"skinShutdownTemperatures,omitempty"`

	// SkinThrottlingTemperatures: Device skin throttling temperature
	// thresholds in Celsius.
	SkinThrottlingTemperatures []float64 `json:"skinThrottlingTemperatures,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "BatteryShutdownTemperatures") to unconditionally include in API
	// requests. By default, fields with empty 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.
	// "BatteryShutdownTemperatures") 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 *HardwareInfo) MarshalJSON() ([]byte, error) {
	type NoMethod HardwareInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HardwareStatus: Hardware status. Temperatures may be compared to the
// temperature thresholds available in hardwareInfo to determine
// hardware health.
type HardwareStatus struct {
	// BatteryTemperatures: Current battery temperatures in Celsius for each
	// battery on the device.
	BatteryTemperatures []float64 `json:"batteryTemperatures,omitempty"`

	// CpuTemperatures: Current CPU temperatures in Celsius for each CPU on
	// the device.
	CpuTemperatures []float64 `json:"cpuTemperatures,omitempty"`

	// CpuUsages: CPU usages in percentage for each core available on the
	// device. Usage is 0 for each unplugged core. Empty array implies that
	// CPU usage is not supported in the system.
	CpuUsages []float64 `json:"cpuUsages,omitempty"`

	// CreateTime: The time the measurements were taken.
	CreateTime string `json:"createTime,omitempty"`

	// FanSpeeds: Fan speeds in RPM for each fan on the device. Empty array
	// means that there are no fans or fan speed is not supported on the
	// system.
	FanSpeeds []float64 `json:"fanSpeeds,omitempty"`

	// GpuTemperatures: Current GPU temperatures in Celsius for each GPU on
	// the device.
	GpuTemperatures []float64 `json:"gpuTemperatures,omitempty"`

	// SkinTemperatures: Current device skin temperatures in Celsius.
	SkinTemperatures []float64 `json:"skinTemperatures,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BatteryTemperatures")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "BatteryTemperatures") 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 *HardwareStatus) MarshalJSON() ([]byte, error) {
	type NoMethod HardwareStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// KeyedAppState: Keyed app state reported by the app.
type KeyedAppState struct {
	// CreateTime: The creation time of the app state on the device.
	CreateTime string `json:"createTime,omitempty"`

	// Data: Optionally, a machine-readable value to be read by the EMM. For
	// example, setting values that the admin can choose to query against in
	// the EMM console (e.g. “notify me if the battery_warning data <
	// 10”).
	Data string `json:"data,omitempty"`

	// Key: The key for the app state. Acts as a point of reference for what
	// the app is providing state for. For example, when providing managed
	// configuration feedback, this key could be the managed configuration
	// key.
	Key string `json:"key,omitempty"`

	// LastUpdateTime: The time the app state was most recently updated.
	LastUpdateTime string `json:"lastUpdateTime,omitempty"`

	// Message: Optionally, a free-form message string to explain the app
	// state. If the state was triggered by a particular value (e.g. a
	// managed configuration value), it should be included in the message.
	Message string `json:"message,omitempty"`

	// Severity: The severity of the app state.
	//
	// Possible values:
	//   "SEVERITY_UNSPECIFIED" - Unspecified severity level.
	//   "INFO" - Information severity level.
	//   "ERROR" - Error severity level. This should only be set for genuine
	// error conditions that a management organization needs to take action
	// to fix.
	Severity string `json:"severity,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateTime") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "CreateTime") 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 *KeyedAppState) MarshalJSON() ([]byte, error) {
	type NoMethod KeyedAppState
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// KioskCustomization: Settings controlling the behavior of a device in
// kiosk mode. To enable kiosk mode, set kioskCustomLauncherEnabled to
// true or specify an app in the policy with installType KIOSK.
type KioskCustomization struct {
	// DeviceSettings: Specifies whether the Settings app is allowed in
	// kiosk mode.
	//
	// Possible values:
	//   "DEVICE_SETTINGS_UNSPECIFIED" - Unspecified, defaults to
	// SETTINGS_ACCESS_ALLOWED.
	//   "SETTINGS_ACCESS_ALLOWED" - Access to the Settings app is allowed
	// in kiosk mode.
	//   "SETTINGS_ACCESS_BLOCKED" - Access to the Settings app is not
	// allowed in kiosk mode.
	DeviceSettings string `json:"deviceSettings,omitempty"`

	// PowerButtonActions: Sets the behavior of a device in kiosk mode when
	// a user presses and holds (long-presses) the Power button.
	//
	// Possible values:
	//   "POWER_BUTTON_ACTIONS_UNSPECIFIED" - Unspecified, defaults to
	// POWER_BUTTON_AVAILABLE.
	//   "POWER_BUTTON_AVAILABLE" - The power menu (e.g. Power off, Restart)
	// is shown when a user long-presses the Power button of a device in
	// kiosk mode.
	//   "POWER_BUTTON_BLOCKED" - The power menu (e.g. Power off, Restart)
	// is not shown when a user long-presses the Power button of a device in
	// kiosk mode. Note: this may prevent users from turning off the device.
	PowerButtonActions string `json:"powerButtonActions,omitempty"`

	// StatusBar: Specifies whether system info and notifications are
	// disabled in kiosk mode.
	//
	// Possible values:
	//   "STATUS_BAR_UNSPECIFIED" - Unspecified, defaults to
	// INFO_AND_NOTIFICATIONS_DISABLED.
	//   "NOTIFICATIONS_AND_SYSTEM_INFO_ENABLED" - System info and
	// notifications are shown on the status bar in kiosk mode.Note: For
	// this policy to take effect, the device's home button must be enabled
	// using kioskCustomization.systemNavigation.
	//   "NOTIFICATIONS_AND_SYSTEM_INFO_DISABLED" - System info and
	// notifications are disabled in kiosk mode.
	//   "SYSTEM_INFO_ONLY" - Only system info is shown on the status bar.
	StatusBar string `json:"statusBar,omitempty"`

	// SystemErrorWarnings: Specifies whether system error dialogs for
	// crashed or unresponsive apps are blocked in kiosk mode. When blocked,
	// the system will force-stop the app as if the user chooses the "close
	// app" option on the UI.
	//
	// Possible values:
	//   "SYSTEM_ERROR_WARNINGS_UNSPECIFIED" - Unspecified, defaults to
	// ERROR_AND_WARNINGS_MUTED.
	//   "ERROR_AND_WARNINGS_ENABLED" - All system error dialogs such as
	// crash and app not responding (ANR) are displayed.
	//   "ERROR_AND_WARNINGS_MUTED" - All system error dialogs, such as
	// crash and app not responding (ANR) are blocked. When blocked, the
	// system force-stops the app as if the user closes the app from the UI.
	SystemErrorWarnings string `json:"systemErrorWarnings,omitempty"`

	// SystemNavigation: Specifies which navigation features are enabled
	// (e.g. Home, Overview buttons) in kiosk mode.
	//
	// Possible values:
	//   "SYSTEM_NAVIGATION_UNSPECIFIED" - Unspecified, defaults to
	// NAVIGATION_DISABLED.
	//   "NAVIGATION_ENABLED" - Home and overview buttons are enabled.
	//   "NAVIGATION_DISABLED" - The home and Overview buttons are not
	// accessible.
	//   "HOME_BUTTON_ONLY" - Only the home button is enabled.
	SystemNavigation string `json:"systemNavigation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeviceSettings") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "DeviceSettings") 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 *KioskCustomization) MarshalJSON() ([]byte, error) {
	type NoMethod KioskCustomization
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LaunchAppAction: An action to launch an app.
type LaunchAppAction struct {
	// PackageName: Package name of app to be launched
	PackageName string `json:"packageName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PackageName") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "PackageName") 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 *LaunchAppAction) MarshalJSON() ([]byte, error) {
	type NoMethod LaunchAppAction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListDevicesResponse: Response to a request to list devices for a
// given enterprise.
type ListDevicesResponse struct {
	// Devices: The list of devices.
	Devices []*Device `json:"devices,omitempty"`

	// NextPageToken: If there are more results, a token to retrieve next
	// page of results.
	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 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 *ListDevicesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListDevicesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListOperationsResponse: The response message for
// Operations.ListOperations.
type ListOperationsResponse struct {
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Operations: A list of operations that matches the specified filter in
	// the request.
	Operations []*Operation `json:"operations,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 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 *ListOperationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListOperationsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListPoliciesResponse: Response to a request to list policies for a
// given enterprise.
type ListPoliciesResponse struct {
	// NextPageToken: If there are more results, a token to retrieve next
	// page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Policies: The list of policies.
	Policies []*Policy `json:"policies,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 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 *ListPoliciesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListPoliciesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListWebAppsResponse: Response to a request to list web apps for a
// given enterprise.
type ListWebAppsResponse struct {
	// NextPageToken: If there are more results, a token to retrieve next
	// page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// WebApps: The list of web apps.
	WebApps []*WebApp `json:"webApps,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 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 *ListWebAppsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListWebAppsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ManagedConfigurationTemplate: The managed configurations template for
// the app, saved from the managed configurations iframe.
type ManagedConfigurationTemplate struct {
	// ConfigurationVariables: Optional, a map containing configuration
	// variables defined for the configuration.
	ConfigurationVariables map[string]string `json:"configurationVariables,omitempty"`

	// TemplateId: The ID of the managed configurations template.
	TemplateId string `json:"templateId,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ConfigurationVariables") to unconditionally include in API requests.
	// By default, fields with empty 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. "ConfigurationVariables")
	// 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 *ManagedConfigurationTemplate) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedConfigurationTemplate
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ManagedProperty: Managed property.
type ManagedProperty struct {
	// DefaultValue: The default value of the property. BUNDLE_ARRAY
	// properties don't have a default value.
	DefaultValue interface{} `json:"defaultValue,omitempty"`

	// Description: A longer description of the property, providing more
	// detail of what it affects. Localized.
	Description string `json:"description,omitempty"`

	// Entries: For CHOICE or MULTISELECT properties, the list of possible
	// entries.
	Entries []*ManagedPropertyEntry `json:"entries,omitempty"`

	// Key: The unique key that the app uses to identify the property, e.g.
	// "com.google.android.gm.fieldname".
	Key string `json:"key,omitempty"`

	// NestedProperties: For BUNDLE_ARRAY properties, the list of nested
	// properties. A BUNDLE_ARRAY property is at most two levels deep.
	NestedProperties []*ManagedProperty `json:"nestedProperties,omitempty"`

	// Title: The name of the property. Localized.
	Title string `json:"title,omitempty"`

	// Type: The type of the property.
	//
	// Possible values:
	//   "MANAGED_PROPERTY_TYPE_UNSPECIFIED" - Not used.
	//   "BOOL" - A property of boolean type.
	//   "STRING" - A property of string type.
	//   "INTEGER" - A property of integer type.
	//   "CHOICE" - A choice of one item from a set.
	//   "MULTISELECT" - A choice of multiple items from a set.
	//   "HIDDEN" - A hidden restriction of string type (the default value
	// can be used to pass along information that can't be modified, such as
	// a version code).
	//   "BUNDLE" - A bundle of properties
	//   "BUNDLE_ARRAY" - An array of property bundles.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DefaultValue") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "DefaultValue") 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 *ManagedProperty) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedProperty
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ManagedPropertyEntry: An entry of a managed property.
type ManagedPropertyEntry struct {
	// Name: The human-readable name of the value. Localized.
	Name string `json:"name,omitempty"`

	// Value: The machine-readable value of the entry, which should be used
	// in the configuration. Not localized.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Name") 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 *ManagedPropertyEntry) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedPropertyEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MemoryEvent: An event related to memory and storage measurements.
type MemoryEvent struct {
	// ByteCount: The number of free bytes in the medium, or for
	// EXTERNAL_STORAGE_DETECTED, the total capacity in bytes of the storage
	// medium.
	ByteCount int64 `json:"byteCount,omitempty,string"`

	// CreateTime: The creation time of the event.
	CreateTime string `json:"createTime,omitempty"`

	// EventType: Event type.
	//
	// Possible values:
	//   "MEMORY_EVENT_TYPE_UNSPECIFIED" - Unspecified. No events have this
	// type.
	//   "RAM_MEASURED" - Free space in RAM was measured.
	//   "INTERNAL_STORAGE_MEASURED" - Free space in internal storage was
	// measured.
	//   "EXTERNAL_STORAGE_DETECTED" - A new external storage medium was
	// detected. The reported byte count is the total capacity of the
	// storage medium.
	//   "EXTERNAL_STORAGE_REMOVED" - An external storage medium was
	// removed. The reported byte count is zero.
	//   "EXTERNAL_STORAGE_MEASURED" - Free space in an external storage
	// medium was measured.
	EventType string `json:"eventType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ByteCount") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "ByteCount") 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 *MemoryEvent) MarshalJSON() ([]byte, error) {
	type NoMethod MemoryEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MemoryInfo: Information about device memory and storage.
type MemoryInfo struct {
	// TotalInternalStorage: Total internal storage on device in bytes.
	TotalInternalStorage int64 `json:"totalInternalStorage,omitempty,string"`

	// TotalRam: Total RAM on device in bytes.
	TotalRam int64 `json:"totalRam,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "TotalInternalStorage") to unconditionally include in API requests.
	// By default, fields with empty 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. "TotalInternalStorage") 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 *MemoryInfo) MarshalJSON() ([]byte, error) {
	type NoMethod MemoryInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NetworkInfo: Device network info.
type NetworkInfo struct {
	// Imei: IMEI number of the GSM device. For example, A1000031212.
	Imei string `json:"imei,omitempty"`

	// Meid: MEID number of the CDMA device. For example, A00000292788E1.
	Meid string `json:"meid,omitempty"`

	// NetworkOperatorName: Alphabetic name of current registered operator.
	// For example, Vodafone.
	NetworkOperatorName string `json:"networkOperatorName,omitempty"`

	// WifiMacAddress: Wi-Fi MAC address of the device. For example,
	// 7c:11:11:11:11:11.
	WifiMacAddress string `json:"wifiMacAddress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Imei") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Imei") 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 *NetworkInfo) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NonComplianceDetail: Provides detail about non-compliance with a
// policy setting.
type NonComplianceDetail struct {
	// CurrentValue: If the policy setting could not be applied, the current
	// value of the setting on the device.
	CurrentValue interface{} `json:"currentValue,omitempty"`

	// FieldPath: For settings with nested fields, if a particular nested
	// field is out of compliance, this specifies the full path to the
	// offending field. The path is formatted in the same way the policy
	// JSON field would be referenced in JavaScript, that is: 1) For
	// object-typed fields, the field name is followed by a dot then by a
	// subfield name. 2) For array-typed fields, the field name is followed
	// by the array index enclosed in brackets. For example, to indicate a
	// problem with the url field in the externalData field in the 3rd
	// application, the path would be applications[2].externalData.url
	FieldPath string `json:"fieldPath,omitempty"`

	// InstallationFailureReason: If package_name is set and the
	// non-compliance reason is APP_NOT_INSTALLED or APP_NOT_UPDATED, the
	// detailed reason the app can't be installed or updated.
	//
	// Possible values:
	//   "INSTALLATION_FAILURE_REASON_UNSPECIFIED" - This value is
	// disallowed.
	//   "INSTALLATION_FAILURE_REASON_UNKNOWN" - An unknown condition is
	// preventing the app from being installed. Some potential reasons are
	// that the device doesn't have enough storage, the device network
	// connection is unreliable, or the installation is taking longer than
	// expected. The installation will be retried automatically.
	//   "IN_PROGRESS" - The installation is still in progress.
	//   "NOT_FOUND" - The app was not found in Play.
	//   "NOT_COMPATIBLE_WITH_DEVICE" - The app is incompatible with the
	// device.
	//   "NOT_APPROVED" - The app has not been approved by the admin.
	//   "PERMISSIONS_NOT_ACCEPTED" - The app has new permissions that have
	// not been accepted by the admin.
	//   "NOT_AVAILABLE_IN_COUNTRY" - The app is not available in the user's
	// country.
	//   "NO_LICENSES_REMAINING" - There are no licenses available to assign
	// to the user.
	//   "NOT_ENROLLED" - The enterprise is no longer enrolled with Managed
	// Google Play or the admin has not accepted the latest Managed Google
	// Play Terms of Service.
	//   "USER_INVALID" - The user is no longer valid. The user may have
	// been deleted or disabled.
	InstallationFailureReason string `json:"installationFailureReason,omitempty"`

	// NonComplianceReason: The reason the device is not in compliance with
	// the setting.
	//
	// Possible values:
	//   "NON_COMPLIANCE_REASON_UNSPECIFIED" - This value is disallowed.
	//   "API_LEVEL" - The setting is not supported in the API level of the
	// Android version running on the device.
	//   "MANAGEMENT_MODE" - The management mode (profile owner, device
	// owner, etc.) doesn't support the setting.
	//   "USER_ACTION" - The user has not taken required action to comply
	// with the setting.
	//   "INVALID_VALUE" - The setting has an invalid value.
	//   "APP_NOT_INSTALLED" - The app required to implement the policy is
	// not installed.
	//   "UNSUPPORTED" - The policy is not supported by the version of
	// Android Device Policy on the device.
	//   "APP_INSTALLED" - A blocked app is installed.
	//   "PENDING" - The setting hasn't been applied at the time of the
	// report, but is expected to be applied shortly.
	//   "APP_INCOMPATIBLE" - The setting can't be applied to the app
	// because the app doesn't support it, for example because its target
	// SDK version is not high enough.
	//   "APP_NOT_UPDATED" - The app is installed, but it hasn't been
	// updated to the minimum version code specified by policy.
	NonComplianceReason string `json:"nonComplianceReason,omitempty"`

	// PackageName: The package name indicating which app is out of
	// compliance, if applicable.
	PackageName string `json:"packageName,omitempty"`

	// SettingName: The name of the policy setting. This is the JSON field
	// name of a top-level Policy field.
	SettingName string `json:"settingName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CurrentValue") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "CurrentValue") 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 *NonComplianceDetail) MarshalJSON() ([]byte, error) {
	type NoMethod NonComplianceDetail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NonComplianceDetailCondition: A compliance rule condition which is
// satisfied if there exists any matching NonComplianceDetail for the
// device. A NonComplianceDetail matches a NonComplianceDetailCondition
// if all the fields which are set within the
// NonComplianceDetailCondition match the corresponding
// NonComplianceDetail fields.
type NonComplianceDetailCondition struct {
	// NonComplianceReason: The reason the device is not in compliance with
	// the setting. If not set, then this condition matches any reason.
	//
	// Possible values:
	//   "NON_COMPLIANCE_REASON_UNSPECIFIED" - This value is disallowed.
	//   "API_LEVEL" - The setting is not supported in the API level of the
	// Android version running on the device.
	//   "MANAGEMENT_MODE" - The management mode (profile owner, device
	// owner, etc.) doesn't support the setting.
	//   "USER_ACTION" - The user has not taken required action to comply
	// with the setting.
	//   "INVALID_VALUE" - The setting has an invalid value.
	//   "APP_NOT_INSTALLED" - The app required to implement the policy is
	// not installed.
	//   "UNSUPPORTED" - The policy is not supported by the version of
	// Android Device Policy on the device.
	//   "APP_INSTALLED" - A blocked app is installed.
	//   "PENDING" - The setting hasn't been applied at the time of the
	// report, but is expected to be applied shortly.
	//   "APP_INCOMPATIBLE" - The setting can't be applied to the app
	// because the app doesn't support it, for example because its target
	// SDK version is not high enough.
	//   "APP_NOT_UPDATED" - The app is installed, but it hasn't been
	// updated to the minimum version code specified by policy.
	NonComplianceReason string `json:"nonComplianceReason,omitempty"`

	// PackageName: The package name of the app that's out of compliance. If
	// not set, then this condition matches any package name.
	PackageName string `json:"packageName,omitempty"`

	// SettingName: The name of the policy setting. This is the JSON field
	// name of a top-level Policy field. If not set, then this condition
	// matches any setting name.
	SettingName string `json:"settingName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NonComplianceReason")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "NonComplianceReason") 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 *NonComplianceDetailCondition) MarshalJSON() ([]byte, error) {
	type NoMethod NonComplianceDetailCondition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Operation: This resource represents a long-running operation that is
// the result of a network API call.
type Operation struct {
	// Done: If the value is false, it means the operation is still in
	// progress. If true, the operation is completed, and either error or
	// response is available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *Status `json:"error,omitempty"`

	// Metadata: Service-specific metadata associated with the operation. It
	// typically contains progress information and common metadata such as
	// create time. Some services might not provide such metadata. Any
	// method that returns a long-running operation should document the
	// metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that originally returns it. If you use the default HTTP
	// mapping, the name should be a resource name ending with
	// operations/{unique_id}.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success. If
	// the original method returns no data on success, such as Delete, the
	// response is google.protobuf.Empty. If the original method is standard
	// Get/Create/Update, the response should be the resource. For other
	// methods, the response should have the type XxxResponse, where Xxx is
	// the original method name. For example, if the original method name is
	// TakeSnapshot(), the inferred response type is TakeSnapshotResponse.
	Response googleapi.RawMessage `json:"response,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Done") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Done") 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 *Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PackageNameList: A list of package names.
type PackageNameList struct {
	// PackageNames: A list of package names.
	PackageNames []string `json:"packageNames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PackageNames") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "PackageNames") 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 *PackageNameList) MarshalJSON() ([]byte, error) {
	type NoMethod PackageNameList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PasswordRequirements: Requirements for the password used to unlock a
// device.
type PasswordRequirements struct {
	// MaximumFailedPasswordsForWipe: Number of incorrect device-unlock
	// passwords that can be entered before a device is wiped. A value of 0
	// means there is no restriction.
	MaximumFailedPasswordsForWipe int64 `json:"maximumFailedPasswordsForWipe,omitempty"`

	// PasswordExpirationTimeout: Password expiration timeout.
	PasswordExpirationTimeout string `json:"passwordExpirationTimeout,omitempty"`

	// PasswordHistoryLength: The length of the password history. After
	// setting this field, the user won't be able to enter a new password
	// that is the same as any password in the history. A value of 0 means
	// there is no restriction.
	PasswordHistoryLength int64 `json:"passwordHistoryLength,omitempty"`

	// PasswordMinimumLength: The minimum allowed password length. A value
	// of 0 means there is no restriction. Only enforced when
	// password_quality is NUMERIC, NUMERIC_COMPLEX, ALPHABETIC,
	// ALPHANUMERIC, or COMPLEX.
	PasswordMinimumLength int64 `json:"passwordMinimumLength,omitempty"`

	// PasswordMinimumLetters: Minimum number of letters required in the
	// password. Only enforced when password_quality is COMPLEX.
	PasswordMinimumLetters int64 `json:"passwordMinimumLetters,omitempty"`

	// PasswordMinimumLowerCase: Minimum number of lower case letters
	// required in the password. Only enforced when password_quality is
	// COMPLEX.
	PasswordMinimumLowerCase int64 `json:"passwordMinimumLowerCase,omitempty"`

	// PasswordMinimumNonLetter: Minimum number of non-letter characters
	// (numerical digits or symbols) required in the password. Only enforced
	// when password_quality is COMPLEX.
	PasswordMinimumNonLetter int64 `json:"passwordMinimumNonLetter,omitempty"`

	// PasswordMinimumNumeric: Minimum number of numerical digits required
	// in the password. Only enforced when password_quality is COMPLEX.
	PasswordMinimumNumeric int64 `json:"passwordMinimumNumeric,omitempty"`

	// PasswordMinimumSymbols: Minimum number of symbols required in the
	// password. Only enforced when password_quality is COMPLEX.
	PasswordMinimumSymbols int64 `json:"passwordMinimumSymbols,omitempty"`

	// PasswordMinimumUpperCase: Minimum number of upper case letters
	// required in the password. Only enforced when password_quality is
	// COMPLEX.
	PasswordMinimumUpperCase int64 `json:"passwordMinimumUpperCase,omitempty"`

	// PasswordQuality: The required password quality.
	//
	// Possible values:
	//   "PASSWORD_QUALITY_UNSPECIFIED" - There are no password
	// requirements.
	//   "BIOMETRIC_WEAK" - The device must be secured with a low-security
	// biometric recognition technology, at minimum. This includes
	// technologies that can recognize the identity of an individual that
	// are roughly equivalent to a 3-digit PIN (false detection is less than
	// 1 in 1,000).
	//   "SOMETHING" - A password is required, but there are no restrictions
	// on what the password must contain.
	//   "NUMERIC" - The password must contain numeric characters.
	//   "NUMERIC_COMPLEX" - The password must contain numeric characters
	// with no repeating (4444) or ordered (1234, 4321, 2468) sequences.
	//   "ALPHABETIC" - The password must contain alphabetic (or symbol)
	// characters.
	//   "ALPHANUMERIC" - The password must contain both numeric and
	// alphabetic (or symbol) characters.
	//   "COMPLEX" - The password must meet the minimum requirements
	// specified in passwordMinimumLength, passwordMinimumLetters,
	// passwordMinimumSymbols, etc. For example, if passwordMinimumSymbols
	// is 2, the password must contain at least two symbols.
	PasswordQuality string `json:"passwordQuality,omitempty"`

	// PasswordScope: The scope that the password requirement applies to.
	//
	// Possible values:
	//   "SCOPE_UNSPECIFIED" - The scope is unspecified. The password
	// requirements are applied to the work profile for work profile devices
	// and the whole device for fully managed or dedicated devices.
	//   "SCOPE_DEVICE" - The password requirements are only applied to the
	// device.
	//   "SCOPE_PROFILE" - The password requirements are only applied to the
	// work profile.
	PasswordScope string `json:"passwordScope,omitempty"`

	// RequirePasswordUnlock: The length of time after a device or work
	// profile is unlocked using a strong form of authentication (password,
	// PIN, pattern) that it can be unlocked using any other authentication
	// method (e.g. fingerprint, trust agents, face). After the specified
	// time period elapses, only strong forms of authentication can be used
	// to unlock the device or work profile.
	//
	// Possible values:
	//   "REQUIRE_PASSWORD_UNLOCK_UNSPECIFIED" - Unspecified. Defaults to
	// USE_DEFAULT_DEVICE_TIMEOUT.
	//   "USE_DEFAULT_DEVICE_TIMEOUT" - The timeout period is set to the
	// device’s default.
	//   "REQUIRE_EVERY_DAY" - The timeout period is set to 24 hours.
	RequirePasswordUnlock string `json:"requirePasswordUnlock,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "MaximumFailedPasswordsForWipe") to unconditionally include in API
	// requests. By default, fields with empty 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.
	// "MaximumFailedPasswordsForWipe") 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 *PasswordRequirements) MarshalJSON() ([]byte, error) {
	type NoMethod PasswordRequirements
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PermissionGrant: Configuration for an Android permission and its
// grant state.
type PermissionGrant struct {
	// Permission: The Android permission or group, e.g.
	// android.permission.READ_CALENDAR or
	// android.permission_group.CALENDAR.
	Permission string `json:"permission,omitempty"`

	// Policy: The policy for granting the permission.
	//
	// Possible values:
	//   "PERMISSION_POLICY_UNSPECIFIED" - Policy not specified. If no
	// policy is specified for a permission at any level, then the PROMPT
	// behavior is used by default.
	//   "PROMPT" - Prompt the user to grant a permission.
	//   "GRANT" - Automatically grant a permission.
	//   "DENY" - Automatically deny a permission.
	Policy string `json:"policy,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Permission") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Permission") 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 *PermissionGrant) MarshalJSON() ([]byte, error) {
	type NoMethod PermissionGrant
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PersistentPreferredActivity: A default activity for handling intents
// that match a particular intent filter. Note: To set up a kiosk, use
// InstallType to KIOSK rather than use persistent preferred activities.
type PersistentPreferredActivity struct {
	// Actions: The intent actions to match in the filter. If any actions
	// are included in the filter, then an intent's action must be one of
	// those values for it to match. If no actions are included, the intent
	// action is ignored.
	Actions []string `json:"actions,omitempty"`

	// Categories: The intent categories to match in the filter. An intent
	// includes the categories that it requires, all of which must be
	// included in the filter in order to match. In other words, adding a
	// category to the filter has no impact on matching unless that category
	// is specified in the intent.
	Categories []string `json:"categories,omitempty"`

	// ReceiverActivity: The activity that should be the default intent
	// handler. This should be an Android component name, e.g.
	// com.android.enterprise.app/.MainActivity. Alternatively, the value
	// may be the package name of an app, which causes Android Device Policy
	// to choose an appropriate activity from the app to handle the intent.
	ReceiverActivity string `json:"receiverActivity,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Actions") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Actions") 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 *PersistentPreferredActivity) MarshalJSON() ([]byte, error) {
	type NoMethod PersistentPreferredActivity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PersonalApplicationPolicy: Policies for apps in the personal profile
// of a company-owned device with a work profile.
type PersonalApplicationPolicy struct {
	// InstallType: The type of installation to perform.
	//
	// Possible values:
	//   "INSTALL_TYPE_UNSPECIFIED" - Unspecified. The default behavior is
	// that all installs are allowed.
	//   "BLOCKED" - The app is blocked and can't be installed in the
	// personal profile.
	InstallType string `json:"installType,omitempty"`

	// PackageName: The package name of the application.
	PackageName string `json:"packageName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstallType") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "InstallType") 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 *PersonalApplicationPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod PersonalApplicationPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PersonalUsagePolicies: Policies controlling personal usage on a
// company-owned device with a work profile.
type PersonalUsagePolicies struct {
	// AccountTypesWithManagementDisabled: Account types that can't be
	// managed by the user.
	AccountTypesWithManagementDisabled []string `json:"accountTypesWithManagementDisabled,omitempty"`

	// CameraDisabled: Whether camera is disabled.
	CameraDisabled bool `json:"cameraDisabled,omitempty"`

	// MaxDaysWithWorkOff: Controls how long the work profile can stay off.
	MaxDaysWithWorkOff int64 `json:"maxDaysWithWorkOff,omitempty"`

	// PersonalApplications: Policy applied to applications in the personal
	// profile.
	PersonalApplications []*PersonalApplicationPolicy `json:"personalApplications,omitempty"`

	// PersonalPlayStoreMode: Used together with personal_applications to
	// control how apps in the personal profile are allowed or blocked.
	//
	// Possible values:
	//   "PLAY_STORE_MODE_UNSPECIFIED" - Unspecified. Default behavior is to
	// allow all installs.
	//   "BLACKLIST" - All Play Store apps are available, except those whose
	// install_type is BLOCKED in personal_applications.
	PersonalPlayStoreMode string `json:"personalPlayStoreMode,omitempty"`

	// ScreenCaptureDisabled: Whether screen capture is disabled.
	ScreenCaptureDisabled bool `json:"screenCaptureDisabled,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AccountTypesWithManagementDisabled") to unconditionally include in
	// API requests. By default, fields with empty 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.
	// "AccountTypesWithManagementDisabled") 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 *PersonalUsagePolicies) MarshalJSON() ([]byte, error) {
	type NoMethod PersonalUsagePolicies
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Policy: A policy resource represents a group of settings that govern
// the behavior of a managed device and the apps installed on it.
type Policy struct {
	// AccountTypesWithManagementDisabled: Account types that can't be
	// managed by the user.
	AccountTypesWithManagementDisabled []string `json:"accountTypesWithManagementDisabled,omitempty"`

	// AddUserDisabled: Whether adding new users and profiles is disabled.
	AddUserDisabled bool `json:"addUserDisabled,omitempty"`

	// AdjustVolumeDisabled: Whether adjusting the master volume is
	// disabled.
	AdjustVolumeDisabled bool `json:"adjustVolumeDisabled,omitempty"`

	// AdvancedSecurityOverrides: Security policies set to the most secure
	// values by default. To maintain the security posture of a device, we
	// don't recommend overriding any of the default values.
	AdvancedSecurityOverrides *AdvancedSecurityOverrides `json:"advancedSecurityOverrides,omitempty"`

	// AlwaysOnVpnPackage: Configuration for an always-on VPN connection.
	// Use with vpn_config_disabled to prevent modification of this setting.
	AlwaysOnVpnPackage *AlwaysOnVpnPackage `json:"alwaysOnVpnPackage,omitempty"`

	// AndroidDevicePolicyTracks: The app tracks for Android Device Policy
	// the device can access. The device receives the latest version among
	// all accessible tracks. If no tracks are specified, then the device
	// only uses the production track.
	//
	// Possible values:
	//   "APP_TRACK_UNSPECIFIED" - This value is ignored.
	//   "PRODUCTION" - The production track, which provides the latest
	// stable release.
	//   "BETA" - The beta track, which provides the latest beta release.
	AndroidDevicePolicyTracks []string `json:"androidDevicePolicyTracks,omitempty"`

	// AppAutoUpdatePolicy: The app auto update policy, which controls when
	// automatic app updates can be applied.
	//
	// Possible values:
	//   "APP_AUTO_UPDATE_POLICY_UNSPECIFIED" - The auto-update policy is
	// not set. Equivalent to CHOICE_TO_THE_USER.
	//   "CHOICE_TO_THE_USER" - The user can control auto-updates.
	//   "NEVER" - Apps are never auto-updated.
	//   "WIFI_ONLY" - Apps are auto-updated over Wi-Fi only.
	//   "ALWAYS" - Apps are auto-updated at any time. Data charges may
	// apply.
	AppAutoUpdatePolicy string `json:"appAutoUpdatePolicy,omitempty"`

	// Applications: Policy applied to apps.
	Applications []*ApplicationPolicy `json:"applications,omitempty"`

	// AutoTimeRequired: Whether auto time is required, which prevents the
	// user from manually setting the date and time.
	AutoTimeRequired bool `json:"autoTimeRequired,omitempty"`

	// BlockApplicationsEnabled: Whether applications other than the ones
	// configured in applications are blocked from being installed. When
	// set, applications that were installed under a previous policy but no
	// longer appear in the policy are automatically uninstalled.
	BlockApplicationsEnabled bool `json:"blockApplicationsEnabled,omitempty"`

	// BluetoothConfigDisabled: Whether configuring bluetooth is disabled.
	BluetoothConfigDisabled bool `json:"bluetoothConfigDisabled,omitempty"`

	// BluetoothContactSharingDisabled: Whether bluetooth contact sharing is
	// disabled.
	BluetoothContactSharingDisabled bool `json:"bluetoothContactSharingDisabled,omitempty"`

	// BluetoothDisabled: Whether bluetooth is disabled. Prefer this setting
	// over bluetooth_config_disabled because bluetooth_config_disabled can
	// be bypassed by the user.
	BluetoothDisabled bool `json:"bluetoothDisabled,omitempty"`

	// CameraDisabled: Whether all cameras on the device are disabled.
	CameraDisabled bool `json:"cameraDisabled,omitempty"`

	// CellBroadcastsConfigDisabled: Whether configuring cell broadcast is
	// disabled.
	CellBroadcastsConfigDisabled bool `json:"cellBroadcastsConfigDisabled,omitempty"`

	// ChoosePrivateKeyRules: Rules for automatically choosing a private key
	// and certificate to authenticate the device to a server. The rules are
	// ordered by increasing precedence, so if an outgoing request matches
	// more than one rule, the last rule defines which private key to use.
	ChoosePrivateKeyRules []*ChoosePrivateKeyRule `json:"choosePrivateKeyRules,omitempty"`

	// ComplianceRules: Rules declaring which mitigating actions to take
	// when a device is not compliant with its policy. When the conditions
	// for multiple rules are satisfied, all of the mitigating actions for
	// the rules are taken. There is a maximum limit of 100 rules. Use
	// policy enforcement rules instead.
	ComplianceRules []*ComplianceRule `json:"complianceRules,omitempty"`

	// CreateWindowsDisabled: Whether creating windows besides app windows
	// is disabled.
	CreateWindowsDisabled bool `json:"createWindowsDisabled,omitempty"`

	// CredentialsConfigDisabled: Whether configuring user credentials is
	// disabled.
	CredentialsConfigDisabled bool `json:"credentialsConfigDisabled,omitempty"`

	// DataRoamingDisabled: Whether roaming data services are disabled.
	DataRoamingDisabled bool `json:"dataRoamingDisabled,omitempty"`

	// DebuggingFeaturesAllowed: Whether the user is allowed to enable
	// debugging features.
	DebuggingFeaturesAllowed bool `json:"debuggingFeaturesAllowed,omitempty"`

	// DefaultPermissionPolicy: The default permission policy for runtime
	// permission requests.
	//
	// Possible values:
	//   "PERMISSION_POLICY_UNSPECIFIED" - Policy not specified. If no
	// policy is specified for a permission at any level, then the PROMPT
	// behavior is used by default.
	//   "PROMPT" - Prompt the user to grant a permission.
	//   "GRANT" - Automatically grant a permission.
	//   "DENY" - Automatically deny a permission.
	DefaultPermissionPolicy string `json:"defaultPermissionPolicy,omitempty"`

	// DeviceOwnerLockScreenInfo: The device owner information to be shown
	// on the lock screen.
	DeviceOwnerLockScreenInfo *UserFacingMessage `json:"deviceOwnerLockScreenInfo,omitempty"`

	// EncryptionPolicy: Whether encryption is enabled
	//
	// Possible values:
	//   "ENCRYPTION_POLICY_UNSPECIFIED" - This value is ignored, i.e. no
	// encryption required
	//   "ENABLED_WITHOUT_PASSWORD" - Encryption required but no password
	// required to boot
	//   "ENABLED_WITH_PASSWORD" - Encryption required with password
	// required to boot
	EncryptionPolicy string `json:"encryptionPolicy,omitempty"`

	// EnsureVerifyAppsEnabled: Whether app verification is force-enabled.
	EnsureVerifyAppsEnabled bool `json:"ensureVerifyAppsEnabled,omitempty"`

	// FactoryResetDisabled: Whether factory resetting from settings is
	// disabled.
	FactoryResetDisabled bool `json:"factoryResetDisabled,omitempty"`

	// FrpAdminEmails: Email addresses of device administrators for factory
	// reset protection. When the device is factory reset, it will require
	// one of these admins to log in with the Google account email and
	// password to unlock the device. If no admins are specified, the device
	// won't provide factory reset protection.
	FrpAdminEmails []string `json:"frpAdminEmails,omitempty"`

	// FunDisabled: Whether the user is allowed to have fun. Controls
	// whether the Easter egg game in Settings is disabled.
	FunDisabled bool `json:"funDisabled,omitempty"`

	// InstallAppsDisabled: Whether user installation of apps is disabled.
	InstallAppsDisabled bool `json:"installAppsDisabled,omitempty"`

	// InstallUnknownSourcesAllowed: Whether the user is allowed to enable
	// the "Unknown Sources" setting, which allows installation of apps from
	// unknown sources.
	InstallUnknownSourcesAllowed bool `json:"installUnknownSourcesAllowed,omitempty"`

	// KeyguardDisabled: Whether the keyguard is disabled.
	KeyguardDisabled bool `json:"keyguardDisabled,omitempty"`

	// KeyguardDisabledFeatures: Disabled keyguard customizations, such as
	// widgets.
	//
	// Possible values:
	//   "KEYGUARD_DISABLED_FEATURE_UNSPECIFIED" - This value is ignored.
	//   "CAMERA" - Disable the camera on secure keyguard screens (e.g.
	// PIN).
	//   "NOTIFICATIONS" - Disable showing all notifications on secure
	// keyguard screens.
	//   "UNREDACTED_NOTIFICATIONS" - Disable unredacted notifications on
	// secure keyguard screens.
	//   "TRUST_AGENTS" - Ignore trust agent state on secure keyguard
	// screens.
	//   "DISABLE_FINGERPRINT" - Disable fingerprint sensor on secure
	// keyguard screens.
	//   "DISABLE_REMOTE_INPUT" - Disable text entry into notifications on
	// secure keyguard screens.
	//   "FACE" - Disable face authentication on secure keyguard screens.
	//   "IRIS" - Disable iris authentication on secure keyguard screens.
	//   "BIOMETRICS" - Disable all biometric authentication on secure
	// keyguard screens.
	//   "ALL_FEATURES" - Disable all current and future keyguard
	// customizations.
	KeyguardDisabledFeatures []string `json:"keyguardDisabledFeatures,omitempty"`

	// KioskCustomLauncherEnabled: Whether the kiosk custom launcher is
	// enabled. This replaces the home screen with a launcher that locks
	// down the device to the apps installed via the applications setting.
	// Apps appear on a single page in alphabetical order. Use
	// kioskCustomization to further configure the kiosk device behavior.
	KioskCustomLauncherEnabled bool `json:"kioskCustomLauncherEnabled,omitempty"`

	// KioskCustomization: Settings controlling the behavior of a device in
	// kiosk mode. To enable kiosk mode, set kioskCustomLauncherEnabled to
	// true or specify an app in the policy with installType KIOSK.
	KioskCustomization *KioskCustomization `json:"kioskCustomization,omitempty"`

	// LocationMode: The degree of location detection enabled. The user may
	// change the value unless the user is otherwise blocked from accessing
	// device settings.
	//
	// Possible values:
	//   "LOCATION_MODE_UNSPECIFIED" - The current device value is not
	// modified.
	//   "HIGH_ACCURACY" - All location detection methods are enabled,
	// including GPS, networks, and other sensors.
	//   "SENSORS_ONLY" - Only GPS and other sensors are enabled.
	//   "BATTERY_SAVING" - Only the network location provider is enabled.
	//   "OFF" - Location detection is disabled.
	LocationMode string `json:"locationMode,omitempty"`

	// LongSupportMessage: A message displayed to the user in the device
	// administators settings screen.
	LongSupportMessage *UserFacingMessage `json:"longSupportMessage,omitempty"`

	// MaximumTimeToLock: Maximum time in milliseconds for user activity
	// until the device locks. A value of 0 means there is no restriction.
	MaximumTimeToLock int64 `json:"maximumTimeToLock,omitempty,string"`

	// MinimumApiLevel: The minimum allowed Android API level.
	MinimumApiLevel int64 `json:"minimumApiLevel,omitempty"`

	// MobileNetworksConfigDisabled: Whether configuring mobile networks is
	// disabled.
	MobileNetworksConfigDisabled bool `json:"mobileNetworksConfigDisabled,omitempty"`

	// ModifyAccountsDisabled: Whether adding or removing accounts is
	// disabled.
	ModifyAccountsDisabled bool `json:"modifyAccountsDisabled,omitempty"`

	// MountPhysicalMediaDisabled: Whether the user mounting physical
	// external media is disabled.
	MountPhysicalMediaDisabled bool `json:"mountPhysicalMediaDisabled,omitempty"`

	// Name: The name of the policy in the form
	// enterprises/{enterpriseId}/policies/{policyId}.
	Name string `json:"name,omitempty"`

	// NetworkEscapeHatchEnabled: Whether the network escape hatch is
	// enabled. If a network connection can't be made at boot time, the
	// escape hatch prompts the user to temporarily connect to a network in
	// order to refresh the device policy. After applying policy, the
	// temporary network will be forgotten and the device will continue
	// booting. This prevents being unable to connect to a network if there
	// is no suitable network in the last policy and the device boots into
	// an app in lock task mode, or the user is otherwise unable to reach
	// device settings.
	NetworkEscapeHatchEnabled bool `json:"networkEscapeHatchEnabled,omitempty"`

	// NetworkResetDisabled: Whether resetting network settings is disabled.
	NetworkResetDisabled bool `json:"networkResetDisabled,omitempty"`

	// OpenNetworkConfiguration: Network configuration for the device. See
	// configure networks for more information.
	OpenNetworkConfiguration googleapi.RawMessage `json:"openNetworkConfiguration,omitempty"`

	// OutgoingBeamDisabled: Whether using NFC to beam data from apps is
	// disabled.
	OutgoingBeamDisabled bool `json:"outgoingBeamDisabled,omitempty"`

	// OutgoingCallsDisabled: Whether outgoing calls are disabled.
	OutgoingCallsDisabled bool `json:"outgoingCallsDisabled,omitempty"`

	// PasswordPolicies: Password requirement policies. Different policies
	// can be set for work profile or fully managed devices by setting the
	// password_scope field in the policy.
	PasswordPolicies []*PasswordRequirements `json:"passwordPolicies,omitempty"`

	// PasswordRequirements: Password requirements. The field
	// password_requirements.require_password_unlock must not be set.
	// DEPRECATED - Use password_policies.
	PasswordRequirements *PasswordRequirements `json:"passwordRequirements,omitempty"`

	// PermissionGrants: Explicit permission or group grants or denials for
	// all apps. These values override the default_permission_policy.
	PermissionGrants []*PermissionGrant `json:"permissionGrants,omitempty"`

	// PermittedAccessibilityServices: Specifies permitted accessibility
	// services. If the field is not set, any accessibility service can be
	// used. If the field is set, only the accessibility services in this
	// list and the system's built-in accessibility service can be used. In
	// particular, if the field is set to empty, only the system's built-in
	// accessibility servicess can be used.
	PermittedAccessibilityServices *PackageNameList `json:"permittedAccessibilityServices,omitempty"`

	// PermittedInputMethods: If present, only the input methods provided by
	// packages in this list are permitted. If this field is present, but
	// the list is empty, then only system input methods are permitted.
	PermittedInputMethods *PackageNameList `json:"permittedInputMethods,omitempty"`

	// PersistentPreferredActivities: Default intent handler activities.
	PersistentPreferredActivities []*PersistentPreferredActivity `json:"persistentPreferredActivities,omitempty"`

	// PersonalUsagePolicies: Policies managing personal usage on a
	// company-owned device.
	PersonalUsagePolicies *PersonalUsagePolicies `json:"personalUsagePolicies,omitempty"`

	// PlayStoreMode: This mode controls which apps are available to the
	// user in the Play Store and the behavior on the device when apps are
	// removed from the policy.
	//
	// Possible values:
	//   "PLAY_STORE_MODE_UNSPECIFIED" - Unspecified. Defaults to WHITELIST.
	//   "WHITELIST" - Only apps that are in the policy are available and
	// any app not in the policy will be automatically uninstalled from the
	// device.
	//   "BLACKLIST" - All apps are available and any app that should not be
	// on the device should be explicitly marked as 'BLOCKED' in the
	// applications policy.
	PlayStoreMode string `json:"playStoreMode,omitempty"`

	// PolicyEnforcementRules: Rules that define the behavior when a
	// particular policy can not be applied on device
	PolicyEnforcementRules []*PolicyEnforcementRule `json:"policyEnforcementRules,omitempty"`

	// PrivateKeySelectionEnabled: Allows showing UI on a device for a user
	// to choose a private key alias if there are no matching rules in
	// ChoosePrivateKeyRules. For devices below Android P, setting this may
	// leave enterprise keys vulnerable.
	PrivateKeySelectionEnabled bool `json:"privateKeySelectionEnabled,omitempty"`

	// RecommendedGlobalProxy: The network-independent global HTTP proxy.
	// Typically proxies should be configured per-network in
	// open_network_configuration. However for unusual configurations like
	// general internal filtering a global HTTP proxy may be useful. If the
	// proxy is not accessible, network access may break. The global proxy
	// is only a recommendation and some apps may ignore it.
	RecommendedGlobalProxy *ProxyInfo `json:"recommendedGlobalProxy,omitempty"`

	// RemoveUserDisabled: Whether removing other users is disabled.
	RemoveUserDisabled bool `json:"removeUserDisabled,omitempty"`

	// SafeBootDisabled: Whether rebooting the device into safe boot is
	// disabled.
	SafeBootDisabled bool `json:"safeBootDisabled,omitempty"`

	// ScreenCaptureDisabled: Whether screen capture is disabled.
	ScreenCaptureDisabled bool `json:"screenCaptureDisabled,omitempty"`

	// SetUserIconDisabled: Whether changing the user icon is disabled.
	SetUserIconDisabled bool `json:"setUserIconDisabled,omitempty"`

	// SetWallpaperDisabled: Whether changing the wallpaper is disabled.
	SetWallpaperDisabled bool `json:"setWallpaperDisabled,omitempty"`

	// SetupActions: Actions to take during the setup process.
	SetupActions []*SetupAction `json:"setupActions,omitempty"`

	// ShareLocationDisabled: Whether location sharing is disabled.
	ShareLocationDisabled bool `json:"shareLocationDisabled,omitempty"`

	// ShortSupportMessage: A message displayed to the user in the settings
	// screen wherever functionality has been disabled by the admin. If the
	// message is longer than 200 characters it may be truncated.
	ShortSupportMessage *UserFacingMessage `json:"shortSupportMessage,omitempty"`

	// SkipFirstUseHintsEnabled: Flag to skip hints on the first use.
	// Enterprise admin can enable the system recommendation for apps to
	// skip their user tutorial and other introductory hints on first
	// start-up.
	SkipFirstUseHintsEnabled bool `json:"skipFirstUseHintsEnabled,omitempty"`

	// SmsDisabled: Whether sending and receiving SMS messages is disabled.
	SmsDisabled bool `json:"smsDisabled,omitempty"`

	// StatusBarDisabled: Whether the status bar is disabled. This disables
	// notifications, quick settings, and other screen overlays that allow
	// escape from full-screen mode. DEPRECATED. To disable the status bar
	// on a kiosk device, use InstallType KIOSK or
	// kioskCustomLauncherEnabled.
	StatusBarDisabled bool `json:"statusBarDisabled,omitempty"`

	// StatusReportingSettings: Status reporting settings
	StatusReportingSettings *StatusReportingSettings `json:"statusReportingSettings,omitempty"`

	// StayOnPluggedModes: The battery plugged in modes for which the device
	// stays on. When using this setting, it is recommended to clear
	// maximum_time_to_lock so that the device doesn't lock itself while it
	// stays on.
	//
	// Possible values:
	//   "BATTERY_PLUGGED_MODE_UNSPECIFIED" - This value is ignored.
	//   "AC" - Power source is an AC charger.
	//   "USB" - Power source is a USB port.
	//   "WIRELESS" - Power source is wireless.
	StayOnPluggedModes []string `json:"stayOnPluggedModes,omitempty"`

	// SystemUpdate: The system update policy, which controls how OS updates
	// are applied. If the update type is WINDOWED, the update window will
	// automatically apply to Play app updates as well.
	SystemUpdate *SystemUpdate `json:"systemUpdate,omitempty"`

	// TetheringConfigDisabled: Whether configuring tethering and portable
	// hotspots is disabled.
	TetheringConfigDisabled bool `json:"tetheringConfigDisabled,omitempty"`

	// UninstallAppsDisabled: Whether user uninstallation of applications is
	// disabled.
	UninstallAppsDisabled bool `json:"uninstallAppsDisabled,omitempty"`

	// UnmuteMicrophoneDisabled: Whether the microphone is muted and
	// adjusting microphone volume is disabled.
	UnmuteMicrophoneDisabled bool `json:"unmuteMicrophoneDisabled,omitempty"`

	// UsbFileTransferDisabled: Whether transferring files over USB is
	// disabled.
	UsbFileTransferDisabled bool `json:"usbFileTransferDisabled,omitempty"`

	// UsbMassStorageEnabled: Whether USB storage is enabled. Deprecated.
	UsbMassStorageEnabled bool `json:"usbMassStorageEnabled,omitempty"`

	// Version: The version of the policy. This is a read-only field. The
	// version is incremented each time the policy is updated.
	Version int64 `json:"version,omitempty,string"`

	// VpnConfigDisabled: Whether configuring VPN is disabled.
	VpnConfigDisabled bool `json:"vpnConfigDisabled,omitempty"`

	// WifiConfigDisabled: Whether configuring Wi-Fi access points is
	// disabled.
	WifiConfigDisabled bool `json:"wifiConfigDisabled,omitempty"`

	// WifiConfigsLockdownEnabled: DEPRECATED - Use wifi_config_disabled.
	WifiConfigsLockdownEnabled bool `json:"wifiConfigsLockdownEnabled,omitempty"`

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

	// ForceSendFields is a list of field names (e.g.
	// "AccountTypesWithManagementDisabled") to unconditionally include in
	// API requests. By default, fields with empty 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.
	// "AccountTypesWithManagementDisabled") 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 *Policy) MarshalJSON() ([]byte, error) {
	type NoMethod Policy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PolicyEnforcementRule: A rule that defines the actions to take if a
// device or work profile is not compliant with the policy specified in
// settingName.
type PolicyEnforcementRule struct {
	// BlockAction: An action to block access to apps and data on a fully
	// managed device or in a work profile. This action also triggers a
	// user-facing notification with information (where possible) on how to
	// correct the compliance issue. Note: wipeAction must also be
	// specified.
	BlockAction *BlockAction `json:"blockAction,omitempty"`

	// SettingName: The top-level policy to enforce. For example,
	// applications or passwordPolicies.
	SettingName string `json:"settingName,omitempty"`

	// WipeAction: An action to reset a fully managed device or delete a
	// work profile. Note: blockAction must also be specified.
	WipeAction *WipeAction `json:"wipeAction,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BlockAction") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "BlockAction") 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 *PolicyEnforcementRule) MarshalJSON() ([]byte, error) {
	type NoMethod PolicyEnforcementRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PostureDetail: Additional details regarding the security posture of
// the device.
type PostureDetail struct {
	// Advice: Corresponding admin-facing advice to mitigate this security
	// risk and improve the security posture of the device.
	Advice []*UserFacingMessage `json:"advice,omitempty"`

	// SecurityRisk: A specific security risk that negatively affects the
	// security posture of the device.
	//
	// Possible values:
	//   "SECURITY_RISK_UNSPECIFIED" - Unspecified.
	//   "UNKNOWN_OS" - SafetyNet detects that the device is running an
	// unknown OS (basicIntegrity check succeeds but ctsProfileMatch fails).
	//   "COMPROMISED_OS" - SafetyNet detects that the device is running a
	// compromised OS (basicIntegrity check fails).
	SecurityRisk string `json:"securityRisk,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Advice") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Advice") 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 *PostureDetail) MarshalJSON() ([]byte, error) {
	type NoMethod PostureDetail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PowerManagementEvent: A power management event.
type PowerManagementEvent struct {
	// BatteryLevel: For BATTERY_LEVEL_COLLECTED events, the battery level
	// as a percentage.
	BatteryLevel float64 `json:"batteryLevel,omitempty"`

	// CreateTime: The creation time of the event.
	CreateTime string `json:"createTime,omitempty"`

	// EventType: Event type.
	//
	// Possible values:
	//   "POWER_MANAGEMENT_EVENT_TYPE_UNSPECIFIED" - Unspecified. No events
	// have this type.
	//   "BATTERY_LEVEL_COLLECTED" - Battery level was measured.
	//   "POWER_CONNECTED" - The device started charging.
	//   "POWER_DISCONNECTED" - The device stopped charging.
	//   "BATTERY_LOW" - The device entered low-power mode.
	//   "BATTERY_OKAY" - The device exited low-power mode.
	//   "BOOT_COMPLETED" - The device booted.
	//   "SHUTDOWN" - The device shut down.
	EventType string `json:"eventType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BatteryLevel") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "BatteryLevel") 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 *PowerManagementEvent) MarshalJSON() ([]byte, error) {
	type NoMethod PowerManagementEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// ProxyInfo: Configuration info for an HTTP proxy. For a direct proxy,
// set the host, port, and excluded_hosts fields. For a PAC script
// proxy, set the pac_uri field.
type ProxyInfo struct {
	// ExcludedHosts: For a direct proxy, the hosts for which the proxy is
	// bypassed. The host names may contain wildcards such as *.example.com.
	ExcludedHosts []string `json:"excludedHosts,omitempty"`

	// Host: The host of the direct proxy.
	Host string `json:"host,omitempty"`

	// PacUri: The URI of the PAC script used to configure the proxy.
	PacUri string `json:"pacUri,omitempty"`

	// Port: The port of the direct proxy.
	Port int64 `json:"port,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExcludedHosts") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "ExcludedHosts") 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 *ProxyInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ProxyInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SecurityPosture: The security posture of the device, as determined by
// the current device state and the policies applied.
type SecurityPosture struct {
	// DevicePosture: Device's security posture value.
	//
	// Possible values:
	//   "POSTURE_UNSPECIFIED" - Unspecified. There is no posture detail for
	// this posture value.
	//   "SECURE" - This device is secure.
	//   "AT_RISK" - This device may be more vulnerable to malicious actors
	// than is recommended for use with corporate data.
	//   "POTENTIALLY_COMPROMISED" - This device may be compromised and
	// corporate data may be accessible to unauthorized actors.
	DevicePosture string `json:"devicePosture,omitempty"`

	// PostureDetails: Additional details regarding the security posture of
	// the device.
	PostureDetails []*PostureDetail `json:"postureDetails,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DevicePosture") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "DevicePosture") 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 *SecurityPosture) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityPosture
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SetupAction: An action executed during setup.
type SetupAction struct {
	// Description: Description of this action.
	Description *UserFacingMessage `json:"description,omitempty"`

	// LaunchApp: An action to launch an app.
	LaunchApp *LaunchAppAction `json:"launchApp,omitempty"`

	// Title: Title of this action.
	Title *UserFacingMessage `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Description") 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 *SetupAction) MarshalJSON() ([]byte, error) {
	type NoMethod SetupAction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SigninDetail: A resource containing sign in details for an
// enterprise.
type SigninDetail struct {
	// AllowPersonalUsage: Controls whether personal usage is allowed on a
	// device provisioned with this enrollment token.For company-owned
	// devices: Enabling personal usage allows the user to set up a work
	// profile on the device. Disabling personal usage requires the user
	// provision the device as a fully managed device.For personally-owned
	// devices: Enabling personal usage allows the user to set up a work
	// profile on the device. Disabling personal usage will prevent the
	// device from provisioning. Personal usage cannot be disabled on
	// personally-owned device.
	//
	// Possible values:
	//   "ALLOW_PERSONAL_USAGE_UNSPECIFIED" - Personal usage restriction is
	// not specified
	//   "PERSONAL_USAGE_ALLOWED" - Personal usage is allowed
	//   "PERSONAL_USAGE_DISALLOWED" - Personal usage is disallowed
	AllowPersonalUsage string `json:"allowPersonalUsage,omitempty"`

	// QrCode: A JSON string whose UTF-8 representation can be used to
	// generate a QR code to enroll a device with this enrollment token. To
	// enroll a device using NFC, the NFC record must contain a serialized
	// java.util.Properties representation of the properties in the JSON.
	// This is a read-only field generated by the server.
	QrCode string `json:"qrCode,omitempty"`

	// SigninEnrollmentToken: An enterprise wide enrollment token used to
	// trigger custom sign-in flow. This is a read-only field generated by
	// the server.
	SigninEnrollmentToken string `json:"signinEnrollmentToken,omitempty"`

	// SigninUrl: Sign-in URL for authentication when device is provisioned
	// with a sign-in enrollment token. The sign-in endpoint should finish
	// authentication flow with a URL in the form of
	// https://enterprise.google.com/android/enroll?et= for a successful
	// login, or https://enterprise.google.com/android/enroll/invalid for a
	// failed login.
	SigninUrl string `json:"signinUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AllowPersonalUsage")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "AllowPersonalUsage") 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 *SigninDetail) MarshalJSON() ([]byte, error) {
	type NoMethod SigninDetail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SignupUrl: An enterprise signup URL.
type SignupUrl struct {
	// Name: The name of the resource. Use this value in the signupUrl field
	// when calling enterprises.create to complete the enterprise signup
	// flow.
	Name string `json:"name,omitempty"`

	// Url: A URL where an enterprise admin can register their enterprise.
	// The page can't be rendered in an iframe.
	Url string `json:"url,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Name") 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 *SignupUrl) MarshalJSON() ([]byte, error) {
	type NoMethod SignupUrl
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SoftwareInfo: Information about device software.
type SoftwareInfo struct {
	// AndroidBuildNumber: Android build ID string meant for displaying to
	// the user. For example, shamu-userdebug 6.0.1 MOB30I 2756745 dev-keys.
	AndroidBuildNumber string `json:"androidBuildNumber,omitempty"`

	// AndroidBuildTime: Build time.
	AndroidBuildTime string `json:"androidBuildTime,omitempty"`

	// AndroidDevicePolicyVersionCode: The Android Device Policy app version
	// code.
	AndroidDevicePolicyVersionCode int64 `json:"androidDevicePolicyVersionCode,omitempty"`

	// AndroidDevicePolicyVersionName: The Android Device Policy app version
	// as displayed to the user.
	AndroidDevicePolicyVersionName string `json:"androidDevicePolicyVersionName,omitempty"`

	// AndroidVersion: The user-visible Android version string. For example,
	// 6.0.1.
	AndroidVersion string `json:"androidVersion,omitempty"`

	// BootloaderVersion: The system bootloader version number, e.g. 0.6.7.
	BootloaderVersion string `json:"bootloaderVersion,omitempty"`

	// DeviceBuildSignature: SHA-256 hash of android.content.pm.Signature
	// (https://developer.android.com/reference/android/content/pm/Signature.
	// html) associated with the system package, which can be used to verify
	// that the system build hasn't been modified.
	DeviceBuildSignature string `json:"deviceBuildSignature,omitempty"`

	// DeviceKernelVersion: Kernel version, for example, 2.6.32.9-g103d848.
	DeviceKernelVersion string `json:"deviceKernelVersion,omitempty"`

	// PrimaryLanguageCode: An IETF BCP 47 language code for the primary
	// locale on the device.
	PrimaryLanguageCode string `json:"primaryLanguageCode,omitempty"`

	// SecurityPatchLevel: Security patch level, e.g. 2016-05-01.
	SecurityPatchLevel string `json:"securityPatchLevel,omitempty"`

	// SystemUpdateInfo: Information about a potential pending system
	// update.
	SystemUpdateInfo *SystemUpdateInfo `json:"systemUpdateInfo,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AndroidBuildNumber")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "AndroidBuildNumber") 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 *SoftwareInfo) MarshalJSON() ([]byte, error) {
	type NoMethod SoftwareInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Status: 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 Status 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 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 *Status) MarshalJSON() ([]byte, error) {
	type NoMethod Status
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// StatusReportingSettings: Settings controlling the behavior of status
// reports.
type StatusReportingSettings struct {
	// ApplicationReportingSettings: Application reporting settings. Only
	// applicable if application_reports_enabled is true.
	ApplicationReportingSettings *ApplicationReportingSettings `json:"applicationReportingSettings,omitempty"`

	// ApplicationReportsEnabled: Whether app reports are enabled.
	ApplicationReportsEnabled bool `json:"applicationReportsEnabled,omitempty"`

	// DeviceSettingsEnabled: Whether device settings reporting is enabled.
	DeviceSettingsEnabled bool `json:"deviceSettingsEnabled,omitempty"`

	// DisplayInfoEnabled: Whether displays reporting is enabled. Report
	// data is not available for personally owned devices with work
	// profiles.
	DisplayInfoEnabled bool `json:"displayInfoEnabled,omitempty"`

	// HardwareStatusEnabled: Whether hardware status reporting is enabled.
	// Report data is not available for personally owned devices with work
	// profiles.
	HardwareStatusEnabled bool `json:"hardwareStatusEnabled,omitempty"`

	// MemoryInfoEnabled: Whether memory reporting is enabled.
	MemoryInfoEnabled bool `json:"memoryInfoEnabled,omitempty"`

	// NetworkInfoEnabled: Whether network info reporting is enabled.
	NetworkInfoEnabled bool `json:"networkInfoEnabled,omitempty"`

	// PowerManagementEventsEnabled: Whether power management event
	// reporting is enabled. Report data is not available for personally
	// owned devices with work profiles.
	PowerManagementEventsEnabled bool `json:"powerManagementEventsEnabled,omitempty"`

	// SoftwareInfoEnabled: Whether software info reporting is enabled.
	SoftwareInfoEnabled bool `json:"softwareInfoEnabled,omitempty"`

	// SystemPropertiesEnabled: Whether system properties reporting is
	// enabled.
	SystemPropertiesEnabled bool `json:"systemPropertiesEnabled,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ApplicationReportingSettings") to unconditionally include in API
	// requests. By default, fields with empty 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.
	// "ApplicationReportingSettings") 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 *StatusReportingSettings) MarshalJSON() ([]byte, error) {
	type NoMethod StatusReportingSettings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SystemUpdate: Configuration for managing system updates
type SystemUpdate struct {
	// EndMinutes: If the type is WINDOWED, the end of the maintenance
	// window, measured as the number of minutes after midnight in device's
	// local time. This value must be between 0 and 1439, inclusive. If this
	// value is less than start_minutes, then the maintenance window spans
	// midnight. If the maintenance window specified is smaller than 30
	// minutes, the actual window is extended to 30 minutes beyond the start
	// time.
	EndMinutes int64 `json:"endMinutes,omitempty"`

	// FreezePeriods: An annually repeating time period in which
	// over-the-air (OTA) system updates are postponed to freeze the OS
	// version running on a device. To prevent freezing the device
	// indefinitely, each freeze period must be separated by at least 60
	// days.
	FreezePeriods []*FreezePeriod `json:"freezePeriods,omitempty"`

	// StartMinutes: If the type is WINDOWED, the start of the maintenance
	// window, measured as the number of minutes after midnight in the
	// device's local time. This value must be between 0 and 1439,
	// inclusive.
	StartMinutes int64 `json:"startMinutes,omitempty"`

	// Type: The type of system update to configure.
	//
	// Possible values:
	//   "SYSTEM_UPDATE_TYPE_UNSPECIFIED" - Follow the default update
	// behavior for the device, which typically requires the user to accept
	// system updates.
	//   "AUTOMATIC" - Install automatically as soon as an update is
	// available.
	//   "WINDOWED" - Install automatically within a daily maintenance
	// window. This also configures Play apps to be updated within the
	// window. This is strongly recommended for kiosk devices because this
	// is the only way apps persistently pinned to the foreground can be
	// updated by Play.
	//   "POSTPONE" - Postpone automatic install up to a maximum of 30 days.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndMinutes") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "EndMinutes") 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 *SystemUpdate) MarshalJSON() ([]byte, error) {
	type NoMethod SystemUpdate
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SystemUpdateInfo: Information about a potential pending system
// update.
type SystemUpdateInfo struct {
	// UpdateReceivedTime: The time when the update was first available. A
	// zero value indicates that this field is not set. This field is set
	// only if an update is available (that is, updateStatus is neither
	// UPDATE_STATUS_UNKNOWN nor UP_TO_DATE).
	UpdateReceivedTime string `json:"updateReceivedTime,omitempty"`

	// UpdateStatus: The status of an update: whether an update exists and
	// what type it is.
	//
	// Possible values:
	//   "UPDATE_STATUS_UNKNOWN" - It is unknown whether there is a pending
	// system update. This happens when, for example, the device API level
	// is less than 26, or if the version of Android Device Policy is
	// outdated.
	//   "UP_TO_DATE" - There is no pending system update available on the
	// device.
	//   "UNKNOWN_UPDATE_AVAILABLE" - There is a pending system update
	// available, but its type is not known.
	//   "SECURITY_UPDATE_AVAILABLE" - There is a pending security update
	// available.
	//   "OS_UPDATE_AVAILABLE" - There is a pending OS update available.
	UpdateStatus string `json:"updateStatus,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UpdateReceivedTime")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "UpdateReceivedTime") 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 *SystemUpdateInfo) MarshalJSON() ([]byte, error) {
	type NoMethod SystemUpdateInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TermsAndConditions: A terms and conditions page to be accepted during
// provisioning.
type TermsAndConditions struct {
	// Content: A well-formatted HTML string. It will be parsed on the
	// client with android.text.Html#fromHtml.
	Content *UserFacingMessage `json:"content,omitempty"`

	// Header: A short header which appears above the HTML content.
	Header *UserFacingMessage `json:"header,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Content") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Content") 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 *TermsAndConditions) MarshalJSON() ([]byte, error) {
	type NoMethod TermsAndConditions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// User: A user belonging to an enterprise.
type User struct {
	// AccountIdentifier: A unique identifier you create for this user, such
	// as user342 or asset#44418. This field must be set when the user is
	// created and can't be updated. This field must not contain personally
	// identifiable information (PII). This identifier must be 1024
	// characters or less; otherwise, the update policy request will fail.
	AccountIdentifier string `json:"accountIdentifier,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccountIdentifier")
	// to unconditionally include in API requests. By default, fields with
	// empty 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. "AccountIdentifier") 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 *User) MarshalJSON() ([]byte, error) {
	type NoMethod User
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UserFacingMessage: Provides a user-facing message with locale info.
// The maximum message length is 4096 characters.
type UserFacingMessage struct {
	// DefaultMessage: The default message displayed if no localized message
	// is specified or the user's locale doesn't match with any of the
	// localized messages. A default message must be provided if any
	// localized messages are provided.
	DefaultMessage string `json:"defaultMessage,omitempty"`

	// LocalizedMessages: A map containing pairs, where locale is a
	// well-formed BCP 47 language
	// (https://www.w3.org/International/articles/language-tags/) code, such
	// as en-US, es-ES, or fr.
	LocalizedMessages map[string]string `json:"localizedMessages,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DefaultMessage") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "DefaultMessage") 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 *UserFacingMessage) MarshalJSON() ([]byte, error) {
	type NoMethod UserFacingMessage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WebApp: A web app.
type WebApp struct {
	// DisplayMode: The display mode of the web app.
	//
	// Possible values:
	//   "DISPLAY_MODE_UNSPECIFIED" - Not used.
	//   "MINIMAL_UI" - Opens the web app with a minimal set of browser UI
	// elements for controlling navigation and viewing the page URL.
	//   "STANDALONE" - Opens the web app to look and feel like a standalone
	// native application. The browser UI elements and page URL are not
	// visible, however the system status bar and back button are visible.
	//   "FULL_SCREEN" - Opens the web app in full screen without any
	// visible controls. The browser UI elements, page URL, system status
	// bar and back button are not visible, and the web app takes up the
	// entirety of the available display area.
	DisplayMode string `json:"displayMode,omitempty"`

	// Icons: A list of icons for the web app. Must have at least one
	// element.
	Icons []*WebAppIcon `json:"icons,omitempty"`

	// Name: The name of the web app, which is generated by the server
	// during creation in the form
	// enterprises/{enterpriseId}/webApps/{packageName}.
	Name string `json:"name,omitempty"`

	// StartUrl: The start URL, i.e. the URL that should load when the user
	// opens the application.
	StartUrl string `json:"startUrl,omitempty"`

	// Title: The title of the web app as displayed to the user (e.g.,
	// amongst a list of other applications, or as a label for an icon).
	Title string `json:"title,omitempty"`

	// VersionCode: The current version of the app.Note that the version can
	// automatically increase during the lifetime of the web app, while
	// Google does internal housekeeping to keep the web app up-to-date.
	VersionCode int64 `json:"versionCode,omitempty,string"`

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

	// ForceSendFields is a list of field names (e.g. "DisplayMode") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "DisplayMode") 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 *WebApp) MarshalJSON() ([]byte, error) {
	type NoMethod WebApp
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WebAppIcon: An icon for a web app. Supported formats are: png, jpg
// and webp.
type WebAppIcon struct {
	// ImageData: The actual bytes of the image in a base64url encoded
	// string (c.f. RFC4648, section 5 "Base 64 Encoding with URL and
	// Filename Safe Alphabet"). - The image type can be png or jpg. - The
	// image should ideally be square. - The image should ideally have a
	// size of 512x512.
	ImageData string `json:"imageData,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ImageData") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "ImageData") 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 *WebAppIcon) MarshalJSON() ([]byte, error) {
	type NoMethod WebAppIcon
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WebToken: A web token used to access the managed Google Play iframe.
type WebToken struct {
	// EnabledFeatures: The features to enable. Use this if you want to
	// control exactly which feature(s) will be activated; leave empty to
	// allow all features.Restrictions / things to note: - If no features
	// are listed here, all features are enabled — this is the default
	// behavior where you give access to all features to your admins. - This
	// must not contain any FEATURE_UNSPECIFIED values. - Repeated values
	// are ignored
	//
	// Possible values:
	//   "FEATURE_UNSPECIFIED" - Unspecified feature.
	//   "PLAY_SEARCH" - The Managed Play search apps page
	// (https://developers.google.com/android/management/apps#search-apps).
	//   "PRIVATE_APPS" - The private apps page
	// (https://developers.google.com/android/management/apps#private-apps).
	//   "WEB_APPS" - The Web Apps page
	// (https://developers.google.com/android/management/apps#web-apps).
	//   "STORE_BUILDER" - The organize apps page
	// (https://developers.google.com/android/management/apps#organize-apps).
	//   "MANAGED_CONFIGURATIONS" - The managed configurations page
	// (https://developers.google.com/android/management/managed-configuratio
	// ns-iframe).
	EnabledFeatures []string `json:"enabledFeatures,omitempty"`

	// Name: The name of the web token, which is generated by the server
	// during creation in the form
	// enterprises/{enterpriseId}/webTokens/{webTokenId}.
	Name string `json:"name,omitempty"`

	// ParentFrameUrl: The URL of the parent frame hosting the iframe with
	// the embedded UI. To prevent XSS, the iframe may not be hosted at
	// other URLs. The URL must use the https scheme.
	ParentFrameUrl string `json:"parentFrameUrl,omitempty"`

	// Permissions: Permissions available to an admin in the embedded UI. An
	// admin must have all of these permissions in order to view the UI.
	// This field is deprecated.
	//
	// Possible values:
	//   "WEB_TOKEN_PERMISSION_UNSPECIFIED" - This value is ignored.
	//   "APPROVE_APPS" - The permission to approve apps for the enterprise.
	Permissions []string `json:"permissions,omitempty"`

	// Value: The token value which is used in the hosting page to generate
	// the iframe with the embedded UI. This is a read-only field generated
	// by the server.
	Value string `json:"value,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "EnabledFeatures") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "EnabledFeatures") 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 *WebToken) MarshalJSON() ([]byte, error) {
	type NoMethod WebToken
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WipeAction: An action to reset a fully managed device or delete a
// work profile. Note: blockAction must also be specified.
type WipeAction struct {
	// PreserveFrp: Whether the factory-reset protection data is preserved
	// on the device. This setting doesn’t apply to work profiles.
	PreserveFrp bool `json:"preserveFrp,omitempty"`

	// WipeAfterDays: Number of days the policy is non-compliant before the
	// device or work profile is wiped. wipeAfterDays must be greater than
	// blockAfterDays.
	WipeAfterDays int64 `json:"wipeAfterDays,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PreserveFrp") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "PreserveFrp") 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 *WipeAction) MarshalJSON() ([]byte, error) {
	type NoMethod WipeAction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "androidmanagement.enterprises.create":

type EnterprisesCreateCall struct {
	s          *Service
	enterprise *Enterprise
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates an enterprise. This is the last step in the
// enterprise signup flow.
func (r *EnterprisesService) Create(enterprise *Enterprise) *EnterprisesCreateCall {
	c := &EnterprisesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.enterprise = enterprise
	return c
}

// EnterpriseToken sets the optional parameter "enterpriseToken": The
// enterprise token appended to the callback URL.
func (c *EnterprisesCreateCall) EnterpriseToken(enterpriseToken string) *EnterprisesCreateCall {
	c.urlParams_.Set("enterpriseToken", enterpriseToken)
	return c
}

// ProjectId sets the optional parameter "projectId": The ID of the
// Google Cloud Platform project which will own the enterprise.
func (c *EnterprisesCreateCall) ProjectId(projectId string) *EnterprisesCreateCall {
	c.urlParams_.Set("projectId", projectId)
	return c
}

// SignupUrlName sets the optional parameter "signupUrlName": The name
// of the SignupUrl used to sign up for the enterprise.
func (c *EnterprisesCreateCall) SignupUrlName(signupUrlName string) *EnterprisesCreateCall {
	c.urlParams_.Set("signupUrlName", signupUrlName)
	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 *EnterprisesCreateCall) Fields(s ...googleapi.Field) *EnterprisesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesCreateCall) Context(ctx context.Context) *EnterprisesCreateCall {
	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 *EnterprisesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.enterprise)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/enterprises")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "androidmanagement.enterprises.create" call.
// Exactly one of *Enterprise or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Enterprise.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 *EnterprisesCreateCall) Do(opts ...googleapi.CallOption) (*Enterprise, 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 := &Enterprise{
		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": "Creates an enterprise. This is the last step in the enterprise signup flow.",
	//   "flatPath": "v1/enterprises",
	//   "httpMethod": "POST",
	//   "id": "androidmanagement.enterprises.create",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "enterpriseToken": {
	//       "description": "The enterprise token appended to the callback URL.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The ID of the Google Cloud Platform project which will own the enterprise.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "signupUrlName": {
	//       "description": "The name of the SignupUrl used to sign up for the enterprise.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/enterprises",
	//   "request": {
	//     "$ref": "Enterprise"
	//   },
	//   "response": {
	//     "$ref": "Enterprise"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.get":

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

// Get: Gets an enterprise.
func (r *EnterprisesService) Get(name string) *EnterprisesGetCall {
	c := &EnterprisesGetCall{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 *EnterprisesGetCall) Fields(s ...googleapi.Field) *EnterprisesGetCall {
	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 *EnterprisesGetCall) IfNoneMatch(entityTag string) *EnterprisesGetCall {
	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 *EnterprisesGetCall) Context(ctx context.Context) *EnterprisesGetCall {
	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 *EnterprisesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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 "androidmanagement.enterprises.get" call.
// Exactly one of *Enterprise or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Enterprise.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 *EnterprisesGetCall) Do(opts ...googleapi.CallOption) (*Enterprise, 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 := &Enterprise{
		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": "Gets an enterprise.",
	//   "flatPath": "v1/enterprises/{enterprisesId}",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the enterprise in the form enterprises/{enterpriseId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Enterprise"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.patch":

type EnterprisesPatchCall struct {
	s          *Service
	name       string
	enterprise *Enterprise
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an enterprise.
func (r *EnterprisesService) Patch(name string, enterprise *Enterprise) *EnterprisesPatchCall {
	c := &EnterprisesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.enterprise = enterprise
	return c
}

// UpdateMask sets the optional parameter "updateMask": The field mask
// indicating the fields to update. If not set, all modifiable fields
// will be modified.
func (c *EnterprisesPatchCall) UpdateMask(updateMask string) *EnterprisesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *EnterprisesPatchCall) Fields(s ...googleapi.Field) *EnterprisesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesPatchCall) Context(ctx context.Context) *EnterprisesPatchCall {
	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 *EnterprisesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.enterprise)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	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("PATCH", 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 "androidmanagement.enterprises.patch" call.
// Exactly one of *Enterprise or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Enterprise.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 *EnterprisesPatchCall) Do(opts ...googleapi.CallOption) (*Enterprise, 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 := &Enterprise{
		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": "Updates an enterprise.",
	//   "flatPath": "v1/enterprises/{enterprisesId}",
	//   "httpMethod": "PATCH",
	//   "id": "androidmanagement.enterprises.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the enterprise in the form enterprises/{enterpriseId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The field mask indicating the fields to update. If not set, all modifiable fields will be modified.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "Enterprise"
	//   },
	//   "response": {
	//     "$ref": "Enterprise"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.applications.get":

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

// Get: Gets info about an application.
func (r *EnterprisesApplicationsService) Get(name string) *EnterprisesApplicationsGetCall {
	c := &EnterprisesApplicationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// LanguageCode sets the optional parameter "languageCode": The
// preferred language for localized application info, as a BCP47 tag
// (e.g. "en-US", "de"). If not specified the default language of the
// application will be used.
func (c *EnterprisesApplicationsGetCall) LanguageCode(languageCode string) *EnterprisesApplicationsGetCall {
	c.urlParams_.Set("languageCode", languageCode)
	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 *EnterprisesApplicationsGetCall) Fields(s ...googleapi.Field) *EnterprisesApplicationsGetCall {
	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 *EnterprisesApplicationsGetCall) IfNoneMatch(entityTag string) *EnterprisesApplicationsGetCall {
	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 *EnterprisesApplicationsGetCall) Context(ctx context.Context) *EnterprisesApplicationsGetCall {
	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 *EnterprisesApplicationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesApplicationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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 "androidmanagement.enterprises.applications.get" call.
// Exactly one of *Application or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Application.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 *EnterprisesApplicationsGetCall) Do(opts ...googleapi.CallOption) (*Application, 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 := &Application{
		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": "Gets info about an application.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/applications/{applicationsId}",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.applications.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "The preferred language for localized application info, as a BCP47 tag (e.g. \"en-US\", \"de\"). If not specified the default language of the application will be used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the application in the form enterprises/{enterpriseId}/applications/{package_name}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/applications/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Application"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.devices.delete":

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

// Delete: Deletes a device. This operation wipes the device.
func (r *EnterprisesDevicesService) Delete(name string) *EnterprisesDevicesDeleteCall {
	c := &EnterprisesDevicesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// WipeDataFlags sets the optional parameter "wipeDataFlags": Optional
// flags that control the device wiping behavior.
//
// Possible values:
//   "WIPE_DATA_FLAG_UNSPECIFIED" - This value is ignored.
//   "PRESERVE_RESET_PROTECTION_DATA" - Preserve the factory reset
// protection data on the device.
//   "WIPE_EXTERNAL_STORAGE" - Additionally wipe the device's external
// storage (such as SD cards).
func (c *EnterprisesDevicesDeleteCall) WipeDataFlags(wipeDataFlags ...string) *EnterprisesDevicesDeleteCall {
	c.urlParams_.SetMulti("wipeDataFlags", append([]string{}, wipeDataFlags...))
	return c
}

// WipeReasonMessage sets the optional parameter "wipeReasonMessage": A
// short message displayed to the user before wiping the work profile on
// personal devices. This has no effect on company owned devices. The
// maximum message length is 200 characters.
func (c *EnterprisesDevicesDeleteCall) WipeReasonMessage(wipeReasonMessage string) *EnterprisesDevicesDeleteCall {
	c.urlParams_.Set("wipeReasonMessage", wipeReasonMessage)
	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 *EnterprisesDevicesDeleteCall) Fields(s ...googleapi.Field) *EnterprisesDevicesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesDevicesDeleteCall) Context(ctx context.Context) *EnterprisesDevicesDeleteCall {
	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 *EnterprisesDevicesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	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("DELETE", 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 "androidmanagement.enterprises.devices.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *EnterprisesDevicesDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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": "Deletes a device. This operation wipes the device.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices/{devicesId}",
	//   "httpMethod": "DELETE",
	//   "id": "androidmanagement.enterprises.devices.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the device in the form enterprises/{enterpriseId}/devices/{deviceId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/devices/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "wipeDataFlags": {
	//       "description": "Optional flags that control the device wiping behavior.",
	//       "enum": [
	//         "WIPE_DATA_FLAG_UNSPECIFIED",
	//         "PRESERVE_RESET_PROTECTION_DATA",
	//         "WIPE_EXTERNAL_STORAGE"
	//       ],
	//       "enumDescriptions": [
	//         "This value is ignored.",
	//         "Preserve the factory reset protection data on the device.",
	//         "Additionally wipe the device's external storage (such as SD cards)."
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "wipeReasonMessage": {
	//       "description": "Optional. A short message displayed to the user before wiping the work profile on personal devices. This has no effect on company owned devices. The maximum message length is 200 characters.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.devices.get":

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

// Get: Gets a device.
func (r *EnterprisesDevicesService) Get(name string) *EnterprisesDevicesGetCall {
	c := &EnterprisesDevicesGetCall{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 *EnterprisesDevicesGetCall) Fields(s ...googleapi.Field) *EnterprisesDevicesGetCall {
	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 *EnterprisesDevicesGetCall) IfNoneMatch(entityTag string) *EnterprisesDevicesGetCall {
	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 *EnterprisesDevicesGetCall) Context(ctx context.Context) *EnterprisesDevicesGetCall {
	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 *EnterprisesDevicesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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 "androidmanagement.enterprises.devices.get" call.
// Exactly one of *Device or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Device.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 *EnterprisesDevicesGetCall) Do(opts ...googleapi.CallOption) (*Device, 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 := &Device{
		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": "Gets a device.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices/{devicesId}",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.devices.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the device in the form enterprises/{enterpriseId}/devices/{deviceId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/devices/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Device"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.devices.issueCommand":

type EnterprisesDevicesIssueCommandCall struct {
	s          *Service
	name       string
	command    *Command
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// IssueCommand: Issues a command to a device. The Operation resource
// returned contains a Command in its metadata field. Use the get
// operation method to get the status of the command.
func (r *EnterprisesDevicesService) IssueCommand(name string, command *Command) *EnterprisesDevicesIssueCommandCall {
	c := &EnterprisesDevicesIssueCommandCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.command = command
	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 *EnterprisesDevicesIssueCommandCall) Fields(s ...googleapi.Field) *EnterprisesDevicesIssueCommandCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesDevicesIssueCommandCall) Context(ctx context.Context) *EnterprisesDevicesIssueCommandCall {
	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 *EnterprisesDevicesIssueCommandCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesIssueCommandCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.command)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:issueCommand")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "androidmanagement.enterprises.devices.issueCommand" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.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 *EnterprisesDevicesIssueCommandCall) Do(opts ...googleapi.CallOption) (*Operation, 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 := &Operation{
		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": "Issues a command to a device. The Operation resource returned contains a Command in its metadata field. Use the get operation method to get the status of the command.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices/{devicesId}:issueCommand",
	//   "httpMethod": "POST",
	//   "id": "androidmanagement.enterprises.devices.issueCommand",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the device in the form enterprises/{enterpriseId}/devices/{deviceId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/devices/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:issueCommand",
	//   "request": {
	//     "$ref": "Command"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.devices.list":

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

// List: Lists devices for a given enterprise.
func (r *EnterprisesDevicesService) List(parent string) *EnterprisesDevicesListCall {
	c := &EnterprisesDevicesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The requested page
// size. The actual page size may be fixed to a min or max value.
func (c *EnterprisesDevicesListCall) PageSize(pageSize int64) *EnterprisesDevicesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results returned by the server.
func (c *EnterprisesDevicesListCall) PageToken(pageToken string) *EnterprisesDevicesListCall {
	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 *EnterprisesDevicesListCall) Fields(s ...googleapi.Field) *EnterprisesDevicesListCall {
	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 *EnterprisesDevicesListCall) IfNoneMatch(entityTag string) *EnterprisesDevicesListCall {
	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 *EnterprisesDevicesListCall) Context(ctx context.Context) *EnterprisesDevicesListCall {
	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 *EnterprisesDevicesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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}/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 "androidmanagement.enterprises.devices.list" call.
// Exactly one of *ListDevicesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListDevicesResponse.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 *EnterprisesDevicesListCall) Do(opts ...googleapi.CallOption) (*ListDevicesResponse, 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 := &ListDevicesResponse{
		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": "Lists devices for a given enterprise.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.devices.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The requested page size. The actual page size may be fixed to a min or max value.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results returned by the server.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The name of the enterprise in the form enterprises/{enterpriseId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/devices",
	//   "response": {
	//     "$ref": "ListDevicesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// 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 *EnterprisesDevicesListCall) Pages(ctx context.Context, f func(*ListDevicesResponse) 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 "androidmanagement.enterprises.devices.patch":

type EnterprisesDevicesPatchCall struct {
	s          *Service
	name       string
	device     *Device
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates a device.
func (r *EnterprisesDevicesService) Patch(name string, device *Device) *EnterprisesDevicesPatchCall {
	c := &EnterprisesDevicesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.device = device
	return c
}

// UpdateMask sets the optional parameter "updateMask": The field mask
// indicating the fields to update. If not set, all modifiable fields
// will be modified.
func (c *EnterprisesDevicesPatchCall) UpdateMask(updateMask string) *EnterprisesDevicesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *EnterprisesDevicesPatchCall) Fields(s ...googleapi.Field) *EnterprisesDevicesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesDevicesPatchCall) Context(ctx context.Context) *EnterprisesDevicesPatchCall {
	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 *EnterprisesDevicesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.device)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	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("PATCH", 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 "androidmanagement.enterprises.devices.patch" call.
// Exactly one of *Device or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Device.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 *EnterprisesDevicesPatchCall) Do(opts ...googleapi.CallOption) (*Device, 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 := &Device{
		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": "Updates a device.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices/{devicesId}",
	//   "httpMethod": "PATCH",
	//   "id": "androidmanagement.enterprises.devices.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the device in the form enterprises/{enterpriseId}/devices/{deviceId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/devices/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The field mask indicating the fields to update. If not set, all modifiable fields will be modified.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "Device"
	//   },
	//   "response": {
	//     "$ref": "Device"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.devices.operations.cancel":

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

// Cancel: Starts asynchronous cancellation on a long-running operation.
// The server makes a best effort to cancel the operation, but success
// is not guaranteed. If the server doesn't support this method, it
// returns google.rpc.Code.UNIMPLEMENTED. Clients can use
// Operations.GetOperation or other methods to check whether the
// cancellation succeeded or whether the operation completed despite
// cancellation. On successful cancellation, the operation is not
// deleted; instead, it becomes an operation with an Operation.error
// value with a google.rpc.Status.code of 1, corresponding to
// Code.CANCELLED.
func (r *EnterprisesDevicesOperationsService) Cancel(name string) *EnterprisesDevicesOperationsCancelCall {
	c := &EnterprisesDevicesOperationsCancelCall{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 *EnterprisesDevicesOperationsCancelCall) Fields(s ...googleapi.Field) *EnterprisesDevicesOperationsCancelCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesDevicesOperationsCancelCall) Context(ctx context.Context) *EnterprisesDevicesOperationsCancelCall {
	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 *EnterprisesDevicesOperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesOperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "androidmanagement.enterprises.devices.operations.cancel" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *EnterprisesDevicesOperationsCancelCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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": "Starts asynchronous cancellation on a long-running operation. The server makes a best effort to cancel the operation, but success is not guaranteed. If the server doesn't support this method, it returns google.rpc.Code.UNIMPLEMENTED. Clients can use Operations.GetOperation or other methods to check whether the cancellation succeeded or whether the operation completed despite cancellation. On successful cancellation, the operation is not deleted; instead, it becomes an operation with an Operation.error value with a google.rpc.Status.code of 1, corresponding to Code.CANCELLED.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices/{devicesId}/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "androidmanagement.enterprises.devices.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/devices/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:cancel",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.devices.operations.delete":

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

// Delete: Deletes a long-running operation. This method indicates that
// the client is no longer interested in the operation result. It does
// not cancel the operation. If the server doesn't support this method,
// it returns google.rpc.Code.UNIMPLEMENTED.
func (r *EnterprisesDevicesOperationsService) Delete(name string) *EnterprisesDevicesOperationsDeleteCall {
	c := &EnterprisesDevicesOperationsDeleteCall{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 *EnterprisesDevicesOperationsDeleteCall) Fields(s ...googleapi.Field) *EnterprisesDevicesOperationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesDevicesOperationsDeleteCall) Context(ctx context.Context) *EnterprisesDevicesOperationsDeleteCall {
	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 *EnterprisesDevicesOperationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesOperationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	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("DELETE", 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 "androidmanagement.enterprises.devices.operations.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *EnterprisesDevicesOperationsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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": "Deletes a long-running operation. This method indicates that the client is no longer interested in the operation result. It does not cancel the operation. If the server doesn't support this method, it returns google.rpc.Code.UNIMPLEMENTED.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices/{devicesId}/operations/{operationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "androidmanagement.enterprises.devices.operations.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be deleted.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/devices/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.devices.operations.get":

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

// Get: Gets the latest state of a long-running operation. Clients can
// use this method to poll the operation result at intervals as
// recommended by the API service.
func (r *EnterprisesDevicesOperationsService) Get(name string) *EnterprisesDevicesOperationsGetCall {
	c := &EnterprisesDevicesOperationsGetCall{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 *EnterprisesDevicesOperationsGetCall) Fields(s ...googleapi.Field) *EnterprisesDevicesOperationsGetCall {
	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 *EnterprisesDevicesOperationsGetCall) IfNoneMatch(entityTag string) *EnterprisesDevicesOperationsGetCall {
	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 *EnterprisesDevicesOperationsGetCall) Context(ctx context.Context) *EnterprisesDevicesOperationsGetCall {
	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 *EnterprisesDevicesOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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 "androidmanagement.enterprises.devices.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.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 *EnterprisesDevicesOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, 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 := &Operation{
		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": "Gets the latest state of a long-running operation. Clients can use this method to poll the operation result at intervals as recommended by the API service.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices/{devicesId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.devices.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/devices/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.devices.operations.list":

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

// List: Lists operations that match the specified filter in the
// request. If the server doesn't support this method, it returns
// UNIMPLEMENTED.NOTE: the name binding allows API services to override
// the binding to use different resource name schemes, such as
// users/*/operations. To override the binding, API services can add a
// binding such as "/v1/{name=users/*}/operations" to their service
// configuration. For backwards compatibility, the default name includes
// the operations collection id, however overriding users must ensure
// the name binding is the parent resource, without the operations
// collection id.
func (r *EnterprisesDevicesOperationsService) List(name string) *EnterprisesDevicesOperationsListCall {
	c := &EnterprisesDevicesOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list
// filter.
func (c *EnterprisesDevicesOperationsListCall) Filter(filter string) *EnterprisesDevicesOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list
// page size.
func (c *EnterprisesDevicesOperationsListCall) PageSize(pageSize int64) *EnterprisesDevicesOperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list
// page token.
func (c *EnterprisesDevicesOperationsListCall) PageToken(pageToken string) *EnterprisesDevicesOperationsListCall {
	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 *EnterprisesDevicesOperationsListCall) Fields(s ...googleapi.Field) *EnterprisesDevicesOperationsListCall {
	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 *EnterprisesDevicesOperationsListCall) IfNoneMatch(entityTag string) *EnterprisesDevicesOperationsListCall {
	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 *EnterprisesDevicesOperationsListCall) Context(ctx context.Context) *EnterprisesDevicesOperationsListCall {
	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 *EnterprisesDevicesOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesDevicesOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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 "androidmanagement.enterprises.devices.operations.list" call.
// Exactly one of *ListOperationsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.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 *EnterprisesDevicesOperationsListCall) Do(opts ...googleapi.CallOption) (*ListOperationsResponse, 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 := &ListOperationsResponse{
		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": "Lists operations that match the specified filter in the request. If the server doesn't support this method, it returns UNIMPLEMENTED.NOTE: the name binding allows API services to override the binding to use different resource name schemes, such as users/*/operations. To override the binding, API services can add a binding such as \"/v1/{name=users/*}/operations\" to their service configuration. For backwards compatibility, the default name includes the operations collection id, however overriding users must ensure the name binding is the parent resource, without the operations collection id.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/devices/{devicesId}/operations",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.devices.operations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/devices/[^/]+/operations$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The standard list page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "ListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// 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 *EnterprisesDevicesOperationsListCall) Pages(ctx context.Context, f func(*ListOperationsResponse) 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 "androidmanagement.enterprises.enrollmentTokens.create":

type EnterprisesEnrollmentTokensCreateCall struct {
	s               *Service
	parent          string
	enrollmenttoken *EnrollmentToken
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Create: Creates an enrollment token for a given enterprise.
func (r *EnterprisesEnrollmentTokensService) Create(parent string, enrollmenttoken *EnrollmentToken) *EnterprisesEnrollmentTokensCreateCall {
	c := &EnterprisesEnrollmentTokensCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.enrollmenttoken = enrollmenttoken
	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 *EnterprisesEnrollmentTokensCreateCall) Fields(s ...googleapi.Field) *EnterprisesEnrollmentTokensCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesEnrollmentTokensCreateCall) Context(ctx context.Context) *EnterprisesEnrollmentTokensCreateCall {
	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 *EnterprisesEnrollmentTokensCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesEnrollmentTokensCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.enrollmenttoken)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/enrollmentTokens")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "androidmanagement.enterprises.enrollmentTokens.create" call.
// Exactly one of *EnrollmentToken or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *EnrollmentToken.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 *EnterprisesEnrollmentTokensCreateCall) Do(opts ...googleapi.CallOption) (*EnrollmentToken, 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 := &EnrollmentToken{
		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": "Creates an enrollment token for a given enterprise.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/enrollmentTokens",
	//   "httpMethod": "POST",
	//   "id": "androidmanagement.enterprises.enrollmentTokens.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The name of the enterprise in the form enterprises/{enterpriseId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/enrollmentTokens",
	//   "request": {
	//     "$ref": "EnrollmentToken"
	//   },
	//   "response": {
	//     "$ref": "EnrollmentToken"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.enrollmentTokens.delete":

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

// Delete: Deletes an enrollment token. This operation invalidates the
// token, preventing its future use.
func (r *EnterprisesEnrollmentTokensService) Delete(name string) *EnterprisesEnrollmentTokensDeleteCall {
	c := &EnterprisesEnrollmentTokensDeleteCall{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 *EnterprisesEnrollmentTokensDeleteCall) Fields(s ...googleapi.Field) *EnterprisesEnrollmentTokensDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesEnrollmentTokensDeleteCall) Context(ctx context.Context) *EnterprisesEnrollmentTokensDeleteCall {
	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 *EnterprisesEnrollmentTokensDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesEnrollmentTokensDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	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("DELETE", 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 "androidmanagement.enterprises.enrollmentTokens.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *EnterprisesEnrollmentTokensDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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": "Deletes an enrollment token. This operation invalidates the token, preventing its future use.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/enrollmentTokens/{enrollmentTokensId}",
	//   "httpMethod": "DELETE",
	//   "id": "androidmanagement.enterprises.enrollmentTokens.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the enrollment token in the form enterprises/{enterpriseId}/enrollmentTokens/{enrollmentTokenId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/enrollmentTokens/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.policies.delete":

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

// Delete: Deletes a policy. This operation is only permitted if no
// devices are currently referencing the policy.
func (r *EnterprisesPoliciesService) Delete(name string) *EnterprisesPoliciesDeleteCall {
	c := &EnterprisesPoliciesDeleteCall{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 *EnterprisesPoliciesDeleteCall) Fields(s ...googleapi.Field) *EnterprisesPoliciesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesPoliciesDeleteCall) Context(ctx context.Context) *EnterprisesPoliciesDeleteCall {
	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 *EnterprisesPoliciesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesPoliciesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	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("DELETE", 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 "androidmanagement.enterprises.policies.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *EnterprisesPoliciesDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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": "Deletes a policy. This operation is only permitted if no devices are currently referencing the policy.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/policies/{policiesId}",
	//   "httpMethod": "DELETE",
	//   "id": "androidmanagement.enterprises.policies.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the policy in the form enterprises/{enterpriseId}/policies/{policyId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/policies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.policies.get":

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

// Get: Gets a policy.
func (r *EnterprisesPoliciesService) Get(name string) *EnterprisesPoliciesGetCall {
	c := &EnterprisesPoliciesGetCall{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 *EnterprisesPoliciesGetCall) Fields(s ...googleapi.Field) *EnterprisesPoliciesGetCall {
	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 *EnterprisesPoliciesGetCall) IfNoneMatch(entityTag string) *EnterprisesPoliciesGetCall {
	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 *EnterprisesPoliciesGetCall) Context(ctx context.Context) *EnterprisesPoliciesGetCall {
	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 *EnterprisesPoliciesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesPoliciesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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 "androidmanagement.enterprises.policies.get" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.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 *EnterprisesPoliciesGetCall) Do(opts ...googleapi.CallOption) (*Policy, 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 := &Policy{
		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": "Gets a policy.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/policies/{policiesId}",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.policies.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the policy in the form enterprises/{enterpriseId}/policies/{policyId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/policies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.policies.list":

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

// List: Lists policies for a given enterprise.
func (r *EnterprisesPoliciesService) List(parent string) *EnterprisesPoliciesListCall {
	c := &EnterprisesPoliciesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The requested page
// size. The actual page size may be fixed to a min or max value.
func (c *EnterprisesPoliciesListCall) PageSize(pageSize int64) *EnterprisesPoliciesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results returned by the server.
func (c *EnterprisesPoliciesListCall) PageToken(pageToken string) *EnterprisesPoliciesListCall {
	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 *EnterprisesPoliciesListCall) Fields(s ...googleapi.Field) *EnterprisesPoliciesListCall {
	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 *EnterprisesPoliciesListCall) IfNoneMatch(entityTag string) *EnterprisesPoliciesListCall {
	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 *EnterprisesPoliciesListCall) Context(ctx context.Context) *EnterprisesPoliciesListCall {
	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 *EnterprisesPoliciesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesPoliciesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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}/policies")
	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 "androidmanagement.enterprises.policies.list" call.
// Exactly one of *ListPoliciesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListPoliciesResponse.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 *EnterprisesPoliciesListCall) Do(opts ...googleapi.CallOption) (*ListPoliciesResponse, 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 := &ListPoliciesResponse{
		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": "Lists policies for a given enterprise.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/policies",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.policies.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The requested page size. The actual page size may be fixed to a min or max value.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results returned by the server.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The name of the enterprise in the form enterprises/{enterpriseId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/policies",
	//   "response": {
	//     "$ref": "ListPoliciesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// 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 *EnterprisesPoliciesListCall) Pages(ctx context.Context, f func(*ListPoliciesResponse) 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 "androidmanagement.enterprises.policies.patch":

type EnterprisesPoliciesPatchCall struct {
	s          *Service
	name       string
	policy     *Policy
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates or creates a policy.
func (r *EnterprisesPoliciesService) Patch(name string, policy *Policy) *EnterprisesPoliciesPatchCall {
	c := &EnterprisesPoliciesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.policy = policy
	return c
}

// UpdateMask sets the optional parameter "updateMask": The field mask
// indicating the fields to update. If not set, all modifiable fields
// will be modified.
func (c *EnterprisesPoliciesPatchCall) UpdateMask(updateMask string) *EnterprisesPoliciesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *EnterprisesPoliciesPatchCall) Fields(s ...googleapi.Field) *EnterprisesPoliciesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesPoliciesPatchCall) Context(ctx context.Context) *EnterprisesPoliciesPatchCall {
	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 *EnterprisesPoliciesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesPoliciesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.policy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	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("PATCH", 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 "androidmanagement.enterprises.policies.patch" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.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 *EnterprisesPoliciesPatchCall) Do(opts ...googleapi.CallOption) (*Policy, 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 := &Policy{
		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": "Updates or creates a policy.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/policies/{policiesId}",
	//   "httpMethod": "PATCH",
	//   "id": "androidmanagement.enterprises.policies.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the policy in the form enterprises/{enterpriseId}/policies/{policyId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/policies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The field mask indicating the fields to update. If not set, all modifiable fields will be modified.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "Policy"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.webApps.create":

type EnterprisesWebAppsCreateCall struct {
	s          *Service
	parent     string
	webapp     *WebApp
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a web app.
func (r *EnterprisesWebAppsService) Create(parent string, webapp *WebApp) *EnterprisesWebAppsCreateCall {
	c := &EnterprisesWebAppsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.webapp = webapp
	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 *EnterprisesWebAppsCreateCall) Fields(s ...googleapi.Field) *EnterprisesWebAppsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesWebAppsCreateCall) Context(ctx context.Context) *EnterprisesWebAppsCreateCall {
	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 *EnterprisesWebAppsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesWebAppsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.webapp)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/webApps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "androidmanagement.enterprises.webApps.create" call.
// Exactly one of *WebApp or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *WebApp.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 *EnterprisesWebAppsCreateCall) Do(opts ...googleapi.CallOption) (*WebApp, 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 := &WebApp{
		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": "Creates a web app.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/webApps",
	//   "httpMethod": "POST",
	//   "id": "androidmanagement.enterprises.webApps.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The name of the enterprise in the form enterprises/{enterpriseId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/webApps",
	//   "request": {
	//     "$ref": "WebApp"
	//   },
	//   "response": {
	//     "$ref": "WebApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.webApps.delete":

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

// Delete: Deletes a web app.
func (r *EnterprisesWebAppsService) Delete(name string) *EnterprisesWebAppsDeleteCall {
	c := &EnterprisesWebAppsDeleteCall{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 *EnterprisesWebAppsDeleteCall) Fields(s ...googleapi.Field) *EnterprisesWebAppsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesWebAppsDeleteCall) Context(ctx context.Context) *EnterprisesWebAppsDeleteCall {
	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 *EnterprisesWebAppsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesWebAppsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	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("DELETE", 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 "androidmanagement.enterprises.webApps.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *EnterprisesWebAppsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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": "Deletes a web app.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/webApps/{webAppsId}",
	//   "httpMethod": "DELETE",
	//   "id": "androidmanagement.enterprises.webApps.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the web app in the form enterprises/{enterpriseId}/webApps/{packageName}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/webApps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.webApps.get":

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

// Get: Gets a web app.
func (r *EnterprisesWebAppsService) Get(name string) *EnterprisesWebAppsGetCall {
	c := &EnterprisesWebAppsGetCall{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 *EnterprisesWebAppsGetCall) Fields(s ...googleapi.Field) *EnterprisesWebAppsGetCall {
	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 *EnterprisesWebAppsGetCall) IfNoneMatch(entityTag string) *EnterprisesWebAppsGetCall {
	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 *EnterprisesWebAppsGetCall) Context(ctx context.Context) *EnterprisesWebAppsGetCall {
	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 *EnterprisesWebAppsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesWebAppsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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 "androidmanagement.enterprises.webApps.get" call.
// Exactly one of *WebApp or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *WebApp.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 *EnterprisesWebAppsGetCall) Do(opts ...googleapi.CallOption) (*WebApp, 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 := &WebApp{
		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": "Gets a web app.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/webApps/{webAppsId}",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.webApps.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the web app in the form enterprises/{enterpriseId}/webApp/{packageName}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/webApps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "WebApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.webApps.list":

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

// List: Lists web apps for a given enterprise.
func (r *EnterprisesWebAppsService) List(parent string) *EnterprisesWebAppsListCall {
	c := &EnterprisesWebAppsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The requested page
// size. The actual page size may be fixed to a min or max value.
func (c *EnterprisesWebAppsListCall) PageSize(pageSize int64) *EnterprisesWebAppsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results returned by the server.
func (c *EnterprisesWebAppsListCall) PageToken(pageToken string) *EnterprisesWebAppsListCall {
	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 *EnterprisesWebAppsListCall) Fields(s ...googleapi.Field) *EnterprisesWebAppsListCall {
	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 *EnterprisesWebAppsListCall) IfNoneMatch(entityTag string) *EnterprisesWebAppsListCall {
	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 *EnterprisesWebAppsListCall) Context(ctx context.Context) *EnterprisesWebAppsListCall {
	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 *EnterprisesWebAppsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesWebAppsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	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}/webApps")
	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 "androidmanagement.enterprises.webApps.list" call.
// Exactly one of *ListWebAppsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListWebAppsResponse.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 *EnterprisesWebAppsListCall) Do(opts ...googleapi.CallOption) (*ListWebAppsResponse, 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 := &ListWebAppsResponse{
		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": "Lists web apps for a given enterprise.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/webApps",
	//   "httpMethod": "GET",
	//   "id": "androidmanagement.enterprises.webApps.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The requested page size. The actual page size may be fixed to a min or max value.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results returned by the server.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The name of the enterprise in the form enterprises/{enterpriseId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/webApps",
	//   "response": {
	//     "$ref": "ListWebAppsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// 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 *EnterprisesWebAppsListCall) Pages(ctx context.Context, f func(*ListWebAppsResponse) 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 "androidmanagement.enterprises.webApps.patch":

type EnterprisesWebAppsPatchCall struct {
	s          *Service
	name       string
	webapp     *WebApp
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates a web app.
func (r *EnterprisesWebAppsService) Patch(name string, webapp *WebApp) *EnterprisesWebAppsPatchCall {
	c := &EnterprisesWebAppsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.webapp = webapp
	return c
}

// UpdateMask sets the optional parameter "updateMask": The field mask
// indicating the fields to update. If not set, all modifiable fields
// will be modified.
func (c *EnterprisesWebAppsPatchCall) UpdateMask(updateMask string) *EnterprisesWebAppsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *EnterprisesWebAppsPatchCall) Fields(s ...googleapi.Field) *EnterprisesWebAppsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesWebAppsPatchCall) Context(ctx context.Context) *EnterprisesWebAppsPatchCall {
	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 *EnterprisesWebAppsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesWebAppsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.webapp)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	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("PATCH", 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 "androidmanagement.enterprises.webApps.patch" call.
// Exactly one of *WebApp or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *WebApp.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 *EnterprisesWebAppsPatchCall) Do(opts ...googleapi.CallOption) (*WebApp, 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 := &WebApp{
		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": "Updates a web app.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/webApps/{webAppsId}",
	//   "httpMethod": "PATCH",
	//   "id": "androidmanagement.enterprises.webApps.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the web app in the form enterprises/{enterpriseId}/webApps/{packageName}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+/webApps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The field mask indicating the fields to update. If not set, all modifiable fields will be modified.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "WebApp"
	//   },
	//   "response": {
	//     "$ref": "WebApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.enterprises.webTokens.create":

type EnterprisesWebTokensCreateCall struct {
	s          *Service
	parent     string
	webtoken   *WebToken
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a web token to access an embeddable managed Google
// Play web UI for a given enterprise.
func (r *EnterprisesWebTokensService) Create(parent string, webtoken *WebToken) *EnterprisesWebTokensCreateCall {
	c := &EnterprisesWebTokensCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.webtoken = webtoken
	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 *EnterprisesWebTokensCreateCall) Fields(s ...googleapi.Field) *EnterprisesWebTokensCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *EnterprisesWebTokensCreateCall) Context(ctx context.Context) *EnterprisesWebTokensCreateCall {
	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 *EnterprisesWebTokensCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EnterprisesWebTokensCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200922")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.webtoken)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/webTokens")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "androidmanagement.enterprises.webTokens.create" call.
// Exactly one of *WebToken or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *WebToken.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 *EnterprisesWebTokensCreateCall) Do(opts ...googleapi.CallOption) (*WebToken, 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 := &WebToken{
		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": "Creates a web token to access an embeddable managed Google Play web UI for a given enterprise.",
	//   "flatPath": "v1/enterprises/{enterprisesId}/webTokens",
	//   "httpMethod": "POST",
	//   "id": "androidmanagement.enterprises.webTokens.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The name of the enterprise in the form enterprises/{enterpriseId}.",
	//       "location": "path",
	//       "pattern": "^enterprises/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/webTokens",
	//   "request": {
	//     "$ref": "WebToken"
	//   },
	//   "response": {
	//     "$ref": "WebToken"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}

// method id "androidmanagement.signupUrls.create":

type SignupUrlsCreateCall struct {
	s          *Service
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates an enterprise signup URL.
func (r *SignupUrlsService) Create() *SignupUrlsCreateCall {
	c := &SignupUrlsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// CallbackUrl sets the optional parameter "callbackUrl": The callback
// URL that the admin will be redirected to after successfully creating
// an enterprise. Before redirecting there the system will add a query
// parameter to this URL named enterpriseToken which will contain an
// opaque token to be used for the create enterprise request. The URL
// will be parsed then reformatted in order to add the enterpriseToken
// parameter, so there may be some minor formatting changes.
func (c *SignupUrlsCreateCall) CallbackUrl(callbackUrl string) *SignupUrlsCreateCall {
	c.urlParams_.Set("callbackUrl", callbackUrl)
	return c
}

// ProjectId sets the optional parameter "projectId": The ID of the
// Google Cloud Platform project which will own the enterprise.
func (c *SignupUrlsCreateCall) ProjectId(projectId string) *SignupUrlsCreateCall {
	c.urlParams_.Set("projectId", projectId)
	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 *SignupUrlsCreateCall) Fields(s ...googleapi.Field) *SignupUrlsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *SignupUrlsCreateCall) Context(ctx context.Context) *SignupUrlsCreateCall {
	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 *SignupUrlsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "androidmanagement.signupUrls.create" call.
// Exactly one of *SignupUrl or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SignupUrl.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 *SignupUrlsCreateCall) Do(opts ...googleapi.CallOption) (*SignupUrl, 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 := &SignupUrl{
		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": "Creates an enterprise signup URL.",
	//   "flatPath": "v1/signupUrls",
	//   "httpMethod": "POST",
	//   "id": "androidmanagement.signupUrls.create",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "callbackUrl": {
	//       "description": "The callback URL that the admin will be redirected to after successfully creating an enterprise. Before redirecting there the system will add a query parameter to this URL named enterpriseToken which will contain an opaque token to be used for the create enterprise request. The URL will be parsed then reformatted in order to add the enterpriseToken parameter, so there may be some minor formatting changes.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The ID of the Google Cloud Platform project which will own the enterprise.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/signupUrls",
	//   "response": {
	//     "$ref": "SignupUrl"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/androidmanagement"
	//   ]
	// }

}
