// Copyright 2019 Google Inc. All rights reserved.
// 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.
//
// See https://developers.google.com/android/management
//
// Usage example:
//
//   import "google.golang.org/api/androidmanagement/v1"
//   ...
//   androidmanagementService, err := androidmanagement.New(oauthHttpClient)
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"
)

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

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.WebTokens = NewEnterprisesWebTokensService(s)
	return rs
}

type EnterprisesService struct {
	s *Service

	Applications *EnterprisesApplicationsService

	Devices *EnterprisesDevicesService

	EnrollmentTokens *EnterprisesEnrollmentTokensService

	Policies *EnterprisesPoliciesService

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

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

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

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

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

// 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.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"
	//   ]
	// }

}
