• 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.appsearch.contactsindexer;
18 
19 import android.annotation.NonNull;
20 import android.os.PersistableBundle;
21 import android.util.AtomicFile;
22 
23 import com.android.internal.annotations.VisibleForTesting;
24 
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.util.Objects;
30 
31 /**
32  * Contacts indexer settings backed by a PersistableBundle.
33  *
34  * Holds settings such as the last time when a full update or delta update was performed.
35  *
36  * <p>This class is NOT thread safe (similar to {@link PersistableBundle} which it wraps).
37  *
38  * @hide
39  */
40 public class ContactsIndexerSettings {
41 
42     private static final String TAG = "ContactsIndexerSettings";
43 
44     /*package*/ static final String SETTINGS_FILE_NAME = "contacts_indexer_settings.pb";
45 
46     /*package*/ static final String LAST_FULL_UPDATE_TIMESTAMP_KEY =
47             "last_full_update_timestamp_millis";
48     /*package*/ static final String LAST_DELTA_UPDATE_TIMESTAMP_KEY =
49             "last_delta_update_timestamp_millis";
50     /*package*/ static final String LAST_DELTA_DELETE_TIMESTAMP_KEY =
51             "last_delta_delete_timestamp_millis";
52 
53     private final File mFile;
54     private PersistableBundle mBundle = new PersistableBundle();
55 
ContactsIndexerSettings(@onNull File baseDir)56     public ContactsIndexerSettings(@NonNull File baseDir) {
57         Objects.requireNonNull(baseDir);
58         mFile = new File(baseDir, SETTINGS_FILE_NAME);
59     }
60 
load()61     public void load() throws IOException {
62         mBundle = readBundle(mFile);
63     }
64 
persist()65     public void persist() throws IOException {
66         writeBundle(mFile, mBundle);
67     }
68 
getLastFullUpdateTimestampMillis()69     public long getLastFullUpdateTimestampMillis() {
70         return mBundle.getLong(LAST_FULL_UPDATE_TIMESTAMP_KEY);
71     }
72 
setLastFullUpdateTimestampMillis(long timestampMillis)73     public void setLastFullUpdateTimestampMillis(long timestampMillis) {
74         mBundle.putLong(LAST_FULL_UPDATE_TIMESTAMP_KEY, timestampMillis);
75     }
76 
getLastDeltaUpdateTimestampMillis()77     public long getLastDeltaUpdateTimestampMillis() {
78         return mBundle.getLong(LAST_DELTA_UPDATE_TIMESTAMP_KEY);
79     }
80 
setLastDeltaUpdateTimestampMillis(long timestampMillis)81     public void setLastDeltaUpdateTimestampMillis(long timestampMillis) {
82         mBundle.putLong(LAST_DELTA_UPDATE_TIMESTAMP_KEY, timestampMillis);
83     }
84 
getLastDeltaDeleteTimestampMillis()85     public long getLastDeltaDeleteTimestampMillis() {
86         return mBundle.getLong(LAST_DELTA_DELETE_TIMESTAMP_KEY);
87     }
88 
setLastDeltaDeleteTimestampMillis(long timestampMillis)89     public void setLastDeltaDeleteTimestampMillis(long timestampMillis) {
90         mBundle.putLong(LAST_DELTA_DELETE_TIMESTAMP_KEY, timestampMillis);
91     }
92 
93     /** Resets all the settings to default values. */
reset()94     public void reset() {
95         setLastDeltaDeleteTimestampMillis(0);
96         setLastDeltaUpdateTimestampMillis(0);
97         setLastFullUpdateTimestampMillis(0);
98     }
99 
100     @VisibleForTesting
101     @NonNull
readBundle(@onNull File src)102     /*package*/ static PersistableBundle readBundle(@NonNull File src) throws
103             IOException {
104         AtomicFile atomicFile = new AtomicFile(src);
105         try (FileInputStream fis = atomicFile.openRead()) {
106             return PersistableBundle.readFromStream(fis);
107         }
108     }
109 
110     @VisibleForTesting
writeBundle(@onNull File dest, @NonNull PersistableBundle bundle)111     /*package*/ static void writeBundle(@NonNull File dest, @NonNull PersistableBundle bundle)
112             throws IOException {
113         AtomicFile atomicFile = new AtomicFile(dest);
114         FileOutputStream fos = null;
115         try {
116             fos = atomicFile.startWrite();
117             bundle.writeToStream(fos);
118             atomicFile.finishWrite(fos);
119         } catch (IOException e ) {
120             if (fos != null) {
121                 atomicFile.failWrite(fos);
122             }
123             throw e;
124         }
125     }
126 }
127