1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2015 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License.
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License.
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.dialer.blocking;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.annotation.TargetApi;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.ContentResolver;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.ContentValues;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.database.Cursor;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.AsyncTask;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Build.VERSION_CODES;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.BlockedNumberContract.BlockedNumbers;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.RequiresApi;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.LogUtil;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.database.FilteredNumberContract;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.database.FilteredNumberContract.FilteredNumber;
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns;
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.Objects;
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/**
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Class which should be used to migrate numbers from {@link FilteredNumberContract} blocking to
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * {@link android.provider.BlockedNumberContract} blocking.
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian@TargetApi(VERSION_CODES.M)
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class BlockedNumbersMigrator {
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Context context;
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Creates a new BlockedNumbersMigrate, using the given {@link ContentResolver} to perform queries
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * against the blocked numbers tables.
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public BlockedNumbersMigrator(Context context) {
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    this.context = Objects.requireNonNull(context);
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @RequiresApi(VERSION_CODES.N)
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @TargetApi(VERSION_CODES.N)
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static boolean migrateToNewBlockingInBackground(ContentResolver resolver) {
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try (Cursor cursor =
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        resolver.query(
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            FilteredNumber.CONTENT_URI,
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            new String[] {FilteredNumberColumns.NUMBER},
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            null,
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            null,
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            null)) {
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cursor == null) {
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        LogUtil.i(
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            "BlockedNumbersMigrator.migrateToNewBlockingInBackground", "migrate - cursor was null");
64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return false;
65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i(
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "BlockedNumbersMigrator.migrateToNewBlockingInBackground",
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "migrate - attempting to migrate " + cursor.getCount() + "numbers");
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int numMigrated = 0;
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      while (cursor.moveToNext()) {
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        String originalNumber =
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            cursor.getString(cursor.getColumnIndex(FilteredNumberColumns.NUMBER));
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (isNumberInNewBlocking(resolver, originalNumber)) {
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          LogUtil.i(
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              "BlockedNumbersMigrator.migrateToNewBlockingInBackground",
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              "migrate - number was already blocked in new blocking");
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          continue;
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ContentValues values = new ContentValues();
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        resolver.insert(BlockedNumbers.CONTENT_URI, values);
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ++numMigrated;
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i(
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "BlockedNumbersMigrator.migrateToNewBlockingInBackground",
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          "migrate - migration complete. " + numMigrated + " numbers migrated.");
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return true;
90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @RequiresApi(VERSION_CODES.N)
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @TargetApi(VERSION_CODES.N)
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static boolean isNumberInNewBlocking(ContentResolver resolver, String originalNumber) {
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try (Cursor cursor =
97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        resolver.query(
98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            BlockedNumbers.CONTENT_URI,
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            new String[] {BlockedNumbers.COLUMN_ID},
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            BlockedNumbers.COLUMN_ORIGINAL_NUMBER + " = ?",
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            new String[] {originalNumber},
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            null)) {
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return cursor != null && cursor.getCount() != 0;
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Copies all of the numbers in the {@link FilteredNumberContract} block list to the {@link
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * android.provider.BlockedNumberContract} block list.
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param listener {@link Listener} called once the migration is complete.
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return {@code true} if the migrate can be attempted, {@code false} otherwise.
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @throws NullPointerException if listener is null
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public boolean migrate(final Listener listener) {
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.i("BlockedNumbersMigrator.migrate", "migrate - start");
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!FilteredNumberCompat.canUseNewFiltering()) {
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i("BlockedNumbersMigrator.migrate", "migrate - can't use new filtering");
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return false;
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Objects.requireNonNull(listener);
122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    new MigratorTask(listener).execute();
123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return true;
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Listener for the operation to migrate from {@link FilteredNumberContract} blocking to {@link
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * android.provider.BlockedNumberContract} blocking.
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public interface Listener {
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    /** Called when the migration operation is finished. */
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    void onComplete();
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @TargetApi(VERSION_CODES.N)
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private class MigratorTask extends AsyncTask<Void, Void, Boolean> {
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    private final Listener listener;
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public MigratorTask(Listener listener) {
142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      this.listener = listener;
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Override
146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    protected Boolean doInBackground(Void... params) {
147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i("BlockedNumbersMigrator.doInBackground", "migrate - start background migration");
148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return migrateToNewBlockingInBackground(context.getContentResolver());
149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Override
152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    protected void onPostExecute(Boolean isSuccessful) {
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i("BlockedNumbersMigrator.onPostExecute", "migrate - marking migration complete");
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      FilteredNumberCompat.setHasMigratedToNewBlocking(context, isSuccessful);
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      LogUtil.i("BlockedNumbersMigrator.onPostExecute", "migrate - calling listener");
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      listener.onComplete();
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
160