package com.robotium.solo; import android.app.Activity; import android.app.Instrumentation; import android.content.Context; import android.view.View; import android.view.Window; import android.widget.TextView; /** * Contains various get methods. Examples are: getView(int id), * getView(Class<T> classToFilterBy, int index). * * @author Renas Reda, renas.reda@robotium.com * */ class Getter { private final Instrumentation instrumentation; private final ActivityUtils activityUtils; private final Waiter waiter; private final int TIMEOUT = 1000; /** * Constructs this object. * * @param inst the {@code Instrumentation} instance * @param viewFetcher the {@code ViewFetcher} instance * @param waiter the {@code Waiter} instance */ public Getter(Instrumentation instrumentation, ActivityUtils activityUtils, Waiter waiter){ this.instrumentation = instrumentation; this.activityUtils = activityUtils; this.waiter = waiter; } /** * Returns a {@code View} with a certain index, from the list of current {@code View}s of the specified type. * * @param classToFilterBy which {@code View}s to choose from * @param index choose among all instances of this type, e.g. {@code Button.class} or {@code EditText.class} * @return a {@code View} with a certain index, from the list of current {@code View}s of the specified type */ public <T extends View> T getView(Class<T> classToFilterBy, int index) { return waiter.waitForAndGetView(index, classToFilterBy); } /** * Returns a {@code View} that shows a given text, from the list of current {@code View}s of the specified type. * * @param classToFilterBy which {@code View}s to choose from * @param text the text that the view shows * @param onlyVisible {@code true} if only visible texts on the screen should be returned * @return a {@code View} showing a given text, from the list of current {@code View}s of the specified type */ public <T extends TextView> T getView(Class<T> classToFilterBy, String text, boolean onlyVisible) { T viewToReturn = (T) waiter.waitForText(classToFilterBy, text, 0, Timeout.getSmallTimeout(), false, onlyVisible, false); if(viewToReturn == null) Log.e(Solo.LOG_TAG, classToFilterBy.getSimpleName() + " with text: '" + text + "' is not found!"); return viewToReturn; } /** * Returns a localized string * * @param id the resource ID for the string * @return the localized string */ public String getString(int id) { Activity activity = activityUtils.getCurrentActivity(false); if(activity == null){ return ""; } return activity.getString(id); } /** * Returns a localized string * * @param id the resource ID for the string * @return the localized string */ public String getString(String id) { Context targetContext = instrumentation.getTargetContext(); String packageName = targetContext.getPackageName(); int viewId = targetContext.getResources().getIdentifier(id, "string", packageName); if(viewId == 0){ viewId = targetContext.getResources().getIdentifier(id, "string", "android"); } return getString(viewId); } /** * Returns a {@code View} with a given id. * * @param id the R.id of the {@code View} to be returned * @param index the index of the {@link View}. {@code 0} if only one is available * @param timeout the timeout in milliseconds * @return a {@code View} with a given id */ public View getView(int id, int index, int timeout){ return waiter.waitForView(id, index, timeout); } /** * Returns a {@code View} with a given id. * * @param id the R.id of the {@code View} to be returned * @param index the index of the {@link View}. {@code 0} if only one is available * @return a {@code View} with a given id */ public View getView(int id, int index){ return getView(id, index, 0); } /** * Returns a {@code View} with a given id. * * @param id the id of the {@link View} to return * @param index the index of the {@link View}. {@code 0} if only one is available * @return a {@code View} with a given id */ public View getView(String id, int index){ View viewToReturn = null; Context targetContext = instrumentation.getTargetContext(); String packageName = targetContext.getPackageName(); int viewId = targetContext.getResources().getIdentifier(id, "id", packageName); if(viewId != 0){ viewToReturn = getView(viewId, index, TIMEOUT); } if(viewToReturn == null){ int androidViewId = targetContext.getResources().getIdentifier(id, "id", "android"); if(androidViewId != 0){ viewToReturn = getView(androidViewId, index, TIMEOUT); } } if(viewToReturn != null){ return viewToReturn; } return getView(viewId, index); } /** * Returns a {@code View} with a given tag. * * @param tag the <code>tag</code> of the {@code View} to be returned * @param index the index of the {@link View}. {@code 0} if only one is available * @param timeout the timeout in milliseconds * @return a {@code View} with a given tag if available, <code>null</code> otherwise */ public View getView(Object tag, int index, int timeout){ //Because https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/View.java#L17005-L17007 if(tag == null) { return null; } final Activity activity = activityUtils.getCurrentActivity(false); View viewToReturn = null; if(index < 1){ index = 0; if(activity != null){ //Using https://github.com/android/platform_frameworks_base/blob/master/core/java/android/app/Activity.java#L2070-L2072 Window window = activity.getWindow(); if(window != null) { View decorView = window.getDecorView(); if(decorView != null) { viewToReturn = decorView.findViewWithTag(tag); } } } } if (viewToReturn != null) { return viewToReturn; } return waiter.waitForView(tag, index, timeout); } /** * Returns a {@code View} with a given tag. * * @param tag the <code>tag</code> of the {@code View} to be returned * @param index the index of the {@link View}. {@code 0} if only one is available * @return a {@code View} with a given tag if available, <code>null</code> otherwise */ public View getView(Object tag, int index){ return getView(tag, index, 0); } }