blob: ab120fa73dd1b963d5ea2fa2373d46b133c39678 [file] [log] [blame]
/*
* Copyright (C) 2017 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.android.tools.profilers;
import com.android.tools.profiler.proto.Cpu;
import com.android.tools.profilers.analytics.FeatureTracker;
import com.android.tools.profilers.cpu.FakeTracePreProcessor;
import com.android.tools.profilers.cpu.ProfilingConfiguration;
import com.android.tools.profilers.cpu.TracePreProcessor;
import com.android.tools.profilers.stacktrace.CodeNavigator;
import com.android.tools.profilers.stacktrace.FakeCodeNavigator;
import com.android.tools.profilers.stacktrace.NativeFrameSymbolizer;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class FakeIdeProfilerServices implements IdeProfilerServices {
public static final String FAKE_ART_SAMPLED_NAME = "Sampled";
public static final String FAKE_ART_INSTRUMENTED_NAME = "Instrumented";
public static final String FAKE_SIMPLEPERF_NAME = "Simpleperf";
public static final String FAKE_ATRACE_NAME = "Atrace";
private final FeatureTracker myFakeFeatureTracker = new FakeFeatureTracker();
private final NativeFrameSymbolizer myFakeSymbolizer = (abi, nativeFrame) -> nativeFrame;
private final CodeNavigator myFakeNavigationService = new FakeCodeNavigator(myFakeFeatureTracker);
private final TracePreProcessor myFakeTracePreProcessor = new FakeTracePreProcessor();
/**
* Callback to be run after the executor calls its execute() method.
*/
@Nullable
Runnable myOnExecute;
/**
* The pool executor runs code in a separate thread. Sometimes is useful to check the state of the profilers
* just before calling pool executor's execute method (e.g. verifying Stage's transient status before making a gRPC call).
*/
@Nullable
Runnable myPrePoolExecute;
/**
* Can toggle for tests via {@link #enableAtrace(boolean)}, but each test starts with this defaulted to false.
*/
private boolean myAtraceEnabled = false;
/**
* Can toggle for tests via {@link #enablePerfetto(boolean)}, but each test starts with this defaulted to false. Enabling this flag
* assumes that {@link #myAtraceEnabled} is true.
*/
private boolean myPerfettoEnabled = false;
/**
* Toggle for including an energy profiler in our profiler view.
*/
private boolean myEnergyProfilerEnabled = false;
/**
* Can toggle for tests via {@link #enableExportTrace(boolean)}, but each test starts with this defaulted to false.
*/
private boolean myExportCpuTraceEnabled = false;
/**
* Toggle for faking fragments UI support in tests.
*/
private boolean myFragmentsEnabled = true;
/**
* Can toggle for tests via {@link #enableImportTrace(boolean)}, but each test starts with this defaulted to false.
*/
private boolean myImportCpuTraceEnabled = false;
/**
* Can toggle for tests via {@link #enableSimpleperfHost(boolean)}, but each test starts with this defaulted to false.
*/
private boolean mySimpleperfHostEnabled = false;
/**
* JNI references alloc/dealloc events are tracked and shown.
*/
private boolean myIsJniReferenceTrackingEnabled = false;
/**
* Toggle for faking live allocation tracking support in tests.
*/
private boolean myLiveTrackingEnabled = false;
/**
* Toggle for faking memory snapshot support in tests.
*/
private boolean myMemorySnapshotEnabled = true;
/**
* Whether a native CPU profiling configuration is preferred over a Java one.
*/
private boolean myNativeProfilingConfigurationPreferred = false;
/**
* Whether long trace files should be parsed.
*/
private boolean myShouldParseLongTraces = false;
/**
* Toggle for faking session import support in tests.
*/
private boolean mySessionsImportEnabled = true;
/**
* Can toggle for tests via {@link #enableStartupCpuProfiling(boolean)}, but each test starts with this defaulted to false.
*/
private boolean myStartupCpuProfilingEnabled = false;
/**
* Can toggle for tests via {@link #enableCpuApiTracing(boolean)}, but each test starts with this defaulted to false.
*/
private boolean myIsCpuApiTracingEnabled = false;
/**
* Whether the new pipeline is used or the old one for devices / processes / sessions.
*/
private boolean myEventsPipelineEnabled = false;
/**
* Toggle for faking {@link FeatureConfig#isCpuNewRecordingWorkflowEnabled()} in tests.
*/
private boolean myCpuNewRecordingWorkflowEnabled = false;
/**
* Toggle for live allocation sampling mode.
*/
private boolean myLiveAllocationsSamplingEnabled = true;
/**
* List of custom CPU profiling configurations.
*/
private final List<ProfilingConfiguration> myCustomProfilingConfigurations = new ArrayList<>();
@NotNull private final ProfilerPreferences myPersistentPreferences;
@NotNull private final ProfilerPreferences myTemporaryPreferences;
/**
* When {@link #openListBoxChooserDialog} is called this index is used to return a specific element in the set of options.
* If this index is out of bounds, null is returned.
*/
private int myListBoxOptionsIndex;
/**
* Fake application id to be used by test.
*/
private String myApplicationId = "";
@Nullable private Notification myNotification;
public FakeIdeProfilerServices() {
myPersistentPreferences = new FakeProfilerPreferences();
myTemporaryPreferences = new FakeProfilerPreferences();
}
@NotNull
@Override
public Executor getMainExecutor() {
return (runnable) -> {
runnable.run();
if (myOnExecute != null) {
myOnExecute.run();
}
};
}
@NotNull
@Override
public Executor getPoolExecutor() {
return (runnable) -> {
if (myPrePoolExecute != null) {
myPrePoolExecute.run();
}
runnable.run();
};
}
@Override
public void saveFile(@NotNull File file, @NotNull Consumer<FileOutputStream> fileOutputStreamConsumer, @Nullable Runnable postRunnable) {
}
@NotNull
@Override
public NativeFrameSymbolizer getNativeFrameSymbolizer() {
return myFakeSymbolizer;
}
@NotNull
@Override
public CodeNavigator getCodeNavigator() {
return myFakeNavigationService;
}
@NotNull
@Override
public FeatureTracker getFeatureTracker() {
return myFakeFeatureTracker;
}
@Override
public void enableAdvancedProfiling() {
// No-op.
}
@NotNull
@Override
public String getApplicationId() {
return myApplicationId;
}
public void setApplicationId(@NotNull String name) {
myApplicationId = name;
}
@NotNull
@Override
public FeatureConfig getFeatureConfig() {
return new FeatureConfig() {
@Override
public boolean isAtraceEnabled() {
return myAtraceEnabled;
}
@Override
public boolean isCpuApiTracingEnabled() {
return myIsCpuApiTracingEnabled;
}
@Override
public boolean isCpuNewRecordingWorkflowEnabled() {
return myCpuNewRecordingWorkflowEnabled;
}
@Override
public boolean isEnergyProfilerEnabled() {
return myEnergyProfilerEnabled;
}
@Override
public boolean isExportCpuTraceEnabled() {
return myExportCpuTraceEnabled;
}
@Override
public boolean isFragmentsEnabled() {
return myFragmentsEnabled;
}
@Override
public boolean isImportCpuTraceEnabled() {
return myImportCpuTraceEnabled;
}
@Override
public boolean isJniReferenceTrackingEnabled() { return myIsJniReferenceTrackingEnabled; }
@Override
public boolean isLiveAllocationsEnabled() {
return myLiveTrackingEnabled;
}
@Override
public boolean isLiveAllocationsSamplingEnabled() {
return myLiveAllocationsSamplingEnabled;
}
@Override
public boolean isMemoryCaptureFilterEnabled() {
return false;
}
@Override
public boolean isMemorySnapshotEnabled() {
return myMemorySnapshotEnabled;
}
@Override
public boolean isPerfettoEnabled() { return myPerfettoEnabled; }
@Override
public boolean isPerformanceMonitoringEnabled() {
return false;
}
@Override
public boolean isSessionImportEnabled() {
return mySessionsImportEnabled;
}
@Override
public boolean isSimpleperfHostEnabled() {
return mySimpleperfHostEnabled;
}
@Override
public boolean isStartupCpuProfilingEnabled() {
return myStartupCpuProfilingEnabled;
}
@Override
public boolean isUnifiedPipelineEnabled() {
return myEventsPipelineEnabled;
}
};
}
@NotNull
@Override
public ProfilerPreferences getTemporaryProfilerPreferences() {
return myTemporaryPreferences;
}
@NotNull
@Override
public ProfilerPreferences getPersistentProfilerPreferences() {
return myPersistentPreferences;
}
@Override
public void openParseLargeTracesDialog(Runnable yesCallback, Runnable noCallback) {
if (myShouldParseLongTraces) {
yesCallback.run();
}
else {
noCallback.run();
}
}
@Override
public <T> T openListBoxChooserDialog(@NotNull String title,
@Nullable String message,
@NotNull T[] options,
@NotNull Function<T, String> listBoxPresentationAdapter) {
if (myListBoxOptionsIndex >= 0 && myListBoxOptionsIndex < options.length) {
return options[myListBoxOptionsIndex];
}
return null;
}
@NotNull
@Override
public TracePreProcessor getSimpleperfTracePreProcessor() {
return myFakeTracePreProcessor;
}
/**
* Sets the listbox options return element index. If this is set to an index out of bounds null is returned.
*/
public void setListBoxOptionsIndex(int optionIndex) {
myListBoxOptionsIndex = optionIndex;
}
public void setShouldParseLongTraces(boolean shouldParseLongTraces) {
myShouldParseLongTraces = shouldParseLongTraces;
}
public void addCustomProfilingConfiguration(String name, Cpu.CpuTraceType type) {
ProfilingConfiguration config =
new ProfilingConfiguration(name, type, Cpu.CpuTraceMode.UNSPECIFIED_MODE);
myCustomProfilingConfigurations.add(config);
}
@Override
public List<ProfilingConfiguration> getUserCpuProfilerConfigs() {
return myCustomProfilingConfigurations;
}
@Override
public List<ProfilingConfiguration> getDefaultCpuProfilerConfigs() {
ProfilingConfiguration artSampled = new ProfilingConfiguration(FAKE_ART_SAMPLED_NAME,
Cpu.CpuTraceType.ART,
Cpu.CpuTraceMode.SAMPLED);
ProfilingConfiguration artInstrumented = new ProfilingConfiguration(FAKE_ART_INSTRUMENTED_NAME,
Cpu.CpuTraceType.ART,
Cpu.CpuTraceMode.INSTRUMENTED);
ProfilingConfiguration simpleperf = new ProfilingConfiguration(FAKE_SIMPLEPERF_NAME,
Cpu.CpuTraceType.SIMPLEPERF,
Cpu.CpuTraceMode.SAMPLED);
ProfilingConfiguration atrace = new ProfilingConfiguration(FAKE_ATRACE_NAME,
Cpu.CpuTraceType.ATRACE,
Cpu.CpuTraceMode.SAMPLED);
return ImmutableList.of(artSampled, artInstrumented, simpleperf, atrace);
}
@Override
public boolean isNativeProfilingConfigurationPreferred() {
return myNativeProfilingConfigurationPreferred;
}
@Override
public void showNotification(@NotNull Notification notification) {
myNotification = notification;
}
@Override
public void reportNoPiiException(@NotNull Throwable t) {
t.printStackTrace();
}
@Nullable
public Notification getNotification() {
return myNotification;
}
public void setNativeProfilingConfigurationPreferred(boolean nativeProfilingConfigurationPreferred) {
myNativeProfilingConfigurationPreferred = nativeProfilingConfigurationPreferred;
}
public void setOnExecute(@Nullable Runnable onExecute) {
myOnExecute = onExecute;
}
public void setPrePoolExecutor(@Nullable Runnable prePoolExecute) {
myPrePoolExecute = prePoolExecute;
}
public void enableAtrace(boolean enabled) {
myAtraceEnabled = enabled;
}
public void enablePerfetto(boolean enabled) {
myPerfettoEnabled = enabled;
}
public void enableEnergyProfiler(boolean enabled) {
myEnergyProfilerEnabled = enabled;
}
public void enableFragments(boolean enabled) {
myFragmentsEnabled = enabled;
}
public void enableJniReferenceTracking(boolean enabled) { myIsJniReferenceTrackingEnabled = enabled; }
public void enableLiveAllocationTracking(boolean enabled) {
myLiveTrackingEnabled = enabled;
}
public void enableStartupCpuProfiling(boolean enabled) {
myStartupCpuProfilingEnabled = enabled;
}
public void enableCpuApiTracing(boolean enabled) {
myIsCpuApiTracingEnabled = enabled;
}
public void enableExportTrace(boolean enabled) {
myExportCpuTraceEnabled = enabled;
}
public void enableImportTrace(boolean enabled) {
myImportCpuTraceEnabled = enabled;
}
public void enableSimpleperfHost(boolean enabled) {
mySimpleperfHostEnabled = enabled;
}
public void enableEventsPipeline(boolean enabled) {
myEventsPipelineEnabled = enabled;
}
public void enableCpuNewRecordingWorkflow(boolean enabled) {
myCpuNewRecordingWorkflowEnabled = enabled;
}
public void enableLiveAllocationsSampling(boolean enabled) {
myLiveAllocationsSamplingEnabled = enabled;
}
}