guard against use of UiDevice prior to its initialization

The source of UI automation permission use to come from the fact
that the test is running as shell or root user; in this case,
it's fine to statically initialize UiDevice.

When running as an Instrumentation, the source of UI automation
permission comes from the privileged token created by system and
passed down via Instrumentation context; in this case, UiDevice
is not properly initialized until it has received the
UiAutomation instance. The particular problem happens when
statically declared UiObject makes use of
UiDevice#getAutomatorBridge() too early: UiObject really
shouldn't be declared statically

Change-Id: If0ecab9960c588c096ed2fb8cc431ef79caa963e
diff --git a/uiautomator/library/core-src/com/android/uiautomator/core/UiDevice.java b/uiautomator/library/core-src/com/android/uiautomator/core/UiDevice.java
index 5a2f3a7..fc23cdf 100644
--- a/uiautomator/library/core-src/com/android/uiautomator/core/UiDevice.java
+++ b/uiautomator/library/core-src/com/android/uiautomator/core/UiDevice.java
@@ -83,6 +83,9 @@
      * @return {@link ShellUiAutomatorBridge}
      */
     UiAutomatorBridge getAutomatorBridge() {
+        if (mUiAutomationBridge == null) {
+            throw new RuntimeException("UiDevice not initialized");
+        }
         return mUiAutomationBridge;
     }
 
@@ -97,7 +100,7 @@
      * @since API Level 18
      */
     public void setCompressedLayoutHeirarchy(boolean compressed) {
-        mUiAutomationBridge.setCompressedLayoutHierarchy(compressed);
+        getAutomatorBridge().setCompressedLayoutHierarchy(compressed);
     }
 
     /**
@@ -123,7 +126,7 @@
      */
     public Point getDisplaySizeDp() {
         Tracer.trace();
-        Display display = mUiAutomationBridge.getDefaultDisplay();
+        Display display = getAutomatorBridge().getDefaultDisplay();
         Point p = new Point();
         display.getRealSize(p);
         DisplayMetrics metrics = new DisplayMetrics();
@@ -166,7 +169,7 @@
      */
     public String getLastTraversedText() {
         Tracer.trace();
-        return mUiAutomationBridge.getQueryController().getLastTraversedText();
+        return getAutomatorBridge().getQueryController().getLastTraversedText();
     }
 
     /**
@@ -176,7 +179,7 @@
      */
     public void clearLastTraversedText() {
         Tracer.trace();
-        mUiAutomationBridge.getQueryController().clearLastTraversedText();
+        getAutomatorBridge().getQueryController().clearLastTraversedText();
     }
 
     /**
@@ -187,7 +190,7 @@
     public boolean pressMenu() {
         Tracer.trace();
         waitForIdle();
-        return mUiAutomationBridge.getInteractionController().sendKeyAndWaitForEvent(
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
                 KeyEvent.KEYCODE_MENU, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
                 KEY_PRESS_EVENT_TIMEOUT);
     }
@@ -200,7 +203,7 @@
     public boolean pressBack() {
         Tracer.trace();
         waitForIdle();
-        return mUiAutomationBridge.getInteractionController().sendKeyAndWaitForEvent(
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
                 KeyEvent.KEYCODE_BACK, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
                 KEY_PRESS_EVENT_TIMEOUT);
     }
@@ -213,7 +216,7 @@
     public boolean pressHome() {
         Tracer.trace();
         waitForIdle();
-        return mUiAutomationBridge.getInteractionController().sendKeyAndWaitForEvent(
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
                 KeyEvent.KEYCODE_HOME, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
                 KEY_PRESS_EVENT_TIMEOUT);
     }
@@ -308,7 +311,7 @@
     public boolean pressKeyCode(int keyCode) {
         Tracer.trace(keyCode);
         waitForIdle();
-        return mUiAutomationBridge.getInteractionController().sendKey(keyCode, 0);
+        return getAutomatorBridge().getInteractionController().sendKey(keyCode, 0);
     }
 
     /**
@@ -323,7 +326,7 @@
     public boolean pressKeyCode(int keyCode, int metaState) {
         Tracer.trace(keyCode, metaState);
         waitForIdle();
-        return mUiAutomationBridge.getInteractionController().sendKey(keyCode, metaState);
+        return getAutomatorBridge().getInteractionController().sendKey(keyCode, metaState);
     }
 
     /**
@@ -371,7 +374,7 @@
      */
     public int getDisplayWidth() {
         Tracer.trace();
-        Display display = mUiAutomationBridge.getDefaultDisplay();
+        Display display = getAutomatorBridge().getDefaultDisplay();
         Point p = new Point();
         display.getSize(p);
         return p.x;
@@ -385,7 +388,7 @@
      */
     public int getDisplayHeight() {
         Tracer.trace();
-        Display display = mUiAutomationBridge.getDefaultDisplay();
+        Display display = getAutomatorBridge().getDefaultDisplay();
         Point p = new Point();
         display.getSize(p);
         return p.y;
@@ -422,7 +425,7 @@
      */
     public boolean swipe(int startX, int startY, int endX, int endY, int steps) {
         Tracer.trace(startX, startY, endX, endY, steps);
-        return mUiAutomationBridge.getInteractionController()
+        return getAutomatorBridge().getInteractionController()
                 .swipe(startX, startY, endX, endY, steps);
     }
 
@@ -441,7 +444,7 @@
      */
     public boolean drag(int startX, int startY, int endX, int endY, int steps) {
         Tracer.trace(startX, startY, endX, endY, steps);
-        return mUiAutomationBridge.getInteractionController()
+        return getAutomatorBridge().getInteractionController()
                 .swipe(startX, startY, endX, endY, steps, true);
     }
 
@@ -456,7 +459,7 @@
      */
     public boolean swipe(Point[] segments, int segmentSteps) {
         Tracer.trace(segments, segmentSteps);
-        return mUiAutomationBridge.getInteractionController().swipe(segments, segmentSteps);
+        return getAutomatorBridge().getInteractionController().swipe(segments, segmentSteps);
     }
 
     /**
@@ -476,7 +479,7 @@
      */
     public void waitForIdle(long timeout) {
         Tracer.trace(timeout);
-        mUiAutomationBridge.waitForIdle(timeout);
+        getAutomatorBridge().waitForIdle(timeout);
     }
 
     /**
@@ -488,7 +491,7 @@
     @Deprecated
     public String getCurrentActivityName() {
         Tracer.trace();
-        return mUiAutomationBridge.getQueryController().getCurrentActivityName();
+        return getAutomatorBridge().getQueryController().getCurrentActivityName();
     }
 
     /**
@@ -498,7 +501,7 @@
      */
     public String getCurrentPackageName() {
         Tracer.trace();
-        return mUiAutomationBridge.getQueryController().getCurrentPackageName();
+        return getAutomatorBridge().getQueryController().getCurrentPackageName();
     }
 
     /**
@@ -620,7 +623,7 @@
     public boolean isNaturalOrientation() {
         Tracer.trace();
         waitForIdle();
-        int ret = mUiAutomationBridge.getRotation();
+        int ret = getAutomatorBridge().getRotation();
         return ret == UiAutomation.ROTATION_FREEZE_0 ||
                 ret == UiAutomation.ROTATION_FREEZE_180;
     }
@@ -632,7 +635,7 @@
     public int getDisplayRotation() {
         Tracer.trace();
         waitForIdle();
-        return mUiAutomationBridge.getRotation();
+        return getAutomatorBridge().getRotation();
     }
 
     /**
@@ -756,7 +759,7 @@
         AccessibilityNodeInfo root =
                 getAutomatorBridge().getQueryController().getAccessibilityRootNode();
         if(root != null) {
-            Display display = mUiAutomationBridge.getDefaultDisplay();
+            Display display = getAutomatorBridge().getDefaultDisplay();
             Point size = new Point();
             display.getSize(size);
             AccessibilityNodeInfoDumper.dumpWindowToFile(root,
@@ -840,6 +843,6 @@
      */
     public boolean takeScreenshot(File storePath, float scale, int quality) {
         Tracer.trace(storePath, scale, quality);
-        return mUiAutomationBridge.takeScreenshot(storePath, quality);
+        return getAutomatorBridge().takeScreenshot(storePath, quality);
     }
 }
diff --git a/uiautomator/library/core-src/com/android/uiautomator/core/UiObject.java b/uiautomator/library/core-src/com/android/uiautomator/core/UiObject.java
index 9fdfae5..4862ca5 100644
--- a/uiautomator/library/core-src/com/android/uiautomator/core/UiObject.java
+++ b/uiautomator/library/core-src/com/android/uiautomator/core/UiObject.java
@@ -65,7 +65,6 @@
     protected static final int FINGER_TOUCH_HALF_WIDTH = 20;
 
     private final UiSelector mSelector;
-    private final UiAutomatorBridge mUiAutomationBridge;
 
     private final Configurator mConfig = Configurator.getInstance();
 
@@ -76,7 +75,6 @@
      * @since API Level 16
      */
     public UiObject(UiSelector selector) {
-        mUiAutomationBridge = UiDevice.getInstance().getAutomatorBridge();
         mSelector = selector;
     }
 
@@ -99,7 +97,7 @@
      * @return {@link QueryController}
      */
     QueryController getQueryController() {
-        return mUiAutomationBridge.getQueryController();
+        return UiDevice.getInstance().getAutomatorBridge().getQueryController();
     }
 
     /**
@@ -109,7 +107,7 @@
      * @return {@link InteractionController}
      */
     InteractionController getInteractionController() {
-        return mUiAutomationBridge.getInteractionController();
+        return UiDevice.getInstance().getAutomatorBridge().getInteractionController();
     }
 
     /**