1 /*
2  * Copyright (C) 2016 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.blocking;
18 
19 import android.content.Context;
20 import android.content.SharedPreferences;
21 import android.preference.PreferenceManager;
22 import android.support.annotation.NonNull;
23 import android.support.annotation.Nullable;
24 import android.support.v4.os.UserManagerCompat;
25 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler.OnHasBlockedNumbersListener;
26 import com.android.dialer.common.Assert;
27 import com.android.dialer.common.LogUtil;
28 import com.android.dialer.common.concurrent.DialerExecutor.Worker;
29 import com.android.dialer.common.concurrent.DialerExecutorFactory;
30 
31 /**
32  * Class responsible for checking if the user can be auto-migrated to {@link
33  * android.provider.BlockedNumberContract} blocking. In order for this to happen, the user cannot
34  * have any numbers that are blocked in the Dialer solution.
35  */
36 public class BlockedNumbersAutoMigrator {
37 
38   static final String HAS_CHECKED_AUTO_MIGRATE_KEY = "checkedAutoMigrate";
39 
40   @NonNull private final Context appContext;
41   @NonNull private final FilteredNumberAsyncQueryHandler queryHandler;
42   @NonNull private final DialerExecutorFactory dialerExecutorFactory;
43 
44   /**
45    * Constructs the BlockedNumbersAutoMigrator with the given {@link
46    * FilteredNumberAsyncQueryHandler}.
47    *
48    * @param queryHandler The FilteredNumberAsyncQueryHandler used to determine if there are blocked
49    *     numbers.
50    * @throws NullPointerException if sharedPreferences or queryHandler are null.
51    */
BlockedNumbersAutoMigrator( @onNull Context appContext, @NonNull FilteredNumberAsyncQueryHandler queryHandler, @NonNull DialerExecutorFactory dialerExecutorFactory)52   public BlockedNumbersAutoMigrator(
53       @NonNull Context appContext,
54       @NonNull FilteredNumberAsyncQueryHandler queryHandler,
55       @NonNull DialerExecutorFactory dialerExecutorFactory) {
56     this.appContext = Assert.isNotNull(appContext);
57     this.queryHandler = Assert.isNotNull(queryHandler);
58     this.dialerExecutorFactory = Assert.isNotNull(dialerExecutorFactory);
59   }
60 
asyncAutoMigrate()61   public void asyncAutoMigrate() {
62     dialerExecutorFactory
63         .createNonUiTaskBuilder(new ShouldAttemptAutoMigrate(appContext))
64         .onSuccess(this::autoMigrate)
65         .build()
66         .executeParallel(null);
67   }
68 
69   /**
70    * Attempts to perform the auto-migration. Auto-migration will only be attempted once and can be
71    * performed only when the user has no blocked numbers. As a result of this method, the user will
72    * be migrated to the framework blocking solution if blocked numbers don't exist.
73    */
autoMigrate(boolean shouldAttemptAutoMigrate)74   private void autoMigrate(boolean shouldAttemptAutoMigrate) {
75     if (!shouldAttemptAutoMigrate) {
76       return;
77     }
78 
79     LogUtil.i("BlockedNumbersAutoMigrator", "attempting to auto-migrate.");
80     queryHandler.hasBlockedNumbers(
81         new OnHasBlockedNumbersListener() {
82           @Override
83           public void onHasBlockedNumbers(boolean hasBlockedNumbers) {
84             if (hasBlockedNumbers) {
85               LogUtil.i("BlockedNumbersAutoMigrator", "not auto-migrating: blocked numbers exist.");
86               return;
87             }
88             LogUtil.i("BlockedNumbersAutoMigrator", "auto-migrating: no blocked numbers.");
89             FilteredNumberCompat.setHasMigratedToNewBlocking(appContext, true);
90           }
91         });
92   }
93 
94   private static class ShouldAttemptAutoMigrate implements Worker<Void, Boolean> {
95     private final Context appContext;
96 
ShouldAttemptAutoMigrate(Context appContext)97     ShouldAttemptAutoMigrate(Context appContext) {
98       this.appContext = appContext;
99     }
100 
101     @Nullable
102     @Override
doInBackground(@ullable Void input)103     public Boolean doInBackground(@Nullable Void input) {
104       if (!UserManagerCompat.isUserUnlocked(appContext)) {
105         LogUtil.i("BlockedNumbersAutoMigrator", "not attempting auto-migrate: device is locked");
106         return false;
107       }
108       SharedPreferences sharedPreferences =
109           PreferenceManager.getDefaultSharedPreferences(appContext);
110 
111       if (sharedPreferences.contains(HAS_CHECKED_AUTO_MIGRATE_KEY)) {
112         LogUtil.v(
113             "BlockedNumbersAutoMigrator", "not attempting auto-migrate: already checked once.");
114         return false;
115       }
116 
117       if (!FilteredNumberCompat.canAttemptBlockOperations(appContext)) {
118         // This may be the case where the user is on the lock screen, so we shouldn't record that
119         // the migration status was checked.
120         LogUtil.i(
121             "BlockedNumbersAutoMigrator", "not attempting auto-migrate: current user can't block");
122         return false;
123       }
124       LogUtil.i(
125           "BlockedNumbersAutoMigrator", "updating state as already checked for auto-migrate.");
126       sharedPreferences.edit().putBoolean(HAS_CHECKED_AUTO_MIGRATE_KEY, true).apply();
127 
128       if (!FilteredNumberCompat.canUseNewFiltering()) {
129         LogUtil.i("BlockedNumbersAutoMigrator", "not attempting auto-migrate: not available.");
130         return false;
131       }
132 
133       if (FilteredNumberCompat.hasMigratedToNewBlocking(appContext)) {
134         LogUtil.i("BlockedNumbersAutoMigrator", "not attempting auto-migrate: already migrated.");
135         return false;
136       }
137       return true;
138     }
139   }
140 }
141