1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app.admin; 18 19 import android.annotation.Nullable; 20 import android.content.ComponentName; 21 import android.stats.devicepolicy.nano.StringList; 22 import android.util.StatsLog; 23 24 import com.android.framework.protobuf.nano.MessageNano; 25 import com.android.internal.util.Preconditions; 26 27 import java.util.Arrays; 28 29 /** 30 * A wrapper for logging managed device events using {@link StatsLog}. 31 * <p/> 32 * This class allows chaining - each of its methods returns a reference to the current instance. 33 * <p/> 34 * Example usage: 35 * <code><pre> 36 * import android.stats.devicepolicy.DevicePolicyEnums; 37 * 38 * DevicePolicyEventLogger 39 * .createEvent(DevicePolicyEnums.USER_RESTRICTION_CHANGED) 40 * .setAdmin(who) 41 * .setString(key) 42 * .setBoolean(enabledFromThisOwner) 43 * .write(); 44 * </pre></code> 45 * 46 * @see StatsLog 47 * @hide 48 */ 49 public class DevicePolicyEventLogger { 50 private final int mEventId; 51 private int mIntValue; 52 private boolean mBooleanValue; 53 private long mTimePeriodMs; 54 private String[] mStringArrayValue; 55 private String mAdminPackageName; 56 DevicePolicyEventLogger(int eventId)57 private DevicePolicyEventLogger(int eventId) { 58 mEventId = eventId; 59 } 60 61 /** 62 * Creates a new {@link DevicePolicyEventLogger} instance for the specified 63 * <code>eventId</code>. 64 * 65 * @param eventId one of {@link android.stats.devicepolicy.DevicePolicyEnums} as defined in 66 * <code>core/proto/android/stats/devicepolicy/device_policy_enums.proto</code> 67 */ createEvent(int eventId)68 public static DevicePolicyEventLogger createEvent(int eventId) { 69 return new DevicePolicyEventLogger(eventId); 70 } 71 72 /** 73 * Returns the event id. 74 */ getEventId()75 public int getEventId() { 76 return mEventId; 77 } 78 79 /** 80 * Sets a generic <code>int</code> value. 81 */ setInt(int value)82 public DevicePolicyEventLogger setInt(int value) { 83 mIntValue = value; 84 return this; 85 } 86 87 /** 88 * Returns the generic <code>int</code> value. 89 */ getInt()90 public int getInt() { 91 return mIntValue; 92 } 93 94 /** 95 * Sets a generic <code>boolean</code> value. 96 */ setBoolean(boolean value)97 public DevicePolicyEventLogger setBoolean(boolean value) { 98 mBooleanValue = value; 99 return this; 100 } 101 102 /** 103 * Returns the generic <code>boolean</code> value. 104 */ getBoolean()105 public boolean getBoolean() { 106 return mBooleanValue; 107 } 108 109 /** 110 * Sets a time period in milliseconds. 111 */ setTimePeriod(long timePeriodMillis)112 public DevicePolicyEventLogger setTimePeriod(long timePeriodMillis) { 113 mTimePeriodMs = timePeriodMillis; 114 return this; 115 } 116 117 /** 118 * Returns the time period in milliseconds. 119 */ getTimePeriod()120 public long getTimePeriod() { 121 return mTimePeriodMs; 122 } 123 124 /** 125 * Sets generic <code>String</code> values. 126 */ setStrings(String... values)127 public DevicePolicyEventLogger setStrings(String... values) { 128 mStringArrayValue = values; 129 return this; 130 } 131 132 /** 133 * Sets generic <code>String</code> values. 134 * <p/> 135 * {@link #write()} logs the concatenation of <code>value</code> and <code>values</code>, 136 * in that order. 137 */ setStrings(String value, String[] values)138 public DevicePolicyEventLogger setStrings(String value, String[] values) { 139 Preconditions.checkNotNull(values, "values parameter cannot be null"); 140 mStringArrayValue = new String[values.length + 1]; 141 mStringArrayValue[0] = value; 142 System.arraycopy(values, 0, mStringArrayValue, 1, values.length); 143 return this; 144 } 145 146 /** 147 * Sets generic <code>String</code> values. 148 * <p/> 149 * {@link #write()} logs the concatenation of <code>value1</code>, <code>value2</code> 150 * and <code>values</code>, in that order. 151 */ setStrings(String value1, String value2, String[] values)152 public DevicePolicyEventLogger setStrings(String value1, String value2, String[] values) { 153 Preconditions.checkNotNull(values, "values parameter cannot be null"); 154 mStringArrayValue = new String[values.length + 2]; 155 mStringArrayValue[0] = value1; 156 mStringArrayValue[1] = value2; 157 System.arraycopy(values, 0, mStringArrayValue, 2, values.length); 158 return this; 159 } 160 161 /** 162 * Returns a copy of the generic <code>String[]</code> value. 163 */ getStringArray()164 public String[] getStringArray() { 165 if (mStringArrayValue == null) { 166 return null; 167 } 168 return Arrays.copyOf(mStringArrayValue, mStringArrayValue.length); 169 } 170 171 /** 172 * Sets the package name of the admin application. 173 */ setAdmin(@ullable String packageName)174 public DevicePolicyEventLogger setAdmin(@Nullable String packageName) { 175 mAdminPackageName = packageName; 176 return this; 177 } 178 179 /** 180 * Sets the package name of the admin application from the {@link ComponentName}. 181 */ setAdmin(@ullable ComponentName componentName)182 public DevicePolicyEventLogger setAdmin(@Nullable ComponentName componentName) { 183 mAdminPackageName = (componentName != null ? componentName.getPackageName() : null); 184 return this; 185 } 186 187 /** 188 * Returns the package name of the admin application. 189 */ getAdminPackageName()190 public String getAdminPackageName() { 191 return mAdminPackageName; 192 } 193 194 /** 195 * Writes the metric to {@link StatsLog}. 196 */ write()197 public void write() { 198 byte[] bytes = stringArrayValueToBytes(mStringArrayValue); 199 StatsLog.write(StatsLog.DEVICE_POLICY_EVENT, mEventId, mAdminPackageName, mIntValue, 200 mBooleanValue, mTimePeriodMs, bytes); 201 } 202 203 /** 204 * Converts the <code>String[] array</code> to <code>byte[]</code>. 205 * <p/> 206 * We can't log <code>String[]</code> using {@link StatsLog}. The convention is to assign 207 * the array to a proto object and convert it to <code>byte[]</code>. 208 */ stringArrayValueToBytes(String[] array)209 private static byte[] stringArrayValueToBytes(String[] array) { 210 if (array == null) { 211 return null; 212 } 213 StringList stringList = new StringList(); 214 stringList.stringValue = array; 215 return MessageNano.toByteArray(stringList); 216 } 217 } 218