1 /*
2  * Copyright (C) 2018 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.dialer.calllog;
18 
19 import android.content.SharedPreferences;
20 import com.android.dialer.common.LogUtil;
21 import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
22 import com.android.dialer.storage.Unencrypted;
23 import com.google.common.util.concurrent.Futures;
24 import com.google.common.util.concurrent.ListenableFuture;
25 import com.google.common.util.concurrent.ListeningExecutorService;
26 import com.google.common.util.concurrent.MoreExecutors;
27 import javax.inject.Inject;
28 
29 /**
30  * Builds the annotated call log on application create once after the feature is enabled to reduce
31  * the latency the first time call log is shown.
32  */
33 public final class AnnotatedCallLogMigrator {
34 
35   private static final String PREF_MIGRATED = "annotatedCallLogMigratorMigrated";
36 
37   private final SharedPreferences sharedPreferences;
38   private final RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker;
39   private final ListeningExecutorService backgroundExecutor;
40 
41   @Inject
AnnotatedCallLogMigrator( @nencrypted SharedPreferences sharedPreferences, @BackgroundExecutor ListeningExecutorService backgroundExecutor, RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker)42   AnnotatedCallLogMigrator(
43       @Unencrypted SharedPreferences sharedPreferences,
44       @BackgroundExecutor ListeningExecutorService backgroundExecutor,
45       RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker) {
46     this.sharedPreferences = sharedPreferences;
47     this.backgroundExecutor = backgroundExecutor;
48     this.refreshAnnotatedCallLogWorker = refreshAnnotatedCallLogWorker;
49   }
50 
51   /**
52    * Builds the annotated call log on application create once after the feature is enabled to reduce
53    * the latency the first time call log is shown.
54    */
migrate()55   public ListenableFuture<Void> migrate() {
56     return Futures.transformAsync(
57         shouldMigrate(),
58         (shouldMigrate) -> {
59           if (!shouldMigrate) {
60             return Futures.immediateFuture(null);
61           }
62           LogUtil.i("AnnotatedCallLogMigrator.migrate", "migrating annotated call log");
63           return Futures.transform(
64               refreshAnnotatedCallLogWorker.refreshWithoutDirtyCheck(),
65               (unused) -> {
66                 sharedPreferences.edit().putBoolean(PREF_MIGRATED, true).apply();
67                 return null;
68               },
69               MoreExecutors.directExecutor());
70         },
71         MoreExecutors.directExecutor());
72   }
73 
74   private ListenableFuture<Boolean> shouldMigrate() {
75     return backgroundExecutor.submit(() -> !sharedPreferences.getBoolean(PREF_MIGRATED, false));
76   }
77 
78   /**
79    * Clears data that indicates if migration happened or not. This is necessary if migration needs
80    * to happen again, for example because the call log framework was disabled via flags due to a
81    * problem.
82    */
83   ListenableFuture<Void> clearData() {
84     return backgroundExecutor.submit(
85         () -> {
86           sharedPreferences.edit().remove(PREF_MIGRATED).apply();
87           return null;
88         });
89   }
90 }
91