1 /*
2  * Copyright (C) 2024 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.provider;
18 
19 import android.database.Cursor;
20 import android.util.Log;
21 
22 import java.util.List;
23 
24 /**
25  * Helper class to create log strings.
26  */
27 final class VerificationLogsHelper {
28     public static final String TAG = "CMP_verifications_";
29 
30     /**
31      * Verifies that all expected columns are present in the returned cursor.
32      */
verifyProjectionForCursor( Cursor cursor, List<String> expectedColumns, List<String> errors )33     static void verifyProjectionForCursor(
34             Cursor cursor,
35             List<String> expectedColumns,
36             List<String> errors
37     ) {
38         // TODO: ignore non compulsory columns?
39         for (String column : expectedColumns) {
40             if (cursor.getColumnIndex(column) == -1) {
41                 errors.add(createColumnNotPresentLog(column));
42             }
43         }
44     }
45 
46     /**
47      * Verifies and logs whether MediaCollectionId is null or empty.
48      */
verifyMediaCollectionId( String mediaCollectionId, List<String> verificationResult, List<String> errors )49     static void verifyMediaCollectionId(
50             String mediaCollectionId,
51             List<String> verificationResult,
52             List<String> errors
53     ) {
54         if (mediaCollectionId != null && !mediaCollectionId.isEmpty()) {
55             verificationResult.add(
56                     CloudMediaProviderContract.MediaCollectionInfo.MEDIA_COLLECTION_ID
57                             + " : " + mediaCollectionId
58             );
59         } else {
60             errors.add(CloudMediaProviderContract.MediaCollectionInfo.MEDIA_COLLECTION_ID
61                     + (mediaCollectionId == null ? " is null" : " is empty"));
62         }
63     }
64 
65     /**
66      * Verifies and logs if the cursor is null or not and the mediaCollectionId inside it.
67      */
verifyCursorNotNullAndMediaCollectionIdPresent( Cursor c, List<String> verificationResult, List<String> errors )68     static void verifyCursorNotNullAndMediaCollectionIdPresent(
69             Cursor c,
70             List<String> verificationResult,
71             List<String> errors
72     ) {
73         if (c != null) {
74             verificationResult.add(createIsNotNullLog("Received cursor"));
75             verificationResult.add(String.format("Number of items in cursor: %s", c.getCount()));
76             verifyMediaCollectionId(
77                     c.getExtras().getString(CloudMediaProviderContract.EXTRA_MEDIA_COLLECTION_ID),
78                     verificationResult,
79                     errors
80             );
81         } else {
82             errors.add(createIsNullLog("Received cursor"));
83         }
84     }
85 
86     /**
87      * Helps log an error for when execution time for an API exceeds the designated threshold.
88      */
verifyTotalTimeForExecution(long totalTimeTakenForExecution, long threshold, List<String> errors)89     static void verifyTotalTimeForExecution(long totalTimeTakenForExecution, long threshold,
90             List<String> errors) {
91         if (threshold < totalTimeTakenForExecution) {
92             errors.add("Total time for execution exceeded threshold.  threshold = " + threshold
93                     + "ms, totalTimeForExecution = " + totalTimeTakenForExecution + "ms");
94         }
95     }
96 
createIsNotNullLog(String value)97     static String createIsNotNullLog(String value) {
98         return String.format("%s is not null.", value);
99     }
100 
createIsNullLog(String value)101     static String createIsNullLog(String value) {
102         return String.format("%s is null.", value);
103     }
104 
createIsNotValidLog(String value)105     static String createIsNotValidLog(String value) {
106         return String.format("%s is not valid.", value);
107     }
108 
createColumnNotPresentLog(String value)109     static String createColumnNotPresentLog(String value) {
110         return String.format("%s column is not present in the returned cursor.", value);
111     }
112 
logVerifications(String authority, String apiName, long totalTimeTakenForExecution, List<String> verifications, List<String> errors)113     static void logVerifications(String authority, String apiName,
114             long totalTimeTakenForExecution,
115             List<String> verifications, List<String> errors) {
116         StringBuilder strb = new StringBuilder("Verifications for : " + apiName + "\n");
117         strb.append("\tTotal time for execution: ").append(totalTimeTakenForExecution).append(
118                 "ms \n");
119         if (!verifications.isEmpty()) {
120             strb.append("\tVerifications:\n");
121             for (String verification : verifications) {
122                 strb.append("\t\t").append(verification).append("\n");
123             }
124         }
125         if (!errors.isEmpty()) {
126             strb.append("\tErrors:\n");
127             for (String error : errors) {
128                 strb.append("\t\t").append(error).append("\n");
129             }
130         }
131         Log.d(TAG + authority, strb.toString());
132     }
133 
logException(String exceptionMessage)134     static void logException(String exceptionMessage) {
135         Log.d(TAG + "Exception", exceptionMessage);
136     }
137 }
138