1cddda72410c992a12db61cef26713b498e31fea4Thanh Le/* 2cddda72410c992a12db61cef26713b498e31fea4Thanh Le * Copyright (C) 2013 DroidDriver committers 3cddda72410c992a12db61cef26713b498e31fea4Thanh Le * 4cddda72410c992a12db61cef26713b498e31fea4Thanh Le * Licensed under the Apache License, Version 2.0 (the "License"); 5cddda72410c992a12db61cef26713b498e31fea4Thanh Le * you may not use this file except in compliance with the License. 6cddda72410c992a12db61cef26713b498e31fea4Thanh Le * You may obtain a copy of the License at 7cddda72410c992a12db61cef26713b498e31fea4Thanh Le * 8cddda72410c992a12db61cef26713b498e31fea4Thanh Le * http://www.apache.org/licenses/LICENSE-2.0 9cddda72410c992a12db61cef26713b498e31fea4Thanh Le * 10cddda72410c992a12db61cef26713b498e31fea4Thanh Le * Unless required by applicable law or agreed to in writing, software 11cddda72410c992a12db61cef26713b498e31fea4Thanh Le * distributed under the License is distributed on an "AS IS" BASIS, 12cddda72410c992a12db61cef26713b498e31fea4Thanh Le * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cddda72410c992a12db61cef26713b498e31fea4Thanh Le * See the License for the specific language governing permissions and 14cddda72410c992a12db61cef26713b498e31fea4Thanh Le * limitations under the License. 15cddda72410c992a12db61cef26713b498e31fea4Thanh Le */ 16cddda72410c992a12db61cef26713b498e31fea4Thanh Le 174b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinpackage io.appium.droiddriver.base; 18cddda72410c992a12db61cef26713b498e31fea4Thanh Le 191e9f07f4cb681fb142202113caedba35737a83efKevin Jinimport android.util.Log; 201e9f07f4cb681fb142202113caedba35737a83efKevin Jin 214b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.DroidDriver; 224b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.Poller; 234b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.UiElement; 244b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.actions.InputInjector; 254b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.exceptions.ElementNotFoundException; 264b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.exceptions.TimeoutException; 274b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.finders.ByXPath; 284b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.finders.Finder; 294b31201b5a2dbf8036da5a8d089a68a39cc1dc44Kevin Jinimport io.appium.droiddriver.util.Logs; 30cddda72410c992a12db61cef26713b498e31fea4Thanh Le 31cddda72410c992a12db61cef26713b498e31fea4Thanh Le/** 327c8b54f99e678a1b40b98fc3069217877ec5199cKevin Jin * Base DroidDriver that implements the common operations. 33cddda72410c992a12db61cef26713b498e31fea4Thanh Le */ 3474676fdd3c8a9e599eddd13bea56898674d9916aKevin Jinpublic abstract class BaseDroidDriver<R, E extends BaseUiElement<R, E>> implements DroidDriver { 35cddda72410c992a12db61cef26713b498e31fea4Thanh Le 36985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin private Poller poller = new DefaultPoller(); 3774676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin private E rootElement; 3821a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin 39b75721c8fc51bd5678f5a8d0df9a1e868d69aa12Kevin Jin @Override 407576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin public UiElement find(Finder finder) { 411e9f07f4cb681fb142202113caedba35737a83efKevin Jin Logs.call(Log.VERBOSE, this, "find", finder); 42e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin return finder.find(getRootElement()); 437576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin } 447576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin 45985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin @Override 467576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin public boolean has(Finder finder) { 47985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin try { 48e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin refreshUiElementTree(); 497576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin find(finder); 50985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin return true; 51985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin } catch (ElementNotFoundException enfe) { 52985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin return false; 53985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin } 546a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } 55cddda72410c992a12db61cef26713b498e31fea4Thanh Le 566a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin @Override 577576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin public boolean has(Finder finder, long timeoutMillis) { 586a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin try { 59f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin getPoller().pollFor(this, finder, Poller.EXISTS, timeoutMillis); 606a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin return true; 616a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } catch (TimeoutException e) { 626a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin return false; 636a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } 646a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } 656a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin 666a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin @Override 677576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin public UiElement on(Finder finder) { 687576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin Logs.call(this, "on", finder); 69f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin return getPoller().pollFor(this, finder, Poller.EXISTS); 70cddda72410c992a12db61cef26713b498e31fea4Thanh Le } 71cddda72410c992a12db61cef26713b498e31fea4Thanh Le 72cddda72410c992a12db61cef26713b498e31fea4Thanh Le @Override 73ce3d103d2784040f32d1a97b848d58a1c9592a15Kevin Jin public void checkExists(Finder finder) { 74ce3d103d2784040f32d1a97b848d58a1c9592a15Kevin Jin Logs.call(this, "checkExists", finder); 75f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin getPoller().pollFor(this, finder, Poller.EXISTS); 766a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } 776a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin 786a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin @Override 79ce3d103d2784040f32d1a97b848d58a1c9592a15Kevin Jin public void checkGone(Finder finder) { 80ce3d103d2784040f32d1a97b848d58a1c9592a15Kevin Jin Logs.call(this, "checkGone", finder); 81f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin getPoller().pollFor(this, finder, Poller.GONE); 82cddda72410c992a12db61cef26713b498e31fea4Thanh Le } 83cddda72410c992a12db61cef26713b498e31fea4Thanh Le 84cddda72410c992a12db61cef26713b498e31fea4Thanh Le @Override 85cddda72410c992a12db61cef26713b498e31fea4Thanh Le public Poller getPoller() { 86cddda72410c992a12db61cef26713b498e31fea4Thanh Le return poller; 87cddda72410c992a12db61cef26713b498e31fea4Thanh Le } 88cddda72410c992a12db61cef26713b498e31fea4Thanh Le 89cddda72410c992a12db61cef26713b498e31fea4Thanh Le @Override 90cddda72410c992a12db61cef26713b498e31fea4Thanh Le public void setPoller(Poller poller) { 91cddda72410c992a12db61cef26713b498e31fea4Thanh Le this.poller = poller; 92cddda72410c992a12db61cef26713b498e31fea4Thanh Le } 936316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin 9474676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin public abstract InputInjector getInjector(); 9521a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin 9674676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin protected abstract E newRootElement(); 9721a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin 9874676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin /** 9974676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin * Returns a new UiElement of type {@code E}. 10074676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin */ 10174676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin protected abstract E newUiElement(R rawElement, E parent); 10274676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin 10374676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin public E getRootElement() { 10421a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin if (rootElement == null) { 105e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin refreshUiElementTree(); 10621a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin } 10721a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin return rootElement; 10821a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin } 10921a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin 110e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin @Override 111e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin public void refreshUiElementTree() { 11274676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin rootElement = newRootElement(); 11321a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin } 1146316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin 1156316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin @Override 1166316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin public boolean dumpUiElementTree(String path) { 117985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin Logs.call(this, "dumpUiElementTree", path); 1186316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin return ByXPath.dumpDom(path, getRootElement()); 1196316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin } 120cddda72410c992a12db61cef26713b498e31fea4Thanh Le} 121