SysuiTestCase.java revision 9c7844cb91b43929d0a86b1c90aa1efb37f5463a
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 static org.mockito.Mockito.mock; 19 20import android.content.Context; 21import android.support.test.InstrumentationRegistry; 22import android.os.Handler; 23import android.os.Looper; 24import android.os.MessageQueue; 25import android.util.ArrayMap; 26 27import com.android.systemui.utils.TestableContext; 28import com.android.systemui.utils.leaks.Tracker; 29 30import org.junit.After; 31import org.junit.Before; 32 33/** 34 * Base class that does System UI specific setup. 35 */ 36public abstract class SysuiTestCase { 37 38 private Handler mHandler; 39 protected TestableContext mContext; 40 protected TestDependency mDependency; 41 42 @Before 43 public void SysuiSetup() throws Exception { 44 System.setProperty("dexmaker.share_classloader", "true"); 45 mContext = new TestableContext(InstrumentationRegistry.getTargetContext(), this); 46 mDependency = new TestDependency(); 47 mDependency.mContext = mContext; 48 mDependency.start(); 49 } 50 51 @After 52 public void cleanup() throws Exception { 53 mContext.getSettingsProvider().clearOverrides(this); 54 } 55 56 protected 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 waitForIdleSync(Handler h) { 68 validateThread(h.getLooper()); 69 Idler idler = new Idler(null); 70 h.getLooper().getQueue().addIdleHandler(idler); 71 // Ensure we are non-idle, so the idle handler can run. 72 h.post(new EmptyRunnable()); 73 idler.waitForIdle(); 74 } 75 76 private static final void validateThread(Looper l) { 77 if (Looper.myLooper() == l) { 78 throw new RuntimeException( 79 "This method can not be called from the looper being synced"); 80 } 81 } 82 83 // Used for leak tracking, returns null to indicate no leak tracking by default. 84 public Tracker getTracker(String tag) { 85 return null; 86 } 87 88 public void injectMockDependency(Class<?> cls) { 89 mDependency.injectTestDependency(cls.getName(), mock(cls)); 90 } 91 92 public void injectTestDependency(Class<?> cls, Object obj) { 93 mDependency.injectTestDependency(cls.getName(), obj); 94 } 95 96 public void injectTestDependency(String key, Object obj) { 97 mDependency.injectTestDependency(key, obj); 98 } 99 100 public static final class EmptyRunnable implements Runnable { 101 public void run() { 102 } 103 } 104 105 public static class TestDependency extends Dependency { 106 private final ArrayMap<String, Object> mObjs = new ArrayMap<>(); 107 108 private void injectTestDependency(String key, Object obj) { 109 mObjs.put(key, obj); 110 } 111 112 @Override 113 protected <T> T createDependency(String cls) { 114 if (mObjs.containsKey(cls)) return (T) mObjs.get(cls); 115 return super.createDependency(cls); 116 } 117 } 118 119 public static final class Idler implements MessageQueue.IdleHandler { 120 private final Runnable mCallback; 121 private boolean mIdle; 122 123 public Idler(Runnable callback) { 124 mCallback = callback; 125 mIdle = false; 126 } 127 128 @Override 129 public boolean queueIdle() { 130 if (mCallback != null) { 131 mCallback.run(); 132 } 133 synchronized (this) { 134 mIdle = true; 135 notifyAll(); 136 } 137 return false; 138 } 139 140 public void waitForIdle() { 141 synchronized (this) { 142 while (!mIdle) { 143 try { 144 wait(); 145 } catch (InterruptedException e) { 146 } 147 } 148 } 149 } 150 } 151} 152