6.4.0 Pre - 新增 barcode/qrcode/shizuku 等模块; 适配高版本系统语言设置; 优化打包功能; 支持应用快捷方式; 修复屏幕旋转相关问题

This commit is contained in:
SuperMonster003
2023-10-25 14:15:44 +08:00
parent 5ee2f62d89
commit 4b64922a0b
194 changed files with 2723 additions and 1497 deletions

View File

@@ -10,11 +10,7 @@ let { autojs, shell, files, util } = global;
* @return {Internal.App}
*/
module.exports = function (scriptRuntime, scope) {
const File = java.io.File;
const Uri = android.net.Uri;
const JavaInteger = java.lang.Integer;
const FileProvider = androidx.core.content.FileProvider;
const AppUtils = org.autojs.autojs.runtime.api.AppUtils;
/**
* @type {org.autojs.autojs.runtime.api.AppUtils}

View File

@@ -0,0 +1,146 @@
// noinspection JSUnusedLocalSymbols,UnnecessaryLocalVariableJS
/* Overwritten protection. */
let { images } = global;
/**
* @param {ScriptRuntime} scriptRuntime
* @param {org.mozilla.javascript.Scriptable | global} scope
* @return {Internal.Barcode}
*/
module.exports = function (scriptRuntime, scope) {
let _ = {
BarcodeCtor: (/* @IIFE */ () => {
const instanceFunc = function __(img, options) {
if (typeof arguments[0] === 'string') {
let image = images.read(/* path = */ arguments[0]);
if (image === null) {
throw TypeError(`Invalid image of path "${arguments[0]}" for barcode(img, options?)`);
}
let args = [ image.oneShot() ].concat(Array.from(arguments).slice(1));
return BarcodeCtor.prototype.recognizeText.apply(BarcodeCtor.prototype, args);
}
return BarcodeCtor.prototype.recognizeText.apply(BarcodeCtor.prototype, arguments);
};
/**
* @implements Internal.Barcode
*/
const BarcodeCtor = function () {
let o = Object.assign(instanceFunc, BarcodeCtor.prototype);
Object.defineProperties(instanceFunc, Object.getOwnPropertyDescriptors(BarcodeCtor.prototype));
return o;
};
BarcodeCtor.prototype = {
constructor: BarcodeCtor,
recognizeTexts() {
let results = this.detectAll.apply(this, arguments);
return results.map(result => result.getRawValue()).filter(o => o !== null);
},
recognizeText() {
let results = this.recognizeTexts.apply(this, arguments);
if (_.shouldTakenAsAll(arguments)) {
return results;
}
return results.length > 0 ? results[0] : null;
},
/**
* @returns {Internal.Barcode.Result[]}
*/
detectAll() {
if (typeof arguments[0] === 'string') {
// @Signature
// detectAll(imgPath: string): Barcode.Result[];
// detectAll(imgPath: string, options: DetectOptionsWithoutIsAll): Barcode.Result[];
let img = images.read(/* path = */ arguments[0]);
if (img === null) {
throw TypeError(`Invalid image of path "${arguments[0]}" for barcode.detectAll(img, options?)`);
}
// @Overload
// detectAll(img: ImageWrapper): Barcode.Result[];
// detectAll(img: ImageWrapper, options: DetectOptionsWithoutIsAll): Barcode.Result[];
return this.detectAll(img.oneShot(), arguments[1]);
}
if (!(arguments[0] instanceof ImageWrapper)) {
// @Signature detectAll(options?: DetectOptionsWithoutIsAll): Barcode.Result[];
// @Overload detectAll(img: ImageWrapper, options?: DetectOptionsWithoutIsAll): Barcode.Result[];
return this.detectAll.apply(this, [ images.captureScreen() ].concat(Array.from(arguments)));
}
// @Signature detectAll(img: ImageWrapper, options?: DetectOptionsWithoutIsAll): Barcode.Result[];
let img = arguments[0];
/** @type {Internal.Barcode.DetectOptionsWithoutIsAll} */
let opt = /* options */ arguments[1] || {};
let formats = (() => {
if (isNullish(opt.format)) {
return [];
}
let results = Array.isArray(opt.format) ? opt.format : [ opt.format ];
let transformer = {
FORMAT_QRCODE: 'FORMAT_QR_CODE',
};
return results.map((result) => {
if (typeof result === 'number') {
return result;
}
if (typeof result === 'string') {
let tmp = result.toUpperCase().replace(/\W+/g, '_');
let prefix = 'FORMAT_';
if (!result.startsWith(prefix)) {
tmp = prefix + tmp;
}
if (tmp in transformer) {
tmp = transformer[tmp];
}
return com.google.mlkit.vision.barcode.common.Barcode[tmp];
}
throw TypeError(`Unknown format (value: ${result}, species: ${species(result)}) for barcode`);
});
})();
let enableAllPotentialBarcodes = Boolean(opt.enableAllPotentialBarcodes);
// noinspection JSValidateTypes
return scriptRuntime.barcode.detect(img, formats, enableAllPotentialBarcodes);
},
detect() {
let results = this.detectAll.apply(this, arguments);
if (_.shouldTakenAsAll(arguments)) {
return results;
}
return results.length > 0 ? results[0] : null;
},
};
return BarcodeCtor;
})(),
/**
* @param {IArguments} args
* @returns {boolean}
*/
shouldTakenAsAll(args) {
if (args.length === 0) {
return false;
}
/**
* @type {Internal.Barcode.DetectOptions | boolean | OmniRegion}
*/
let arg = args[args.length - 1];
return arg === true || isObject(arg) && Boolean(arg.isAll);
},
};
/**
* @type {Internal.Barcode}
*/
const barcode = new _.BarcodeCtor();
return barcode;
};

View File

@@ -638,7 +638,7 @@ module.exports = function (scriptRuntime, scope) {
if (alphaMatters === true) {
return this.toInt(colorA) === this.toInt(colorB);
}
throw TypeError(`Invalid argument isStrict (value: ${alphaMatters}, type: ${species(alphaMatters)}) for colors.isEqual`);
throw TypeError(`Invalid argument isStrict (value: ${alphaMatters}, species: ${species(alphaMatters)}) for colors.isEqual`);
},
/**
* Get a ColorStateList containing a single color or more.

View File

@@ -71,7 +71,7 @@ module.exports = function (scriptRuntime, scope) {
setEngineExecArgv() {
engines.myEngine().setExecArgv(/* @IIFE */ ((e) => {
let execArgv = {};
let iterator = e.getTag(ExecutionConfig.CREATOR.getTag()).arguments.entrySet().iterator();
let iterator = e.getTag(ExecutionConfig.tag).arguments.entrySet().iterator();
while (iterator.hasNext()) {
let entry = iterator.next();
execArgv[entry.getKey()] = entry.getValue();

View File

@@ -49,6 +49,9 @@ module.exports = function (scriptRuntime, scope) {
Images.prototype = {
constructor: Images,
captureScreen(path) {
if (rtImages.getScreenCapturer() === null) {
this.requestScreenCapture();
}
return path === undefined
? rtImages.captureScreen()
: rtImages.captureScreen(path);

View File

@@ -40,7 +40,7 @@ module.exports = function (scriptRuntime, scope) {
enumerable: true, /* Emphasis. */
};
const instanceFunc = function (img, options) {
const instanceFunc = function __(img, options) {
if (typeof arguments[0] === 'string') {
let img = images.read(/* path = */ arguments[0]);
if (img === null) {
@@ -87,7 +87,7 @@ module.exports = function (scriptRuntime, scope) {
// @Signature
// recognizeText(imgPath: string, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
// recognizeText(imgPath: string, region: Images.Options.Region): string[];
// recognizeText(imgPath: string, region: OmniRegion): string[];
let img = images.read(/* path = */ arguments[0]);
if (img === null) {
@@ -95,12 +95,25 @@ module.exports = function (scriptRuntime, scope) {
}
// @Overload
// recognizeText(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
// recognizeText(img: ImageWrapper, region: Images.Options.Region): string[];
// recognizeText(img: ImageWrapper, region: OmniRegion): string[];
return this.recognizeText(img.oneShot(), arguments[1]);
}
if (!(arguments[0] instanceof ImageWrapper)) {
// @Signature
// recognizeText(options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
// recognizeText(region: OmniRegion): string[];
// @Overload
// recognizeText(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
// recognizeText(img: ImageWrapper, region: OmniRegion): string[];
return this.recognizeText.apply(this, [ images.captureScreen() ].concat(Array.from(arguments)));
}
if (_.shouldTakenAsRegion(arguments[1])) {
// @Signature recognizeText(img: ImageWrapper, region: Images.Options.Region): string[];
// @Signature recognizeText(img: ImageWrapper, region: OmniRegion): string[];
// @Overload recognizeText(img: ImageWrapper, options: DetectOptionsMLKit | DetectOptionsPaddle): string[];
return this.recognizeText(img, { region: arguments[1] });
@@ -144,7 +157,7 @@ module.exports = function (scriptRuntime, scope) {
// @Signature
// detect(imgPath: string, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
// detect(imgPath: string, region: Images.Options.Region): org.autojs.autojs.runtime.api.OcrResult[];
// detect(imgPath: string, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
let img = images.read(/* path = */ arguments[0]);
if (img === null) {
@@ -152,12 +165,25 @@ module.exports = function (scriptRuntime, scope) {
}
// @Overload
// detect(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
// detect(img: ImageWrapper, region: Images.Options.Region): org.autojs.autojs.runtime.api.OcrResult[];
// detect(img: ImageWrapper, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
return this.detect(img.oneShot(), arguments[1]);
}
if (!(arguments[0] instanceof ImageWrapper)) {
// @Signature
// detect(options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
// detect(region: OmniRegion): string[];
// @Overload
// detect(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
// detect(img: ImageWrapper, region: OmniRegion): string[];
return this.detect.apply(this, [ images.captureScreen() ].concat(Array.from(arguments)));
}
if (_.shouldTakenAsRegion(arguments[1])) {
// @Signature detect(img: ImageWrapper, region: Images.Options.Region): org.autojs.autojs.runtime.api.OcrResult[];
// @Signature detect(img: ImageWrapper, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
// @Overload detect(img: ImageWrapper, options: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
return this.detect(img, { region: arguments[1] });

View File

@@ -0,0 +1,121 @@
// noinspection JSUnusedLocalSymbols,UnnecessaryLocalVariableJS
/* Overwritten protection. */
let { images, qrcode } = global;
/**
* @param {ScriptRuntime} scriptRuntime
* @param {org.mozilla.javascript.Scriptable | global} scope
* @return {Internal.QrCode}
*/
module.exports = function (scriptRuntime, scope) {
let _ = {
QrCodeCtor: (/* @IIFE */ () => {
const instanceFunc = function __(img, options) {
if (typeof arguments[0] === 'string') {
let image = images.read(/* path = */ arguments[0]);
if (image === null) {
throw TypeError(`Invalid image of path "${arguments[0]}" for qrcode(img, options?)`);
}
let args = [ image.oneShot() ].concat(Array.from(arguments).slice(1));
return QrCodeCtor.prototype.recognizeText.apply(QrCodeCtor.prototype, args);
}
return QrCodeCtor.prototype.recognizeText.apply(QrCodeCtor.prototype, arguments);
};
/**
* @implements Internal.QrCode
*/
const QrCodeCtor = function () {
let o = Object.assign(instanceFunc, QrCodeCtor.prototype);
Object.defineProperties(instanceFunc, Object.getOwnPropertyDescriptors(QrCodeCtor.prototype));
return o;
};
QrCodeCtor.prototype = {
constructor: QrCodeCtor,
recognizeTexts() {
let results = this.detectAll.apply(this, arguments);
return results.map(result => result.getRawValue()).filter(o => o !== null);
},
recognizeText() {
let results = this.recognizeTexts.apply(this, arguments);
if (_.shouldTakenAsAll(arguments)) {
return results;
}
return results.length > 0 ? results[0] : null;
},
/**
* @returns {Internal.Barcode.Result[]}
*/
detectAll() {
if (typeof arguments[0] === 'string') {
// @Signature
// detectAll(imgPath: string): QrCode.Result[];
// detectAll(imgPath: string, options: DetectOptionsWithoutIsAll): QrCode.Result[];
let img = images.read(/* path = */ arguments[0]);
if (img === null) {
throw TypeError(`Invalid image of path "${arguments[0]}" for qrcode.detectAll(img, options?)`);
}
// @Overload
// detectAll(img: ImageWrapper): QrCode.Result[];
// detectAll(img: ImageWrapper, options: DetectOptionsWithoutIsAll): QrCode.Result[];
return this.detectAll(img.oneShot(), arguments[1]);
}
if (!(arguments[0] instanceof ImageWrapper)) {
// @Signature detectAll(options?: DetectOptionsWithoutIsAll): QrCode.Result[];
// @Overload detectAll(img: ImageWrapper, options?: DetectOptionsWithoutIsAll): QrCode.Result[];
return this.detectAll.apply(this, [ images.captureScreen() ].concat(Array.from(arguments)));
}
// @Signature detectAll(img: ImageWrapper, options?: DetectOptionsWithoutIsAll): QrCode.Result[];
let img = arguments[0];
/** @type {Internal.QrCode.DetectOptionsWithoutIsAll} */
let opt = /* options */ arguments[1] || {};
let enableAllPotentialBarcodes = Boolean(opt.enableAllPotentialBarcodes);
let formats = [ com.google.mlkit.vision.barcode.common.Barcode.FORMAT_QR_CODE ];
// noinspection JSValidateTypes
return scriptRuntime.barcode.detect(img, formats, enableAllPotentialBarcodes);
},
detect() {
let results = this.detectAll.apply(this, arguments);
if (_.shouldTakenAsAll(arguments)) {
return results;
}
return results.length > 0 ? results[0] : null;
},
};
return QrCodeCtor;
})(),
/**
* @param {IArguments} args
* @returns {boolean}
*/
shouldTakenAsAll(args) {
if (args.length === 0) {
return false;
}
/**
* @type {Internal.QrCode.DetectOptions | boolean | OmniRegion}
*/
let arg = args[args.length - 1];
return arg === true || isObject(arg) && Boolean(arg.isAll);
},
};
/**
* @type {Internal.QrCode}
*/
const qrcode = new _.QrCodeCtor();
return qrcode;
};

View File

@@ -0,0 +1,45 @@
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
/**
* @param {ScriptRuntime} scriptRuntime
* @param {org.mozilla.javascript.Scriptable | global} scope
* @return {Internal.Shizuku}
*/
module.exports = function (scriptRuntime, scope) {
const rtShizuku = scriptRuntime.shizuku;
let _ = {
ShizukuCtor: (/* @IIFE */ () => {
/**
* @implements Internal.Shizuku
*/
const ShizukuCtor = function () {
/** @global */
const shizuku = function (cmd) {
return rtShizuku.execCommand(cmd);
};
return Object.assign(shizuku, ShizukuCtor.prototype);
};
ShizukuCtor.prototype = {
constructor: ShizukuCtor,
ensureService() {
rtShizuku.ensureService();
},
execCommand() {
return rtShizuku.execCommand.apply(rtShizuku, arguments);
},
};
return ShizukuCtor;
})(),
};
/**
* @type {Internal.Shizuku}
*/
const shizuku = new _.ShizukuCtor();
return shizuku;
};

View File

@@ -1,86 +1,113 @@
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
// noinspection JSUnusedLocalSymbols,UnnecessaryLocalVariableJS
/**
* @param {ScriptRuntime} scriptRuntime
* @param {org.autojs.autojs.runtime.ScriptRuntime} scriptRuntime
* @param {org.mozilla.javascript.Scriptable | global} scope
* @return {Internal.Toast}
*/
module.exports = function (scriptRuntime, scope) {
let rtToast = scriptRuntime.toast;
const ScriptToast = org.autojs.autojs.runtime.api.ScriptToast;
let _ = {
uiHandler: runtime.getUiHandler(),
ToastCtor: (/* @IIFE */ () => {
/**
* @implements Internal.Toast
*/
const Ctor = function () {
const ToastCtor = function () {
// @Caution by SuperMonster003 on Oct 11, 2022.
// ! android.widget.Toast.makeText() doesn't work well on Android API Level 28 (Android 9) [P].
// ! There hasn't been a solution for this so far.
// ! Tested devices:
// ! 1. SONY XPERIA XZ1 Compact (G8441)
// ! 2. Android Studio AVD (Android 9.0 x86)
/** @global */
const instance = function (msg, isLong, isForcible) {
const toast = function (msg, isLong, isForcible) {
let $ = {
badge: {
long: /^l(ong)?$/i,
short: /^s(hort)?$/i,
forcible: /^f(orcible)?$/i,
},
toast() {
this.init(arguments);
this.show();
},
init() {
this.message = isNullish(msg) ? '' : String(msg);
this.isForcible = this.parseIsForcible(isForcible);
this.isLong = this.parseIsLong(isLong);
this.isForcible = this.parseIsForcible(isForcible);
},
parseIsLong(isLong) {
if (typeof isLong === 'boolean') {
return isLong;
parseIsLong(o) {
let def = typeof this.isLong === 'boolean' ? this.isLong : false;
if (typeof o === 'boolean') {
return o;
}
if (typeof isLong === 'number') {
return Boolean(isLong);
if (typeof o === 'number') {
return Boolean(o);
}
if (typeof isLong === 'string') {
if (this.badge.long.test(isLong)) {
if (typeof o === 'string') {
if (this.badge.long.test(o)) {
return true;
}
if (this.badge.short.test(isLong)) {
if (this.badge.short.test(o)) {
return false;
}
if (this.badge.forcible.test(isLong)) {
if (this.badge.forcible.test(o)) {
this.isForcible = true;
return false;
return def;
}
throw Error(`Invalid param: {name: isLong, value: ${isLong}, type: ${species(isLong)}.`);
throw Error(`Invalid param: {name: isLong, value: ${o}, type: ${species(o)}.`);
}
return false;
return def;
},
parseIsForcible(isForcible) {
if (typeof isForcible === 'boolean') {
return isForcible;
parseIsForcible(o) {
let def = typeof this.isForcible === 'boolean' ? this.isForcible : false;
if (typeof o === 'boolean') {
return o;
}
if (typeof isForcible === 'number') {
return Boolean(isForcible);
if (typeof o === 'number') {
return Boolean(o);
}
if (typeof isForcible === 'string') {
if (this.badge.forcible.test(isForcible)) {
if (typeof o === 'string') {
if (this.badge.forcible.test(o)) {
return true;
}
throw Error(`Invalid param: {name: isForcible, value: ${isForcible}, type: ${species(isForcible)}.`);
if (this.badge.long.test(o)) {
this.isLong = true;
return def;
}
if (this.badge.short.test(o)) {
this.isLong = false;
return def;
}
throw Error(`Invalid param: {name: isForcible, value: ${o}, type: ${species(o)}.`);
}
return false;
return def;
},
makeToast() {
rtToast.makeToast(this.message, this.isLong, this.isForcible);
show() {
if ($.isForcible) {
ToastCtor.prototype.dismissAll();
}
scriptRuntime.uiHandler.toast($.message, $.isLong);
},
};
$.init();
$.makeToast();
$.toast();
};
return Object.assign(instance, Ctor.prototype);
return Object.assign(toast, ToastCtor.prototype);
};
Ctor.prototype = {
constructor: Ctor,
dismissAll: () => rtToast.dismissAll(),
ToastCtor.prototype = {
constructor: ToastCtor,
dismissAll() {
runtime.uiHandler.dismissAllToasts();
},
};
return Ctor;
return ToastCtor;
})(),
};

View File

@@ -317,7 +317,7 @@ module.exports = function (scriptRuntime, scope) {
})();
},
afterApplyAttribute(context, inflater, view, ns, attrName, value, parent) {
// Empty method body
/* Empty body. */
},
afterApplyAttributes(context, view, inflater, attrs, parent) {
context.remove('widget');
@@ -326,13 +326,13 @@ module.exports = function (scriptRuntime, scope) {
return false;
},
afterInflateChildren(context, inflater, node, parent) {
// Empty method body
/* Empty body. */
},
beforeApplyPendingAttributesOfChildren(context, inflater, view) {
return false;
},
afterApplyPendingAttributesOfChildren(context, inflater, view) {
// Empty method body
/* Empty body. */
},
afterInflateView(context, view, node, parent, attachToParent) {
let { widget } = view;

View File

@@ -15,12 +15,16 @@ module.exports = function (scriptRuntime, scope) {
* @implements Internal.OcrMLKit
*/
const OcrMLKitCtor = function () {
return Object.assign(function () {
let instanceFunc = function __() {
let argArray = Array.from(arguments);
if (arguments.length === 0 || !(arguments[0] instanceof ImageWrapper)) {
return __.apply(this, [ images.captureScreen() ].concat(argArray));
}
/** @type {Internal.Ocr.ModeName} */
argArray[ocr['_forcibleModeArgIndex']] = ocr['_modeName']['mlkit'];
return ocr.recognizeText.apply(ocr, argArray);
}, OcrMLKitCtor.prototype);
};
return Object.assign(instanceFunc, OcrMLKitCtor.prototype);
};
OcrMLKitCtor.prototype = {

View File

@@ -15,12 +15,16 @@ module.exports = function (scriptRuntime, scope) {
* @implements Internal.OcrPaddle
*/
const OcrPaddleCtor = function () {
return Object.assign(function () {
const instanceFunc = function __() {
let argArray = Array.from(arguments);
if (arguments.length === 0 || !(arguments[0] instanceof ImageWrapper)) {
return __.apply(this, [ images.captureScreen() ].concat(argArray));
}
/** @type {Internal.Ocr.ModeName} */
argArray[ocr['_forcibleModeArgIndex']] = ocr['_modeName']['paddle'];
return ocr.recognizeText.apply(ocr, argArray);
}, OcrPaddleCtor.prototype);
};
return Object.assign(instanceFunc, OcrPaddleCtor.prototype);
};
OcrPaddleCtor.prototype = {