• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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