blob: 66d00dd6c5c67e2e7c64345d310416c818ca01f4 [file] [log] [blame]
Chris Wren930ecca2014-11-12 17:43:41 -05001/*
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
Jason Monk893f0bd2017-06-01 11:21:14 -040018import static org.mockito.Mockito.spy;
19import static org.mockito.Mockito.when;
20
21import android.app.Instrumentation;
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040022import android.content.Context;
Jason Monk86bc3312016-08-16 13:17:56 -040023import android.os.Handler;
24import android.os.Looper;
25import android.os.MessageQueue;
Jason Monkaa573e92017-01-27 17:00:29 -050026import android.support.test.InstrumentationRegistry;
Jason Monk25a52b62017-05-23 10:42:59 -040027import android.support.test.filters.SmallTest;
Jason Monk340b0e52017-03-08 14:57:56 -050028import android.testing.LeakCheck;
Jorim Jaggie549a8d2017-05-15 02:40:05 +020029import android.util.Log;
Jason Monke9789282016-11-09 08:59:56 -050030
Jason Monk893f0bd2017-06-01 11:21:14 -040031import org.junit.After;
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040032import org.junit.Before;
Jason Monk340b0e52017-03-08 14:57:56 -050033import org.junit.Rule;
Jason Monkc429f692017-06-27 13:13:49 -040034import org.mockito.invocation.InvocationOnMock;
35import org.mockito.stubbing.Answer;
Chris Wren930ecca2014-11-12 17:43:41 -050036
Jorim Jaggie549a8d2017-05-15 02:40:05 +020037import java.util.concurrent.ExecutionException;
38import java.util.concurrent.Future;
39
Chris Wren930ecca2014-11-12 17:43:41 -050040/**
41 * Base class that does System UI specific setup.
42 */
Jason Monk9abca5e2016-11-11 16:18:14 -050043public abstract class SysuiTestCase {
Jason Monk86bc3312016-08-16 13:17:56 -040044
Jorim Jaggie549a8d2017-05-15 02:40:05 +020045 private static final String TAG = "SysuiTestCase";
46
Jason Monk86bc3312016-08-16 13:17:56 -040047 private Handler mHandler;
Jason Monk340b0e52017-03-08 14:57:56 -050048 @Rule
49 public SysuiTestableContext mContext = new SysuiTestableContext(
50 InstrumentationRegistry.getContext(), getLeakCheck());
51 public TestableDependency mDependency = new TestableDependency(mContext);
Jason Monk893f0bd2017-06-01 11:21:14 -040052 private Instrumentation mRealInstrumentation;
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040053
54 @Before
55 public void SysuiSetup() throws Exception {
Jason Monk556cfb62016-12-16 14:01:25 -050056 System.setProperty("dexmaker.share_classloader", "true");
Jason Monk685db722017-01-23 17:36:50 -050057 SystemUIFactory.createFromConfig(mContext);
Jason Monk893f0bd2017-06-01 11:21:14 -040058
59 mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
60 Instrumentation inst = spy(mRealInstrumentation);
Jason Monkc429f692017-06-27 13:13:49 -040061 when(inst.getContext()).thenAnswer(invocation -> {
62 throw new RuntimeException(
63 "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
64 });
65 when(inst.getTargetContext()).thenAnswer(invocation -> {
66 throw new RuntimeException(
67 "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
68 });
Jason Monk893f0bd2017-06-01 11:21:14 -040069 InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
70 }
71
72 @After
73 public void SysuiTeardown() {
74 InstrumentationRegistry.registerInstance(mRealInstrumentation,
75 InstrumentationRegistry.getArguments());
Jason Monke9789282016-11-09 08:59:56 -050076 }
77
Jason Monk340b0e52017-03-08 14:57:56 -050078 protected LeakCheck getLeakCheck() {
79 return null;
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040080 }
81
Jason Monk340b0e52017-03-08 14:57:56 -050082 public Context getContext() {
Geoffrey Pitsch2c403db2016-08-26 09:09:39 -040083 return mContext;
Chris Wren930ecca2014-11-12 17:43:41 -050084 }
Jason Monk86bc3312016-08-16 13:17:56 -040085
86 protected void waitForIdleSync() {
87 if (mHandler == null) {
88 mHandler = new Handler(Looper.getMainLooper());
89 }
90 waitForIdleSync(mHandler);
91 }
92
Jorim Jaggie549a8d2017-05-15 02:40:05 +020093 protected void waitForUiOffloadThread() {
94 Future<?> future = Dependency.get(UiOffloadThread.class).submit(() -> {});
95 try {
96 future.get();
97 } catch (InterruptedException | ExecutionException e) {
98 Log.e(TAG, "Failed to wait for ui offload thread.", e);
99 }
100 }
101
Jason Monkde850bb2017-02-01 19:26:30 -0500102 public static void waitForIdleSync(Handler h) {
Jason Monk86bc3312016-08-16 13:17:56 -0400103 validateThread(h.getLooper());
104 Idler idler = new Idler(null);
105 h.getLooper().getQueue().addIdleHandler(idler);
106 // Ensure we are non-idle, so the idle handler can run.
107 h.post(new EmptyRunnable());
108 idler.waitForIdle();
109 }
110
111 private static final void validateThread(Looper l) {
112 if (Looper.myLooper() == l) {
113 throw new RuntimeException(
114 "This method can not be called from the looper being synced");
115 }
116 }
117
118 public static final class EmptyRunnable implements Runnable {
119 public void run() {
120 }
121 }
122
123 public static final class Idler implements MessageQueue.IdleHandler {
124 private final Runnable mCallback;
125 private boolean mIdle;
126
127 public Idler(Runnable callback) {
128 mCallback = callback;
129 mIdle = false;
130 }
131
132 @Override
133 public boolean queueIdle() {
134 if (mCallback != null) {
135 mCallback.run();
136 }
137 synchronized (this) {
138 mIdle = true;
139 notifyAll();
140 }
141 return false;
142 }
143
144 public void waitForIdle() {
145 synchronized (this) {
146 while (!mIdle) {
147 try {
148 wait();
149 } catch (InterruptedException e) {
150 }
151 }
152 }
153 }
154 }
Chris Wren930ecca2014-11-12 17:43:41 -0500155}