// Copyright 2019 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"

	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
	option "google.golang.org/api/option"
	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

const apiId = "androidmanagement:v1"
const apiName = "androidmanagement"
const apiVersion = "v1"
const basePath = "https://androidmanagement.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...)
	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
}

// 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)
}

// Application: Information about an app.
type Application struct {
	// 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. "ManagedProperties")
	// 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. "ManagedProperties") 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 {
	// 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.
	InstallType string `json:"installType,omitempty"`

	// LockTaskAllowed: Whether the app is allowed to lock itself in
	// full-screen mode.
	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:
	// <table> <tr><td><i>type</i></td><td><i>JSON value</i></td></tr>
	// <tr><td>BOOL</td><td>true or false</td></tr>
	// <tr><td>STRING</td><td>string</td></tr>
	// <tr><td>INTEGER</td><td>number</td></tr>
	// <tr><td>CHOICE</td><td>string</td></tr>
	// <tr><td>MULTISELECT</td><td>array of strings</td></tr>
	// <tr><td>HIDDEN</td><td>string</td></tr>
	// <tr><td>BUNDLE_ARRAY</td><td>array of objects</td></tr> </table>
	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.
	// "DefaultPermissionPolicy") 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. "DefaultPermissionPolicy")
	// 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:
	//   "INSTALLED" - App is installed on the device
	//   "REMOVED" - App was removed from 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)
}

// 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)
}

// 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"`

	// 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"`

	// 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"`

	// 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"`

	// 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. Maximum of 1
	// SigninDetail is supported.
	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)
}

// 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)
}

// 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 <key, value>
	// 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_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
	// Play or the admin has not accepted the latest managed 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 have the format of
	// operations/some/unique/name.
	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 contain at least a letter, a
	// numerical digit and a special symbol. Other password constraints, for
	// example, password_minimum_letters are enforced.
	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"`

	// 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.
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)
}

// Policy: A policy resources represents a group 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"`

	// 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.
	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 keyguard
	// secure screens.
	//   "DISABLE_REMOTE_INPUT" - Disable text entry into notifications 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.
	// The apps appear on a single page in alphabetical order. It is
	// recommended to also use status_bar_disabled to block access to device
	// settings.
	KioskCustomLauncherEnabled bool `json:"kioskCustomLauncherEnabled,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"`

	// 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. 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"`

	// 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"`

	// 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"`

	// 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.
	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.
	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)
}

// 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)
}

// 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 {
	// 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=<token> 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. "QrCode") 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. "QrCode") 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"`

	// 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). The error
// model is designed to be:
// Simple to use and understand for most users
// Flexible enough to meet unexpected needsOverviewThe Status message
// contains three pieces of data: error code, error message, and error
// details. The error code should be an enum value of google.rpc.Code,
// but it may accept additional error codes if needed. The error message
// should be a developer-facing English message that helps developers
// understand and resolve the error. If a localized user-facing error
// message is needed, put the localized message in the error details or
// localize it in the client. The optional error details may contain
// arbitrary information about the error. There is a predefined set of
// error detail types in the package google.rpc that can be used for
// common error conditions.Language mappingThe Status message is the
// logical representation of the error model, but it is not necessarily
// the actual wire format. When the Status message is exposed in
// different client libraries and different wire protocols, it can be
// mapped differently. For example, it will likely be mapped to some
// exceptions in Java, but more likely mapped to some error codes in
// C.Other usesThe error model and the Status message can be used in a
// variety of environments, either with or without APIs, to provide a
// consistent developer experience across different environments.Example
// uses of this error model include:
// Partial errors. If a service needs to return partial errors to the
// client, it may embed the Status in the normal response to indicate
// the partial errors.
// Workflow errors. A typical workflow has multiple steps. Each step may
// have a Status message for error reporting.
// Batch operations. If a client uses batch request and batch response,
// the Status message should be used directly inside batch response, one
// for each error sub-response.
// Asynchronous operations. If an API call embeds asynchronous operation
// results in its response, the status of those operations should be
// represented directly using the Status message.
// Logging. If some API errors are stored in logs, the message Status
// could be used directly after any stripping needed for
// security/privacy reasons.
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.
	DisplayInfoEnabled bool `json:"displayInfoEnabled,omitempty"`

	// HardwareStatusEnabled: Whether hardware status reporting is enabled.
	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.
	PowerManagementEventsEnabled bool `json:"powerManagementEventsEnabled,omitempty"`

	// SoftwareInfoEnabled: Whether software info reporting is enabled.
	SoftwareInfoEnabled bool `json:"softwareInfoEnabled,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"`

	// 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)
}

// 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 <locale, message> 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.<p>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"). <ul> <li>The image type can be png or jpg.
	// <li>The image should ideally be square. <li>The image should ideally
	// have a size of 512x512. </ul>
	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 {
	// 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.
	//
	// 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. "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 *WebToken) MarshalJSON() ([]byte, error) {
	type NoMethod WebToken
	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)
	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)
	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)
	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)
	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"
//   "PRESERVE_RESET_PROTECTION_DATA"
//   "WIPE_EXTERNAL_STORAGE"
func (c *EnterprisesDevicesDeleteCall) WipeDataFlags(wipeDataFlags ...string) *EnterprisesDevicesDeleteCall {
	c.urlParams_.SetMulti("wipeDataFlags", append([]string{}, wipeDataFlags...))
	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)
	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"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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)
	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"
	//   ]
	// }

}
