• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016, 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 com.android.managedprovisioning.analytics;
18 
19 import static android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED;
20 import static com.android.managedprovisioning.common.Globals.ACTION_RESUME_PROVISIONING;
21 import static java.nio.charset.StandardCharsets.UTF_8;
22 
23 import android.content.Context;
24 import android.content.Intent;
25 import android.nfc.NdefRecord;
26 import android.os.SystemClock;
27 import android.support.annotation.NonNull;
28 import android.support.annotation.Nullable;
29 
30 import com.android.managedprovisioning.parser.PropertiesProvisioningDataParser;
31 import com.android.managedprovisioning.task.AbstractProvisioningTask;
32 
33 import java.io.IOException;
34 import java.io.StringReader;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Set;
38 import java.util.Properties;
39 
40 /**
41  * Class containing various auxiliary methods used by provisioning analytics tracker.
42  */
43 public class AnalyticsUtils {
44 
AnalyticsUtils()45     public AnalyticsUtils() {}
46 
47     private static final String PROVISIONING_EXTRA_PREFIX = "android.app.extra.PROVISIONING_";
48 
49     /**
50      * Returns package name of the installer package, null if package is not present on the device
51      * and empty string if installer package is not present on the device.
52      *
53      * @param context Context used to get package manager
54      * @param packageName Package name of the installed package
55      */
56     @Nullable
getInstallerPackageName(Context context, String packageName)57     public static String getInstallerPackageName(Context context, String packageName) {
58         try {
59             return context.getPackageManager().getInstallerPackageName(packageName);
60         } catch (IllegalArgumentException e) {
61             return null;
62         }
63     }
64 
65     /**
66      * Returns elapsed real time.
67      */
elapsedRealTime()68     public Long elapsedRealTime() {
69         return SystemClock.elapsedRealtime();
70     }
71 
72     /**
73      * Returns list of all valid provisioning extras sent by the dpc.
74      *
75      * @param intent Intent that started provisioning
76      */
77     @NonNull
getAllProvisioningExtras(Intent intent)78     public static List<String> getAllProvisioningExtras(Intent intent) {
79         if (intent == null || ACTION_RESUME_PROVISIONING.equals(intent.getAction())) {
80             // Provisioning extras should have already been logged for resume case.
81             return new ArrayList<String>();
82         } else if (ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
83             return getExtrasFromProperties(intent);
84         } else {
85             return getExtrasFromBundle(intent);
86         }
87     }
88 
89     /**
90      * Returns unique string for all provisioning task errors.
91      *
92      * @param task Provisioning task which threw error
93      * @param errorCode Unique code from class indicating the error
94      */
95     @Nullable
getErrorString(AbstractProvisioningTask task, int errorCode)96     public static String getErrorString(AbstractProvisioningTask task, int errorCode) {
97         if (task == null) {
98             return null;
99         }
100         // We do not have definite codes for all provisioning errors yet. We just pass the task's
101         // class name and the internal task's error code to generate a unique error code.
102         return task.getClass().getSimpleName() + ":" + errorCode;
103     }
104 
105     @NonNull
getExtrasFromBundle(Intent intent)106     private static List<String> getExtrasFromBundle(Intent intent) {
107         List<String> provisioningExtras = new ArrayList<String>();
108         if (intent != null && intent.getExtras() != null) {
109             final Set<String> keys = intent.getExtras().keySet();
110             for (String key : keys) {
111                 if (isValidProvisioningExtra(key)) {
112                     provisioningExtras.add(key);
113                 }
114             }
115         }
116         return provisioningExtras;
117     }
118 
119     @NonNull
getExtrasFromProperties(Intent intent)120     private static List<String> getExtrasFromProperties(Intent intent) {
121         List<String> provisioningExtras = new ArrayList<String>();
122         NdefRecord firstRecord = PropertiesProvisioningDataParser.getFirstNdefRecord(intent);
123         if (firstRecord != null) {
124             try {
125                 Properties props = new Properties();
126                 props.load(new StringReader(new String(firstRecord.getPayload(), UTF_8)));
127                 final Set<String> keys = props.stringPropertyNames();
128                 for (String key : keys) {
129                     if (isValidProvisioningExtra(key)) {
130                         provisioningExtras.add(key);
131                     }
132                 }
133             } catch (IOException e) {
134             }
135         }
136         return provisioningExtras;
137     }
138 
139     /**
140      * Returns if a string is a valid provisioning extra.
141      */
isValidProvisioningExtra(String provisioningExtra)142     private static boolean isValidProvisioningExtra(String provisioningExtra) {
143         // Currently it verifies using the prefix. We should further change this to verify using the
144         // actual DPM extras.
145         return provisioningExtra != null && provisioningExtra.startsWith(PROVISIONING_EXTRA_PREFIX);
146     }
147 }
148