diff --git a/Android.bp b/Android.bp index 7e038ce8d3ae1..c5ec1611c5eab 100644 --- a/Android.bp +++ b/Android.bp @@ -725,6 +725,7 @@ java_defaults { "android.hardware.radio-V1.3-java", "android.hardware.usb.gadget-V1.0-java", "netd_aidl_interface-java", + "devicepolicyprotosnano", ], // Loaded with System.loadLibrary by android.view.textclassifier diff --git a/core/java/android/app/admin/DevicePolicyEventLogger.java b/core/java/android/app/admin/DevicePolicyEventLogger.java new file mode 100644 index 0000000000000..f39a5f4480a88 --- /dev/null +++ b/core/java/android/app/admin/DevicePolicyEventLogger.java @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2018 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 android.app.admin; + +import android.stats.devicepolicy.nano.StringList; +import android.util.StatsLog; + +import com.android.framework.protobuf.nano.MessageNano; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.Preconditions; + +/** + * A wrapper for logging managed device events using {@link StatsLog}. + *
+ * This class allows chaining - each of its methods returns a reference to the current instance. + * + * Example usage: + *
+ * import android.stats.devicepolicy.DevicePolicyEnums;
+ *
+ * DevicePolicyEventLogger
+ * .createEvent(DevicePolicyEnums.USER_RESTRICTION_CHANGED)
+ * .setAdminPackageName(who)
+ * .setString(key)
+ * .setBoolean(enabledFromThisOwner)
+ * .write();
+ *
+ *
+ * @see StatsLog
+ * @hide
+ */
+public final class DevicePolicyEventLogger {
+ private final int mEventId;
+ private int mIntValue;
+ private boolean mBooleanValue;
+ private long mTimePeriodMs;
+ private String[] mStringArrayValue;
+ private String mAdminPackageName;
+
+ private DevicePolicyEventLogger(int eventId) {
+ mEventId = eventId;
+ }
+
+ /**
+ * Creates a new {@link DevicePolicyEventLogger} instance for the specified
+ * eventId.
+ *
+ * @param eventId one of {@link android.stats.devicepolicy.DevicePolicyEnums} as defined in
+ * core/proto/android/stats/devicepolicy/device_policy_enums.proto
+ */
+ public static DevicePolicyEventLogger createEvent(int eventId) {
+ return new DevicePolicyEventLogger(eventId);
+ }
+
+ /**
+ * Returns the event id.
+ */
+ @VisibleForTesting
+ public int getEventId() {
+ return mEventId;
+ }
+
+ /**
+ * Sets a generic int value.
+ */
+ public DevicePolicyEventLogger setInt(int value) {
+ mIntValue = value;
+ return this;
+ }
+
+ /**
+ * Returns the generic int value.
+ */
+ @VisibleForTesting
+ public int getInt() {
+ return mIntValue;
+ }
+
+ /**
+ * Sets a generic boolean value.
+ */
+ public DevicePolicyEventLogger setBoolean(boolean value) {
+ mBooleanValue = value;
+ return this;
+ }
+
+ /**
+ * Returns the generic boolean value.
+ */
+ @VisibleForTesting
+ public boolean getBoolean() {
+ return mBooleanValue;
+ }
+
+ /**
+ * Sets a time period in milliseconds.
+ */
+ public DevicePolicyEventLogger setTimePeriod(long timePeriodMillis) {
+ mTimePeriodMs = timePeriodMillis;
+ return this;
+ }
+
+ /**
+ * Returns the time period in milliseconds.
+ */
+ @VisibleForTesting
+ public long getTimePeriod() {
+ return mTimePeriodMs;
+ }
+
+ /**
+ * Sets generic String values.
+ */
+ public DevicePolicyEventLogger setStrings(String... values) {
+ mStringArrayValue = values;
+ return this;
+ }
+
+ /**
+ * Sets generic String values.
+ *
+ * {@link #write()} logs the concatenation of value and values,
+ * in that order.
+ */
+ public DevicePolicyEventLogger setStrings(String value, String[] values) {
+ Preconditions.checkNotNull(values, "values parameter cannot be null");
+ mStringArrayValue = new String[values.length + 1];
+ mStringArrayValue[0] = value;
+ System.arraycopy(values, 0, mStringArrayValue, 1, values.length);
+ return this;
+ }
+
+ /**
+ * Sets generic String values.
+ *
+ * {@link #write()} logs the concatenation of value1, value2
+ * and values, in that order.
+ */
+ public DevicePolicyEventLogger setStrings(String value1, String value2, String[] values) {
+ Preconditions.checkNotNull(values, "values parameter cannot be null");
+ mStringArrayValue = new String[values.length + 2];
+ mStringArrayValue[0] = value1;
+ mStringArrayValue[1] = value2;
+ System.arraycopy(values, 0, mStringArrayValue, 2, values.length);
+ return this;
+ }
+
+ /**
+ * Returns the generic String[] value.
+ */
+ @VisibleForTesting
+ public String[] getStringArray() {
+ return mStringArrayValue;
+ }
+
+ /**
+ * Sets the package name of the admin application.
+ */
+ public DevicePolicyEventLogger setAdminPackageName(String packageName) {
+ mAdminPackageName = packageName;
+ return this;
+ }
+
+ /**
+ * Returns the package name of the admin application.
+ */
+ @VisibleForTesting
+ public String getAdminPackageName() {
+ return mAdminPackageName;
+ }
+
+ /**
+ * Writes the metric to {@link StatsLog}.
+ */
+ public void write() {
+ byte[] bytes = stringArrayValueToBytes(mStringArrayValue);
+ StatsLog.write(StatsLog.DEVICE_POLICY_EVENT, mEventId, mAdminPackageName, mIntValue,
+ mBooleanValue, mTimePeriodMs, bytes);
+ }
+
+ /**
+ * Converts the String[] array to byte[].
+ *
+ * We can't log String[] using {@link StatsLog}. The convention is to assign
+ * the array to a proto object and convert it to byte[].
+ */
+ private static byte[] stringArrayValueToBytes(String[] array) {
+ if (array == null) {
+ return null;
+ }
+ StringList stringList = new StringList();
+ stringList.stringValue = array;
+ return MessageNano.toByteArray(stringList);
+ }
+}