kivyforge 3.0.0.dev0__py3-none-any.whl

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.
Files changed (225) hide show
  1. kivyforge/__init__.py +9 -0
  2. kivyforge/artifacts/__init__.py +41 -0
  3. kivyforge/artifacts/cache.py +81 -0
  4. kivyforge/artifacts/collect.py +354 -0
  5. kivyforge/artifacts/download.py +125 -0
  6. kivyforge/artifacts/frameworks.py +240 -0
  7. kivyforge/artifacts/native_stage_util.py +346 -0
  8. kivyforge/artifacts/runtime.py +65 -0
  9. kivyforge/artifacts/verify.py +45 -0
  10. kivyforge/artifacts/wheels.py +89 -0
  11. kivyforge/bundle/__init__.py +1 -0
  12. kivyforge/bundle/pycompile.py +161 -0
  13. kivyforge/cli/__init__.py +52 -0
  14. kivyforge/cli/_common.py +62 -0
  15. kivyforge/cli/_platform.py +84 -0
  16. kivyforge/cli/build.py +111 -0
  17. kivyforge/cli/clean.py +135 -0
  18. kivyforge/cli/doctor.py +52 -0
  19. kivyforge/cli/init.py +612 -0
  20. kivyforge/cli/init_writer.py +716 -0
  21. kivyforge/cli/lock.py +261 -0
  22. kivyforge/cli/open_cmd.py +15 -0
  23. kivyforge/cli/package.py +134 -0
  24. kivyforge/cli/run.py +162 -0
  25. kivyforge/cli/status.py +20 -0
  26. kivyforge/cli/upgrade.py +314 -0
  27. kivyforge/config/__init__.py +46 -0
  28. kivyforge/config/errors.py +43 -0
  29. kivyforge/config/icons.py +60 -0
  30. kivyforge/config/loader.py +3079 -0
  31. kivyforge/config/model.py +817 -0
  32. kivyforge/doctor/__init__.py +19 -0
  33. kivyforge/doctor/checks_common.py +95 -0
  34. kivyforge/doctor/probe.py +357 -0
  35. kivyforge/doctor/result.py +41 -0
  36. kivyforge/lock/__init__.py +42 -0
  37. kivyforge/lock/_pip_shim.py +63 -0
  38. kivyforge/lock/find_links.py +182 -0
  39. kivyforge/lock/model.py +69 -0
  40. kivyforge/lock/pep751.py +111 -0
  41. kivyforge/lock/reader.py +30 -0
  42. kivyforge/lock/resolver.py +124 -0
  43. kivyforge/lock/wheelruntime/__init__.py +70 -0
  44. kivyforge/lock/wheelruntime/builder.py +280 -0
  45. kivyforge/lock/wheelruntime/model.py +94 -0
  46. kivyforge/lock/wheelruntime/native_binaries.py +127 -0
  47. kivyforge/lock/wheelruntime/pbs_github.py +133 -0
  48. kivyforge/lock/wheelruntime/profile.py +104 -0
  49. kivyforge/lock/wheelruntime/resolver.py +248 -0
  50. kivyforge/lock/wheelruntime/runtime.py +161 -0
  51. kivyforge/lock/wheelruntime/serialize.py +245 -0
  52. kivyforge/platforms/__init__.py +114 -0
  53. kivyforge/platforms/android/__init__.py +140 -0
  54. kivyforge/platforms/android/adb.py +215 -0
  55. kivyforge/platforms/android/bootstrap/__init__.py +7 -0
  56. kivyforge/platforms/android/bootstrap/contract.py +166 -0
  57. kivyforge/platforms/android/bootstrap/render.py +244 -0
  58. kivyforge/platforms/android/bootstrap/templates/androidtest/KivyforgeContractTest.java +76 -0
  59. kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivy_bootstrap.py +50 -0
  60. kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivyforge_bootstrap.py +54 -0
  61. kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivyforge_selftest.py +97 -0
  62. kivyforge/platforms/android/bootstrap/templates/cpp/CMakeLists.txt +20 -0
  63. kivyforge/platforms/android/bootstrap/templates/cpp/main.c +150 -0
  64. kivyforge/platforms/android/bootstrap/templates/java/org/jnius/NativeInvocationHandler.java +48 -0
  65. kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonActivity.java +75 -0
  66. kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonBundle.java +132 -0
  67. kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonService.java +189 -0
  68. kivyforge/platforms/android/bootstrap/templates/java/org/renpy/android/Hardware.java +276 -0
  69. kivyforge/platforms/android/bootstrap/templates/sdl2/LICENSE-SDL.txt +18 -0
  70. kivyforge/platforms/android/bootstrap/templates/sdl2/SDL_REVISION.txt +3 -0
  71. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDevice.java +22 -0
  72. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceBLESteamController.java +650 -0
  73. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceManager.java +698 -0
  74. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceUSB.java +309 -0
  75. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDL.java +90 -0
  76. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLActivity.java +2120 -0
  77. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLAudioManager.java +514 -0
  78. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLControllerManager.java +856 -0
  79. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLSurface.java +405 -0
  80. kivyforge/platforms/android/bootstrap/templates/sdl3/LICENSE-SDL.txt +18 -0
  81. kivyforge/platforms/android/bootstrap/templates/sdl3/SDL_REVISION.txt +3 -0
  82. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDevice.java +21 -0
  83. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceBLESteamController.java +829 -0
  84. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceManager.java +698 -0
  85. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceUSB.java +354 -0
  86. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDL.java +90 -0
  87. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLActivity.java +2240 -0
  88. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLAudioManager.java +126 -0
  89. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLControllerManager.java +1010 -0
  90. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLDummyEdit.java +66 -0
  91. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLInputConnection.java +136 -0
  92. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLSensorManager.java +73 -0
  93. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLSurface.java +464 -0
  94. kivyforge/platforms/android/cli.py +1023 -0
  95. kivyforge/platforms/android/doctor.py +899 -0
  96. kivyforge/platforms/android/elf.py +148 -0
  97. kivyforge/platforms/android/generate/__init__.py +1 -0
  98. kivyforge/platforms/android/generate/manifest.py +261 -0
  99. kivyforge/platforms/android/generate/project.py +462 -0
  100. kivyforge/platforms/android/generate/services.py +187 -0
  101. kivyforge/platforms/android/gradle_wrapper/NOTICE +3 -0
  102. kivyforge/platforms/android/gradle_wrapper/SHA256SUMS +1 -0
  103. kivyforge/platforms/android/gradle_wrapper/gradle-wrapper.jar +0 -0
  104. kivyforge/platforms/android/gradle_wrapper/gradlew +164 -0
  105. kivyforge/platforms/android/gradle_wrapper/gradlew.bat +90 -0
  106. kivyforge/platforms/android/gradlew.py +60 -0
  107. kivyforge/platforms/android/icons.py +237 -0
  108. kivyforge/platforms/android/lock/__init__.py +1 -0
  109. kivyforge/platforms/android/lock/archives.py +109 -0
  110. kivyforge/platforms/android/lock/builder.py +387 -0
  111. kivyforge/platforms/android/lock/markers.py +71 -0
  112. kivyforge/platforms/android/lock/maven.py +252 -0
  113. kivyforge/platforms/android/lock/model.py +113 -0
  114. kivyforge/platforms/android/lock/python_meta.py +199 -0
  115. kivyforge/platforms/android/lock/reader.py +206 -0
  116. kivyforge/platforms/android/lock/resolver.py +276 -0
  117. kivyforge/platforms/android/lock/writer.py +121 -0
  118. kivyforge/platforms/android/policy.py +214 -0
  119. kivyforge/platforms/android/signing.py +145 -0
  120. kivyforge/platforms/android/smoke.py +43 -0
  121. kivyforge/platforms/android/splash.py +293 -0
  122. kivyforge/platforms/android/stage/__init__.py +1 -0
  123. kivyforge/platforms/android/stage/bundle.py +295 -0
  124. kivyforge/platforms/android/stage/jnilibs.py +186 -0
  125. kivyforge/platforms/android/stage/runtime.py +61 -0
  126. kivyforge/platforms/android/stage/wheels.py +106 -0
  127. kivyforge/platforms/android/toolchain.py +29 -0
  128. kivyforge/platforms/base.py +157 -0
  129. kivyforge/platforms/ios/__init__.py +129 -0
  130. kivyforge/platforms/ios/assets.py +193 -0
  131. kivyforge/platforms/ios/buildsettings.py +128 -0
  132. kivyforge/platforms/ios/cli.py +543 -0
  133. kivyforge/platforms/ios/doctor.py +410 -0
  134. kivyforge/platforms/ios/entitlements.py +34 -0
  135. kivyforge/platforms/ios/generator.py +318 -0
  136. kivyforge/platforms/ios/lock/__init__.py +71 -0
  137. kivyforge/platforms/ios/lock/builder.py +393 -0
  138. kivyforge/platforms/ios/lock/markers.py +69 -0
  139. kivyforge/platforms/ios/lock/model.py +95 -0
  140. kivyforge/platforms/ios/lock/python_meta.py +187 -0
  141. kivyforge/platforms/ios/lock/reader.py +191 -0
  142. kivyforge/platforms/ios/lock/resolver.py +304 -0
  143. kivyforge/platforms/ios/lock/spm.py +217 -0
  144. kivyforge/platforms/ios/lock/writer.py +114 -0
  145. kivyforge/platforms/ios/lock/xcframework.py +188 -0
  146. kivyforge/platforms/ios/materialize.py +59 -0
  147. kivyforge/platforms/ios/plist.py +91 -0
  148. kivyforge/platforms/ios/privacy.py +39 -0
  149. kivyforge/platforms/ios/skeleton.py +165 -0
  150. kivyforge/platforms/ios/sources.py +63 -0
  151. kivyforge/platforms/ios/staging.py +225 -0
  152. kivyforge/platforms/ios/swift_packages.py +324 -0
  153. kivyforge/platforms/ios/templates/kivyforge_bootstrap.h +34 -0
  154. kivyforge/platforms/ios/templates/kivyforge_bootstrap.m +146 -0
  155. kivyforge/platforms/ios/templates/main.m +15 -0
  156. kivyforge/platforms/ios/templates/main_config.h.in +12 -0
  157. kivyforge/platforms/ios/xcframeworks.py +194 -0
  158. kivyforge/platforms/ios/xcode/__init__.py +76 -0
  159. kivyforge/platforms/ios/xcode/commands.py +296 -0
  160. kivyforge/platforms/ios/xcode/runner.py +316 -0
  161. kivyforge/platforms/linux/__init__.py +120 -0
  162. kivyforge/platforms/linux/appimage.py +169 -0
  163. kivyforge/platforms/linux/bundle.py +235 -0
  164. kivyforge/platforms/linux/cli.py +232 -0
  165. kivyforge/platforms/linux/desktop.py +71 -0
  166. kivyforge/platforms/linux/doctor.py +438 -0
  167. kivyforge/platforms/linux/elftools.py +95 -0
  168. kivyforge/platforms/linux/icons.py +129 -0
  169. kivyforge/platforms/linux/launcher.py +107 -0
  170. kivyforge/platforms/linux/lock/__init__.py +126 -0
  171. kivyforge/platforms/linux/lock/profile.py +254 -0
  172. kivyforge/platforms/linux/lock/runtime.py +75 -0
  173. kivyforge/platforms/linux/native_stage.py +47 -0
  174. kivyforge/platforms/linux/runtime_stage.py +107 -0
  175. kivyforge/platforms/linux/wheels_stage.py +103 -0
  176. kivyforge/platforms/macos/__init__.py +121 -0
  177. kivyforge/platforms/macos/bundle.py +255 -0
  178. kivyforge/platforms/macos/cli.py +269 -0
  179. kivyforge/platforms/macos/doctor.py +480 -0
  180. kivyforge/platforms/macos/icns.py +75 -0
  181. kivyforge/platforms/macos/launcher.py +118 -0
  182. kivyforge/platforms/macos/lock/__init__.py +112 -0
  183. kivyforge/platforms/macos/lock/profile.py +119 -0
  184. kivyforge/platforms/macos/lock/runtime.py +58 -0
  185. kivyforge/platforms/macos/machotools.py +138 -0
  186. kivyforge/platforms/macos/native_stage.py +47 -0
  187. kivyforge/platforms/macos/notarize.py +143 -0
  188. kivyforge/platforms/macos/plist.py +37 -0
  189. kivyforge/platforms/macos/runtime_stage.py +110 -0
  190. kivyforge/platforms/macos/signing.py +78 -0
  191. kivyforge/platforms/macos/wheels_stage.py +108 -0
  192. kivyforge/platforms/windows/__init__.py +133 -0
  193. kivyforge/platforms/windows/assets.py +76 -0
  194. kivyforge/platforms/windows/bundle.py +298 -0
  195. kivyforge/platforms/windows/cli.py +314 -0
  196. kivyforge/platforms/windows/doctor.py +563 -0
  197. kivyforge/platforms/windows/fsswap.py +87 -0
  198. kivyforge/platforms/windows/icons.py +64 -0
  199. kivyforge/platforms/windows/launcher/__init__.py +193 -0
  200. kivyforge/platforms/windows/launcher/build_launcher.py +507 -0
  201. kivyforge/platforms/windows/launcher/launcher.c +379 -0
  202. kivyforge/platforms/windows/lock/__init__.py +112 -0
  203. kivyforge/platforms/windows/lock/profile.py +101 -0
  204. kivyforge/platforms/windows/lock/runtime.py +64 -0
  205. kivyforge/platforms/windows/naming.py +52 -0
  206. kivyforge/platforms/windows/native_stage.py +66 -0
  207. kivyforge/platforms/windows/petools.py +98 -0
  208. kivyforge/platforms/windows/rcedit.py +116 -0
  209. kivyforge/platforms/windows/runtime_stage.py +221 -0
  210. kivyforge/platforms/windows/signing.py +168 -0
  211. kivyforge/platforms/windows/vendor/LICENSE.rcedit +29 -0
  212. kivyforge/platforms/windows/vendor/NOTICE +17 -0
  213. kivyforge/platforms/windows/vendor/SHA256SUMS +4 -0
  214. kivyforge/platforms/windows/vendor/TOOLSET.txt +4 -0
  215. kivyforge/platforms/windows/vendor/__init__.py +12 -0
  216. kivyforge/platforms/windows/vendor/fetch_rcedit.py +97 -0
  217. kivyforge/platforms/windows/vendor/launcher-amd64.exe +0 -0
  218. kivyforge/platforms/windows/vendor/rcedit-x64.exe +0 -0
  219. kivyforge/platforms/windows/wheels_stage.py +139 -0
  220. kivyforge-3.0.0.dev0.dist-info/METADATA +609 -0
  221. kivyforge-3.0.0.dev0.dist-info/RECORD +225 -0
  222. kivyforge-3.0.0.dev0.dist-info/WHEEL +5 -0
  223. kivyforge-3.0.0.dev0.dist-info/entry_points.txt +3 -0
  224. kivyforge-3.0.0.dev0.dist-info/licenses/LICENSE +21 -0
  225. kivyforge-3.0.0.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,698 @@
1
+ package org.libsdl.app;
2
+
3
+ import android.app.Activity;
4
+ import android.app.AlertDialog;
5
+ import android.app.PendingIntent;
6
+ import android.bluetooth.BluetoothAdapter;
7
+ import android.bluetooth.BluetoothDevice;
8
+ import android.bluetooth.BluetoothManager;
9
+ import android.bluetooth.BluetoothProfile;
10
+ import android.os.Build;
11
+ import android.util.Log;
12
+ import android.content.BroadcastReceiver;
13
+ import android.content.Context;
14
+ import android.content.DialogInterface;
15
+ import android.content.Intent;
16
+ import android.content.IntentFilter;
17
+ import android.content.SharedPreferences;
18
+ import android.content.pm.PackageManager;
19
+ import android.hardware.usb.*;
20
+ import android.os.Handler;
21
+ import android.os.Looper;
22
+
23
+ import java.util.ArrayList;
24
+ import java.util.HashMap;
25
+ import java.util.Iterator;
26
+ import java.util.List;
27
+
28
+ public class HIDDeviceManager {
29
+ private static final String TAG = "hidapi";
30
+ private static final String ACTION_USB_PERMISSION = "org.libsdl.app.USB_PERMISSION";
31
+
32
+ private static HIDDeviceManager sManager;
33
+ private static int sManagerRefCount = 0;
34
+
35
+ static public HIDDeviceManager acquire(Context context) {
36
+ if (sManagerRefCount == 0) {
37
+ sManager = new HIDDeviceManager(context);
38
+ }
39
+ ++sManagerRefCount;
40
+ return sManager;
41
+ }
42
+
43
+ static public void release(HIDDeviceManager manager) {
44
+ if (manager == sManager) {
45
+ --sManagerRefCount;
46
+ if (sManagerRefCount == 0) {
47
+ sManager.close();
48
+ sManager = null;
49
+ }
50
+ }
51
+ }
52
+
53
+ private Context mContext;
54
+ private HashMap<Integer, HIDDevice> mDevicesById = new HashMap<Integer, HIDDevice>();
55
+ private HashMap<BluetoothDevice, HIDDeviceBLESteamController> mBluetoothDevices = new HashMap<BluetoothDevice, HIDDeviceBLESteamController>();
56
+ private int mNextDeviceId = 0;
57
+ private SharedPreferences mSharedPreferences = null;
58
+ private boolean mIsChromebook = false;
59
+ private UsbManager mUsbManager;
60
+ private Handler mHandler;
61
+ private BluetoothManager mBluetoothManager;
62
+ private List<BluetoothDevice> mLastBluetoothDevices;
63
+
64
+ private final BroadcastReceiver mUsbBroadcast = new BroadcastReceiver() {
65
+ @Override
66
+ public void onReceive(Context context, Intent intent) {
67
+ String action = intent.getAction();
68
+ if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
69
+ UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
70
+ handleUsbDeviceAttached(usbDevice);
71
+ } else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
72
+ UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
73
+ handleUsbDeviceDetached(usbDevice);
74
+ } else if (action.equals(HIDDeviceManager.ACTION_USB_PERMISSION)) {
75
+ UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
76
+ handleUsbDevicePermission(usbDevice, intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false));
77
+ }
78
+ }
79
+ };
80
+
81
+ private final BroadcastReceiver mBluetoothBroadcast = new BroadcastReceiver() {
82
+ @Override
83
+ public void onReceive(Context context, Intent intent) {
84
+ String action = intent.getAction();
85
+ // Bluetooth device was connected. If it was a Steam Controller, handle it
86
+ if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
87
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
88
+ Log.d(TAG, "Bluetooth device connected: " + device);
89
+
90
+ if (isSteamController(device)) {
91
+ connectBluetoothDevice(device);
92
+ }
93
+ }
94
+
95
+ // Bluetooth device was disconnected, remove from controller manager (if any)
96
+ if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
97
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
98
+ Log.d(TAG, "Bluetooth device disconnected: " + device);
99
+
100
+ disconnectBluetoothDevice(device);
101
+ }
102
+ }
103
+ };
104
+
105
+ private HIDDeviceManager(final Context context) {
106
+ mContext = context;
107
+
108
+ HIDDeviceRegisterCallback();
109
+
110
+ mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE);
111
+ mIsChromebook = SDLActivity.isChromebook();
112
+
113
+ // if (shouldClear) {
114
+ // SharedPreferences.Editor spedit = mSharedPreferences.edit();
115
+ // spedit.clear();
116
+ // spedit.apply();
117
+ // }
118
+ // else
119
+ {
120
+ mNextDeviceId = mSharedPreferences.getInt("next_device_id", 0);
121
+ }
122
+ }
123
+
124
+ Context getContext() {
125
+ return mContext;
126
+ }
127
+
128
+ int getDeviceIDForIdentifier(String identifier) {
129
+ SharedPreferences.Editor spedit = mSharedPreferences.edit();
130
+
131
+ int result = mSharedPreferences.getInt(identifier, 0);
132
+ if (result == 0) {
133
+ result = mNextDeviceId++;
134
+ spedit.putInt("next_device_id", mNextDeviceId);
135
+ }
136
+
137
+ spedit.putInt(identifier, result);
138
+ spedit.apply();
139
+ return result;
140
+ }
141
+
142
+ private void initializeUSB() {
143
+ mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
144
+ if (mUsbManager == null) {
145
+ return;
146
+ }
147
+
148
+ /*
149
+ // Logging
150
+ for (UsbDevice device : mUsbManager.getDeviceList().values()) {
151
+ Log.i(TAG,"Path: " + device.getDeviceName());
152
+ Log.i(TAG,"Manufacturer: " + device.getManufacturerName());
153
+ Log.i(TAG,"Product: " + device.getProductName());
154
+ Log.i(TAG,"ID: " + device.getDeviceId());
155
+ Log.i(TAG,"Class: " + device.getDeviceClass());
156
+ Log.i(TAG,"Protocol: " + device.getDeviceProtocol());
157
+ Log.i(TAG,"Vendor ID " + device.getVendorId());
158
+ Log.i(TAG,"Product ID: " + device.getProductId());
159
+ Log.i(TAG,"Interface count: " + device.getInterfaceCount());
160
+ Log.i(TAG,"---------------------------------------");
161
+
162
+ // Get interface details
163
+ for (int index = 0; index < device.getInterfaceCount(); index++) {
164
+ UsbInterface mUsbInterface = device.getInterface(index);
165
+ Log.i(TAG," ***** *****");
166
+ Log.i(TAG," Interface index: " + index);
167
+ Log.i(TAG," Interface ID: " + mUsbInterface.getId());
168
+ Log.i(TAG," Interface class: " + mUsbInterface.getInterfaceClass());
169
+ Log.i(TAG," Interface subclass: " + mUsbInterface.getInterfaceSubclass());
170
+ Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol());
171
+ Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount());
172
+
173
+ // Get endpoint details
174
+ for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
175
+ {
176
+ UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
177
+ Log.i(TAG," ++++ ++++ ++++");
178
+ Log.i(TAG," Endpoint index: " + epi);
179
+ Log.i(TAG," Attributes: " + mEndpoint.getAttributes());
180
+ Log.i(TAG," Direction: " + mEndpoint.getDirection());
181
+ Log.i(TAG," Number: " + mEndpoint.getEndpointNumber());
182
+ Log.i(TAG," Interval: " + mEndpoint.getInterval());
183
+ Log.i(TAG," Packet size: " + mEndpoint.getMaxPacketSize());
184
+ Log.i(TAG," Type: " + mEndpoint.getType());
185
+ }
186
+ }
187
+ }
188
+ Log.i(TAG," No more devices connected.");
189
+ */
190
+
191
+ // Register for USB broadcasts and permission completions
192
+ IntentFilter filter = new IntentFilter();
193
+ filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
194
+ filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
195
+ filter.addAction(HIDDeviceManager.ACTION_USB_PERMISSION);
196
+ if (Build.VERSION.SDK_INT >= 33) { /* Android 13.0 (TIRAMISU) */
197
+ mContext.registerReceiver(mUsbBroadcast, filter, Context.RECEIVER_EXPORTED);
198
+ } else {
199
+ mContext.registerReceiver(mUsbBroadcast, filter);
200
+ }
201
+
202
+ for (UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
203
+ handleUsbDeviceAttached(usbDevice);
204
+ }
205
+ }
206
+
207
+ UsbManager getUSBManager() {
208
+ return mUsbManager;
209
+ }
210
+
211
+ private void shutdownUSB() {
212
+ try {
213
+ mContext.unregisterReceiver(mUsbBroadcast);
214
+ } catch (Exception e) {
215
+ // We may not have registered, that's okay
216
+ }
217
+ }
218
+
219
+ private boolean isHIDDeviceInterface(UsbDevice usbDevice, UsbInterface usbInterface) {
220
+ if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
221
+ return true;
222
+ }
223
+ if (isXbox360Controller(usbDevice, usbInterface) || isXboxOneController(usbDevice, usbInterface)) {
224
+ return true;
225
+ }
226
+ return false;
227
+ }
228
+
229
+ private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) {
230
+ final int XB360_IFACE_SUBCLASS = 93;
231
+ final int XB360_IFACE_PROTOCOL = 1; // Wired
232
+ final int XB360W_IFACE_PROTOCOL = 129; // Wireless
233
+ final int[] SUPPORTED_VENDORS = {
234
+ 0x0079, // GPD Win 2
235
+ 0x044f, // Thrustmaster
236
+ 0x045e, // Microsoft
237
+ 0x046d, // Logitech
238
+ 0x056e, // Elecom
239
+ 0x06a3, // Saitek
240
+ 0x0738, // Mad Catz
241
+ 0x07ff, // Mad Catz
242
+ 0x0e6f, // PDP
243
+ 0x0f0d, // Hori
244
+ 0x1038, // SteelSeries
245
+ 0x11c9, // Nacon
246
+ 0x12ab, // Unknown
247
+ 0x1430, // RedOctane
248
+ 0x146b, // BigBen
249
+ 0x1532, // Razer Sabertooth
250
+ 0x15e4, // Numark
251
+ 0x162e, // Joytech
252
+ 0x1689, // Razer Onza
253
+ 0x1949, // Lab126, Inc.
254
+ 0x1bad, // Harmonix
255
+ 0x20d6, // PowerA
256
+ 0x24c6, // PowerA
257
+ 0x2c22, // Qanba
258
+ 0x2dc8, // 8BitDo
259
+ 0x3537, // GameSir
260
+ 0x37d7, // Flydigi
261
+ 0x9886, // ASTRO Gaming
262
+ };
263
+
264
+ if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
265
+ usbInterface.getInterfaceSubclass() == XB360_IFACE_SUBCLASS &&
266
+ (usbInterface.getInterfaceProtocol() == XB360_IFACE_PROTOCOL ||
267
+ usbInterface.getInterfaceProtocol() == XB360W_IFACE_PROTOCOL)) {
268
+ int vendor_id = usbDevice.getVendorId();
269
+ for (int supportedVid : SUPPORTED_VENDORS) {
270
+ if (vendor_id == supportedVid) {
271
+ return true;
272
+ }
273
+ }
274
+ }
275
+ return false;
276
+ }
277
+
278
+ private boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterface) {
279
+ final int XB1_IFACE_SUBCLASS = 71;
280
+ final int XB1_IFACE_PROTOCOL = 208;
281
+ final int[] SUPPORTED_VENDORS = {
282
+ 0x03f0, // HP
283
+ 0x044f, // Thrustmaster
284
+ 0x045e, // Microsoft
285
+ 0x0738, // Mad Catz
286
+ 0x0b05, // ASUS
287
+ 0x0e6f, // PDP
288
+ 0x0f0d, // Hori
289
+ 0x10f5, // Turtle Beach
290
+ 0x1532, // Razer Wildcat
291
+ 0x20d6, // PowerA
292
+ 0x24c6, // PowerA
293
+ 0x294b, // Snakebyte
294
+ 0x2dc8, // 8BitDo
295
+ 0x2e24, // Hyperkin
296
+ 0x2e95, // SCUF
297
+ 0x3285, // Nacon
298
+ 0x3537, // GameSir
299
+ 0x366c, // ByoWave
300
+ };
301
+
302
+ if (usbInterface.getId() == 0 &&
303
+ usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
304
+ usbInterface.getInterfaceSubclass() == XB1_IFACE_SUBCLASS &&
305
+ usbInterface.getInterfaceProtocol() == XB1_IFACE_PROTOCOL) {
306
+ int vendor_id = usbDevice.getVendorId();
307
+ for (int supportedVid : SUPPORTED_VENDORS) {
308
+ if (vendor_id == supportedVid) {
309
+ return true;
310
+ }
311
+ }
312
+ }
313
+ return false;
314
+ }
315
+
316
+ private void handleUsbDeviceAttached(UsbDevice usbDevice) {
317
+ connectHIDDeviceUSB(usbDevice);
318
+ }
319
+
320
+ private void handleUsbDeviceDetached(UsbDevice usbDevice) {
321
+ List<Integer> devices = new ArrayList<Integer>();
322
+ for (HIDDevice device : mDevicesById.values()) {
323
+ if (usbDevice.equals(device.getDevice())) {
324
+ devices.add(device.getId());
325
+ }
326
+ }
327
+ for (int id : devices) {
328
+ HIDDevice device = mDevicesById.get(id);
329
+ mDevicesById.remove(id);
330
+ device.shutdown();
331
+ HIDDeviceDisconnected(id);
332
+ }
333
+ }
334
+
335
+ private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) {
336
+ for (HIDDevice device : mDevicesById.values()) {
337
+ if (usbDevice.equals(device.getDevice())) {
338
+ boolean opened = false;
339
+ if (permission_granted) {
340
+ opened = device.open();
341
+ }
342
+ HIDDeviceOpenResult(device.getId(), opened);
343
+ }
344
+ }
345
+ }
346
+
347
+ private void connectHIDDeviceUSB(UsbDevice usbDevice) {
348
+ synchronized (this) {
349
+ int interface_mask = 0;
350
+ for (int interface_index = 0; interface_index < usbDevice.getInterfaceCount(); interface_index++) {
351
+ UsbInterface usbInterface = usbDevice.getInterface(interface_index);
352
+ if (isHIDDeviceInterface(usbDevice, usbInterface)) {
353
+ // Check to see if we've already added this interface
354
+ // This happens with the Xbox Series X controller which has a duplicate interface 0, which is inactive
355
+ int interface_id = usbInterface.getId();
356
+ if ((interface_mask & (1 << interface_id)) != 0) {
357
+ continue;
358
+ }
359
+ interface_mask |= (1 << interface_id);
360
+
361
+ HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_index);
362
+ int id = device.getId();
363
+ mDevicesById.put(id, device);
364
+ HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), usbInterface.getId(), usbInterface.getInterfaceClass(), usbInterface.getInterfaceSubclass(), usbInterface.getInterfaceProtocol(), false, 0);
365
+ }
366
+ }
367
+ }
368
+ }
369
+
370
+ private void initializeBluetooth() {
371
+ Log.d(TAG, "Initializing Bluetooth");
372
+
373
+ if (Build.VERSION.SDK_INT >= 31 /* Android 12 */ &&
374
+ mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH_CONNECT, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
375
+ Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH_CONNECT");
376
+ return;
377
+ }
378
+
379
+ if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
380
+ mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
381
+ Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH");
382
+ return;
383
+ }
384
+
385
+ if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
386
+ Log.d(TAG, "Couldn't initialize Bluetooth, this version of Android does not support Bluetooth LE");
387
+ return;
388
+ }
389
+
390
+ // Find bonded bluetooth controllers and create SteamControllers for them
391
+ mBluetoothManager = (BluetoothManager)mContext.getSystemService(Context.BLUETOOTH_SERVICE);
392
+ if (mBluetoothManager == null) {
393
+ // This device doesn't support Bluetooth.
394
+ return;
395
+ }
396
+
397
+ BluetoothAdapter btAdapter = mBluetoothManager.getAdapter();
398
+ if (btAdapter == null) {
399
+ // This device has Bluetooth support in the codebase, but has no available adapters.
400
+ return;
401
+ }
402
+
403
+ // Get our bonded devices.
404
+ for (BluetoothDevice device : btAdapter.getBondedDevices()) {
405
+
406
+ Log.d(TAG, "Bluetooth device available: " + device);
407
+ if (isSteamController(device)) {
408
+ connectBluetoothDevice(device);
409
+ }
410
+
411
+ }
412
+
413
+ // NOTE: These don't work on Chromebooks, to my undying dismay.
414
+ IntentFilter filter = new IntentFilter();
415
+ filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
416
+ filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
417
+ if (Build.VERSION.SDK_INT >= 33) { /* Android 13.0 (TIRAMISU) */
418
+ mContext.registerReceiver(mBluetoothBroadcast, filter, Context.RECEIVER_EXPORTED);
419
+ } else {
420
+ mContext.registerReceiver(mBluetoothBroadcast, filter);
421
+ }
422
+
423
+ if (mIsChromebook) {
424
+ mHandler = new Handler(Looper.getMainLooper());
425
+ mLastBluetoothDevices = new ArrayList<BluetoothDevice>();
426
+
427
+ // final HIDDeviceManager finalThis = this;
428
+ // mHandler.postDelayed(new Runnable() {
429
+ // @Override
430
+ // public void run() {
431
+ // finalThis.chromebookConnectionHandler();
432
+ // }
433
+ // }, 5000);
434
+ }
435
+ }
436
+
437
+ private void shutdownBluetooth() {
438
+ try {
439
+ mContext.unregisterReceiver(mBluetoothBroadcast);
440
+ } catch (Exception e) {
441
+ // We may not have registered, that's okay
442
+ }
443
+ }
444
+
445
+ // Chromebooks do not pass along ACTION_ACL_CONNECTED / ACTION_ACL_DISCONNECTED properly.
446
+ // This function provides a sort of dummy version of that, watching for changes in the
447
+ // connected devices and attempting to add controllers as things change.
448
+ void chromebookConnectionHandler() {
449
+ if (!mIsChromebook) {
450
+ return;
451
+ }
452
+
453
+ ArrayList<BluetoothDevice> disconnected = new ArrayList<BluetoothDevice>();
454
+ ArrayList<BluetoothDevice> connected = new ArrayList<BluetoothDevice>();
455
+
456
+ List<BluetoothDevice> currentConnected = mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT);
457
+
458
+ for (BluetoothDevice bluetoothDevice : currentConnected) {
459
+ if (!mLastBluetoothDevices.contains(bluetoothDevice)) {
460
+ connected.add(bluetoothDevice);
461
+ }
462
+ }
463
+ for (BluetoothDevice bluetoothDevice : mLastBluetoothDevices) {
464
+ if (!currentConnected.contains(bluetoothDevice)) {
465
+ disconnected.add(bluetoothDevice);
466
+ }
467
+ }
468
+
469
+ mLastBluetoothDevices = currentConnected;
470
+
471
+ for (BluetoothDevice bluetoothDevice : disconnected) {
472
+ disconnectBluetoothDevice(bluetoothDevice);
473
+ }
474
+ for (BluetoothDevice bluetoothDevice : connected) {
475
+ connectBluetoothDevice(bluetoothDevice);
476
+ }
477
+
478
+ final HIDDeviceManager finalThis = this;
479
+ mHandler.postDelayed(new Runnable() {
480
+ @Override
481
+ public void run() {
482
+ finalThis.chromebookConnectionHandler();
483
+ }
484
+ }, 10000);
485
+ }
486
+
487
+ boolean connectBluetoothDevice(BluetoothDevice bluetoothDevice) {
488
+ Log.v(TAG, "connectBluetoothDevice device=" + bluetoothDevice);
489
+ synchronized (this) {
490
+ if (mBluetoothDevices.containsKey(bluetoothDevice)) {
491
+ Log.v(TAG, "Steam controller with address " + bluetoothDevice + " already exists, attempting reconnect");
492
+
493
+ HIDDeviceBLESteamController device = mBluetoothDevices.get(bluetoothDevice);
494
+ device.reconnect();
495
+
496
+ return false;
497
+ }
498
+ HIDDeviceBLESteamController device = new HIDDeviceBLESteamController(this, bluetoothDevice);
499
+ int id = device.getId();
500
+ mBluetoothDevices.put(bluetoothDevice, device);
501
+ mDevicesById.put(id, device);
502
+
503
+ // The Steam Controller will mark itself connected once initialization is complete
504
+ }
505
+ return true;
506
+ }
507
+
508
+ void disconnectBluetoothDevice(BluetoothDevice bluetoothDevice) {
509
+ synchronized (this) {
510
+ HIDDeviceBLESteamController device = mBluetoothDevices.get(bluetoothDevice);
511
+ if (device == null)
512
+ return;
513
+
514
+ int id = device.getId();
515
+ mBluetoothDevices.remove(bluetoothDevice);
516
+ mDevicesById.remove(id);
517
+ device.shutdown();
518
+ HIDDeviceDisconnected(id);
519
+ }
520
+ }
521
+
522
+ boolean isSteamController(BluetoothDevice bluetoothDevice) {
523
+ // Sanity check. If you pass in a null device, by definition it is never a Steam Controller.
524
+ if (bluetoothDevice == null) {
525
+ return false;
526
+ }
527
+
528
+ // If the device has no local name, we really don't want to try an equality check against it.
529
+ if (bluetoothDevice.getName() == null) {
530
+ return false;
531
+ }
532
+
533
+ // Steam Controllers will always support Bluetooth Low Energy
534
+ if ((bluetoothDevice.getType() & BluetoothDevice.DEVICE_TYPE_LE) == 0) {
535
+ return false;
536
+ }
537
+
538
+ // Match on the name either the original Steam Controller or the new second-generation one advertise with.
539
+ return bluetoothDevice.getName().equals("SteamController") || bluetoothDevice.getName().startsWith("Steam Ctrl");
540
+ }
541
+
542
+ private void close() {
543
+ shutdownUSB();
544
+ shutdownBluetooth();
545
+ synchronized (this) {
546
+ for (HIDDevice device : mDevicesById.values()) {
547
+ device.shutdown();
548
+ }
549
+ mDevicesById.clear();
550
+ mBluetoothDevices.clear();
551
+ HIDDeviceReleaseCallback();
552
+ }
553
+ }
554
+
555
+ public void setFrozen(boolean frozen) {
556
+ synchronized (this) {
557
+ for (HIDDevice device : mDevicesById.values()) {
558
+ device.setFrozen(frozen);
559
+ }
560
+ }
561
+ }
562
+
563
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
564
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
565
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
566
+
567
+ private HIDDevice getDevice(int id) {
568
+ synchronized (this) {
569
+ HIDDevice result = mDevicesById.get(id);
570
+ if (result == null) {
571
+ Log.v(TAG, "No device for id: " + id);
572
+ Log.v(TAG, "Available devices: " + mDevicesById.keySet());
573
+ }
574
+ return result;
575
+ }
576
+ }
577
+
578
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
579
+ ////////// JNI interface functions
580
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
581
+
582
+ boolean initialize(boolean usb, boolean bluetooth) {
583
+ Log.v(TAG, "initialize(" + usb + ", " + bluetooth + ")");
584
+
585
+ if (usb) {
586
+ initializeUSB();
587
+ }
588
+ if (bluetooth) {
589
+ initializeBluetooth();
590
+ }
591
+ return true;
592
+ }
593
+
594
+ boolean openDevice(int deviceID) {
595
+ Log.v(TAG, "openDevice deviceID=" + deviceID);
596
+ HIDDevice device = getDevice(deviceID);
597
+ if (device == null) {
598
+ HIDDeviceDisconnected(deviceID);
599
+ return false;
600
+ }
601
+
602
+ // Look to see if this is a USB device and we have permission to access it
603
+ UsbDevice usbDevice = device.getDevice();
604
+ if (usbDevice != null && !mUsbManager.hasPermission(usbDevice)) {
605
+ HIDDeviceOpenPending(deviceID);
606
+ try {
607
+ final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31
608
+ int flags;
609
+ if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
610
+ flags = FLAG_MUTABLE;
611
+ } else {
612
+ flags = 0;
613
+ }
614
+
615
+ Intent intent = new Intent(HIDDeviceManager.ACTION_USB_PERMISSION);
616
+ intent.setPackage(mContext.getPackageName());
617
+ mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, intent, flags));
618
+ } catch (Exception e) {
619
+ Log.v(TAG, "Couldn't request permission for USB device " + usbDevice);
620
+ HIDDeviceOpenResult(deviceID, false);
621
+ }
622
+ return false;
623
+ }
624
+
625
+ try {
626
+ return device.open();
627
+ } catch (Exception e) {
628
+ Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
629
+ }
630
+ return false;
631
+ }
632
+
633
+ int writeReport(int deviceID, byte[] report, boolean feature) {
634
+ try {
635
+ //Log.v(TAG, "writeReport deviceID=" + deviceID + " length=" + report.length);
636
+ HIDDevice device;
637
+ device = getDevice(deviceID);
638
+ if (device == null) {
639
+ HIDDeviceDisconnected(deviceID);
640
+ return -1;
641
+ }
642
+
643
+ return device.writeReport(report, feature);
644
+ } catch (Exception e) {
645
+ Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
646
+ }
647
+ return -1;
648
+ }
649
+
650
+ boolean readReport(int deviceID, byte[] report, boolean feature) {
651
+ try {
652
+ //Log.v(TAG, "readReport deviceID=" + deviceID);
653
+ HIDDevice device;
654
+ device = getDevice(deviceID);
655
+ if (device == null) {
656
+ HIDDeviceDisconnected(deviceID);
657
+ return false;
658
+ }
659
+
660
+ return device.readReport(report, feature);
661
+ } catch (Exception e) {
662
+ Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
663
+ }
664
+ return false;
665
+ }
666
+
667
+ void closeDevice(int deviceID) {
668
+ try {
669
+ Log.v(TAG, "closeDevice deviceID=" + deviceID);
670
+ HIDDevice device;
671
+ device = getDevice(deviceID);
672
+ if (device == null) {
673
+ HIDDeviceDisconnected(deviceID);
674
+ return;
675
+ }
676
+
677
+ device.close();
678
+ } catch (Exception e) {
679
+ Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
680
+ }
681
+ }
682
+
683
+
684
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
685
+ /////////////// Native methods
686
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
687
+
688
+ private native void HIDDeviceRegisterCallback();
689
+ private native void HIDDeviceReleaseCallback();
690
+
691
+ native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number, int interface_class, int interface_subclass, int interface_protocol, boolean bBluetooth, int reportID);
692
+ native void HIDDeviceOpenPending(int deviceID);
693
+ native void HIDDeviceOpenResult(int deviceID, boolean opened);
694
+ native void HIDDeviceDisconnected(int deviceID);
695
+
696
+ native void HIDDeviceInputReport(int deviceID, byte[] report);
697
+ native void HIDDeviceReportResponse(int deviceID, byte[] report);
698
+ }