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.healthconnect.storage; 18 19 import android.util.Slog; 20 21 import com.android.server.healthconnect.storage.datatypehelpers.AccessLogsHelper; 22 import com.android.server.healthconnect.storage.datatypehelpers.ActivityDateHelper; 23 import com.android.server.healthconnect.storage.datatypehelpers.AppInfoHelper; 24 import com.android.server.healthconnect.storage.datatypehelpers.ChangeLogsHelper; 25 import com.android.server.healthconnect.storage.datatypehelpers.ChangeLogsRequestHelper; 26 import com.android.server.healthconnect.storage.datatypehelpers.PreferenceHelper; 27 import com.android.server.healthconnect.storage.request.DeleteTableRequest; 28 import com.android.server.healthconnect.storage.utils.RecordHelperProvider; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 /** 34 * A service that is run periodically to handle deletion of stale entries in HC DB. 35 * 36 * @hide 37 */ 38 public class AutoDeleteService { 39 private static final String AUTO_DELETE_DURATION_RECORDS_KEY = 40 "auto_delete_duration_records_key"; 41 private static final String TAG = "HealthConnectAutoDelete"; 42 43 /** Gets auto delete period for automatically deleting record entries */ getRecordRetentionPeriodInDays()44 public static int getRecordRetentionPeriodInDays() { 45 String result = 46 PreferenceHelper.getInstance().getPreference(AUTO_DELETE_DURATION_RECORDS_KEY); 47 48 if (result == null) return 0; 49 return Integer.parseInt(result); 50 } 51 52 /** Sets auto delete period for automatically deleting record entries */ setRecordRetentionPeriodInDays(int days)53 public static void setRecordRetentionPeriodInDays(int days) { 54 PreferenceHelper.getInstance() 55 .insertOrReplacePreference(AUTO_DELETE_DURATION_RECORDS_KEY, String.valueOf(days)); 56 } 57 58 /** Starts the Auto Deletion process. */ startAutoDelete()59 public static void startAutoDelete() { 60 try { 61 // Only do transactional operations here - as this job might get cancelled for several 62 // reasons, such as: User switch, low battery etc. 63 deleteStaleRecordEntries(); 64 deleteStaleChangeLogEntries(); 65 deleteStaleAccessLogEntries(); 66 // Update the recordTypesUsed by packages if required after the deletion of records. 67 AppInfoHelper.getInstance().syncAppInfoRecordTypesUsed(); 68 // Re-sync activity dates table 69 ActivityDateHelper.getInstance().reSyncForAllRecords(); 70 } catch (Exception e) { 71 Slog.e(TAG, "Auto delete run failed", e); 72 // Don't rethrow as that will crash system_server 73 } 74 } 75 deleteStaleRecordEntries()76 private static void deleteStaleRecordEntries() { 77 String recordAutoDeletePeriodString = 78 PreferenceHelper.getInstance().getPreference(AUTO_DELETE_DURATION_RECORDS_KEY); 79 int recordAutoDeletePeriod = 80 recordAutoDeletePeriodString == null 81 ? 0 82 : Integer.parseInt(recordAutoDeletePeriodString); 83 if (recordAutoDeletePeriod != 0) { 84 // 0 represents that no period is set,to delete only if not 0 else don't do anything 85 List<DeleteTableRequest> deleteTableRequests = new ArrayList<>(); 86 RecordHelperProvider.getInstance() 87 .getRecordHelpers() 88 .values() 89 .forEach( 90 (recordHelper) -> { 91 DeleteTableRequest request = 92 recordHelper.getDeleteRequestForAutoDelete( 93 recordAutoDeletePeriod); 94 deleteTableRequests.add(request); 95 }); 96 try { 97 TransactionManager.getInitialisedInstance() 98 .deleteWithoutChangeLogs(deleteTableRequests); 99 } catch (Exception exception) { 100 Slog.e(TAG, "Auto delete for records failed", exception); 101 // Don't rethrow as that will crash system_server 102 } 103 } 104 } 105 deleteStaleChangeLogEntries()106 private static void deleteStaleChangeLogEntries() { 107 try { 108 TransactionManager.getInitialisedInstance() 109 .deleteWithoutChangeLogs( 110 List.of( 111 ChangeLogsHelper.getInstance().getDeleteRequestForAutoDelete(), 112 ChangeLogsRequestHelper.getInstance() 113 .getDeleteRequestForAutoDelete())); 114 } catch (Exception exception) { 115 Slog.e(TAG, "Auto delete for Change logs failed", exception); 116 // Don't rethrow as that will crash system_server 117 } 118 } 119 deleteStaleAccessLogEntries()120 private static void deleteStaleAccessLogEntries() { 121 try { 122 TransactionManager.getInitialisedInstance() 123 .deleteWithoutChangeLogs( 124 List.of( 125 AccessLogsHelper.getInstance() 126 .getDeleteRequestForAutoDelete())); 127 } catch (Exception exception) { 128 Slog.e(TAG, "Auto delete for Access logs failed", exception); 129 // Don't rethrow as that will crash system_server 130 } 131 } 132 } 133