Skip to content

Commit a44993b

Browse files
committed
Handling uiautomator crash, restarting appium driver. This should handle when the emulator is relaunched.
1 parent 4d3b2aa commit a44993b

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

ansible/roles/android_root/tasks/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282

8383
- name: Download rootAVD script
8484
get_url:
85-
url: https://raw.githubusercontent.com/newbit1/rootAVD/master/rootAVD.sh
85+
url: https://gitlab.com/newbit/rootAVD/-/raw/master/rootAVD.sh
8686
dest: "{{ root_tools_dir }}/rootAVD.sh"
8787
mode: "0755"
8888
become: yes

ansible/roles/android_x86/tasks/main.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@
9595
- name: Create an x86 AVD in /opt/android-sdk/avd
9696
shell: |
9797
{{ android_home }}/cmdline-tools/latest/bin/avdmanager create avd -n {{ avd_name }} -k "{{ sys_img }}" --device "{{ device_skin }}" --force
98-
args:
99-
creates: "{{ android_home }}/avd/{{ avd_name }}.avd"
98+
# args:
99+
# creates: "{{ android_home }}/avd/{{ avd_name }}.avd"
100100
become: yes
101101
environment:
102102
ANDROID_SDK_ROOT: "{{ android_home }}"
@@ -147,7 +147,7 @@
147147
[Service]
148148
User={{ ansible_user }}
149149
WorkingDirectory={{ android_home }}
150-
ExecStart={{ android_home }}/emulator/emulator -avd {{ avd_name }} -no-window -no-audio -no-boot-anim -no-metrics -gpu swiftshader_indirect -accel off -no-snapshot -no-snapshot-load -no-snapshot-save
150+
ExecStart={{ android_home }}/emulator/emulator -avd {{ avd_name }} -no-window -no-audio -no-boot-anim -no-metrics -gpu swiftshader_indirect -accel off -no-snapshot -no-snapshot-load -no-snapshot-save -writable-system -selinux disabled -qemu -enable-kvm
151151
Restart=always
152152
StandardOutput=journal
153153
StandardError=journal

server/server.py

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from flask import Flask, make_response, redirect, request, send_file
1111
from flask_restful import Api, Resource
12+
from selenium.common import exceptions as selenium_exceptions
1213

1314
from automator import KindleAutomator
1415
from handlers.test_fixtures_handler import TestFixturesHandler
@@ -123,21 +124,48 @@ def post(self):
123124
return {"error": str(e)}, 500
124125

125126

127+
def handle_uiautomator_crash(f):
128+
"""Decorator to handle UiAutomator2 server crashes by restarting the driver."""
129+
130+
def wrapper(*args, **kwargs):
131+
try:
132+
return f(*args, **kwargs)
133+
except Exception as e:
134+
# Check if it's the UiAutomator2 server crash error
135+
if isinstance(e, selenium_exceptions.WebDriverException) and "cannot be proxied to UiAutomator2 server because the instrumentation process is not running" in str(e):
136+
logger.warning("UiAutomator2 server crashed. Attempting to restart driver...")
137+
if server.automator and server.automator.ensure_driver_running():
138+
# Retry the operation after driver restart
139+
logger.info("Driver restarted successfully. Retrying operation...")
140+
return f(*args, **kwargs)
141+
else:
142+
logger.error("Failed to restart driver after UiAutomator2 server crash")
143+
return {"error": "Failed to restart driver after UiAutomator2 server crash"}, 500
144+
# Re-raise other exceptions
145+
raise
146+
147+
return wrapper
148+
149+
126150
def ensure_automator_healthy(f):
127151
"""Decorator to ensure automator is initialized and healthy before each operation."""
128152

129-
def wrapper(*args, **kwargs):
130-
try:
131-
if not server.automator:
132-
logger.info("No automator found, initializing...")
133-
server.initialize_automator()
134-
if not server.automator.initialize_driver():
135-
return {"error": "Failed to initialize driver"}, 500
153+
@handle_uiautomator_crash
154+
def wrapped_function(*args, **kwargs):
155+
if not server.automator:
156+
logger.info("No automator found, initializing...")
157+
server.initialize_automator()
158+
if not server.automator.initialize_driver():
159+
return {"error": "Failed to initialize driver"}, 500
136160

137-
if not server.automator.ensure_driver_running():
138-
return {"error": "Failed to ensure driver is running"}, 500
161+
if not server.automator.ensure_driver_running():
162+
return {"error": "Failed to ensure driver is running"}, 500
139163

140-
return f(*args, **kwargs)
164+
return f(*args, **kwargs)
165+
166+
def wrapper(*args, **kwargs):
167+
try:
168+
return wrapped_function(*args, **kwargs)
141169
except Exception as e:
142170
logger.error(f"Error in automator health check: {e}")
143171
logger.error(f"Traceback: {traceback.format_exc()}")

0 commit comments

Comments
 (0)