SysuiTestCase.java revision 25a52b65b2cac1f49f37f4532cfa62282432957a
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 */ 16package com.android.systemui; 17 18import android.content.Context; 19import android.os.Handler; 20import android.os.Looper; 21import android.os.MessageQueue; 22import android.support.test.InstrumentationRegistry; 23import android.support.test.filters.SmallTest; 24import android.testing.LeakCheck; 25import android.util.Log; 26 27import org.junit.Before; 28import org.junit.Rule; 29 30import java.util.concurrent.ExecutionException; 31import java.util.concurrent.Future; 32 33/** 34 * Base class that does System UI specific setup. 35 */ 36public abstract class SysuiTestCase { 37 38 private static final String TAG = "SysuiTestCase"; 39 40 private Handler mHandler; 41 @Rule 42 public SysuiTestableContext mContext = new SysuiTestableContext( 43 InstrumentationRegistry.getContext(), getLeakCheck()); 44 public TestableDependency mDependency = new TestableDependency(mContext); 45 46 @Before 47 public void SysuiSetup() throws Exception { 48 System.setProperty("dexmaker.share_classloader", "true"); 49 SystemUIFactory.createFromConfig(mContext); 50 } 51 52 protected LeakCheck getLeakCheck() { 53 return null; 54 } 55 56 public Context getContext() { 57 return mContext; 58 } 59 60 protected void waitForIdleSync() { 61 if (mHandler == null) { 62 mHandler = new Handler(Looper.getMainLooper()); 63 } 64 waitForIdleSync(mHandler); 65 } 66 67 protected void waitForUiOffloadThread() { 68 Future<?> future = Dependency.get(UiOffloadThread.class).submit(() -> {}); 69 try { 70 future.get(); 71 } catch (InterruptedException | ExecutionException e) { 72 Log.e(TAG, "Failed to wait for ui offload thread.", e); 73 } 74 } 75 76 public static void waitForIdleSync(Handler h) { 77 validateThread(h.getLooper()); 78 Idler idler = new Idler(null); 79 h.getLooper().getQueue().addIdleHandler(idler); 80 // Ensure we are non-idle, so the idle handler can run. 81 h.post(new EmptyRunnable()); 82 idler.waitForIdle(); 83 } 84 85 private static final void validateThread(Looper l) { 86 if (Looper.myLooper() == l) { 87 throw new RuntimeException( 88 "This method can not be called from the looper being synced"); 89 } 90 } 91 92 public static final class EmptyRunnable implements Runnable { 93 public void run() { 94 } 95 } 96 97 public static final class Idler implements MessageQueue.IdleHandler { 98 private final Runnable mCallback; 99 private boolean mIdle; 100 101 public Idler(Runnable callback) { 102 mCallback = callback; 103 mIdle = false; 104 } 105 106 @Override 107 public boolean queueIdle() { 108 if (mCallback != null) { 109 mCallback.run(); 110 } 111 synchronized (this) { 112 mIdle = true; 113 notifyAll(); 114 } 115 return false; 116 } 117 118 public void waitForIdle() { 119 synchronized (this) { 120 while (!mIdle) { 121 try { 122 wait(); 123 } catch (InterruptedException e) { 124 } 125 } 126 } 127 } 128 } 129} 130