Repository navigation
Expand file tree
/
Copy pathAndroidManifest.xml
More file actions
223 lines (201 loc) · 12.4 KB
/
Copy pathAndroidManifest.xml
File metadata and controls
223 lines (201 loc) · 12.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
<?xml version="1.0" encoding="utf-8"?>
<!-- EVTasker is an independent system app: it reads and writes the vehicle directly
through the shared EVHardware layer, and works with no EVProfile installed.
sharedUserId + the platform signature are what grant vehicle access (the car
permissions are signature|privileged), exactly as EVProfile does.
EVProfile is optional: when it is installed, the "Apply EVProfile profile" action
becomes available (via its signature-protected bridge). That is the only capability
that needs EVProfile. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="android.uid.system">
<!-- Vehicle access (Android Automotive / SAIC) — same set EVProfile uses. -->
<uses-permission android:name="android.car.permission.CAR_ENERGY" />
<uses-permission android:name="android.car.permission.CAR_POWERTRAIN" />
<uses-permission android:name="android.car.permission.CAR_VENDOR_EXTENSION" />
<uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE" />
<!-- Exterior lights (CR-046): read for light conditions, control for the standstill
actions. Signature-level, granted by the platform signature like the rest. -->
<uses-permission android:name="android.car.permission.CAR_EXTERIOR_LIGHTS" />
<uses-permission android:name="android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- Own vehicle service: foreground + wake + start at boot to catch the ignition. -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<!-- Since API 34 a foreground service only reaches a "while in use" permission through a
matching service type. The vehicle service ran as connectedDevice alone, so its
position reads returned nothing and every "near a place" condition was unanswerable
on the car while evaluating perfectly in a test. -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- The SAIC hard-key report is otherwise forgeable by any app. Requiring this from
the sender admits the platform-signed OEM hard-key service only. -->
<permission
android:name="com.evsuite.tasker.permission.RECEIVE_HARDKEY"
android:protectionLevel="signature" />
<!-- Bluetooth: paired list for the editor, and live connection tracking for rules. -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Switching the radio itself on or off, for the "Bluetooth" action. Only that action
uses it; without it the action reports unsupported and nothing else changes. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Reads how much data the head unit's own connection has carried, for the two "data
used" conditions. Android's counters, the ones the Settings screen shows; nothing is
attributed to an app and nothing leaves the car. Signature-level, so without it those
two conditions report unavailable and nothing else changes. -->
<uses-permission
android:name="android.permission.READ_NETWORK_USAGE_HISTORY"
tools:ignore="ProtectedPermissions" />
<!-- Enumerating the head unit's media sessions, for the "media control" action on the
A9 generations: they have no SAIC media service, so the framework's sessions are the
only way to reach the player that is actually playing. Granted by the platform
signature; without it that action falls back to the media key. -->
<uses-permission
android:name="android.permission.MEDIA_CONTENT_CONTROL"
tools:ignore="ProtectedPermissions" />
<!-- Wi-Fi: the network name for the "Wi-Fi network" condition, and the switch for the
"Wi-Fi" action. The name is read, never sent anywhere. -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- Reads which phone the head unit made hands-free, for the "hands-free phone"
condition. Granted by the platform signature; without it that one condition
reports as unreadable and nothing else changes. -->
<uses-permission
android:name="android.permission.BLUETOOTH_PRIVILEGED"
tools:ignore="ProtectedPermissions" />
<!-- Requested only when the user chooses "Call a contact". The OEM PBAP client
publishes the paired phone's downloaded phone book through ContactsContract. -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- The head unit has no SIM and sends nothing itself: a message is handed to the paired
phone over the Bluetooth message profile, and the phone sends it. The platform still
counts that as sending an SMS and the Bluetooth stack enforces this permission on the
call, so the action was refused on every car until it was asked for. Requested only
when the user writes a "send a message" action. -->
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- Declared false, and meant: the head unit has no modem and never will. The permission
above is about the paired phone's radio, not the car's. -->
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<!-- Position, for the "near a place" condition only. Last known fix, never a live
request, never sent anywhere: it is compared to a point stored in the rule and the
result is a yes/no. Denying it disables that one condition and nothing else.
COARSE is declared alongside FINE because the platform requires the pair; a radius
in metres is what FINE is for, and COARSE alone still answers a wide-enough one.
The vehicle service holds a one-minute subscription while it lives: on a head unit
with no other GPS client there is no "last known" fix for anyone to read, so the
only way the cache is ever warm is that this app filled it. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- The "call a webhook" action, on every channel. The app opens no connection of its
own: it calls the HTTPS URL a rule carries, when that rule fires, and reports the
status code. Held here rather than in the unstable channel alone because a rule that
rings a doorbell or opens a gate is written on the channel people actually drive. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Optional EVProfile bridge (the "apply profile" action only). Signature-level,
obtained solely because both APKs are signed with the same platform key. -->
<uses-permission android:name="com.evsuite.profile.permission.CONTROL_PROFILES" />
<!-- API 30+: list installed apps for the "launch an app" action; detect EVProfile. -->
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
<!-- Every EVProfile channel: the offline and unstable builds carry a suffixed
application id and are the same app. Declaring only the stable id made
EVProfile invisible on a car that had it, and the profile actions vanished
from the rule editor with it. -->
<package android:name="com.evsuite.profile" />
<package android:name="com.evsuite.profile.offline" />
<package android:name="com.evsuite.profile.unstable" />
<package android:name="com.evsuite.profile.offline.unstable" />
<!-- API 30+: without this the TTS engine is invisible and the "speak" action
would report "no speech engine" on a car that has one installed. -->
<intent>
<action android:name="android.intent.action.TTS_SERVICE" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="geo" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="google.navigation" />
</intent>
<!-- Runtime-compatible map components that publish no geo: filter; explicit
package visibility lets the app offer navigation when either is installed. -->
<package android:name="com.saicmotor.navigation" />
<package android:name="com.telenav.app.arp" />
<package android:name="com.nng.igo.primong" />
<package android:name="com.mmi.navimaps_auto" />
</queries>
<application
android:name=".EVTaskerApp"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:theme="@style/Theme.EVTasker"
android:allowBackup="false"
android:fullBackupContent="false"
android:supportsRtl="true">
<!-- Car API (CarPropertyManager / CarHvacManager reflection targets). -->
<uses-library android:name="android.car" android:required="false" />
<activity
android:name=".ui.MainActivity"
android:exported="true"
android:taskAffinity=""
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.RuleEditorActivity"
android:exported="false"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustResize" />
<!-- One case of a rule ("if", "else if", "else"), edited on its own screen. -->
<activity
android:name=".ui.BranchEditorActivity"
android:exported="false"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustResize" />
<!-- Long profile-safety guidance needs the whole vehicle display, never a popup. -->
<activity
android:name=".ui.ProfileAutomationWarningActivity"
android:exported="false"
android:screenOrientation="landscape" />
<!-- A rule's own yes/no question. Launched from the vehicle service while a rule is
running, so it comes up over whatever the head unit is showing; excluded from
recents because it belongs to that one rule and means nothing after it. -->
<activity
android:name=".ui.ConfirmActionActivity"
android:excludeFromRecents="true"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="landscape" />
<!-- Persistent vehicle service: inits EVHardware, listens for ignition, evaluates
rules and applies actions directly. connectedDevice matches what it does. -->
<service
android:name=".service.TaskerVehicleService"
android:exported="false"
android:directBootAware="true"
android:foregroundServiceType="connectedDevice|location" />
<!-- Runs one evaluation cycle for a manual test (from the Rules screen). -->
<service
android:name=".service.TaskerRunService"
android:exported="false"
android:foregroundServiceType="connectedDevice|location" />
<receiver
android:name=".receiver.BootReceiver"
android:exported="true"
android:directBootAware="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
</application>
</manifest>