diff options
Diffstat (limited to 'java')
6 files changed, 116 insertions, 1 deletions
diff --git a/java/com/android/dialer/binary/common/DialerApplication.java b/java/com/android/dialer/binary/common/DialerApplication.java index c23926021..58829b8be 100644 --- a/java/com/android/dialer/binary/common/DialerApplication.java +++ b/java/com/android/dialer/binary/common/DialerApplication.java @@ -48,7 +48,7 @@ public abstract class DialerApplication extends Application implements HasRootCo new FilteredNumberAsyncQueryHandler(this), DialerExecutorComponent.get(this).dialerExecutorFactory()) .asyncAutoMigrate(); - CallLogComponent.get(this).callLogFramework().registerContentObservers(getApplicationContext()); + CallLogComponent.get(this).callLogFramework().onApplicationCreate(getApplicationContext()); Futures.addCallback( CallLogComponent.get(this).getAnnotatedCallLogMigrator().migrate(), new DefaultFutureCallback<>(), diff --git a/java/com/android/dialer/calllog/AndroidManifest.xml b/java/com/android/dialer/calllog/AndroidManifest.xml new file mode 100644 index 000000000..69731fe39 --- /dev/null +++ b/java/com/android/dialer/calllog/AndroidManifest.xml @@ -0,0 +1,32 @@ +<!-- + ~ Copyright (C) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.dialer.calllog"> + + <uses-sdk + android:minSdkVersion="23" + android:targetSdkVersion="27"/> + + <application> + + <service + android:exported="false" + android:name=".CallLogConfig$PollingJob" + android:permission="android.permission.BIND_JOB_SERVICE"/> + + </application> + +</manifest> diff --git a/java/com/android/dialer/calllog/CallLogComponent.java b/java/com/android/dialer/calllog/CallLogComponent.java index a2a5084fc..c7b44a818 100644 --- a/java/com/android/dialer/calllog/CallLogComponent.java +++ b/java/com/android/dialer/calllog/CallLogComponent.java @@ -34,6 +34,8 @@ public abstract class CallLogComponent { public abstract ClearMissedCalls getClearMissedCalls(); + public abstract CallLogConfig callLogConfig(); + public static CallLogComponent get(Context context) { return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component()) .callLogComponent(); diff --git a/java/com/android/dialer/calllog/CallLogConfig.java b/java/com/android/dialer/calllog/CallLogConfig.java index e388acfbd..e6fa9c78f 100644 --- a/java/com/android/dialer/calllog/CallLogConfig.java +++ b/java/com/android/dialer/calllog/CallLogConfig.java @@ -16,12 +16,28 @@ package com.android.dialer.calllog; +import android.annotation.SuppressLint; +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.ComponentName; +import android.content.Context; import android.content.SharedPreferences; +import android.support.v4.os.UserManagerCompat; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; +import com.android.dialer.common.concurrent.ThreadUtil; import com.android.dialer.configprovider.ConfigProvider; +import com.android.dialer.constants.ScheduledJobIds; import com.android.dialer.storage.Unencrypted; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; /** @@ -149,4 +165,61 @@ public final class CallLogConfig { public boolean isCallLogFrameworkEnabled() { return sharedPreferences.getBoolean(NEW_CALL_LOG_FRAMEWORK_ENABLED_PREF_KEY, false); } + + static void schedulePollingJob(Context appContext) { + if (UserManagerCompat.isUserUnlocked(appContext)) { + JobScheduler jobScheduler = Assert.isNotNull(appContext.getSystemService(JobScheduler.class)); + @SuppressLint("MissingPermission") // Dialer has RECEIVE_BOOT permission + JobInfo jobInfo = + new JobInfo.Builder( + ScheduledJobIds.CALL_LOG_CONFIG_POLLING_JOB, + new ComponentName(appContext, PollingJob.class)) + .setPeriodic(TimeUnit.HOURS.toMillis(24)) + .setPersisted(true) + .setRequiresCharging(true) + .setRequiresDeviceIdle(true) + .build(); + LogUtil.i("CallLogConfig.schedulePollingJob", "scheduling"); + jobScheduler.schedule(jobInfo); + } + } + + /** + * Job which periodically force updates the {@link CallLogConfig}. This job is necessary to + * support {@link ConfigProvider ConfigProviders} which do not provide a reliable mechanism for + * listening to changes and calling {@link CallLogConfig#update()} directly, such as the {@link + * com.android.dialer.configprovider.SharedPrefConfigProvider}. + */ + public static final class PollingJob extends JobService { + + @Override + public boolean onStartJob(JobParameters params) { + LogUtil.enterBlock("PollingJob.onStartJob"); + Futures.addCallback( + CallLogComponent.get(getApplicationContext()).callLogConfig().update(), + new FutureCallback<Void>() { + @Override + public void onSuccess(Void unused) { + jobFinished(params, false /* needsReschedule */); + } + + @Override + public void onFailure(Throwable throwable) { + ThreadUtil.getUiThreadHandler() + .post( + () -> { + throw new RuntimeException(throwable); + }); + jobFinished(params, false /* needsReschedule */); + } + }, + MoreExecutors.directExecutor()); + return true; + } + + @Override + public boolean onStopJob(JobParameters params) { + return false; + } + } } diff --git a/java/com/android/dialer/calllog/CallLogFramework.java b/java/com/android/dialer/calllog/CallLogFramework.java index 7da8d9c0c..61535e606 100644 --- a/java/com/android/dialer/calllog/CallLogFramework.java +++ b/java/com/android/dialer/calllog/CallLogFramework.java @@ -39,6 +39,12 @@ public final class CallLogFramework { this.dataSources = dataSources; } + /** Performs necessary setup work when the application is created. */ + public void onApplicationCreate(Context appContext) { + registerContentObservers(appContext); + CallLogConfig.schedulePollingJob(appContext); + } + /** Registers the content observers for all data sources. */ public void registerContentObservers(Context appContext) { LogUtil.enterBlock("CallLogFramework.registerContentObservers"); diff --git a/java/com/android/dialer/constants/ScheduledJobIds.java b/java/com/android/dialer/constants/ScheduledJobIds.java index 1a852d0e7..7ffd2da82 100644 --- a/java/com/android/dialer/constants/ScheduledJobIds.java +++ b/java/com/android/dialer/constants/ScheduledJobIds.java @@ -50,6 +50,8 @@ public final class ScheduledJobIds { public static final int VOIP_REGISTRATION = 300; + public static final int CALL_LOG_CONFIG_POLLING_JOB = 400; + // Job Ids from 10_000 to 10_100 should be reserved for proto upload jobs. public static final int PROTO_UPLOAD_JOB_MIN_ID = 10_000; public static final int PROTO_UPLOAD_JOB_MAX_ID = 10_100; |