Skip to content
This repository has been archived by the owner on Dec 15, 2020. It is now read-only.

Commit

Permalink
Log which services time out during scan
Browse files Browse the repository at this point in the history
BUG=31819023

Change-Id: Ic8482e3e49a49159dcc2a8bcc719a3a68084b33f
  • Loading branch information
dsaff committed Oct 7, 2016
1 parent 49ae30e commit d36d14d
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 13 deletions.
Expand Up @@ -57,6 +57,7 @@ public final class TrackerConstants {
public static final String CATEGORY_NOTES = "Notes";
public static final String CATEGORY_APP = "App";
public static final String CATEGORY_TRIGGERS = "Triggers";
public static final String CATEGORY_API = "API";

// Event actions
public static final String ACTION_CREATE = "Create";
Expand All @@ -71,6 +72,7 @@ public final class TrackerConstants {
public static final String ACTION_TRY_RECORDING_FROM_TRIGGER = "TryRecordingFromTrigger";
public static final String ACTION_TRY_STOP_RECORDING_FROM_TRIGGER =
"TryStopRecordingFromTrigger";
public static final String ACTION_API_SCAN_TIMEOUT = "ApiScanTimeout";

// Labels
public static final String LABEL_RECORD = "record";
Expand Down
Expand Up @@ -29,6 +29,9 @@
import com.google.android.apps.forscience.whistlepunk.AppSingleton;
import com.google.android.apps.forscience.whistlepunk.ExternalSensorProvider;
import com.google.android.apps.forscience.whistlepunk.R;
import com.google.android.apps.forscience.whistlepunk.WhistlePunkApplication;
import com.google.android.apps.forscience.whistlepunk.analytics.TrackerConstants;
import com.google.android.apps.forscience.whistlepunk.analytics.UsageTracker;
import com.google.android.apps.forscience.whistlepunk.devicemanager.ExternalSensorDiscoverer;
import com.google.android.apps.forscience.whistlepunk.metadata.ExternalSensorSpec;
import com.google.android.apps.forscience.whistlepunk.sensors.SystemScheduler;
Expand All @@ -48,11 +51,13 @@ public class ScalarInputDiscoverer implements ExternalSensorDiscoverer {
private final Executor mUiThreadExecutor;
private final Scheduler mScheduler;
private final long mScanTimeoutMillis;
private UsageTracker mUsageTracker;

public ScalarInputDiscoverer(Consumer<AppDiscoveryCallbacks> serviceFinder,
Context context) {
this(serviceFinder, defaultStringSource(context), AppSingleton.getUiThreadExecutor(),
new SystemScheduler(), DEFAULT_SCAN_TIMEOUT_MILLIS);
new SystemScheduler(), DEFAULT_SCAN_TIMEOUT_MILLIS,
WhistlePunkApplication.getUsageTracker(context));
}

private static ScalarInputStringSource defaultStringSource(final Context context) {
Expand All @@ -68,12 +73,14 @@ public String generateCouldNotFindServiceErrorMessage(String serviceId) {
@VisibleForTesting
public ScalarInputDiscoverer(
Consumer<AppDiscoveryCallbacks> serviceFinder, ScalarInputStringSource stringSource,
Executor uiThreadExecutor, Scheduler scheduler, long scanTimeoutMillis) {
Executor uiThreadExecutor, Scheduler scheduler, long scanTimeoutMillis,
UsageTracker usageTracker) {
mServiceFinder = serviceFinder;
mStringSource = stringSource;
mUiThreadExecutor = uiThreadExecutor;
mScheduler = scheduler;
mScanTimeoutMillis = scanTimeoutMillis;
mUsageTracker = usageTracker;
}

@Override
Expand Down Expand Up @@ -147,7 +154,10 @@ private void scheduleTaskTimeout(final TaskPool pool, final String taskId) {
mScheduler.schedule(Delay.millis(mScanTimeoutMillis), new Runnable() {
@Override
public void run() {
pool.taskDone(taskId);
if (pool.taskDone(taskId)) {
mUsageTracker.trackEvent(TrackerConstants.CATEGORY_API,
TrackerConstants.ACTION_API_SCAN_TIMEOUT, taskId, mScanTimeoutMillis);
}
}
});
}
Expand Down Expand Up @@ -208,12 +218,13 @@ public void addTask(String taskId) {
mTaskIds.add(taskId);
}

public void taskDone(String taskId) {
mTaskIds.remove(taskId);
public boolean taskDone(String taskId) {
boolean wasRemoved = mTaskIds.remove(taskId);
if (mTaskIds.isEmpty()) {
mOnDone.run();
mOnDone = null;
}
return wasRemoved;
}
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* 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.forscience.whistlepunk.api.scalarinput;

import com.google.android.apps.forscience.whistlepunk.analytics.UsageTracker;

import java.util.ArrayList;
import java.util.List;

public class RecordingUsageTracker implements UsageTracker {
public List<TrackedEvent> events = new ArrayList<>();

public void setOptOut(boolean optOut) {

}

@Override
public void trackScreenView(String screenName) {

}

@Override
public void trackEvent(String category, String action, String label, long value) {
events.add(new TrackedEvent(category, action, label, value));
}
}
Expand Up @@ -20,6 +20,7 @@

import com.google.android.apps.forscience.javalib.Consumer;
import com.google.android.apps.forscience.whistlepunk.MockScheduler;
import com.google.android.apps.forscience.whistlepunk.WhistlePunkApplication;
import com.google.android.apps.forscience.whistlepunk.devicemanager.ExternalSensorDiscoverer;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
Expand Down Expand Up @@ -50,7 +51,8 @@ public TestSensorDiscoverer(String serviceName, Executor executor) {
public ScalarInputDiscoverer makeScalarInputDiscoverer(
final String serviceId) {
return new ScalarInputDiscoverer(makeFinder(serviceId), new TestStringSource(),
MoreExecutors.directExecutor(), new MockScheduler(), 100);
MoreExecutors.directExecutor(), new MockScheduler(), 100,
new RecordingUsageTracker());
}

@NonNull
Expand Down
@@ -0,0 +1,46 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* 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.forscience.whistlepunk.api.scalarinput;

public class TrackedEvent {
private final String mCategory;
private final String mAction;
private final String mLabel;
private final long mValue;

public TrackedEvent(String category, String action, String label, long value) {
mCategory = category;
mAction = action;
mLabel = label;
mValue = value;
}

public String getCategory() {
return mCategory;
}

public String getAction() {
return mAction;
}

public String getLabel() {
return mLabel;
}

public long getValue() {
return mValue;
}
}
Expand Up @@ -17,10 +17,10 @@

import static org.junit.Assert.assertEquals;

import com.google.android.apps.forscience.whistlepunk.api.scalarinput.RecordingUsageTracker;
import com.google.android.apps.forscience.whistlepunk.api.scalarinput.ScalarInputDiscoverer;
import com.google.android.apps.forscience.whistlepunk.api.scalarinput.ScalarInputSpec;
import com.google.android.apps.forscience.whistlepunk.metadata.ExternalSensorSpec;
import com.google.android.apps.forscience.whistlepunk.sensors.SystemScheduler;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.MoreExecutors;

Expand All @@ -47,7 +47,8 @@ public Map<String,ExternalSensorProvider> getProviders() {

providers.put(ScalarInputSpec.TYPE,
new ScalarInputDiscoverer(null, null,
MoreExecutors.directExecutor(), new MockScheduler(), 100).getProvider());
MoreExecutors.directExecutor(), new MockScheduler(), 100,
new RecordingUsageTracker()).getProvider());
return providers;
}
}
Expand Up @@ -34,6 +34,9 @@

import org.junit.Test;

import java.util.HashSet;
import java.util.Set;

public class ScalarInputDiscovererTest {
@Test
public void testStartScanning() {
Expand Down Expand Up @@ -81,7 +84,8 @@ public ISensorConnector getConnector() throws RemoteException {
}
});
}
}, new TestStringSource(), MoreExecutors.directExecutor(), new MockScheduler(), 100);
}, new TestStringSource(), MoreExecutors.directExecutor(), new MockScheduler(), 100,
new RecordingUsageTracker());

AccumulatingConsumer<ExternalSensorDiscoverer.DiscoveredSensor> c =
new AccumulatingConsumer<>();
Expand Down Expand Up @@ -110,6 +114,7 @@ public void testScanAllDevices() {
service2.addDevice("deviceId2", "deviceName2");
service2.addSensor("deviceId2", "sensorAddress2", "sensorName2");

RecordingUsageTracker usageTracker = new RecordingUsageTracker();
ScalarInputDiscoverer sid = new ScalarInputDiscoverer(
new Consumer<AppDiscoveryCallbacks>() {
@Override
Expand All @@ -118,7 +123,8 @@ public void take(AppDiscoveryCallbacks adc) {
adc.onServiceFound("serviceId2", service2);
adc.onDiscoveryDone();
}
}, new TestStringSource(), executor, new MockScheduler(), 100);
}, new TestStringSource(), executor, new MockScheduler(), 100,
usageTracker);
final AccumulatingConsumer<ExternalSensorDiscoverer.DiscoveredSensor> c =
new AccumulatingConsumer<>();
RecordingRunnable onScanDone = new RecordingRunnable() {
Expand All @@ -135,6 +141,7 @@ public void run() {
assertFalse(onScanDone.hasRun);
executor.drain();
assertTrue(onScanDone.hasRun);
assertTrue(usageTracker.events.isEmpty());
}

@Test
Expand All @@ -155,8 +162,10 @@ protected void onSensorsDone(ISensorConsumer c) {
discoverer.addSensor(s.getDeviceId(), s.getSensorAddress(), s.getSensorName());
MockScheduler scheduler = new MockScheduler();

RecordingUsageTracker usageTracker = new RecordingUsageTracker();
ScalarInputDiscoverer sid = new ScalarInputDiscoverer(discoverer.makeFinder("serviceId"),
new TestStringSource(), MoreExecutors.directExecutor(), scheduler, 100);
new TestStringSource(), MoreExecutors.directExecutor(), scheduler, 100,
usageTracker);

AccumulatingConsumer<ExternalSensorDiscoverer.DiscoveredSensor> c =
new AccumulatingConsumer<>();
Expand All @@ -170,6 +179,13 @@ protected void onSensorsDone(ISensorConsumer c) {
assertFalse(onScanDone.hasRun);
scheduler.incrementTime(200);
assertTrue(onScanDone.hasRun);
assertEquals(2, usageTracker.events.size());
Set<String> eventLabels = new HashSet<>();
for (TrackedEvent event : usageTracker.events) {
eventLabels.add(event.getLabel());
}
assertTrue(eventLabels.toString(), eventLabels.contains("SERVICE:serviceId"));
assertTrue(eventLabels.toString(), eventLabels.contains("DEVICE:" + s.getDeviceId()));
}

private Context getContext() {
Expand Down
3 changes: 1 addition & 2 deletions unheadered.sh
Expand Up @@ -19,6 +19,5 @@

find . -name build -prune \
-o -name third_party -prune \
-o -name '*.java' \
-o -name '*.aidl' \
-o \( -name '*.java' -o -name '*.aidl' \) \
-exec grep -L "Google Inc. All Rights Reserved." {} \;

0 comments on commit d36d14d

Please sign in to comment.