Skip to content

Commit 142a353

Browse files
feat: Assume the minimum device API level is 26 (#1020)
BREAKING CHANGE: Assume the minimum device API level is 26
1 parent 7b72403 commit 142a353

File tree

10 files changed

+19
-169
lines changed

10 files changed

+19
-169
lines changed

lib/commands/device/utils.js

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -193,26 +193,10 @@ export async function pushSettingsApp(throwIfError) {
193193
return;
194194
}
195195

196-
const fixSettingsAppPermissionsForLegacyApis = async () => {
197-
if ((await this.adb.getApiLevel()) > 23) {
198-
return;
199-
}
200-
201-
// Android 6- devices should have granted permissions
202-
// https://github.com/appium/appium/pull/11640#issuecomment-438260477
203-
const perms = ['SET_ANIMATION_SCALE', 'CHANGE_CONFIGURATION', 'ACCESS_FINE_LOCATION'];
204-
this.log.info(`Granting permissions ${perms} to '${SETTINGS_HELPER_ID}'`);
205-
await this.adb.grantPermissions(
206-
SETTINGS_HELPER_ID,
207-
perms.map((x) => `android.permission.${x}`),
208-
);
209-
};
210-
211196
try {
212197
await B.all([
213198
this.settingsApp.adjustNotificationsPermissions(),
214199
this.settingsApp.adjustMediaProjectionServicePermissions(),
215-
fixSettingsAppPermissionsForLegacyApis(),
216200
]);
217201
} catch (e) {
218202
this.log.debug(e.stack);

lib/commands/geolocation.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,7 @@ export async function mobileResetGeolocation() {
152152
*/
153153
export async function setMockLocationApp(appId) {
154154
try {
155-
if ((await this.adb.getApiLevel()) < 23) {
156-
await this.adb.shell(['settings', 'put', 'secure', 'mock_location', '1']);
157-
} else {
158-
await this.adb.shell(['appops', 'set', appId, 'android:mock_location', 'allow']);
159-
}
155+
await this.adb.shell(['appops', 'set', appId, 'android:mock_location', 'allow']);
160156
} catch (err) {
161157
this.log.warn(`Unable to set mock location for app '${appId}': ${err.message}`);
162158
return;
@@ -192,11 +188,6 @@ export async function setMockLocationApp(appId) {
192188
*/
193189
async function resetMockLocation() {
194190
try {
195-
if ((await this.adb.getApiLevel()) < 23) {
196-
await this.adb.shell(['settings', 'put', 'secure', 'mock_location', '0']);
197-
return;
198-
}
199-
200191
const thirdPartyPkgIdsPromise = getThirdPartyPackages.bind(this)();
201192
let pkgIds = [];
202193
if (await this.adb.fileExists(MOCK_APP_IDS_STORE)) {

lib/commands/intent.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ const SUPPORTED_EXTRA_TYPES = [
2121
'sa',
2222
'sal',
2323
];
24-
const API_LEVEL_ANDROID_8 = 26;
2524

2625
/**
2726
* @deprecated
@@ -123,7 +122,7 @@ export async function mobileStartActivity(
123122
) {
124123
const cmd = [
125124
'am',
126-
(await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8 ? 'start' : 'start-activity',
125+
'start-activity',
127126
];
128127
if (!_.isNil(user)) {
129128
cmd.push('--user', String(user));
@@ -250,11 +249,7 @@ export async function mobileStartService(
250249
flags,
251250
) {
252251
const cmd = ['am'];
253-
if ((await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8) {
254-
cmd.push('startservice');
255-
} else {
256-
cmd.push(foreground ? 'start-foreground-service' : 'start-service');
257-
}
252+
cmd.push(foreground ? 'start-foreground-service' : 'start-service');
258253
if (!_.isNil(user)) {
259254
cmd.push('--user', String(user));
260255
}
@@ -303,7 +298,7 @@ export async function mobileStopService(
303298
) {
304299
const cmd = [
305300
'am',
306-
(await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8 ? 'stopservice' : 'stop-service',
301+
'stop-service',
307302
];
308303
if (!_.isNil(user)) {
309304
cmd.push('--user', String(user));

lib/commands/lock/helpers.js

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,6 @@ export function stringKeyToArr(key) {
159159
* @returns {Promise<void>}
160160
*/
161161
export async function fingerprintUnlock(capabilities) {
162-
if ((await this.adb.getApiLevel()) < 23) {
163-
throw new Error('Fingerprint unlock only works for Android 6+ emulators');
164-
}
165162
await this.adb.fingerprint(String(capabilities.unlockKey));
166163
await sleep(UNLOCK_WAIT_TIME);
167164
}
@@ -175,31 +172,19 @@ export async function pinUnlock(capabilities) {
175172
this.log.info(`Trying to unlock device using pin ${capabilities.unlockKey}`);
176173
await this.adb.dismissKeyguard();
177174
const keys = stringKeyToArr(String(capabilities.unlockKey));
178-
if ((await this.adb.getApiLevel()) >= 21) {
179-
const els = await this.findElOrEls('id', 'com.android.systemui:id/digit_text', true);
180-
if (_.isEmpty(els)) {
181-
// fallback to pin with key event
182-
return await pinUnlockWithKeyEvent.bind(this)(capabilities);
183-
}
184-
const pins = {};
185-
for (const el of els) {
186-
const text = await this.getAttribute('text', util.unwrapElement(el));
187-
pins[text] = el;
188-
}
189-
for (const pin of keys) {
190-
const el = pins[pin];
191-
await this.click(util.unwrapElement(el));
192-
}
193-
} else {
194-
for (const pin of keys) {
195-
let el;
196-
try {
197-
el = await this.findElOrEls('id', `com.android.keyguard:id/key${pin}`, false);
198-
} catch {
199-
return await pinUnlockWithKeyEvent.bind(this)(capabilities);
200-
}
201-
await this.click(util.unwrapElement(el));
202-
}
175+
const els = await this.findElOrEls('id', 'com.android.systemui:id/digit_text', true);
176+
if (_.isEmpty(els)) {
177+
// fallback to pin with key event
178+
return await pinUnlockWithKeyEvent.bind(this)(capabilities);
179+
}
180+
const pins = {};
181+
for (const el of els) {
182+
const text = await this.getAttribute('text', util.unwrapElement(el));
183+
pins[text] = el;
184+
}
185+
for (const pin of keys) {
186+
const el = pins[pin];
187+
await this.click(util.unwrapElement(el));
203188
}
204189
await waitForUnlock(this.adb);
205190
}

lib/commands/performance.js

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -161,32 +161,6 @@ function parseMeminfoForApi19To29(entries, valDict) {
161161
}
162162
}
163163

164-
/**
165-
* ['<System Type', '<pps>', '<shared dirty>', '<private dirty>', '<heap size>', '<heap alloc>', '<heap free>']
166-
* !!! valDict gets mutated
167-
*/
168-
function parseMeminfoForApiBelow19(entries, valDict) {
169-
const type = entries[0];
170-
if (type === MEMINFO_TITLES.NATIVE) {
171-
[
172-
,
173-
valDict.nativePss,
174-
,
175-
valDict.nativePrivateDirty,
176-
valDict.nativeHeapSize,
177-
valDict.nativeHeapAllocatedSize,
178-
] = entries;
179-
} else if (type === MEMINFO_TITLES.DALVIK) {
180-
[, valDict.dalvikPss, , valDict.dalvikPrivateDirty] = entries;
181-
} else if (type === MEMINFO_TITLES.EGL) {
182-
[, valDict.eglPss, , valDict.eglPrivateDirty] = entries;
183-
} else if (type === MEMINFO_TITLES.GL) {
184-
[, valDict.glPss, , valDict.glPrivateDirty] = entries;
185-
} else if (type === MEMINFO_TITLES.TOTAL) {
186-
[, valDict.totalPss, , valDict.totalPrivateDirty] = entries;
187-
}
188-
}
189-
190164
/**
191165
* API level 30 and above
192166
* ['<System Type>', '<Memory Type>', <pss total>, <private dirty>, <private clean>, <swapPss dirty>, <rss total>, <heap size>, <heap alloc>, <heap free>]
@@ -246,10 +220,8 @@ export async function getMemoryInfo(packageName, retries = 2) {
246220
const entries = line.trim().split(/\s+/).filter(Boolean);
247221
if (apiLevel >= 30) {
248222
parseMeminfoForApiAbove29(entries, valDict);
249-
} else if (apiLevel > 18 && apiLevel < 30) {
250-
parseMeminfoForApi19To29(entries, valDict);
251223
} else {
252-
parseMeminfoForApiBelow19(entries, valDict);
224+
parseMeminfoForApi19To29(entries, valDict);
253225
}
254226
}
255227
if (valDict.totalPrivateDirty && valDict.totalPrivateDirty !== 'nodex') {

lib/commands/recordscreen.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,6 @@ async function verifyScreenRecordIsSupported(adb, isEmulator) {
203203
`Screen recording does not work on emulators running Android API level less than ${MIN_EMULATOR_API_LEVEL}`,
204204
);
205205
}
206-
if (apiLevel < 19) {
207-
throw new Error(
208-
`Screen recording not available on API Level ${apiLevel}. Minimum API Level is 19.`,
209-
);
210-
}
211206
}
212207

213208
/**

test/unit/commands/geolocation-specs.js

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,7 @@ describe('Geolocation', function () {
2626
});
2727

2828
describe('setMockLocationApp', function () {
29-
it('should enable mock location for api level below 23', async function () {
30-
sandbox.stub(driver.adb, 'getApiLevel').resolves(18);
31-
sandbox.stub(driver.adb, 'shell')
32-
.withArgs(['settings', 'put', 'secure', 'mock_location', '1'])
33-
.onFirstCall()
34-
.returns('');
35-
sandbox.stub(driver.adb, 'fileExists').throws();
36-
await setMockLocationApp.bind(driver)('io.appium.settings');
37-
});
38-
it('should enable mock location for api level 23 and above', async function () {
39-
sandbox.stub(driver.adb, 'getApiLevel').resolves(23);
29+
it('should enable mock location', async function () {
4030
sandbox.stub(driver.adb, 'shell')
4131
.withArgs(['appops', 'set', 'io.appium.settings', 'android:mock_location', 'allow'])
4232
.onFirstCall()

test/unit/commands/lock-specs.js

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,6 @@ describe('Lock', function () {
9999
sandbox.stub(unlockHelpers, 'fingerprintUnlock').onFirstCall();
100100
await unlockWithOptions.bind(driver)({unlockType: 'fingerprint', unlockKey: '1111'});
101101
});
102-
it('should throw an error is api is lower than 23 and trying to use fingerprintUnlock', async function () {
103-
sandbox.stub(driver.adb, 'isScreenLocked').onCall(0).returns(true);
104-
sandbox.stub(driver.adb, 'isLockManagementSupported').onCall(0).returns(false);
105-
sandbox.stub(driver.adb, 'getApiLevel').onFirstCall().returns(21);
106-
await unlockWithOptions.bind(driver)({unlockType: 'fingerprint', unlockKey: '1111'})
107-
.should.be.rejectedWith('Fingerprint');
108-
});
109102
});
110103
describe('validateUnlockCapabilities', function () {
111104
function toCaps(unlockType, unlockKey) {
@@ -178,13 +171,6 @@ describe('Lock', function () {
178171
sandbox.stub(asyncboxHelpers, 'sleep').withArgs(UNLOCK_WAIT_TIME).onFirstCall();
179172
await fingerprintUnlock.bind(driver)(caps).should.be.fulfilled;
180173
});
181-
it('should throw error if API level < 23', async function () {
182-
sandbox.stub(driver.adb, 'getApiLevel').returns(22);
183-
sandbox.stub(driver.adb, 'fingerprint').throws();
184-
sandbox.stub(asyncboxHelpers, 'sleep').throws();
185-
await fingerprintUnlock.bind(driver)({})
186-
.should.eventually.be.rejectedWith('only works for Android 6+');
187-
});
188174
});
189175
describe('pinUnlock', function() {
190176
const caps = {unlockKey: '13579'};
@@ -223,28 +209,6 @@ describe('Lock', function () {
223209

224210
await pinUnlock.bind(driver)(caps);
225211

226-
driver.click.getCall(0).args[0].should.equal(1);
227-
driver.click.getCall(1).args[0].should.equal(3);
228-
driver.click.getCall(2).args[0].should.equal(5);
229-
driver.click.getCall(3).args[0].should.equal(7);
230-
driver.click.getCall(4).args[0].should.equal(9);
231-
});
232-
it('should be able to unlock device using pin (API level < 21)', async function () {
233-
sandbox.stub(driver.adb, 'dismissKeyguard').onFirstCall();
234-
sandbox.stub(unlockHelpers, 'stringKeyToArr').returns(keys);
235-
sandbox.stub(driver.adb, 'getApiLevel').returns(20);
236-
const findElOrElsStub = sandbox.stub(driver, 'findElOrEls');
237-
for (let pin of keys) {
238-
findElOrElsStub
239-
.withArgs('id', `com.android.keyguard:id/key${pin}`, false)
240-
.returns({ELEMENT: parseInt(pin, 10)});
241-
}
242-
sandbox.stub(driver.adb, 'isScreenLocked').returns(false);
243-
sandbox.stub(asyncboxHelpers, 'sleep').withArgs(UNLOCK_WAIT_TIME).onFirstCall();
244-
sandbox.stub(driver, 'click');
245-
246-
await pinUnlock.bind(driver)(caps);
247-
248212
driver.click.getCall(0).args[0].should.equal(1);
249213
driver.click.getCall(1).args[0].should.equal(3);
250214
driver.click.getCall(2).args[0].should.equal(5);

test/unit/commands/performance-specs.js

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,6 @@ describe('performance data', function () {
159159
GL mtrack 110 105 0 555 0 0 0
160160
TOTAL 555 555 555 0 555 555
161161
TOTAL 106 101 555 0 555 555 555`;
162-
const dumpsysDataAPI18 = `
163-
Shared Private Heap Heap Heap
164-
Pss Dirty Dirty Size Alloc Free
165-
------ ------ ------ ------ ------ ------
166-
Native 107 555 102 112 111 555
167-
Dalvik 108 555 103 555 555 555
168-
EGL 109 555 104 555 0 0
169-
GL 110 555 105 555 0 0
170-
TOTAL 106 555 101 555 555 555`;
171162
const expectedResult = [
172163
MEMORY_KEYS,
173164
[
@@ -220,12 +211,6 @@ describe('performance data', function () {
220211
(await getMemoryInfo.bind(driver)(PACKAGE_NAME)).should.be.deep.equal(expectedResult);
221212
asyncbox.retryInterval.calledWith(RETRY_COUNT, RETRY_PAUSE).should.be.true;
222213
});
223-
it('should return memory info for API<=18', async function () {
224-
adb.getApiLevel.returns(18);
225-
adb.shell.withArgs(shellArgs).returns(dumpsysDataAPI18);
226-
(await getMemoryInfo.bind(driver)(PACKAGE_NAME)).should.be.deep.equal(expectedResult);
227-
asyncbox.retryInterval.calledWith(RETRY_COUNT, RETRY_PAUSE).should.be.true;
228-
});
229214
it('should throw error if data is not valid', async function () {
230215
adb.shell.returns('TOTAL nodex nodex nodex nodex nodex nodex nodex');
231216
await getMemoryInfo

test/unit/commands/recordscreen-specs.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,6 @@ describe('recording the screen', function () {
2929
.startRecordingScreen()
3030
.should.be.rejectedWith(/Screen recording does not work on emulators/);
3131
});
32-
33-
it('should fail to recording the screen on a device with API level 18', async function () {
34-
mocks.driver.expects('isEmulator').returns(false);
35-
mocks.adb.expects('getApiLevel').returns(18);
36-
37-
await driver
38-
.startRecordingScreen()
39-
.should.be.rejectedWith(
40-
/Screen recording not available on API Level 18. Minimum API Level is 19/
41-
);
42-
});
4332
})
4433
);
4534
});

0 commit comments

Comments
 (0)