1 /* 2 * Copyright (C) 2022 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.server.appsearch.contactsindexer; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.util.ArraySet; 22 23 import com.android.server.appsearch.stats.AppSearchStatsLog; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.util.Set; 28 29 /** 30 * The class to hold stats for DeltaUpdate or FullUpdate. 31 * 32 * <p>This will be used to populate {@link 33 * AppSearchStatsLog#CONTACTS_INDEXER_UPDATE_STATS_REPORTED}. 34 * 35 * <p>This class is not thread-safe. 36 * 37 * @hide 38 */ 39 public class ContactsUpdateStats { 40 @IntDef( 41 value = { 42 UNKNOWN_UPDATE_TYPE, 43 DELTA_UPDATE, 44 FULL_UPDATE, 45 }) 46 @Retention(RetentionPolicy.SOURCE) 47 public @interface UpdateType {} 48 49 public static final int UNKNOWN_UPDATE_TYPE = 50 AppSearchStatsLog.CONTACTS_INDEXER_UPDATE_STATS_REPORTED__UPDATE_TYPE__UNKNOWN; 51 52 /** Incremental update reacting to CP2 change notifications. */ 53 public static final int DELTA_UPDATE = 54 AppSearchStatsLog.CONTACTS_INDEXER_UPDATE_STATS_REPORTED__UPDATE_TYPE__DELTA; 55 56 /** Complete update to bring AppSearch in sync with CP2. */ 57 public static final int FULL_UPDATE = 58 AppSearchStatsLog.CONTACTS_INDEXER_UPDATE_STATS_REPORTED__UPDATE_TYPE__FULL; 59 60 @IntDef( 61 value = { 62 ERROR_CODE_CP2_RUNTIME_EXCEPTION, 63 ERROR_CODE_CP2_NULL_CURSOR, 64 ERROR_CODE_APP_SEARCH_SYSTEM_ERROR, 65 ERROR_CODE_CONTACTS_INDEXER_UNKNOWN_ERROR, 66 }) 67 @Retention(RetentionPolicy.SOURCE) 68 public @interface ErrorCode {} 69 70 // Error code logged from CP2 runtime exceptions 71 public static final int ERROR_CODE_CP2_RUNTIME_EXCEPTION = 10000; 72 // Error code logged from CP2 null query cursors 73 public static final int ERROR_CODE_CP2_NULL_CURSOR = 10001; 74 // Error code logged from AppSearch system errors. This code may be combined with an 75 // AppSearchResult code from toFailedResult on the throwable from onSystemError(). 76 public static final int ERROR_CODE_APP_SEARCH_SYSTEM_ERROR = 10100; 77 // Error code logged from ContactsIndexer for otherwise uncaught exceptions 78 public static final int ERROR_CODE_CONTACTS_INDEXER_UNKNOWN_ERROR = 10200; 79 80 @UpdateType int mUpdateType = UNKNOWN_UPDATE_TYPE; 81 // Status for updates. 82 // In case of success, we will just have one success status stored. 83 // In case of Error, we store the unique error codes during the update. 84 Set<Integer> mUpdateStatuses = new ArraySet<>(); 85 // Status for deletions. 86 // In case of success, we will just have one success status stored. 87 // In case of Error, we store the unique error codes during the deletion. 88 Set<Integer> mDeleteStatuses = new ArraySet<>(); 89 90 // Start time in millis for update and delete. 91 long mUpdateAndDeleteStartTimeMillis; 92 // Start time in millis for last full update 93 long mLastFullUpdateStartTimeMillis; 94 // Start time in millis for last delta update 95 long mLastDeltaUpdateStartTimeMillis; 96 // Time in millis of last contact updated from CP2 97 long mLastContactUpdatedTimeMillis; 98 // Time in millis of last contact deleted from CP2 99 long mLastContactDeletedTimeMillis; 100 // The mLastContactUpdatedTimeMillis from the previous update. This field is logged only for 101 // full updates and should match the current mLastContactUpdatedTimeMillis. 102 // Delta updates are run in response to CP2 notifications, so we expect the last contact updated 103 // to have changed. Full updates are scheduled as a fix/maintenance job, so it's not expected 104 // for the last contact updated to have changed. It's possible that a full update lands right as 105 // a contact is updated, but we expect this to happen very rarely or not at all. There is an 106 // issue if we find that these timestamps frequently do not match. 107 long mPreviousLastContactUpdatedTimeMillis; 108 109 // 110 // Update for both old and new contacts(a.k.a insertion). 111 // 112 // # of old and new contacts failed to be updated. 113 int mContactsUpdateFailedCount; 114 // # of old and new contacts succeeds to be updated. 115 int mContactsUpdateSucceededCount; 116 // # of contacts update skipped due to NO significant change during the update. 117 int mContactsUpdateSkippedCount; 118 // Total # of old and new contacts to be updated. 119 // It should equal to 120 // mContactsUpdateFailedCount + mContactsUpdateSucceededCount + mContactsUpdateSkippedCount 121 int mTotalContactsToBeUpdated; 122 // Among the succeeded and failed contacts updates, how many of them are for the new contacts 123 // currently NOT available in AppSearch. 124 int mNewContactsToBeUpdated; 125 126 // 127 // Deletion for old documents. 128 // 129 // # of old contacts that failed to be deleted. This includes contacts that were not found. 130 int mContactsDeleteFailedCount; 131 // # of old contacts that were deleted successfully. 132 int mContactsDeleteSucceededCount; 133 // # of old contacts to be deleted that were not found. 134 int mContactsDeleteNotFoundCount; 135 // Total # of old contacts to be deleted. It should equal 136 // mContactsDeleteFailedCount + mContactsDeleteSucceededCount 137 int mTotalContactsToBeDeleted; 138 clear()139 public void clear() { 140 mUpdateType = UNKNOWN_UPDATE_TYPE; 141 mUpdateStatuses.clear(); 142 mDeleteStatuses.clear(); 143 mUpdateAndDeleteStartTimeMillis = 0; 144 mLastFullUpdateStartTimeMillis = 0; 145 mLastDeltaUpdateStartTimeMillis = 0; 146 mLastContactUpdatedTimeMillis = 0; 147 mLastContactDeletedTimeMillis = 0; 148 mPreviousLastContactUpdatedTimeMillis = 0; 149 // Update for old and new contacts 150 mContactsUpdateFailedCount = 0; 151 mContactsUpdateSucceededCount = 0; 152 mContactsUpdateSkippedCount = 0; 153 mNewContactsToBeUpdated = 0; 154 mTotalContactsToBeUpdated = 0; 155 // delete for old contacts 156 mContactsDeleteFailedCount = 0; 157 mContactsDeleteSucceededCount = 0; 158 mContactsDeleteNotFoundCount = 0; 159 mTotalContactsToBeDeleted = 0; 160 } 161 162 @NonNull toString()163 public String toString() { 164 return "UpdateType: " 165 + mUpdateType 166 + ", UpdateStatus: " 167 + mUpdateStatuses.toString() 168 + ", DeleteStatus: " 169 + mDeleteStatuses.toString() 170 + ", UpdateAndDeleteStartTimeMillis: " 171 + mUpdateAndDeleteStartTimeMillis 172 + ", LastFullUpdateStartTimeMillis: " 173 + mLastFullUpdateStartTimeMillis 174 + ", LastDeltaUpdateStartTimeMillis: " 175 + mLastDeltaUpdateStartTimeMillis 176 + ", LastContactUpdatedTimeMillis: " 177 + mLastContactUpdatedTimeMillis 178 + ", LastContactDeletedTimeMillis: " 179 + mLastContactDeletedTimeMillis 180 + ", PreviousLastContactUpdatedTimeMillis: " 181 + mPreviousLastContactUpdatedTimeMillis 182 + ", ContactsUpdateFailedCount: " 183 + mContactsUpdateFailedCount 184 + ", ContactsUpdateSucceededCount: " 185 + mContactsUpdateSucceededCount 186 + ", NewContactsToBeUpdated: " 187 + mNewContactsToBeUpdated 188 + ", ContactsUpdateSkippedCount: " 189 + mContactsUpdateSkippedCount 190 + ", TotalContactsToBeUpdated: " 191 + mTotalContactsToBeUpdated 192 + ", ContactsDeleteFailedCount: " 193 + mContactsDeleteFailedCount 194 + ", ContactsDeleteSucceededCount: " 195 + mContactsDeleteSucceededCount 196 + ", ContactsDeleteNotFoundCount: " 197 + mContactsDeleteNotFoundCount 198 + ", TotalContactsToBeDeleted: " 199 + mTotalContactsToBeDeleted; 200 } 201 } 202