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); + } +}