Merge "Add a unit test for ChangeReporter."
This commit is contained in:
@@ -21,6 +21,7 @@ import android.util.Slog;
|
|||||||
import android.util.StatsLog;
|
import android.util.StatsLog;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -37,7 +38,7 @@ public final class ChangeReporter {
|
|||||||
private static final String TAG = "CompatibilityChangeReporter";
|
private static final String TAG = "CompatibilityChangeReporter";
|
||||||
private int mSource;
|
private int mSource;
|
||||||
|
|
||||||
private final class ChangeReport {
|
private static final class ChangeReport {
|
||||||
long mChangeId;
|
long mChangeId;
|
||||||
int mState;
|
int mState;
|
||||||
|
|
||||||
@@ -65,9 +66,13 @@ public final class ChangeReporter {
|
|||||||
@GuardedBy("mReportedChanges")
|
@GuardedBy("mReportedChanges")
|
||||||
private final Map<Integer, Set<ChangeReport>> mReportedChanges;
|
private final Map<Integer, Set<ChangeReport>> mReportedChanges;
|
||||||
|
|
||||||
|
// When true will of every time to debug (logcat).
|
||||||
|
private boolean mDebugLogAll;
|
||||||
|
|
||||||
public ChangeReporter(int source) {
|
public ChangeReporter(int source) {
|
||||||
mSource = source;
|
mSource = source;
|
||||||
mReportedChanges = new HashMap<>();
|
mReportedChanges = new HashMap<>();
|
||||||
|
mDebugLogAll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,20 +84,76 @@ public final class ChangeReporter {
|
|||||||
* @param state of the reported change - enabled/disabled/only logged
|
* @param state of the reported change - enabled/disabled/only logged
|
||||||
*/
|
*/
|
||||||
public void reportChange(int uid, long changeId, int state) {
|
public void reportChange(int uid, long changeId, int state) {
|
||||||
ChangeReport report = new ChangeReport(changeId, state);
|
if (shouldWriteToStatsLog(uid, changeId, state)) {
|
||||||
|
StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId,
|
||||||
|
state, mSource);
|
||||||
|
}
|
||||||
|
if (shouldWriteToDebug(uid, changeId, state)) {
|
||||||
|
debugLog(uid, changeId, state);
|
||||||
|
}
|
||||||
|
markAsReported(uid, new ChangeReport(changeId, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start logging all the time to logcat.
|
||||||
|
*/
|
||||||
|
public void startDebugLogAll() {
|
||||||
|
mDebugLogAll = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop logging all the time to logcat.
|
||||||
|
*/
|
||||||
|
public void stopDebugLogAll() {
|
||||||
|
mDebugLogAll = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the next report should be logged to statsLog.
|
||||||
|
*
|
||||||
|
* @param uid affected by the change
|
||||||
|
* @param changeId the reported change id
|
||||||
|
* @param state of the reported change - enabled/disabled/only logged
|
||||||
|
* @return true if the report should be logged
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean shouldWriteToStatsLog(int uid, long changeId, int state) {
|
||||||
|
return !isAlreadyReported(uid, new ChangeReport(changeId, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the next report should be logged to logcat.
|
||||||
|
*
|
||||||
|
* @param uid affected by the change
|
||||||
|
* @param changeId the reported change id
|
||||||
|
* @param state of the reported change - enabled/disabled/only logged
|
||||||
|
* @return true if the report should be logged
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean shouldWriteToDebug(int uid, long changeId, int state) {
|
||||||
|
return mDebugLogAll || !isAlreadyReported(uid, new ChangeReport(changeId, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAlreadyReported(int uid, ChangeReport report) {
|
||||||
|
synchronized (mReportedChanges) {
|
||||||
|
Set<ChangeReport> reportedChangesForUid = mReportedChanges.get(uid);
|
||||||
|
if (reportedChangesForUid == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return reportedChangesForUid.contains(report);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void markAsReported(int uid, ChangeReport report) {
|
||||||
synchronized (mReportedChanges) {
|
synchronized (mReportedChanges) {
|
||||||
Set<ChangeReport> reportedChangesForUid = mReportedChanges.get(uid);
|
Set<ChangeReport> reportedChangesForUid = mReportedChanges.get(uid);
|
||||||
if (reportedChangesForUid == null) {
|
if (reportedChangesForUid == null) {
|
||||||
mReportedChanges.put(uid, new HashSet<ChangeReport>());
|
mReportedChanges.put(uid, new HashSet<ChangeReport>());
|
||||||
reportedChangesForUid = mReportedChanges.get(uid);
|
reportedChangesForUid = mReportedChanges.get(uid);
|
||||||
}
|
}
|
||||||
if (!reportedChangesForUid.contains(report)) {
|
reportedChangesForUid.add(report);
|
||||||
debugLog(uid, changeId, state);
|
|
||||||
StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId,
|
|
||||||
state, mSource);
|
|
||||||
reportedChangesForUid.add(report);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
core/tests/PlatformCompatFramework/Android.bp
Normal file
14
core/tests/PlatformCompatFramework/Android.bp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
android_test {
|
||||||
|
name: "PlatformCompatFrameworkTests",
|
||||||
|
// Include all test java files.
|
||||||
|
srcs: ["src/**/*.java"],
|
||||||
|
libs: [
|
||||||
|
"android.test.runner",
|
||||||
|
"android.test.base",
|
||||||
|
],
|
||||||
|
static_libs: [
|
||||||
|
"junit",
|
||||||
|
"androidx.test.rules",
|
||||||
|
],
|
||||||
|
platform_apis: true,
|
||||||
|
}
|
||||||
11
core/tests/PlatformCompatFramework/AndroidManifest.xml
Normal file
11
core/tests/PlatformCompatFramework/AndroidManifest.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.android.internal.compat">
|
||||||
|
<application android:label="ChangeReporterTest">
|
||||||
|
<uses-library android:name="android.test.runner" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
android:targetPackage="com.android.internal.compat"/>
|
||||||
|
</manifest>
|
||||||
7
core/tests/PlatformCompatFramework/OWNERS
Normal file
7
core/tests/PlatformCompatFramework/OWNERS
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Use this reviewer by default.
|
||||||
|
platform-compat-eng+reviews@google.com
|
||||||
|
|
||||||
|
andreionea@google.com
|
||||||
|
atrost@google.com
|
||||||
|
mathewi@google.com
|
||||||
|
satayev@google.com
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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.internal.compat;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ChangeReporterTest {
|
||||||
|
@Test
|
||||||
|
public void testStatsLogOnce() {
|
||||||
|
ChangeReporter reporter = new ChangeReporter(0);
|
||||||
|
int myUid = 1022, otherUid = 1023;
|
||||||
|
long myChangeId = 500L, otherChangeId = 600L;
|
||||||
|
int myState = 1, otherState = 2;
|
||||||
|
|
||||||
|
assertTrue(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
|
||||||
|
reporter.reportChange(myUid, myChangeId, myState);
|
||||||
|
|
||||||
|
// Same report will not be logged again.
|
||||||
|
assertFalse(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
|
||||||
|
// Other reports will be logged.
|
||||||
|
assertTrue(reporter.shouldWriteToStatsLog(otherUid, myChangeId, myState));
|
||||||
|
assertTrue(reporter.shouldWriteToStatsLog(myUid, otherChangeId, myState));
|
||||||
|
assertTrue(reporter.shouldWriteToStatsLog(myUid, myChangeId, otherState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStatsLogAfterReset() {
|
||||||
|
ChangeReporter reporter = new ChangeReporter(0);
|
||||||
|
int myUid = 1022;
|
||||||
|
long myChangeId = 500L;
|
||||||
|
int myState = 1;
|
||||||
|
|
||||||
|
assertTrue(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
|
||||||
|
reporter.reportChange(myUid, myChangeId, myState);
|
||||||
|
|
||||||
|
// Same report will not be logged again.
|
||||||
|
assertFalse(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
|
||||||
|
reporter.resetReportedChanges(myUid);
|
||||||
|
|
||||||
|
// Same report will be logged again after reset.
|
||||||
|
assertTrue(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDebugLogOnce() {
|
||||||
|
ChangeReporter reporter = new ChangeReporter(0);
|
||||||
|
int myUid = 1022, otherUid = 1023;
|
||||||
|
long myChangeId = 500L, otherChangeId = 600L;
|
||||||
|
int myState = 1, otherState = 2;
|
||||||
|
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
reporter.reportChange(myUid, myChangeId, myState);
|
||||||
|
|
||||||
|
// Same report will not be logged again.
|
||||||
|
assertFalse(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
// Other reports will be logged.
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(otherUid, myChangeId, myState));
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(myUid, otherChangeId, myState));
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(myUid, myChangeId, otherState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDebugLogAfterReset() {
|
||||||
|
ChangeReporter reporter = new ChangeReporter(0);
|
||||||
|
int myUid = 1022;
|
||||||
|
long myChangeId = 500L;
|
||||||
|
int myState = 1;
|
||||||
|
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
reporter.reportChange(myUid, myChangeId, myState);
|
||||||
|
|
||||||
|
// Same report will not be logged again.
|
||||||
|
assertFalse(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
reporter.resetReportedChanges(myUid);
|
||||||
|
|
||||||
|
// Same report will be logged again after reset.
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDebugLogWithLogAll() {
|
||||||
|
ChangeReporter reporter = new ChangeReporter(0);
|
||||||
|
int myUid = 1022;
|
||||||
|
long myChangeId = 500L;
|
||||||
|
int myState = 1;
|
||||||
|
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
reporter.reportChange(myUid, myChangeId, myState);
|
||||||
|
|
||||||
|
reporter.startDebugLogAll();
|
||||||
|
// Same report will be logged again.
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
assertTrue(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
|
||||||
|
reporter.stopDebugLogAll();
|
||||||
|
assertFalse(reporter.shouldWriteToDebug(myUid, myChangeId, myState));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user