From f8137caf2afeb7ff926cb1c449a36d2ca395eecf Mon Sep 17 00:00:00 2001 From: Marc-Olivier Andrez Date: Tue, 6 Oct 2020 18:45:23 +0200 Subject: [PATCH] Fix XML parsing error when using MIUI 12 on Pocophone X3 #283 My script uses `AndroidViewClient` but cannot create a `ViewClient` ```python3 from com.dtmilano.android.viewclient import ViewClient def createViewClient(): return ViewClient(*ViewClient.connectToDeviceOrExit(serialno='.*')) vc = createViewClient() ``` The script returns the following stack trace: ```sh File "/home/bob/workspace/script.py", line 4, in createViewClient return ViewClient(*ViewClient.connectToDeviceOrExit(serialno='.*')) File "/home/bob/.local/lib/python3.6/site-packages/com/dtmilano/android/viewclient.py", line 2690, in __init__ self.dump() File "/home/bob/.local/lib/python3.6/site-packages/com/dtmilano/android/viewclient.py", line 3522, in dump self.setViewsFromUiAutomatorDump(received) File "/home/bob/.local/lib/python3.6/site-packages/com/dtmilano/android/viewclient.py", line 3105, in setViewsFromUiAutomatorDump self.__parseTreeFromUiAutomatorDump(received) File "/home/bob/.local/lib/python3.6/site-packages/com/dtmilano/android/viewclient.py", line 3323, in __parseTreeFromUiAutomatorDump self.root = parser.Parse(receivedXml[start_xml_index:end_xml_index + 1]) File "/home/bob/.local/lib/python3.6/site-packages/com/dtmilano/android/viewclient.py", line 2394, in Parse _ = parser.Parse(encoded, True) File "../Modules/pyexpat.c", line 284, in CharacterData File "/home/bob/.local/lib/python3.6/site-packages/com/dtmilano/android/viewclient.py", line 2381, in CharacterData element = self.nodeStack[-1] IndexError: list index out of range ``` When I execute the command `adb shell uiautomator dump` on my device a Pocophone X3 with MIUI 12 installed, I get the following result: ```sh adb shell uiautomator dump java.io.FileNotFoundException: /data/system/theme_config/theme_compatibility.xml: open failed: ENOENT (No such file or directory) at libcore.io.IoBridge.open(IoBridge.java:496) at java.io.FileInputStream.(FileInputStream.java:159) at java.io.FileInputStream.(FileInputStream.java:115) at java.io.FileReader.(FileReader.java:58) at miui.content.res.ThemeCompatibilityLoader.getVersion(ThemeCompatibilityLoader.java:108) at miui.content.res.ThemeCompatibilityLoader.getConfigDocumentTree(ThemeCompatibilityLoader.java:126) at miui.content.res.ThemeCompatibilityLoader.loadConfig(ThemeCompatibilityLoader.java:59) at miui.content.res.ThemeCompatibility.(ThemeCompatibility.java:31) at miui.content.res.ThemeCompatibility.isThemeEnabled(ThemeCompatibility.java:111) at android.content.res.MiuiResourcesImpl.(MiuiResourcesImpl.java:41) at android.content.res.Resources.(Resources.java:285) at android.content.res.MiuiResources.(MiuiResources.java:49) at android.content.res.Resources.getSystem(Resources.java:206) at android.util.MiuiMultiWindowAdapter.(MiuiMultiWindowAdapter.java:79) at android.view.Display.getSize(Display.java:665) at com.android.commands.uiautomator.DumpCommand.run(DumpCommand.java:98) at com.android.commands.uiautomator.Launcher.main(Launcher.java:83) at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:380) Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory) at libcore.io.Linux.open(Native Method) at libcore.io.ForwardingOs.open(ForwardingOs.java:167) at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252) at libcore.io.IoBridge.open(IoBridge.java:482) ... 18 more UI hierchary dumped to: /sdcard/window_dump.xml ``` So `uiautomator` throws an error, but still succeeds to dump the XML. The constructor of `ViewClient` calls `parser.Parse(receivedXml[start_xml_index:end_xml_index + 1])` [Ln 3323](https://github.com/dtmilano/AndroidViewClient/blob/master/src/com/dtmilano/android/viewclient.py#L3323), but the XML contained in `received` cannot be parsed because it still contains parts of the exceptions: `start_xml_index = receivedXml.index("<")` will return the first index of '<', which is in the exception (`java.io.FileInputStream.`). We fixed the issue by filtering out the exception from the `received` variable [Ln 3461](https://github.com/dtmilano/AndroidViewClient/blob/master/src/com/dtmilano/android/viewclient.py#L3460): ```python3 received = re.sub(re.compile('java.io.FileNotFoundException.*<\?xml', re.DOTALL),'") except ValueError: raise ValueError("received does not contain valid XML: " + receivedXml)