@elizaos/capacitor-system 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxActivityVersion = project.hasProperty('androidxActivityVersion') ? rootProject.ext.androidxActivityVersion : '1.8.0'
4
+ }
5
+
6
+ apply plugin: 'com.android.library'
7
+ android {
8
+ namespace = "ai.eliza.plugins.system"
9
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
10
+ defaultConfig {
11
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
12
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
13
+ }
14
+ compileOptions {
15
+ sourceCompatibility JavaVersion.VERSION_17
16
+ targetCompatibility JavaVersion.VERSION_17
17
+ }
18
+ }
19
+
20
+ repositories {
21
+ google()
22
+ maven { url = uri(rootProject.ext.mavenCentralMirrorUrl) }
23
+ mavenCentral()
24
+ }
25
+
26
+ dependencies {
27
+ implementation project(':capacitor-android')
28
+ implementation "androidx.activity:activity:$androidxActivityVersion"
29
+ }
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" />
@@ -0,0 +1,146 @@
1
+ package ai.eliza.plugins.system
2
+
3
+ import android.app.role.RoleManager
4
+ import android.content.ComponentName
5
+ import android.content.Context
6
+ import android.content.Intent
7
+ import android.os.Build
8
+ import android.provider.Settings
9
+ import android.provider.Telephony
10
+ import android.telecom.TelecomManager
11
+ import androidx.activity.result.ActivityResult
12
+ import com.getcapacitor.JSArray
13
+ import com.getcapacitor.JSObject
14
+ import com.getcapacitor.Plugin
15
+ import com.getcapacitor.PluginCall
16
+ import com.getcapacitor.PluginMethod
17
+ import com.getcapacitor.annotation.ActivityCallback
18
+ import com.getcapacitor.annotation.CapacitorPlugin
19
+
20
+ @CapacitorPlugin(name = "ElizaSystem")
21
+ class SystemPlugin : Plugin() {
22
+ private val roleMap = mapOf(
23
+ "home" to RoleManager.ROLE_HOME,
24
+ "dialer" to RoleManager.ROLE_DIALER,
25
+ "sms" to RoleManager.ROLE_SMS,
26
+ "assistant" to RoleManager.ROLE_ASSISTANT
27
+ )
28
+
29
+ @PluginMethod
30
+ fun getStatus(call: PluginCall) {
31
+ val result = JSObject()
32
+ val roles = JSArray()
33
+ result.put("packageName", context.packageName)
34
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
35
+ val roleManager = context.getSystemService(Context.ROLE_SERVICE) as RoleManager
36
+ for ((name, androidRole) in roleMap) {
37
+ val role = JSObject()
38
+ val available = roleManager.isRoleAvailable(androidRole)
39
+ val holders = if (available) roleHolders(name) else emptyList()
40
+ val held = holders.contains(context.packageName)
41
+ role.put("role", name)
42
+ role.put("androidRole", androidRole)
43
+ role.put("available", available)
44
+ role.put("held", held)
45
+ role.put("holders", JSArray(holders))
46
+ roles.put(role)
47
+ }
48
+ }
49
+ result.put("roles", roles)
50
+ call.resolve(result)
51
+ }
52
+
53
+ @PluginMethod
54
+ fun requestRole(call: PluginCall) {
55
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
56
+ call.reject("Android role requests require Android 10 or newer")
57
+ return
58
+ }
59
+
60
+ val roleName = call.getString("role")?.trim()
61
+ val androidRole = roleMap[roleName]
62
+ if (roleName.isNullOrEmpty() || androidRole == null) {
63
+ call.reject("role must be one of ${roleMap.keys.joinToString(", ")}")
64
+ return
65
+ }
66
+
67
+ val roleManager = context.getSystemService(Context.ROLE_SERVICE) as RoleManager
68
+ if (!roleManager.isRoleAvailable(androidRole)) {
69
+ call.reject("$androidRole is not available on this device")
70
+ return
71
+ }
72
+
73
+ if (roleManager.isRoleHeld(androidRole)) {
74
+ call.resolve(roleRequestResult(roleName, true, 0))
75
+ return
76
+ }
77
+
78
+ startActivityForResult(
79
+ call,
80
+ roleManager.createRequestRoleIntent(androidRole),
81
+ "handleRoleRequestResult"
82
+ )
83
+ }
84
+
85
+ @ActivityCallback
86
+ private fun handleRoleRequestResult(call: PluginCall, result: ActivityResult) {
87
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
88
+ call.reject("Android role requests require Android 10 or newer")
89
+ return
90
+ }
91
+
92
+ val roleName = call.getString("role")?.trim()
93
+ val androidRole = roleMap[roleName]
94
+ if (roleName.isNullOrEmpty() || androidRole == null) {
95
+ call.reject("role must be one of ${roleMap.keys.joinToString(", ")}")
96
+ return
97
+ }
98
+
99
+ val roleManager = context.getSystemService(Context.ROLE_SERVICE) as RoleManager
100
+ call.resolve(roleRequestResult(roleName, roleManager.isRoleHeld(androidRole), result.resultCode))
101
+ }
102
+
103
+ private fun roleHolders(name: String): List<String> {
104
+ return when (name) {
105
+ "home" -> listOfNotNull(resolveHomePackage())
106
+ "dialer" -> listOfNotNull(resolveDefaultDialerPackage())
107
+ "sms" -> listOfNotNull(Telephony.Sms.getDefaultSmsPackage(context))
108
+ "assistant" -> listOfNotNull(resolveAssistantPackage())
109
+ else -> emptyList()
110
+ }
111
+ }
112
+
113
+ private fun resolveHomePackage(): String? {
114
+ val intent = Intent(Intent.ACTION_MAIN)
115
+ intent.addCategory(Intent.CATEGORY_HOME)
116
+ val resolved = context.packageManager.resolveActivity(intent, 0)
117
+ return resolved?.activityInfo?.packageName
118
+ }
119
+
120
+ private fun resolveDefaultDialerPackage(): String? {
121
+ val telecom = context.getSystemService(Context.TELECOM_SERVICE) as? TelecomManager
122
+ return telecom?.defaultDialerPackage
123
+ }
124
+
125
+ private fun resolveAssistantPackage(): String? {
126
+ val flattened = Settings.Secure.getString(context.contentResolver, "assistant")
127
+ if (flattened.isNullOrBlank()) return null
128
+ return ComponentName.unflattenFromString(flattened)?.packageName
129
+ }
130
+
131
+ private fun roleRequestResult(roleName: String, held: Boolean, resultCode: Int): JSObject {
132
+ val result = JSObject()
133
+ result.put("role", roleName)
134
+ result.put("held", held)
135
+ result.put("resultCode", resultCode)
136
+ return result
137
+ }
138
+
139
+ @PluginMethod
140
+ fun openSettings(call: PluginCall) {
141
+ val intent = Intent(Settings.ACTION_SETTINGS)
142
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
143
+ context.startActivity(intent)
144
+ call.resolve()
145
+ }
146
+ }
@@ -0,0 +1,25 @@
1
+ export type AndroidRoleName = "home" | "dialer" | "sms" | "assistant";
2
+ export interface AndroidRoleStatus {
3
+ role: AndroidRoleName;
4
+ androidRole: string;
5
+ held: boolean;
6
+ holders: string[];
7
+ available: boolean;
8
+ }
9
+ export interface SystemStatus {
10
+ packageName: string;
11
+ roles: AndroidRoleStatus[];
12
+ }
13
+ export interface AndroidRoleRequestResult {
14
+ role: AndroidRoleName;
15
+ held: boolean;
16
+ resultCode: number;
17
+ }
18
+ export interface SystemPlugin {
19
+ getStatus(): Promise<SystemStatus>;
20
+ requestRole(options: {
21
+ role: AndroidRoleName;
22
+ }): Promise<AndroidRoleRequestResult>;
23
+ openSettings(): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,WAAW,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IACnC,WAAW,CAAC,OAAO,EAAE;QACnB,IAAI,EAAE,eAAe,CAAC;KACvB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACtC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { SystemPlugin } from "./definitions";
2
+ export * from "./definitions";
3
+ export declare const System: SystemPlugin;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,cAAc,eAAe,CAAC;AAI9B,eAAO,MAAM,MAAM,cAEjB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { registerPlugin } from "@capacitor/core";
2
+ export * from "./definitions";
3
+ const loadWeb = () => import("./web").then((m) => new m.SystemWeb());
4
+ export const System = registerPlugin("ElizaSystem", {
5
+ web: loadWeb,
6
+ });
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,cAAc,eAAe,CAAC;AAE9B,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,MAAM,GAAG,cAAc,CAAe,aAAa,EAAE;IAChE,GAAG,EAAE,OAAO;CACb,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { WebPlugin } from "@capacitor/core";
2
+ import type { AndroidRoleName, AndroidRoleRequestResult, SystemPlugin, SystemStatus } from "./definitions";
3
+ export declare class SystemWeb extends WebPlugin implements SystemPlugin {
4
+ getStatus(): Promise<SystemStatus>;
5
+ openSettings(): Promise<void>;
6
+ requestRole(options: {
7
+ role: AndroidRoleName;
8
+ }): Promise<AndroidRoleRequestResult>;
9
+ }
10
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,YAAY,EACb,MAAM,eAAe,CAAC;AAEvB,qBAAa,SAAU,SAAQ,SAAU,YAAW,YAAY;IACxD,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;IAOlC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B,WAAW,CAAC,OAAO,EAAE;QACzB,IAAI,EAAE,eAAe,CAAC;KACvB,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAKtC"}
@@ -0,0 +1,16 @@
1
+ import { WebPlugin } from "@capacitor/core";
2
+ export class SystemWeb extends WebPlugin {
3
+ async getStatus() {
4
+ return {
5
+ packageName: "web",
6
+ roles: [],
7
+ };
8
+ }
9
+ async openSettings() {
10
+ throw new Error("System settings are only available on Android.");
11
+ }
12
+ async requestRole(options) {
13
+ throw new Error(`Android role ${options.role} is only available on Android.`);
14
+ }
15
+ }
16
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAS5C,MAAM,OAAO,SAAU,SAAQ,SAAS;IACtC,KAAK,CAAC,SAAS;QACb,OAAO;YACL,WAAW,EAAE,KAAK;YAClB,KAAK,EAAE,EAAE;SACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAEjB;QACC,MAAM,IAAI,KAAK,CACb,gBAAgB,OAAO,CAAC,IAAI,gCAAgC,CAC7D,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const loadWeb = () => Promise.resolve().then(function () { return web; }).then((m) => new m.SystemWeb());
6
+ const System = core.registerPlugin("ElizaSystem", {
7
+ web: loadWeb,
8
+ });
9
+
10
+ class SystemWeb extends core.WebPlugin {
11
+ async getStatus() {
12
+ return {
13
+ packageName: "web",
14
+ roles: [],
15
+ };
16
+ }
17
+ async openSettings() {
18
+ throw new Error("System settings are only available on Android.");
19
+ }
20
+ async requestRole(options) {
21
+ throw new Error(`Android role ${options.role} is only available on Android.`);
22
+ }
23
+ }
24
+
25
+ var web = /*#__PURE__*/Object.freeze({
26
+ __proto__: null,
27
+ SystemWeb: SystemWeb
28
+ });
29
+
30
+ exports.System = System;
31
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\nexport * from \"./definitions\";\nconst loadWeb = () => import(\"./web\").then((m) => new m.SystemWeb());\nexport const System = registerPlugin(\"ElizaSystem\", {\n web: loadWeb,\n});\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nexport class SystemWeb extends WebPlugin {\n async getStatus() {\n return {\n packageName: \"web\",\n roles: [],\n };\n }\n async openSettings() {\n throw new Error(\"System settings are only available on Android.\");\n }\n async requestRole(options) {\n throw new Error(`Android role ${options.role} is only available on Android.`);\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AAEA,MAAM,OAAO,GAAG,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;AACxD,MAAC,MAAM,GAAGA,mBAAc,CAAC,aAAa,EAAE;AACpD,IAAI,GAAG,EAAE,OAAO;AAChB,CAAC;;ACJM,MAAM,SAAS,SAASC,cAAS,CAAC;AACzC,IAAI,MAAM,SAAS,GAAG;AACtB,QAAQ,OAAO;AACf,YAAY,WAAW,EAAE,KAAK;AAC9B,YAAY,KAAK,EAAE,EAAE;AACrB,SAAS;AACT,IAAI;AACJ,IAAI,MAAM,YAAY,GAAG;AACzB,QAAQ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC;AACzE,IAAI;AACJ,IAAI,MAAM,WAAW,CAAC,OAAO,EAAE;AAC/B,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;AACrF,IAAI;AACJ;;;;;;;;;"}
package/dist/plugin.js ADDED
@@ -0,0 +1,34 @@
1
+ var capacitorSystem = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const loadWeb = () => Promise.resolve().then(function () { return web; }).then((m) => new m.SystemWeb());
5
+ const System = core.registerPlugin("ElizaSystem", {
6
+ web: loadWeb,
7
+ });
8
+
9
+ class SystemWeb extends core.WebPlugin {
10
+ async getStatus() {
11
+ return {
12
+ packageName: "web",
13
+ roles: [],
14
+ };
15
+ }
16
+ async openSettings() {
17
+ throw new Error("System settings are only available on Android.");
18
+ }
19
+ async requestRole(options) {
20
+ throw new Error(`Android role ${options.role} is only available on Android.`);
21
+ }
22
+ }
23
+
24
+ var web = /*#__PURE__*/Object.freeze({
25
+ __proto__: null,
26
+ SystemWeb: SystemWeb
27
+ });
28
+
29
+ exports.System = System;
30
+
31
+ return exports;
32
+
33
+ })({}, capacitorExports);
34
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\nexport * from \"./definitions\";\nconst loadWeb = () => import(\"./web\").then((m) => new m.SystemWeb());\nexport const System = registerPlugin(\"ElizaSystem\", {\n web: loadWeb,\n});\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nexport class SystemWeb extends WebPlugin {\n async getStatus() {\n return {\n packageName: \"web\",\n roles: [],\n };\n }\n async openSettings() {\n throw new Error(\"System settings are only available on Android.\");\n }\n async requestRole(options) {\n throw new Error(`Android role ${options.role} is only available on Android.`);\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;IAEA,MAAM,OAAO,GAAG,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;AACxD,UAAC,MAAM,GAAGA,mBAAc,CAAC,aAAa,EAAE;IACpD,IAAI,GAAG,EAAE,OAAO;IAChB,CAAC;;ICJM,MAAM,SAAS,SAASC,cAAS,CAAC;IACzC,IAAI,MAAM,SAAS,GAAG;IACtB,QAAQ,OAAO;IACf,YAAY,WAAW,EAAE,KAAK;IAC9B,YAAY,KAAK,EAAE,EAAE;IACrB,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,YAAY,GAAG;IACzB,QAAQ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC;IACzE,IAAI;IACJ,IAAI,MAAM,WAAW,CAAC,OAAO,EAAE;IAC/B,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACrF,IAAI;IACJ;;;;;;;;;;;;;;;"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@elizaos/capacitor-system",
3
+ "version": "1.0.0",
4
+ "description": "Android system-role status bridge for ElizaOS.",
5
+ "main": "./dist/plugin.cjs.js",
6
+ "module": "./dist/esm/index.js",
7
+ "types": "./dist/esm/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/esm/index.d.ts",
11
+ "import": "./dist/esm/index.js",
12
+ "require": "./dist/plugin.cjs.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "android/src/main/",
18
+ "android/build.gradle",
19
+ "dist/"
20
+ ],
21
+ "scripts": {
22
+ "build": "npm run clean && tsc && rollup -c rollup.config.mjs",
23
+ "clean": "rimraf ./dist",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "license": "MIT",
27
+ "capacitor": {
28
+ "android": {
29
+ "src": "android"
30
+ }
31
+ },
32
+ "devDependencies": {
33
+ "@capacitor/cli": "^8.0.0",
34
+ "@capacitor/core": "^8.3.1",
35
+ "rimraf": "^6.0.0",
36
+ "rollup": "^4.60.2",
37
+ "typescript": "^6.0.0"
38
+ },
39
+ "peerDependencies": {
40
+ "@capacitor/core": "^8.3.1"
41
+ },
42
+ "elizaos": {
43
+ "platforms": [
44
+ "browser",
45
+ "node"
46
+ ],
47
+ "runtime": "both",
48
+ "platformDetails": {
49
+ "browser": "Web fallback reports no Android roles.",
50
+ "android": true
51
+ }
52
+ },
53
+ "publishConfig": {
54
+ "access": "public"
55
+ }
56
+ }