Documentation
¶
Overview ¶
Package android is the Android platform. It is ordinary Go: everything that needs the Android framework goes through the Host the embedding host supplies.
Index ¶
- Constants
- Variables
- type AppIdentity
- type AppInfo
- type DispatchReceipt
- type FailureReason
- type ForegroundState
- type Host
- type HostError
- type HostReturn
- type LaunchDefinition
- type LaunchExtra
- type Platform
- func (*Platform) ConsoleManager() platforms.ConsoleManager
- func (*Platform) ForwardCmd(*platforms.CmdEnv) (platforms.CmdResult, error)
- func (*Platform) GamepadPress(string) error
- func (*Platform) ID() string
- func (p *Platform) InvalidateHostSnapshot()
- func (*Platform) KeyboardPress(string) error
- func (p *Platform) LaunchMedia(cfg *config.Instance, path string, launcher *platforms.Launcher, ...) error
- func (*Platform) LaunchSystem(*config.Instance, string) error
- func (p *Platform) Launchers(*config.Instance) []platforms.Launcher
- func (*Platform) LookupMapping(*tokens.Token) (string, bool)
- func (*Platform) ManagedByPackageManager() bool
- func (p *Platform) ReadSourceDir(ctx context.Context, path string) ([]platforms.SourceEntry, error)
- func (p *Platform) ReadSourceFile(ctx context.Context, path string, limit int64) ([]byte, error)
- func (p *Platform) ReconcileExternalSessions(ctx context.Context) error
- func (p *Platform) ReconcileSessions(ctx context.Context, observed HostReturn) error
- func (p *Platform) RefreshLauncherDependencies() error
- func (*Platform) ReturnToMenu() error
- func (*Platform) RootDirs(*config.Instance) []string
- func (*Platform) ScanHook(*tokens.Token) error
- func (p *Platform) Scrapers(*config.Instance) map[string]platforms.Scraper
- func (*Platform) Screenshot() (*platforms.ScreenshotResult, error)
- func (p *Platform) SetMediaHistoryHooks(hooks platforms.MediaHistoryHooks)
- func (*Platform) SetTrackedProcess(*os.Process)
- func (p *Platform) Settings() platforms.Settings
- func (p *Platform) SourceRoots(ctx context.Context) ([]string, error)
- func (p *Platform) StartPost(ctx context.Context, _ *config.Instance, ...) error
- func (*Platform) StartPre(*config.Instance) error
- func (p *Platform) Stop() error
- func (*Platform) StopActiveLauncher(platforms.StopIntent) error
- func (*Platform) SupportedReaders(*config.Instance) []readers.Reader
Constants ¶
const ( // StrategyFilesystemPath hands the target a transient filesystem path. StrategyFilesystemPath = "filesystem_path" // StrategyContentURI hands the target a content URI with a read grant. StrategyContentURI = "content_uri" // StrategyApp starts an installed app with no media at all. The optional // literal extras select one profile-defined variant of it. StrategyApp = "app" )
Variables ¶
var ErrAppIdentity = errors.New("invalid android app identity")
ErrAppIdentity is returned for a virtual path that is not a launchable Android app identity.
var ErrLaunchDefinition = errors.New("invalid or unsupported launch definition")
ErrLaunchDefinition reports a launch definition that is malformed or asks for a capability this platform does not support.
Functions ¶
This section is empty.
Types ¶
type AppIdentity ¶
AppIdentity is an installed app, optionally one profile-defined variant of it. It is identity only: the activity, action and extras that actually start the app live in the catalog, so an app that renames an activity does not invalidate identities already written to a card.
func ParseAppPath ¶
func ParseAppPath(path string) (AppIdentity, error)
ParseAppPath reads an "android://" virtual path back into an identity.
func (AppIdentity) AppPath ¶
func (a AppIdentity) AppPath() string
AppPath renders the identity as "android://<package>[:<variant>]/<Name>".
type AppInfo ¶
AppInfo is one launchable app the host found. Label is the app's own display name, which the host reads from the platform, never Core.
type DispatchReceipt ¶
DispatchReceipt names the component the host actually started, so the platform can confirm it is the one the definition asked for.
type FailureReason ¶
type FailureReason string
FailureReason is a stable code for why the host could not inspect or start a launch target. It carries no user-facing text.
const ( FailureHostUnavailable FailureReason = "host-unavailable" // FailureInvalidResponse means the host answered with something malformed. FailureInvalidResponse FailureReason = "invalid-response" // FailureNotInstalled means the target package is not installed. FailureNotInstalled FailureReason = "not-installed" FailureActivityUnavailable FailureReason = "activity-unavailable" // FailureStorageDenied means the target app has no storage permission. FailureStorageDenied FailureReason = "storage-denied" // FailureStorageVersion means the target build's storage access cannot be verified. FailureStorageVersion FailureReason = "storage-version" // FailureProviderUnsupported means the document provider cannot yield a local file. FailureProviderUnsupported FailureReason = "provider-unsupported" // FailureStorageUnmounted means the volume holding the media is not mounted. FailureStorageUnmounted FailureReason = "storage-unmounted" FailureSourceUnavailable FailureReason = "source-unavailable" // FailureSourceRevoked means the host's own access to the media's source // folder was revoked or withdrawn, distinct from FailureSourceUnavailable's // unspecified cause: the user can act on this one by re-granting access. FailureSourceRevoked FailureReason = "source-revoked" // FailureForegroundRequired means the host UI must be in front to start an activity. FailureForegroundRequired FailureReason = "foreground-required" // FailureCancelled means the dispatch was cancelled before it started. FailureCancelled FailureReason = "cancelled" // FailureOutcomeUnknown means the host cannot tell whether the target started. FailureOutcomeUnknown FailureReason = "outcome-unknown" // FailureRefused covers every other refusal. FailureRefused FailureReason = "refused" )
type ForegroundState ¶
type ForegroundState struct {
BootID string
Permission string
SampledMs int64
ElapsedMs int64
Version int
Interactive bool
Unlocked bool
}
ForegroundState is a host-owned snapshot taken before intent dispatch or a reconciliation pass. It also supplies the boot and elapsed clocks needed to reject cross-boot replay.
type Host ¶
type Host interface {
// InspectTarget reports whether the definition's package and activity are
// installed and launchable. A nil error means they are; a *HostError says
// why not.
InspectTarget(definition *LaunchDefinition) error
// InstalledCores lists the launcher core files the host found. scanned is
// false when the host has not looked, which is not evidence of absence.
InstalledCores() (files []string, scanned bool)
// MediaFolders returns the references of the media folders Core may
// index now. A folder whose grant was revoked is not listed.
MediaFolders(ctx context.Context) ([]string, error)
// ReadMediaDir lists the directory at segments below the folder named by
// reference; no segments lists the folder itself.
ReadMediaDir(ctx context.Context, reference string, segments []string) ([]platforms.SourceEntry, error)
// ReadFile returns up to limit+1 bytes of the file at segments below the
// folder named by reference, so an oversized file is detectable. It is
// used only at launch, to read the small amount of a media file's own
// content a launch needs; indexing never reads a file's content.
ReadFile(ctx context.Context, reference string, segments []string, limit int64) ([]byte, error)
// Dispatch starts a validated definition for the file at segments below
// the folder named by reference. Cancelling ctx abandons a dispatch in
// flight. A *HostError says why the host refused.
Dispatch(
ctx context.Context,
definition *LaunchDefinition,
reference string,
segments []string,
) (DispatchReceipt, error)
// InstalledApps lists the launchable apps the host found. scanned is false
// when the host has not looked, which is not evidence of absence.
InstalledApps() (apps []AppInfo, scanned bool)
// AppIcon returns a readable, app-private PNG for a launchable package.
// An unavailable icon is not evidence that the app is absent.
AppIcon(packageName string) (path string, err error)
// DispatchApp starts a definition that carries no media. A *HostError says
// why the host refused.
DispatchApp(definition *LaunchDefinition) (DispatchReceipt, error)
// ForegroundState reads a fresh framework snapshot: boot identity, Usage
// Access permission, and screen/keyguard state, on both the wall and
// elapsed clocks. It is read fresh before every dispatch and
// reconciliation pass; the platform never caches it.
ForegroundState() (ForegroundState, error)
// ForegroundEvents queries a bounded window of privacy-filtered
// foreground evidence for one already-dispatched launch's whole
// package - never a specific activity, so an intent that forwards
// through more than one activity of the same app still reads as one
// session. Cancelling ctx abandons a query in flight.
ForegroundEvents(
ctx context.Context, launchID, target string, fromMs, toMs int64,
) (database.ForegroundEvidence, error)
}
Host is the embedding host's authority over the Android framework. The platform never touches packages, intents or document providers itself. Implementations must be safe for concurrent use.
Media folders the user granted to the host are named by the host's own reference for each, which Core treats as opaque. Core turns references into source roots and never shows or stores one.
type HostError ¶
type HostError struct {
Reason FailureReason
}
HostError is the typed failure a Host returns. Any other error from a Host is treated as FailureHostUnavailable.
type HostReturn ¶
type HostReturn struct {
// ObserverStartedElapsedMs is when the UI process now reporting started.
// A launch dispatched before it came from a process that died, so no
// return can ever be observed for it. Zero when unknown.
ObserverStartedElapsedMs int64
// ReturnedWallMs and ReturnedElapsedMs are the earliest launcher resume
// the host has not yet delivered. Zero when there was none.
ReturnedWallMs int64
ReturnedElapsedMs int64
}
HostReturn is what the host observed of its own launcher UI, all from one boot: the UI process cannot outlive a reboot.
type LaunchDefinition ¶
type LaunchDefinition struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Variant string `json:"variant,omitempty"`
System string `json:"system"`
Package string `json:"package"`
Activity string `json:"activity"`
Action string `json:"action"`
Strategy string `json:"strategy"`
StorageAccess string `json:"storageAccess"`
Repair string `json:"repair"`
DataSource string `json:"dataSource,omitempty"`
// Data is an Intent data URI, set only at dispatch from a file the
// definition itself carries no reference to. Reserved for the one
// package whose exported activity reads its target from Intent data
// (scummVMPackage); every other definition must leave it empty.
Data string `json:"data,omitempty"`
Extensions []string `json:"extensions"`
Extras []LaunchExtra `json:"extras,omitempty"`
Version int `json:"version"`
MaxTargetSDK int `json:"maxTargetSdk,omitempty"`
GrantReadURI bool `json:"grantReadUri,omitempty"`
ClipData bool `json:"clipData,omitempty"`
}
LaunchDefinition is binding data: which component to start and how media reaches it. Version 1 carries a transient filesystem path. Version 2 carries a content URI with an explicit read grant and ClipData. A host must never silently substitute one strategy for the other.
func (*LaunchDefinition) Validate ¶
func (d *LaunchDefinition) Validate() error
Validate reports ErrLaunchDefinition unless every field is bounded and the definition uses exactly one supported strategy.
type LaunchExtra ¶
type LaunchExtra struct {
Name string `json:"name"`
Type string `json:"type"`
Source string `json:"source"`
Suffix string `json:"suffix,omitempty"`
Value string `json:"value,omitempty"`
}
LaunchExtra binds one typed intent extra to a host capability, not a string template. Extras are string unless a package's own intent contract needs otherwise; adding a type for general use requires host negotiation.
type Platform ¶
type Platform struct {
// contains filtered or unexported fields
}
Platform implements platforms.Platform for Android. Token readers, input and screenshots have no host capability yet and report ErrNotSupported.
func New ¶
New builds the platform over the directories the host owns. A nil host yields a platform with no launchers and no media.
func (*Platform) ConsoleManager ¶
func (*Platform) ConsoleManager() platforms.ConsoleManager
func (*Platform) ForwardCmd ¶
func (*Platform) GamepadPress ¶
func (*Platform) InvalidateHostSnapshot ¶
func (p *Platform) InvalidateHostSnapshot()
InvalidateHostSnapshot drops the memoised host report so the next launcher listing or launch asks the host again. An embedding host calls it when packages are installed, removed or changed, and when the RetroArch core list changes.
func (*Platform) KeyboardPress ¶
func (*Platform) LaunchMedia ¶
func (p *Platform) LaunchMedia( cfg *config.Instance, path string, launcher *platforms.Launcher, db *database.Database, options *platforms.LaunchOptions, ) error
LaunchMedia starts path with launcher, or with the launcher Core's usual inference picks when none was chosen upstream.
func (*Platform) Launchers ¶
Launchers lists the catalog in precedence order: within a system, the first launcher is the preferred one.
func (*Platform) ManagedByPackageManager ¶
ManagedByPackageManager is true: the host's package is the only update path.
func (*Platform) ReadSourceDir ¶
ReadSourceDir lists a directory in one of the host's media folders.
func (*Platform) ReadSourceFile ¶
ReadSourceFile returns up to limit+1 bytes of the file at path, so an oversized file is detectable. Unlike SourceRoots/ReadSourceDir, this is not part of platforms.SourceRootReader (indexing never calls it) - it satisfies the separate platforms.SourceFileReader capability instead, used at launch time by ScummVM/GameNative and to serve a scraped folder cover's bytes.
func (*Platform) ReconcileExternalSessions ¶
ReconcileExternalSessions queries only recorded launch targets. The persisted cursor and store transaction make repeated host observations idempotent. It is run at startup and after every host return.
func (*Platform) ReconcileSessions ¶
func (p *Platform) ReconcileSessions(ctx context.Context, observed HostReturn) error
ReconcileSessions runs after the frontend returns: it closes approximate launches from the observed return, then queries foreground evidence once it has settled.
func (*Platform) RefreshLauncherDependencies ¶
RefreshLauncherDependencies drops the memoised host report, so an explicit launchers.refresh sees a RetroArch core install without waiting out hostSnapshotTTL.
func (*Platform) ReturnToMenu ¶
func (*Platform) RootDirs ¶
RootDirs is empty: media comes from the host's media folders, which Core indexes as source roots.
func (*Platform) Scrapers ¶
Scrapers offers the libretro thumbnail scraper (box art, screenshots and title screens for indexed media, matched by libretro's own sanitised name; it never runs automatically after indexing, since it is the only scraper that downloads) and, once a host is present, an app icon scraper for installed apps offered as media.
func (*Platform) Screenshot ¶
func (*Platform) Screenshot() (*platforms.ScreenshotResult, error)
func (*Platform) SetMediaHistoryHooks ¶
func (p *Platform) SetMediaHistoryHooks(hooks platforms.MediaHistoryHooks)
SetMediaHistoryHooks receives the service's profile and history notification hooks. Android history for a LifecycleExternal launcher comes from session reconciliation, not the active-media tracker.
func (*Platform) SetTrackedProcess ¶
func (*Platform) SourceRoots ¶
SourceRoots lists the media folders the user granted to the host.
func (*Platform) Stop ¶
Stop drops the launcher contexts StartPost supplied. A host reuses one Platform across starts, and the manager from the previous run holds a cancelled context: leaving it in place makes launcherContext's readiness check pass with a dead context instead of refusing the launch.
func (*Platform) StopActiveLauncher ¶
func (*Platform) StopActiveLauncher(platforms.StopIntent) error