Home | History | Annotate | Download | only in systemui
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      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 package com.android.systemui;
     17 
     18 import static org.mockito.Mockito.spy;
     19 import static org.mockito.Mockito.when;
     20 
     21 import android.app.Instrumentation;
     22 import android.content.Context;
     23 import android.os.Handler;
     24 import android.os.Looper;
     25 import android.os.MessageQueue;
     26 import android.support.test.InstrumentationRegistry;
     27 import android.support.test.filters.SmallTest;
     28 import android.testing.LeakCheck;
     29 import android.util.Log;
     30 
     31 import org.junit.After;
     32 import org.junit.Before;
     33 import org.junit.Rule;
     34 import org.mockito.invocation.InvocationOnMock;
     35 import org.mockito.stubbing.Answer;
     36 
     37 import java.util.concurrent.ExecutionException;
     38 import java.util.concurrent.Future;
     39 
     40 /**
     41  * Base class that does System UI specific setup.
     42  */
     43 public abstract class SysuiTestCase {
     44 
     45     private static final String TAG = "SysuiTestCase";
     46 
     47     private Handler mHandler;
     48     @Rule
     49     public SysuiTestableContext mContext = new SysuiTestableContext(
     50             InstrumentationRegistry.getContext(), getLeakCheck());
     51     public TestableDependency mDependency = new TestableDependency(mContext);
     52     private Instrumentation mRealInstrumentation;
     53 
     54     @Before
     55     public void SysuiSetup() throws Exception {
     56         System.setProperty("dexmaker.share_classloader", "true");
     57         mContext.setTheme(R.style.Theme_SystemUI);
     58         SystemUIFactory.createFromConfig(mContext);
     59 
     60         mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
     61         Instrumentation inst = spy(mRealInstrumentation);
     62         when(inst.getContext()).thenAnswer(invocation -> {
     63             throw new RuntimeException(
     64                     "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
     65         });
     66         when(inst.getTargetContext()).thenAnswer(invocation -> {
     67             throw new RuntimeException(
     68                     "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
     69         });
     70         InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
     71     }
     72 
     73     @After
     74     public void SysuiTeardown() {
     75         InstrumentationRegistry.registerInstance(mRealInstrumentation,
     76                 InstrumentationRegistry.getArguments());
     77     }
     78 
     79     protected LeakCheck getLeakCheck() {
     80         return null;
     81     }
     82 
     83     public Context getContext() {
     84         return mContext;
     85     }
     86 
     87     protected void waitForIdleSync() {
     88         if (mHandler == null) {
     89             mHandler = new Handler(Looper.getMainLooper());
     90         }
     91         waitForIdleSync(mHandler);
     92     }
     93 
     94     protected void waitForUiOffloadThread() {
     95         Future<?> future = Dependency.get(UiOffloadThread.class).submit(() -> {});
     96         try {
     97             future.get();
     98         } catch (InterruptedException | ExecutionException e) {
     99             Log.e(TAG, "Failed to wait for ui offload thread.", e);
    100         }
    101     }
    102 
    103     public static void waitForIdleSync(Handler h) {
    104         validateThread(h.getLooper());
    105         Idler idler = new Idler(null);
    106         h.getLooper().getQueue().addIdleHandler(idler);
    107         // Ensure we are non-idle, so the idle handler can run.
    108         h.post(new EmptyRunnable());
    109         idler.waitForIdle();
    110     }
    111 
    112     private static final void validateThread(Looper l) {
    113         if (Looper.myLooper() == l) {
    114             throw new RuntimeException(
    115                 "This method can not be called from the looper being synced");
    116         }
    117     }
    118 
    119     public static final class EmptyRunnable implements Runnable {
    120         public void run() {
    121         }
    122     }
    123 
    124     public static final class Idler implements MessageQueue.IdleHandler {
    125         private final Runnable mCallback;
    126         private boolean mIdle;
    127 
    128         public Idler(Runnable callback) {
    129             mCallback = callback;
    130             mIdle = false;
    131         }
    132 
    133         @Override
    134         public boolean queueIdle() {
    135             if (mCallback != null) {
    136                 mCallback.run();
    137             }
    138             synchronized (this) {
    139                 mIdle = true;
    140                 notifyAll();
    141             }
    142             return false;
    143         }
    144 
    145         public void waitForIdle() {
    146             synchronized (this) {
    147                 while (!mIdle) {
    148                     try {
    149                         wait();
    150                     } catch (InterruptedException e) {
    151                     }
    152                 }
    153             }
    154         }
    155     }
    156 }
    157