aboutsummaryrefslogtreecommitdiff
path: root/src/io/appium/droiddriver/instrumentation/RootFinder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/io/appium/droiddriver/instrumentation/RootFinder.java')
-rw-r--r--src/io/appium/droiddriver/instrumentation/RootFinder.java95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/io/appium/droiddriver/instrumentation/RootFinder.java b/src/io/appium/droiddriver/instrumentation/RootFinder.java
new file mode 100644
index 0000000..0cdc54e
--- /dev/null
+++ b/src/io/appium/droiddriver/instrumentation/RootFinder.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 DroidDriver committers
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.appium.droiddriver.instrumentation;
+
+import android.os.Build;
+import android.view.View;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+import io.appium.droiddriver.exceptions.DroidDriverException;
+
+/**
+ * Class to find the root view.
+ */
+public class RootFinder {
+
+ private static final String VIEW_FIELD_NAME = "mViews";
+ private static final Field viewsField;
+ private static final Object windowManagerObj;
+
+ static {
+ String windowManagerClassName =
+ Build.VERSION.SDK_INT >= 17 ? "android.view.WindowManagerGlobal"
+ : "android.view.WindowManagerImpl";
+ String instanceMethod = Build.VERSION.SDK_INT >= 17 ? "getInstance" : "getDefault";
+ try {
+ Class<?> clazz = Class.forName(windowManagerClassName);
+ Method getMethod = clazz.getMethod(instanceMethod);
+ windowManagerObj = getMethod.invoke(null);
+ viewsField = clazz.getDeclaredField(VIEW_FIELD_NAME);
+ viewsField.setAccessible(true);
+ } catch (InvocationTargetException ite) {
+ throw new DroidDriverException(String.format("could not invoke: %s on %s", instanceMethod,
+ windowManagerClassName), ite.getCause());
+ } catch (ClassNotFoundException cnfe) {
+ throw new DroidDriverException(String.format("could not find class: %s",
+ windowManagerClassName), cnfe);
+ } catch (NoSuchFieldException nsfe) {
+ throw new DroidDriverException(String.format("could not find field: %s on %s",
+ VIEW_FIELD_NAME, windowManagerClassName), nsfe);
+ } catch (NoSuchMethodException nsme) {
+ throw new DroidDriverException(String.format("could not find method: %s on %s",
+ instanceMethod, windowManagerClassName), nsme);
+ } catch (RuntimeException re) {
+ throw new DroidDriverException(String.format(
+ "reflective setup failed using obj: %s method: %s field: %s", windowManagerClassName,
+ instanceMethod, VIEW_FIELD_NAME), re);
+ } catch (IllegalAccessException iae) {
+ throw new DroidDriverException(String.format(
+ "reflective setup failed using obj: %s method: %s field: %s", windowManagerClassName,
+ instanceMethod, VIEW_FIELD_NAME), iae);
+ }
+ }
+
+ /**
+ * @return a list of {@link View}s.
+ */
+ @SuppressWarnings("unchecked")
+ public static List<View> getRootViews() {
+ List<View> views = null;
+
+ try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ views = (List<View>) viewsField.get(windowManagerObj);
+ } else {
+ views = Arrays.asList((View[]) viewsField.get(windowManagerObj));
+ }
+ return views;
+ } catch (RuntimeException re) {
+ throw new DroidDriverException(String.format("Reflective access to %s on %s failed.",
+ viewsField, windowManagerObj), re);
+ } catch (IllegalAccessException iae) {
+ throw new DroidDriverException(String.format("Reflective access to %s on %s failed.",
+ viewsField, windowManagerObj), iae);
+ }
+ }
+}