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