app/src/main/AndroidManifest.xml (11152 bytes)
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools"> 4 5 <!-- 6 Not grantable at install. Declared so that `adb shell pm grant` can turn 7 it on for the power-gesture switches; without it those rows report the 8 refusal and print the command instead. 9 --> 10 <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" 11 tools:ignore="ProtectedPermissions" /> 12 13 14 <!-- 15 Voice typing only. The speech recognition app does the recording; Android 16 still requires the app that asks for it to hold the permission. Requested 17 at run time, from the Voice typing screen, and never otherwise. 18 --> 19 20 <uses-permission android:name="android.permission.RECORD_AUDIO" /> 21 22 <!-- Required of any app that wants to be offered the wallet role. --> 23 <uses-permission android:name="android.permission.QUICK_ACCESS_WALLET" /> 24 25 <!-- 26 Package visibility. We need to see launchable apps to offer them as 27 targets, resolve the camera intent to tell whether we are the default, 28 and reach the Viwoods AI activities by explicit component. 29 --> 30 <queries> 31 <intent> 32 <action android:name="android.intent.action.MAIN" /> 33 <category android:name="android.intent.category.LAUNCHER" /> 34 </intent> 35 <intent> 36 <action android:name="android.media.action.STILL_IMAGE_CAMERA" /> 37 </intent> 38 <!-- Speech recognition apps, for voice typing. --> 39 <intent> 40 <action android:name="android.speech.RecognitionService" /> 41 </intent> 42 <!-- Ink Recents, which the Recent apps action opens. --> 43 <package android:name="dev.equwal.inkrecents" /> 44 <package android:name="com.viwoods.launcher" /> 45 <package android:name="com.viwoods.viwoodsai" /> 46 <package android:name="com.viwoods.settings" /> 47 </queries> 48 49 <!-- 50 hasFragileUserData: on uninstall, Android asks the user whether to keep 51 the data of the app. With the data kept, a new install has every setting. 52 --> 53 <application 54 android:allowBackup="true" 55 android:hasFragileUserData="true" 56 android:icon="@mipmap/ic_launcher" 57 android:label="@string/app_name" 58 android:supportsRtl="true" 59 android:theme="@style/Theme.App"> 60 61 <!-- Configuration UI --> 62 <activity 63 android:name=".ui.MainActivity" 64 android:exported="true" 65 android:label="@string/app_name"> 66 <intent-filter> 67 <action android:name="android.intent.action.MAIN" /> 68 <category android:name="android.intent.category.LAUNCHER" /> 69 </intent-filter> 70 </activity> 71 72 <activity android:name=".ui.TriggerListActivity" android:exported="false" /> 73 <activity android:name=".ui.ActionPickerActivity" android:exported="false" /> 74 <activity android:name=".ui.PowerActivity" android:exported="false" /> 75 <activity android:name=".ui.ChordActivity" android:exported="false" /> 76 <activity android:name=".ui.ViwoodsActivity" android:exported="false" /> 77 <activity android:name=".ui.TimingActivity" android:exported="false" /> 78 <activity android:name=".ui.KeyTesterActivity" android:exported="false" /> 79 <activity android:name=".ui.LicenseActivity" android:exported="false" /> 80 <activity android:name=".ui.NavigationActivity" android:exported="false" /> 81 <activity android:name=".ui.ShellActivity" android:exported="false" /> 82 <activity android:name=".ui.DisplayActivity" android:exported="false" /> 83 <activity android:name=".ui.VoiceActivity" android:exported="false" /> 84 <activity android:name=".ui.BackupActivity" android:exported="false" /> 85 <activity android:name=".ui.PermissionsActivity" android:exported="false" /> 86 <!-- The hub's sub-screens. --> 87 <activity android:name=".ui.KeysActivity" android:exported="false" /> 88 <activity android:name=".ui.SetupActivity" android:exported="false" /> 89 <activity android:name=".ui.HomeHubActivity" android:exported="false" /> 90 <activity android:name=".ui.AdvancedActivity" android:exported="false" /> 91 <activity android:name=".ui.HacksActivity" android:exported="false" /> 92 <!-- The guided flow the hub opens first. --> 93 <activity android:name=".setup.GuidedSetupActivity" android:exported="false" /> 94 <activity android:name=".menu.MenuEditActivity" android:exported="false" /> 95 <!-- The action menu: a box over the app in front, in a task of its own. --> 96 <activity 97 android:name=".menu.MenuActivity" 98 android:exported="false" 99 android:excludeFromRecents="true" 100 android:noHistory="true" 101 android:launchMode="singleInstance" 102 android:taskAffinity="" 103 android:theme="@style/Theme.Invisible" /> 104 <!-- See-through and unfocusable: on top only so the microphone is allowed. --> 105 <activity 106 android:name=".voice.DictationActivity" 107 android:exported="false" 108 android:excludeFromRecents="true" 109 android:launchMode="singleInstance" 110 android:taskAffinity="" 111 android:theme="@style/Theme.Invisible" /> 112 <activity 113 android:name=".home.RecentsActivity" 114 android:exported="false" 115 android:excludeFromRecents="true" 116 android:noHistory="true" 117 android:taskAffinity="" 118 android:theme="@style/Theme.Invisible" /> 119 120 <activity android:name=".ui.ReportActivity" android:exported="false" /> 121 <activity android:name=".ui.DetectActivity" android:exported="false" /> 122 123 <!-- 124 The three impersonation entry points. Each starts disabled: the app 125 must not show up as an assistant, camera or wallet candidate until 126 the user ticks that channel. Channels.syncComponents flips them. 127 --> 128 129 <!-- 130 Long-pressing Power fires ACTION_ASSIST at whichever app holds the 131 assistant role. Invisible, no-history, no task affinity, so nothing 132 is drawn and nothing lands in Recents. 133 --> 134 <activity 135 android:name=".channel.AssistActivity" 136 android:enabled="false" 137 android:exported="true" 138 android:excludeFromRecents="true" 139 android:noHistory="true" 140 android:launchMode="singleInstance" 141 android:taskAffinity="" 142 android:theme="@style/Theme.Invisible"> 143 <intent-filter> 144 <action android:name="android.intent.action.ASSIST" /> 145 <category android:name="android.intent.category.DEFAULT" /> 146 </intent-filter> 147 <intent-filter> 148 <action android:name="android.intent.action.VOICE_COMMAND" /> 149 <category android:name="android.intent.category.DEFAULT" /> 150 </intent-filter> 151 </activity> 152 153 <!-- 154 Target for the firmware's own AI key hook (Settings.System 155 CustomAiKey), which only the shell can set. No intent filter: it is 156 reached by explicit component, and only by the firmware. Always 157 enabled, because the hook outlives any switch inside the app. 158 --> 159 <activity 160 android:name=".channel.AiKeyActivity" 161 android:exported="true" 162 android:excludeFromRecents="true" 163 android:noHistory="true" 164 android:launchMode="singleInstance" 165 android:taskAffinity="" 166 android:theme="@style/Theme.Invisible" /> 167 168 <!-- Double press Power, when the firmware target is the camera. --> 169 <activity 170 android:name=".channel.CameraShimActivity" 171 android:enabled="false" 172 android:exported="true" 173 android:excludeFromRecents="true" 174 android:noHistory="true" 175 android:launchMode="singleInstance" 176 android:taskAffinity="" 177 android:theme="@style/Theme.Invisible"> 178 <intent-filter> 179 <action android:name="android.media.action.STILL_IMAGE_CAMERA" /> 180 <category android:name="android.intent.category.DEFAULT" /> 181 </intent-filter> 182 <intent-filter> 183 <action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" /> 184 <category android:name="android.intent.category.DEFAULT" /> 185 </intent-filter> 186 <intent-filter> 187 <action android:name="android.media.action.IMAGE_CAPTURE" /> 188 <category android:name="android.intent.category.DEFAULT" /> 189 </intent-filter> 190 </activity> 191 192 <!-- Double press Power when the target is the wallet, plus the QS tile. --> 193 <activity 194 android:name=".channel.WalletActivity" 195 android:enabled="false" 196 android:exported="true" 197 android:excludeFromRecents="true" 198 android:noHistory="true" 199 android:launchMode="singleInstance" 200 android:taskAffinity="" 201 android:theme="@style/Theme.Invisible"> 202 <intent-filter> 203 <action android:name="android.service.quickaccesswallet.action.VIEW_WALLET" /> 204 <category android:name="android.intent.category.DEFAULT" /> 205 </intent-filter> 206 </activity> 207 208 <!-- 209 The wallet role is not offered to an app that cannot serve cards, so 210 this exists to satisfy the requirement. It serves none. 211 --> 212 <service 213 android:name=".channel.WalletService" 214 android:enabled="false" 215 android:exported="true" 216 android:label="@string/wallet_label" 217 android:permission="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE"> 218 <intent-filter> 219 <action android:name="android.service.quickaccesswallet.QuickAccessWalletService" /> 220 </intent-filter> 221 <meta-data 222 android:name="android.quickaccesswallet" 223 android:resource="@xml/quick_access_wallet" /> 224 </service> 225 226 <!-- 227 The accessibility channel. This is the only component that sees the 228 AI key and the volume keys; Power never reaches it. 229 --> 230 <service 231 android:name=".engine.KeyFilterService" 232 android:exported="false" 233 android:label="@string/service_label" 234 android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> 235 <intent-filter> 236 <action android:name="android.accessibilityservice.AccessibilityService" /> 237 </intent-filter> 238 <meta-data 239 android:name="android.accessibilityservice" 240 android:resource="@xml/accessibility_service_config" /> 241 </service> 242 243 </application> 244 245 </manifest>