aboutsummaryrefslogtreecommitdiff
path: root/src/io/appium/droiddriver/helpers/DroidDrivers.java
blob: 7725bf5650b34022e5c28d901ba1b702446382b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * 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.helpers;

import android.annotation.TargetApi;
import android.app.Instrumentation;
import android.os.Build;

import io.appium.droiddriver.DroidDriver;
import io.appium.droiddriver.exceptions.DroidDriverException;
import io.appium.droiddriver.instrumentation.InstrumentationDriver;
import io.appium.droiddriver.uiautomation.UiAutomationDriver;
import io.appium.droiddriver.util.InstrumentationUtils;

/**
 * Static utility methods using a singleton {@link DroidDriver} instance. This class is NOT
 * required, but it is handy and using a singleton driver can avoid memory leak when you have many
 * instances around (for example, one in every test - JUnit framework keeps the test instances in
 * memory after running them).
 */
public class DroidDrivers {
  private static DroidDriver driver;

  /**
   * Gets the singleton driver. Throws if {@link #setSingleton} has not been called.
   */
  public static DroidDriver get() {
    if (driver == null) {
      throw new DroidDriverException("setSingleton() has not been called");
    }
    return driver;
  }

  /**
   * Sets the singleton driver.
   */
  public static void setSingleton(DroidDriver driver) {
    if (DroidDrivers.driver != null) {
      throw new DroidDriverException("setSingleton() can only be called once");
    }
    DroidDrivers.driver = driver;
  }

  /**
   * Returns whether the running target (device or emulator) has {@link android.app.UiAutomation}
   * API, which is introduced in SDK API 18 (JELLY_BEAN_MR2).
   */
  public static boolean hasUiAutomation() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
  }

  /**
   * Returns a new DroidDriver instance. If am instrument options have "driver", treat it as the
   * fully-qualified-class-name and create a new instance of it with {@code instrumentation} as the
   * argument; otherwise a new platform-dependent default DroidDriver instance.
   */
  public static DroidDriver newDriver() {
    Instrumentation instrumentation = InstrumentationUtils.getInstrumentation();
    String driverClass = InstrumentationUtils.getD2Option("driver");
    if (driverClass != null) {
      try {
        return (DroidDriver) Class.forName(driverClass).getConstructor(Instrumentation.class)
            .newInstance(instrumentation);
      } catch (Throwable t) {
        throw DroidDriverException.propagate(t);
      }
    }

    // If "dd.driver" is not specified, return default.
    if (hasUiAutomation()) {
      checkUiAutomation();
      return new UiAutomationDriver(instrumentation);
    }
    return new InstrumentationDriver(instrumentation);
  }

  /** Checks if UiAutomation API is available */
  @TargetApi(18)
  public static void checkUiAutomation() {
    if (!hasUiAutomation()) {
      throw new DroidDriverException("UiAutomation is not available below API 18. "
          + "See http://developer.android.com/reference/android/app/UiAutomation.html");
    }
    if (InstrumentationUtils.getInstrumentation().getUiAutomation() == null) {
      throw new DroidDriverException(
          "uiAutomation==null: did you forget to set '-w' flag for 'am instrument'?");
    }
  }
}