blob: 6615b1d9276617a40643c4bb97672b662597887e [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.apps.common.testing.ui.espresso.base;
import com.google.android.apps.common.testing.testrunner.ActivityLifecycleMonitor;
import com.google.android.apps.common.testing.testrunner.ActivityLifecycleMonitorRegistry;
import com.google.android.apps.common.testing.testrunner.InstrumentationRegistry;
import com.google.android.apps.common.testing.testrunner.inject.TargetContext;
import com.google.android.apps.common.testing.ui.espresso.FailureHandler;
import com.google.android.apps.common.testing.ui.espresso.Root;
import com.google.android.apps.common.testing.ui.espresso.UiController;
import com.google.common.base.Optional;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import dagger.Module;
import dagger.Provides;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Dagger module for creating the implementation classes within the base package.
*/
@Module(library = true, injects = {
BaseLayerModule.FailureHandlerHolder.class, FailureHandler.class})
public class BaseLayerModule {
@Provides @Singleton
public ActivityLifecycleMonitor provideLifecycleMonitor() {
// TODO(user): replace with installation of AndroidInstrumentationModule once
// proguard issues resolved.
return ActivityLifecycleMonitorRegistry.getInstance();
}
@Provides @TargetContext
public Context provideTargetContext() {
// TODO(user): replace with installation of AndroidInstrumentationModule once
// proguard issues resolved.
return InstrumentationRegistry.getInstance().getTargetContext();
}
@Provides @Singleton
public Looper provideMainLooper() {
return Looper.getMainLooper();
}
@Provides
public UiController provideUiController(UiControllerImpl uiControllerImpl) {
return uiControllerImpl;
}
@Provides @Singleton @CompatAsyncTask
public Optional<AsyncTaskPoolMonitor> provideCompatAsyncTaskMonitor(
ThreadPoolExecutorExtractor extractor) {
Optional<ThreadPoolExecutor> compatThreadPool = extractor.getCompatAsyncTaskThreadPool();
if (compatThreadPool.isPresent()) {
return Optional.of(new AsyncTaskPoolMonitor(compatThreadPool.get()));
} else {
return Optional.<AsyncTaskPoolMonitor>absent();
}
}
@Provides @Singleton @MainThread
public Executor provideMainThreadExecutor(Looper mainLooper) {
final Handler handler = new Handler(mainLooper);
return new Executor() {
@Override
public void execute(Runnable runnable) {
handler.post(runnable);
}
};
}
@Provides @Singleton @SdkAsyncTask
public AsyncTaskPoolMonitor provideSdkAsyncTaskMonitor(ThreadPoolExecutorExtractor extractor) {
return new AsyncTaskPoolMonitor(extractor.getAsyncTaskThreadPool());
}
@Provides
public List<Root> provideKnownRoots(RootsOracle rootsOracle) {
// RootsOracle acts as a provider, but returning Providers is illegal, so delegate.
return rootsOracle.get();
}
@Provides @Singleton
public EventInjector provideEventInjector() {
// On API 16 and above, android uses input manager to inject events. On API < 16,
// they use Window Manager. So we need to create our InjectionStrategy depending on the api
// level. Instrumentation does not check if the event presses went through by checking the
// boolean return value of injectInputEvent, which is why we created this class to better
// handle lost/dropped press events. Instrumentation cannot be used as a fallback strategy,
// since this will be executed on the main thread.
int sdkVersion = Build.VERSION.SDK_INT;
EventInjectionStrategy injectionStrategy = null;
if (sdkVersion >= 16) { // Use InputManager for API level 16 and up.
InputManagerEventInjectionStrategy strategy = new InputManagerEventInjectionStrategy();
strategy.initialize();
injectionStrategy = strategy;
} else if (sdkVersion >= 7) {
// else Use WindowManager for API level 15 through 7.
WindowManagerEventInjectionStrategy strategy = new WindowManagerEventInjectionStrategy();
strategy.initialize();
injectionStrategy = strategy;
} else {
throw new RuntimeException(
"API Level 6 and below is not supported. You are running: " + sdkVersion);
}
return new EventInjector(injectionStrategy);
}
/**
* Holder for AtomicReference<FailureHandler> which allows updating it at runtime.
*/
@Singleton
public static class FailureHandlerHolder {
private final AtomicReference<FailureHandler> holder;
@Inject
public FailureHandlerHolder(@Default FailureHandler defaultHandler) {
holder = new AtomicReference<FailureHandler>(defaultHandler);
}
public void update(FailureHandler handler) {
holder.set(handler);
}
public FailureHandler get() {
return holder.get();
}
}
@Provides
FailureHandler provideFailureHandler(FailureHandlerHolder holder) {
return holder.get();
}
@Provides
@Default
FailureHandler provideFailureHander(DefaultFailureHandler impl) {
return impl;
}
}