devicely 2.1.5 → 2.1.6

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.
@@ -1,476 +0,0 @@
1
- #!/bin/bash
2
- # Android Multi-Device Manager - Enhanced with Connect All, Disconnect All, Select All, Deselect All
3
-
4
- # Session tracking files (persistent across invocations)
5
- DEVICE_SESSIONS_FILE="/tmp/android_multi_sessions"
6
- DEVICE_PORTS_FILE="/tmp/android_multi_ports"
7
- SCRIPT_DIR="$(dirname "$0")"
8
- # Check for config files in both local and npm package locations
9
- if [ -f "$SCRIPT_DIR/devices.conf" ]; then
10
- CONFIG_FILE="$SCRIPT_DIR/devices.conf"
11
- elif [ -f "$SCRIPT_DIR/../../config/devices.conf" ]; then
12
- CONFIG_FILE="$SCRIPT_DIR/../../config/devices.conf"
13
- else
14
- echo "❌ Required file not found: devices.conf"
15
- exit 1
16
- fi
17
-
18
- # Colors
19
- GREEN='\033[0;32m'
20
- YELLOW='\033[1;33m'
21
- RED='\033[0;31m'
22
- CYAN='\033[0;36m'
23
- BLUE='\033[0;34m'
24
- NC='\033[0m'
25
-
26
- # Initialize UIAutomator2 and create persistent session
27
- init_device_session() {
28
- local serial=$1
29
- local device_name=$2
30
-
31
- echo -e "${YELLOW}🚀 Initializing UIAutomator2 session for $device_name...${NC}"
32
-
33
- # Check if already has active session
34
- if [ -f "$DEVICE_SESSIONS_FILE" ]; then
35
- local existing=$(grep "^$serial:" "$DEVICE_SESSIONS_FILE" 2>/dev/null)
36
- if [ -n "$existing" ]; then
37
- local port=$(echo "$existing" | awk -F':' '{print $NF}')
38
- local session=$(echo "$existing" | awk -F':' '{print $(NF-1)}')
39
-
40
- # Verify session still active
41
- if curl -s "http://localhost:$port/wd/hub/session/$session/status" &>/dev/null 2>&1; then
42
- echo -e "${GREEN}✅ Using existing session (port $port)${NC}"
43
- return 0
44
- else
45
- # Clean up stale entry
46
- sed -i.bak "/^$serial:/d" "$DEVICE_SESSIONS_FILE" 2>/dev/null
47
- sed -i.bak "/^$serial:/d" "$DEVICE_PORTS_FILE" 2>/dev/null
48
- fi
49
- fi
50
- fi
51
-
52
- # Find available port
53
- local port=$((6790 + RANDOM % 1000))
54
-
55
- # Start UIAutomator2 server
56
- adb -s "$serial" shell am instrument -w -e disableAnalytics true \
57
- io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner &>/dev/null &
58
-
59
- # Port forward
60
- adb -s "$serial" forward tcp:$port tcp:6790
61
-
62
- # Wait for server
63
- echo -e "${CYAN} Waiting for UIAutomator2...${NC}"
64
- local retries=0
65
- while [ $retries -lt 20 ]; do
66
- if curl -s "http://localhost:$port/wd/hub/status" &>/dev/null; then
67
- echo -e "${GREEN} ✓ Server ready${NC}"
68
- break
69
- fi
70
- sleep 1
71
- ((retries++))
72
- done
73
-
74
- if [ $retries -eq 20 ]; then
75
- echo -e "${RED} ✗ Server failed to start${NC}"
76
- return 1
77
- fi
78
-
79
- # Create session
80
- echo -e "${CYAN} Creating session...${NC}"
81
- curl -s -X POST "http://localhost:$port/wd/hub/session" \
82
- -H "Content-Type: application/json" \
83
- -d '{"capabilities":{"alwaysMatch":{"platformName":"Android","automationName":"UiAutomator2"}}}' \
84
- > /tmp/uia2_session_$$.json 2>/dev/null
85
-
86
- local session_id=$(python3 -c "
87
- import json
88
- try:
89
- with open('/tmp/uia2_session_$$.json') as f:
90
- data = json.load(f)
91
- sid = data.get('sessionId', data.get('value', {}).get('sessionId', ''))
92
- if sid: print(sid)
93
- except: pass
94
- " 2>/dev/null)
95
-
96
- rm -f /tmp/uia2_session_$$.json
97
-
98
- if [ -z "$session_id" ]; then
99
- echo -e "${RED} ✗ Failed to create session${NC}"
100
- return 1
101
- fi
102
-
103
- # Store session info
104
- echo "$serial:$session_id:$port" >> "$DEVICE_SESSIONS_FILE"
105
- echo "$serial:$port" >> "$DEVICE_PORTS_FILE"
106
-
107
- echo -e "${GREEN}✅ Session ready: $session_id (port $port)${NC}"
108
- return 0
109
- }
110
-
111
- # Connect wireless device
112
- connect_wireless() {
113
- local ip=$1
114
- local port=${2:-5555}
115
- local device_name=${3:-"Android-$ip"}
116
-
117
- echo -e "${CYAN}📱 Connecting to $device_name ($ip:$port)...${NC}"
118
-
119
- local result=$(adb connect "$ip:$port" 2>&1)
120
- if echo "$result" | grep -q "connected\|already connected"; then
121
- echo -e "${GREEN}✅ ADB connected${NC}"
122
- init_device_session "$ip:$port" "$device_name"
123
- return $?
124
- else
125
- echo -e "${RED}❌ Connection failed: $result${NC}"
126
- return 1
127
- fi
128
- }
129
-
130
- # Get all Android devices from config
131
- get_android_devices_from_config() {
132
- if [ ! -f "$CONFIG_FILE" ]; then
133
- return
134
- fi
135
-
136
- while IFS=',' read -r name type rest; do
137
- [[ "$name" =~ ^# ]] || [[ -z "$name" ]] && continue
138
- if [[ "$type" == "android-wireless" ]]; then
139
- echo "$name,$rest"
140
- fi
141
- done < "$CONFIG_FILE"
142
- }
143
-
144
- # Connect all devices from config
145
- connect_all_devices() {
146
- echo -e "${YELLOW}🔌 Connecting all Android devices from config...${NC}"
147
- echo ""
148
-
149
- local connected_count=0
150
- local failed_count=0
151
-
152
- while IFS=',' read -r name rest; do
153
- if [ -n "$name" ]; then
154
- local ip=$(echo "$rest" | awk -F',' '{print $1}')
155
- local port=$(echo "$rest" | awk -F',' '{print $2}')
156
- port=${port:-5555}
157
-
158
- echo -e "${BLUE}Connecting: $name${NC}"
159
- if connect_wireless "$ip" "$port" "$name"; then
160
- ((connected_count++))
161
- else
162
- ((failed_count++))
163
- fi
164
- echo ""
165
- fi
166
- done < <(get_android_devices_from_config)
167
-
168
- echo -e "${GREEN}✅ Connected: $connected_count${NC}"
169
- [ $failed_count -gt 0 ] && echo -e "${RED}❌ Failed: $failed_count${NC}"
170
- }
171
-
172
- # Disconnect device
173
- disconnect_device() {
174
- local serial=$1
175
-
176
- echo -e "${YELLOW}🔌 Disconnecting $serial...${NC}"
177
-
178
- if [ -f "$DEVICE_SESSIONS_FILE" ]; then
179
- local info=$(grep "^$serial:" "$DEVICE_SESSIONS_FILE" 2>/dev/null)
180
- if [ -n "$info" ]; then
181
- local session_id=$(echo "$info" | awk -F':' '{print $(NF-1)}')
182
- local port=$(echo "$info" | awk -F':' '{print $NF}')
183
-
184
- # Delete session
185
- curl -s -X DELETE "http://localhost:$port/wd/hub/session/$session_id" &>/dev/null
186
- echo -e "${CYAN} ✓ Session closed${NC}"
187
-
188
- # Remove port forward
189
- adb -s "$serial" forward --remove "tcp:$port" 2>/dev/null
190
- echo -e "${CYAN} ✓ Port removed${NC}"
191
- fi
192
- fi
193
-
194
- # Disconnect ADB
195
- if [[ "$serial" == *":"* ]]; then
196
- adb disconnect "$serial" &>/dev/null
197
- echo -e "${CYAN} ✓ ADB disconnected${NC}"
198
- fi
199
-
200
- # Clean up tracking files
201
- sed -i.bak "/^$serial:/d" "$DEVICE_SESSIONS_FILE" 2>/dev/null
202
- sed -i.bak "/^$serial:/d" "$DEVICE_PORTS_FILE" 2>/dev/null
203
-
204
- echo -e "${GREEN}✅ Disconnected${NC}"
205
- }
206
-
207
- # Disconnect all devices
208
- disconnect_all_devices() {
209
- echo -e "${YELLOW}🔌 Disconnecting all devices...${NC}"
210
- echo ""
211
-
212
- if [ ! -f "$DEVICE_SESSIONS_FILE" ] || [ ! -s "$DEVICE_SESSIONS_FILE" ]; then
213
- echo -e "${YELLOW} No devices connected${NC}"
214
- return
215
- fi
216
-
217
- local count=0
218
- while IFS=: read -r serial session_id port; do
219
- disconnect_device "$serial"
220
- ((count++))
221
- echo ""
222
- done < "$DEVICE_SESSIONS_FILE"
223
-
224
- rm -f "$DEVICE_SESSIONS_FILE" "$DEVICE_PORTS_FILE"
225
- echo -e "${GREEN}✅ Disconnected $count device(s)${NC}"
226
- }
227
-
228
- # List devices
229
- list_devices() {
230
- echo -e "${CYAN}📱 Connected Devices:${NC}"
231
- echo ""
232
-
233
- if [ ! -f "$DEVICE_SESSIONS_FILE" ] || [ ! -s "$DEVICE_SESSIONS_FILE" ]; then
234
- echo -e "${YELLOW} No devices with active sessions${NC}"
235
- return
236
- fi
237
-
238
- local index=1
239
- local active_count=0
240
- while IFS=: read -r serial session_id port; do
241
- if curl -s "http://localhost:$port/wd/hub/status" &>/dev/null; then
242
- echo -e "${GREEN} $index. ✅ $serial (port $port, session ${session_id:0:8}...)${NC}"
243
- ((active_count++))
244
- else
245
- echo -e "${RED} $index. ❌ $serial (stale - cleaning up)${NC}"
246
- disconnect_device "$serial" &>/dev/null
247
- fi
248
- ((index++))
249
- done < "$DEVICE_SESSIONS_FILE"
250
-
251
- echo ""
252
- echo -e "${CYAN}Total active: $active_count${NC}"
253
- }
254
-
255
- # Device selection management
256
- select_devices_interactive() {
257
- if [ ! -f "$DEVICE_SESSIONS_FILE" ] || [ ! -s "$DEVICE_SESSIONS_FILE" ]; then
258
- echo -e "${RED}❌ No connected devices to select${NC}"
259
- return
260
- fi
261
-
262
- # Load connected devices
263
- local -a ALL_DEVICES
264
- while IFS=: read -r serial rest; do
265
- ALL_DEVICES+=("$serial")
266
- done < "$DEVICE_SESSIONS_FILE"
267
-
268
- # Initialize selection (all selected by default)
269
- local -a SELECTED_DEVICES=("${ALL_DEVICES[@]}")
270
-
271
- while true; do
272
- echo ""
273
- echo -e "${CYAN}╔═══════════════════════════════════════╗${NC}"
274
- echo -e "${CYAN}║ Device Selection Manager ║${NC}"
275
- echo -e "${CYAN}╚═══════════════════════════════════════╝${NC}"
276
- echo ""
277
-
278
- # Show devices with selection status
279
- for i in "${!ALL_DEVICES[@]}"; do
280
- local device="${ALL_DEVICES[$i]}"
281
- local is_selected="⬜"
282
- if [[ " ${SELECTED_DEVICES[*]} " == *" $device "* ]]; then
283
- is_selected="✅"
284
- fi
285
- echo -e " $((i+1)). $is_selected $device"
286
- done
287
-
288
- echo ""
289
- echo -e "${CYAN}Commands:${NC}"
290
- echo -e "${YELLOW} all - Select all devices${NC}"
291
- echo -e "${YELLOW} none - Deselect all devices${NC}"
292
- echo -e "${YELLOW} 1,2,3 - Select specific devices by numbers${NC}"
293
- echo -e "${YELLOW} +1,2 - Add devices to selection${NC}"
294
- echo -e "${YELLOW} -1,2 - Remove devices from selection${NC}"
295
- echo -e "${YELLOW} toggle 1,2 - Toggle device selection${NC}"
296
- echo -e "${YELLOW} list - Show current selection${NC}"
297
- echo -e "${YELLOW} done - Finish selection${NC}"
298
- echo ""
299
-
300
- read -e -p "Selection > " DEVICE_CMD
301
-
302
- case "$DEVICE_CMD" in
303
- "done"|"exit"|"")
304
- break
305
- ;;
306
- "all")
307
- SELECTED_DEVICES=("${ALL_DEVICES[@]}")
308
- echo -e "${GREEN}✅ All devices selected: $(IFS=', '; echo "${SELECTED_DEVICES[*]}")${NC}"
309
- ;;
310
- "none"|"clear")
311
- SELECTED_DEVICES=()
312
- echo -e "${YELLOW}🔄 All devices deselected${NC}"
313
- ;;
314
- "list"|"show")
315
- if [ ${#SELECTED_DEVICES[@]} -eq 0 ]; then
316
- echo -e "${RED}❌ No devices selected${NC}"
317
- else
318
- echo -e "${GREEN}✅ Selected: $(IFS=', '; echo "${SELECTED_DEVICES[*]}")${NC}"
319
- fi
320
- ;;
321
- +*)
322
- # Add devices
323
- add_nums="${DEVICE_CMD:1}"
324
- IFS=',' read -ra NUMS <<< "$add_nums"
325
- for num in "${NUMS[@]}"; do
326
- num=$(echo "$num" | xargs)
327
- if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#ALL_DEVICES[@]} ]; then
328
- device="${ALL_DEVICES[$((num-1))]}"
329
- if [[ ! " ${SELECTED_DEVICES[*]} " == *" $device "* ]]; then
330
- SELECTED_DEVICES+=("$device")
331
- echo -e "${GREEN}✅ Added: $device${NC}"
332
- fi
333
- fi
334
- done
335
- ;;
336
- -*)
337
- # Remove devices
338
- remove_nums="${DEVICE_CMD:1}"
339
- IFS=',' read -ra NUMS <<< "$remove_nums"
340
- for num in "${NUMS[@]}"; do
341
- num=$(echo "$num" | xargs)
342
- if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#ALL_DEVICES[@]} ]; then
343
- device="${ALL_DEVICES[$((num-1))]}"
344
- new_selected=()
345
- for selected in "${SELECTED_DEVICES[@]}"; do
346
- if [ "$selected" != "$device" ]; then
347
- new_selected+=("$selected")
348
- fi
349
- done
350
- SELECTED_DEVICES=("${new_selected[@]}")
351
- echo -e "${YELLOW}➖ Removed: $device${NC}"
352
- fi
353
- done
354
- ;;
355
- toggle*)
356
- # Toggle devices
357
- toggle_nums="${DEVICE_CMD#toggle }"
358
- IFS=',' read -ra NUMS <<< "$toggle_nums"
359
- for num in "${NUMS[@]}"; do
360
- num=$(echo "$num" | xargs)
361
- if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#ALL_DEVICES[@]} ]; then
362
- device="${ALL_DEVICES[$((num-1))]}"
363
- if [[ " ${SELECTED_DEVICES[*]} " == *" $device "* ]]; then
364
- # Remove from selection
365
- new_selected=()
366
- for selected in "${SELECTED_DEVICES[@]}"; do
367
- if [ "$selected" != "$device" ]; then
368
- new_selected+=("$selected")
369
- fi
370
- done
371
- SELECTED_DEVICES=("${new_selected[@]}")
372
- echo -e "${YELLOW}⬜ Deselected: $device${NC}"
373
- else
374
- # Add to selection
375
- SELECTED_DEVICES+=("$device")
376
- echo -e "${GREEN}✅ Selected: $device${NC}"
377
- fi
378
- fi
379
- done
380
- ;;
381
- [0-9]*)
382
- # Direct number selection
383
- SELECTED_DEVICES=()
384
- IFS=',' read -ra NUMS <<< "$DEVICE_CMD"
385
- for num in "${NUMS[@]}"; do
386
- num=$(echo "$num" | xargs)
387
- if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#ALL_DEVICES[@]} ]; then
388
- SELECTED_DEVICES+=("${ALL_DEVICES[$((num-1))]}")
389
- fi
390
- done
391
- if [ ${#SELECTED_DEVICES[@]} -gt 0 ]; then
392
- echo -e "${GREEN}✅ Selected: $(IFS=', '; echo "${SELECTED_DEVICES[*]}")${NC}"
393
- else
394
- echo -e "${RED}❌ No valid device numbers provided${NC}"
395
- fi
396
- ;;
397
- *)
398
- echo -e "${RED}❌ Unknown command: $DEVICE_CMD${NC}"
399
- ;;
400
- esac
401
- done
402
-
403
- if [ ${#SELECTED_DEVICES[@]} -eq 0 ]; then
404
- SELECTED_DEVICES=("${ALL_DEVICES[@]}")
405
- echo -e "${YELLOW}⚠️ No devices selected, using all devices${NC}"
406
- fi
407
-
408
- echo ""
409
- echo -e "${CYAN}🎯 Selected devices: $(IFS=', '; echo "${SELECTED_DEVICES[*]}")${NC}"
410
- }
411
-
412
- # Main menu
413
- show_menu() {
414
- echo ""
415
- echo -e "${CYAN}╔══════════════════════════════════════════════════╗${NC}"
416
- echo -e "${CYAN}║ Android Multi-Device Manager (Enhanced) ║${NC}"
417
- echo -e "${CYAN}╚══════════════════════════════════════════════════╝${NC}"
418
- echo ""
419
- echo "1. Connect Wireless Device"
420
- echo "2. Connect All Devices (from config)"
421
- echo "3. List Connected Devices"
422
- echo "4. Disconnect Device"
423
- echo "5. Disconnect All Devices"
424
- echo "6. Select/Manage Devices"
425
- echo "7. Exit"
426
- echo ""
427
- }
428
-
429
- # Main loop
430
- while true; do
431
- show_menu
432
- read -p "Select option: " choice
433
-
434
- case $choice in
435
- 1)
436
- read -p "IP Address: " ip
437
- read -p "Port [5555]: " port
438
- port=${port:-5555}
439
- read -p "Device Name [optional]: " name
440
- echo ""
441
- connect_wireless "$ip" "$port" "$name"
442
- ;;
443
- 2)
444
- echo ""
445
- connect_all_devices
446
- ;;
447
- 3)
448
- echo ""
449
- list_devices
450
- ;;
451
- 4)
452
- echo ""
453
- list_devices
454
- echo ""
455
- read -p "Serial (e.g., 192.168.1.100:5555): " serial
456
- echo ""
457
- disconnect_device "$serial"
458
- ;;
459
- 5)
460
- echo ""
461
- disconnect_all_devices
462
- ;;
463
- 6)
464
- select_devices_interactive
465
- ;;
466
- 7)
467
- echo -e "${YELLOW}Exit (sessions remain active)${NC}"
468
- exit 0
469
- ;;
470
- *)
471
- echo -e "${RED}Invalid option${NC}"
472
- ;;
473
- esac
474
-
475
- read -p "Press Enter to continue..."
476
- done