Move UiEventLogger interface to modules-utils.

This is so the soures can be accessed both fom framework and modules.
The implementation needs the local StatsLog, so cannot be reused.

Test: m
Test: atest SystemUITests
Test: make statsd_testdrive $ANDROID_HOST_OUT/bin/statsd_testdrive 90
Bug: 218862369
Change-Id: I27ebffa6817575f1377beb80f4092287d9b12c49
Merged-In: I27ebffa6817575f1377beb80f4092287d9b12c49
This commit is contained in:
Corina
2022-02-10 18:35:43 +00:00
committed by Corina Grigoras
parent 682fdd6970
commit 9629248c81
6 changed files with 5 additions and 281 deletions

View File

@@ -340,6 +340,7 @@ java_defaults {
"soundtrigger_middleware-aidl-java", "soundtrigger_middleware-aidl-java",
"modules-utils-preconditions", "modules-utils-preconditions",
"modules-utils-os", "modules-utils-os",
"modules-utils-uieventlogger-interface",
"framework-permission-aidl-java", "framework-permission-aidl-java",
], ],
} }

View File

@@ -129,16 +129,16 @@ genrule {
out: ["com/android/internal/util/FrameworkStatsLog.java"], out: ["com/android/internal/util/FrameworkStatsLog.java"],
} }
// Library that provides functionality to log UiEvents in framework space.
// If this functionality is needed outside the framework, the interfaces library
// can be re-used and a local implementation is needed.
java_library { java_library {
name: "uieventloggerlib", name: "uieventloggerlib",
srcs: [ srcs: [
"com/android/internal/logging/UiEvent.java",
"com/android/internal/logging/UiEventLogger.java",
"com/android/internal/logging/UiEventLoggerImpl.java", "com/android/internal/logging/UiEventLoggerImpl.java",
"com/android/internal/logging/InstanceId.java",
"com/android/internal/logging/InstanceIdSequence.java",
":statslog-framework-java-gen", ":statslog-framework-java-gen",
], ],
static_libs: ["modules-utils-uieventlogger-interface"],
} }
filegroup { filegroup {

View File

@@ -1,98 +0,0 @@
/*
* Copyright (C) 2020 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.logging;
import static java.lang.Math.max;
import static java.lang.Math.min;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.annotations.VisibleForTesting;
/**
* An opaque identifier used to disambiguate which logs refer to a particular instance of some
* UI element. Useful when there might be multiple instances simultaneously active.
* Obtain from InstanceIdSequence. Clipped to range [0, INSTANCE_ID_MAX].
*/
public final class InstanceId implements Parcelable {
// At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values
static final int INSTANCE_ID_MAX = 1 << 20;
private final int mId;
InstanceId(int id) {
mId = min(max(0, id), INSTANCE_ID_MAX);
}
private InstanceId(Parcel in) {
this(in.readInt());
}
@VisibleForTesting
public int getId() {
return mId;
}
/**
* Create a fake instance ID for testing purposes. Not for production use. See also
* InstanceIdSequenceFake, which is a testing replacement for InstanceIdSequence.
* @param id The ID you want to assign.
* @return new InstanceId.
*/
@VisibleForTesting
public static InstanceId fakeInstanceId(int id) {
return new InstanceId(id);
}
@Override
public int hashCode() {
return mId;
}
@Override
public boolean equals(@Nullable Object obj) {
if (!(obj instanceof InstanceId)) {
return false;
}
return mId == ((InstanceId) obj).mId;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mId);
}
public static final Parcelable.Creator<InstanceId> CREATOR =
new Parcelable.Creator<InstanceId>() {
@Override
public InstanceId createFromParcel(Parcel in) {
return new InstanceId(in);
}
@Override
public InstanceId[] newArray(int size) {
return new InstanceId[size];
}
};
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright (C) 2020 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.logging;
import static java.lang.Math.max;
import static java.lang.Math.min;
import com.android.internal.annotations.VisibleForTesting;
import java.security.SecureRandom;
import java.util.Random;
/**
* Generates random InstanceIds in range [1, instanceIdMax] for passing to
* UiEventLogger.logWithInstanceId(). Holds a SecureRandom, which self-seeds on
* first use; try to give it a long lifetime. Safe for concurrent use.
*/
public class InstanceIdSequence {
protected final int mInstanceIdMax;
private final Random mRandom = new SecureRandom();
/**
* Constructs a sequence with identifiers [1, instanceIdMax]. Capped at INSTANCE_ID_MAX.
* @param instanceIdMax Limiting value of identifiers. Normally positive: otherwise you get
* an all-1 sequence.
*/
public InstanceIdSequence(int instanceIdMax) {
mInstanceIdMax = min(max(1, instanceIdMax), InstanceId.INSTANCE_ID_MAX);
}
/**
* Gets the next instance from the sequence. Safe for concurrent use.
* @return new InstanceId
*/
public InstanceId newInstanceId() {
return newInstanceIdInternal(1 + mRandom.nextInt(mInstanceIdMax));
}
/**
* Factory function for instance IDs, used for testing.
* @param id
* @return new InstanceId(id)
*/
@VisibleForTesting
protected InstanceId newInstanceIdInternal(int id) {
return new InstanceId(id);
}
}

View File

@@ -1,30 +0,0 @@
/*
* 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.logging;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(SOURCE)
@Target(FIELD)
public @interface UiEvent {
/** An explanation, suitable for Android analysts, of the UI event that this log represents. */
String doc();
}

View File

@@ -1,87 +0,0 @@
/*
* 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.logging;
import android.annotation.NonNull;
import android.annotation.Nullable;
/**
* Logging interface for UI events. Normal implementation is UiEventLoggerImpl.
* For testing, use fake implementation UiEventLoggerFake.
*
* See go/sysui-event-logs and UiEventReported atom in atoms.proto.
*/
public interface UiEventLogger {
/** Put your Event IDs in enums that implement this interface, and document them using the
* UiEventEnum annotation.
* Event IDs must be globally unique. This will be enforced by tooling (forthcoming).
* OEMs should use event IDs above 100000 and below 1000000 (1 million).
*/
interface UiEventEnum {
int getId();
}
/**
* Log a simple event, with no package information. Does nothing if event.getId() <= 0.
* @param event an enum implementing UiEventEnum interface.
*/
void log(@NonNull UiEventEnum event);
/**
* Log an event with package information. Does nothing if event.getId() <= 0.
* Give both uid and packageName if both are known, but one may be omitted if unknown.
* @param event an enum implementing UiEventEnum interface.
* @param uid the uid of the relevant app, if known (0 otherwise).
* @param packageName the package name of the relevant app, if known (null otherwise).
*/
void log(@NonNull UiEventEnum event, int uid, @Nullable String packageName);
/**
* Log an event with package information and an instance ID.
* Does nothing if event.getId() <= 0.
* @param event an enum implementing UiEventEnum interface.
* @param uid the uid of the relevant app, if known (0 otherwise).
* @param packageName the package name of the relevant app, if known (null otherwise).
* @param instance An identifier obtained from an InstanceIdSequence. If null, reduces to log().
*/
void logWithInstanceId(@NonNull UiEventEnum event, int uid, @Nullable String packageName,
@Nullable InstanceId instance);
/**
* Log an event with ranked-choice information along with package.
* Does nothing if event.getId() <= 0.
* @param event an enum implementing UiEventEnum interface.
* @param uid the uid of the relevant app, if known (0 otherwise).
* @param packageName the package name of the relevant app, if known (null otherwise).
* @param position the position picked.
*/
void logWithPosition(@NonNull UiEventEnum event, int uid, @Nullable String packageName,
int position);
/**
* Log an event with ranked-choice information along with package and instance ID.
* Does nothing if event.getId() <= 0.
* @param event an enum implementing UiEventEnum interface.
* @param uid the uid of the relevant app, if known (0 otherwise).
* @param packageName the package name of the relevant app, if known (null otherwise).
* @param instance An identifier obtained from an InstanceIdSequence. If null, reduces to
* logWithPosition().
* @param position the position picked.
*/
void logWithInstanceIdAndPosition(@NonNull UiEventEnum event, int uid,
@Nullable String packageName, @Nullable InstanceId instance, int position);
}