Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2016 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.location.cts;
     18 
     19 import android.content.Context;
     20 import android.content.pm.PackageManager;
     21 import android.util.Log;
     22 
     23 import java.util.concurrent.Callable;
     24 import java.util.concurrent.CountDownLatch;
     25 import java.util.concurrent.TimeUnit;
     26 
     27 public class TestUtils {
     28     private static final long STANDARD_WAIT_TIME_MS = 50;
     29     private static final long STANDARD_SLEEP_TIME_MS = 50;
     30 
     31     public static boolean waitFor(CountDownLatch latch, int timeInSec) throws InterruptedException {
     32         // Since late 2014, if the main thread has been occupied for long enough, Android will
     33         // increase its priority. Such new behavior can causes starvation to the background thread -
     34         // even if the main thread has called await() to yield its execution, the background thread
     35         // still can't get scheduled.
     36         //
     37         // Here we're trying to wait on the main thread for a PendingIntent from a background
     38         // thread. Because of the starvation problem, the background thread may take up to 5 minutes
     39         // to deliver the PendingIntent if we simply call await() on the main thread. In order to
     40         // give the background thread a chance to run, we call Thread.sleep() in a loop. Such dirty
     41         // hack isn't ideal, but at least it can work.
     42         //
     43         // See also: b/17423027
     44         long waitTimeRounds = (TimeUnit.SECONDS.toMillis(timeInSec)) /
     45                 (STANDARD_WAIT_TIME_MS + STANDARD_SLEEP_TIME_MS);
     46         for (int i = 0; i < waitTimeRounds; ++i) {
     47             Thread.sleep(STANDARD_SLEEP_TIME_MS);
     48             if (latch.await(STANDARD_WAIT_TIME_MS, TimeUnit.MILLISECONDS)) {
     49                 return true;
     50             }
     51         }
     52         return false;
     53     }
     54 
     55     public static boolean waitForWithCondition(int timeInSec, Callable<Boolean> callback)
     56         throws Exception {
     57         long waitTimeRounds = (TimeUnit.SECONDS.toMillis(timeInSec)) / STANDARD_SLEEP_TIME_MS;
     58         for (int i = 0; i < waitTimeRounds; ++i) {
     59             Thread.sleep(STANDARD_SLEEP_TIME_MS);
     60             if(callback.call()) return true;
     61         }
     62         return false;
     63     }
     64 
     65     public static boolean deviceHasGpsFeature(Context context) {
     66         // If device does not have a GPS, skip the test.
     67         if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)) {
     68             return true;
     69         }
     70         Log.w("LocationTestUtils", "GPS feature not present on device, skipping GPS test.");
     71         return false;
     72     }
     73 }
     74