Skip to content

feat: add skipSettingsAppInstall capability to skip installing the Settings helper app#1077

Merged
KazuCocoa merged 3 commits into
appium:masterfrom
AsijitM:feat-skip-settings-app-install
Jul 15, 2026
Merged

feat: add skipSettingsAppInstall capability to skip installing the Settings helper app#1077
KazuCocoa merged 3 commits into
appium:masterfrom
AsijitM:feat-skip-settings-app-install

Conversation

@AsijitM

@AsijitM AsijitM commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Problem

initDevice unconditionally installs the Appium Settings helper app via pushSettingsApp:

const shouldThrowError = Boolean(language || locale || ... || !skipUnlock);
await pushSettingsApp.bind(this)(shouldThrowError);

Some environments already provision the Settings helper app as part of a managed device
image / device farm. In those setups, re-pushing it on every session is redundant work and
can be undesirable (extra installs, timing, or immutable-image constraints).

There is already skipDeviceInitialization to skip the whole init block, but that is too
coarse — it also skips locale/logcat/geolocation setup. There is no way to keep device
initialization while skipping only the Settings app install.

Fix

Add an opt-in boolean capability skipSettingsAppInstall. When set, initDevice skips the
pushSettingsApp call and logs that Settings-app-dependent features may be unavailable. All
other initialization still runs.

  • Defaults to falseno behavior change for existing users.
  • Follows the existing capability pattern in this driver (e.g. chromedriverGrantPermissions,
    skipDeviceInitialization).

Changes

  • lib/constraints.ts: add skipSettingsAppInstall: { isBoolean: true }.
  • lib/commands/device/common.ts: guard the pushSettingsApp call with the new capability.

Notes

  • Happy to add docs and a unit test if maintainers are on board with the capability.

…ttings helper app

Some environments (e.g. managed device farms / prebuilt device images) already
provision the Appium Settings helper app, so re-installing it on every session
is redundant and can be undesirable. Add an opt-in boolean capability
`skipSettingsAppInstall` that skips the `pushSettingsApp` step in `initDevice`.

Defaults to false, so existing behavior is unchanged. When enabled, features
that depend on the Settings app (locale/language, IME handling, geolocation
mocking, window animation control, unlock) may be unavailable, which is logged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread lib/commands/device/common.ts
@AsijitM

AsijitM commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — and I think the installOrUpgrade behavior is actually the reason the skip is needed, rather than a reason it isn't.

The setup this targets is a managed device farm: the host provisions io.appium.settings itself during device setup and pins a specific version of it, and that app is the session's mock-location provider. The driver bundles its own io.appium.settings version, so when the two differ, installOrUpgrade doesn't no-op — it takes the upgrade branch and reinstalls the app mid-session. In our case that has two concrete consequences:

  1. it overrides the host-pinned version with the driver's bundled one, and
  2. reinstalling io.appium.settings breaks the active mock-location flow for the session.

So pushSettingsApp isn't redundant work here — it's disruptive precisely in the "a different version is already installed" branch. skipDeviceInitialization is too coarse to help (it also drops locale/logcat/geolocation init), so today there's no way to keep device init while leaving a host-managed Settings app untouched.

That's the gap skipSettingsAppInstall fills — opt-in, default false, so no change for anyone who doesn't manage the app themselves. Happy to reword the cap doc to make the "host owns/pins the Settings helper" intent explicit and add a unit test if you're good with the direction.

Comment thread lib/commands/device/common.ts Outdated
if (skipSettingsAppInstall) {
this.log.info(
`'skipSettingsAppInstall' is set. Skipping installation of the Appium Settings helper app. ` +
`Capabilities and features that depend on it (locale/language, IME/keyboard handling, ` +

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets not enumerate features as the list may change

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — dropped the enumerated feature list; the new log message no longer names specific features.

Comment thread lib/commands/device/common.ts Outdated
this.log.info(
`'skipSettingsAppInstall' is set. Skipping installation of the Appium Settings helper app. ` +
`Capabilities and features that depend on it (locale/language, IME/keyboard handling, ` +
`geolocation mocking, window animation control, unlock) may be unavailable.`,

@mykola-mokhnach mykola-mokhnach Jul 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also alter the below code? Some of it is going to fail if Settings app is not installed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Addressed by requiring the app to be present when the cap is set: it now checks adb.isAppInstalled(SETTINGS_HELPER_ID) and throws a clear error if it's missing, so the setMockLocationApp / ensureDeviceLocale / keyboard setup below are guaranteed a present Settings app instead of failing opaquely.

@KazuCocoa

Copy link
Copy Markdown
Member

What about tweaking this to "skipSettingsAppReinstall"?
Then, it will raise exception in case the device doesn't have settings app. It will not "install" or "reinstall" settings app but check if the device has settings app

… to be present

Address review feedback. Instead of silently skipping when the Settings helper
app may be absent, rename the capability to skipSettingsAppReinstall and, when
set, verify the app is already installed via adb.isAppInstalled and throw a clear
error if it is not - rather than (re)installing it. Device init and mock-location
setup below depend on the app being present, so this fails fast instead of
letting those steps break opaquely. Also drops the enumerated feature list from
the log message, and adds unit tests for the present/absent cases.
@AsijitM

AsijitM commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@KazuCocoa adopted, thanks — renamed the capability to skipSettingsAppReinstall, and when it's set the driver now verifies the Settings app is present (adb.isAppInstalled) and raises a clear error if it isn't, installing/reinstalling nothing. Added unit tests for both the present (no reinstall) and absent (throws) cases. Agreed this is cleaner than the silent skip.

@mykola-mokhnach
mykola-mokhnach requested a review from KazuCocoa July 9, 2026 16:48

@KazuCocoa KazuCocoa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lg, thank you!

We'll merge after fixing the conflict

@AsijitM

AsijitM commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@KazuCocoa @mykola-mokhnach I have resolved the conflicts now.

@KazuCocoa
KazuCocoa merged commit fba4a2c into appium:master Jul 15, 2026
5 checks passed
github-actions Bot pushed a commit that referenced this pull request Jul 15, 2026
## [13.4.0](v13.3.4...v13.4.0) (2026-07-15)

### Features

* add skipSettingsAppInstall capability to skip installing the Settings helper app ([#1077](#1077)) ([fba4a2c](fba4a2c))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 13.4.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants