SysuiTestCase.java revision de850bbcaa61c1874b803f2086443febbafd81a4
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 SystemUIFactory.createFromConfig(mContext); 47 mDependency = new TestDependency(); 48 mDependency.mContext = mContext; 49 mDependency.start(); 50 } 51 52 @After 53 public void cleanup() throws Exception { 54 mContext.getSettingsProvider().clearOverrides(this); 55 } 56 57 protected Context getContext() { 58 return mContext; 59 } 60 61 protected void waitForIdleSync() { 62 if (mHandler == null) { 63 mHandler = new Handler(Looper.getMainLooper()); 64 } 65 waitForIdleSync(mHandler); 66 } 67 68 public static void waitForIdleSync(Handler h) { 69 validateThread(h.getLooper()); 70 Idler idler = new Idler(null); 71 h.getLooper().getQueue().addIdleHandler(idler); 72 // Ensure we are non-idle, so the idle handler can run. 73 h.post(new EmptyRunnable()); 74 idler.waitForIdle(); 75 } 76 77 private static final void validateThread(Looper l) { 78 if (Looper.myLooper() == l) { 79 throw new RuntimeException( 80 "This method can not be called from the looper being synced"); 81 } 82 } 83 84 // Used for leak tracking, returns null to indicate no leak tracking by default. 85 public Tracker getTracker(String tag) { 86 return null; 87 } 88 89 public void injectMockDependency(Class<?> cls) { 90 mDependency.injectTestDependency(cls.getName(), mock(cls)); 91 } 92 93 public void injectTestDependency(Class<?> cls, Object obj) { 94 mDependency.injectTestDependency(cls.getName(), obj); 95 } 96 97 public void injectTestDependency(String key, Object obj) { 98 mDependency.injectTestDependency(key, obj); 99 } 100 101 public static final class EmptyRunnable implements Runnable { 102 public void run() { 103 } 104 } 105 106 public static class TestDependency extends Dependency { 107 private final ArrayMap<String, Object> mObjs = new ArrayMap<>(); 108 109 private void injectTestDependency(String key, Object obj) { 110 mObjs.put(key, obj); 111 } 112 113 @Override 114 protected <T> T createDependency(String cls) { 115 if (mObjs.containsKey(cls)) return (T) mObjs.get(cls); 116 return super.createDependency(cls); 117 } 118 } 119 120 public static final class Idler implements MessageQueue.IdleHandler { 121 private final Runnable mCallback; 122 private boolean mIdle; 123 124 public Idler(Runnable callback) { 125 mCallback = callback; 126 mIdle = false; 127 } 128 129 @Override 130 public boolean queueIdle() { 131 if (mCallback != null) { 132 mCallback.run(); 133 } 134 synchronized (this) { 135 mIdle = true; 136 notifyAll(); 137 } 138 return false; 139 } 140 141 public void waitForIdle() { 142 synchronized (this) { 143 while (!mIdle) { 144 try { 145 wait(); 146 } catch (InterruptedException e) { 147 } 148 } 149 } 150 } 151 } 152} 153