DumpCommand.java revision 89f6117cb1fbeab3770106cf54e05af1f597be81
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.commands.uiautomator; 18 19import android.app.UiAutomation; 20import android.os.Environment; 21import android.view.accessibility.AccessibilityNodeInfo; 22 23import com.android.commands.uiautomator.Launcher.Command; 24import com.android.uiautomator.core.AccessibilityNodeInfoDumper; 25import com.android.uiautomator.core.UiAutomationShellWrapper; 26 27import java.io.File; 28import java.util.concurrent.TimeoutException; 29 30/** 31 * Implementation of the dump subcommand 32 * 33 * This creates an XML dump of current UI hierarchy 34 */ 35public class DumpCommand extends Command { 36 37 private static final File DEFAULT_DUMP_FILE = new File( 38 Environment.getLegacyExternalStorageDirectory(), "window_dump.xml"); 39 40 public DumpCommand() { 41 super("dump"); 42 } 43 44 @Override 45 public String shortHelp() { 46 return "creates an XML dump of current UI hierarchy"; 47 } 48 49 @Override 50 public String detailedOptions() { 51 return " dump [file]\n" 52 + " [file]: the location where the dumped XML should be stored, default is\n " 53 + DEFAULT_DUMP_FILE.getAbsolutePath() + "\n"; 54 } 55 56 @Override 57 public void run(String[] args) { 58 File dumpFile = DEFAULT_DUMP_FILE; 59 if (args.length > 0) { 60 dumpFile = new File(args[0]); 61 } 62 UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper(); 63 automationWrapper.connect(); 64 // It appears that the bridge needs time to be ready. Making calls to the 65 // bridge immediately after connecting seems to cause exceptions. So let's also 66 // do a wait for idle in case the app is busy. 67 try { 68 UiAutomation uiAutomation = automationWrapper.getUiAutomation(); 69 uiAutomation.waitForIdle(1000, 1000 * 10); 70 AccessibilityNodeInfo info = uiAutomation.getRootInActiveWindow(); 71 if (info == null) { 72 System.err.println("ERROR: null root node returned by UiTestAutomationBridge."); 73 return; 74 } 75 AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile); 76 } catch (TimeoutException re) { 77 System.err.println("ERROR: could not get idle state."); 78 return; 79 } finally { 80 automationWrapper.disconnect(); 81 } 82 System.out.println( 83 String.format("UI hierchary dumped to: %s", dumpFile.getAbsolutePath())); 84 } 85} 86