From 636578906c1ae45a5514059afd8279277c106b9b Mon Sep 17 00:00:00 2001 From: zachh Date: Wed, 21 Mar 2018 15:03:30 -0700 Subject: Removed appContext from CallLogDataSource and PhoneLookup. Impls can access appContext via dagger. Test: existing PiperOrigin-RevId: 189974157 Change-Id: Ie64d2c6f9ba08fc914d3c31f7e014c2beef3ab00 --- .../android/dialer/calllog/CallLogFramework.java | 4 ++-- .../calllog/RefreshAnnotatedCallLogWorker.java | 8 +++---- .../calllog/datasources/CallLogDataSource.java | 28 ++++++++++------------ .../phonelookup/PhoneLookupDataSource.java | 26 +++++++++++--------- .../systemcalllog/SystemCallLogDataSource.java | 18 ++++++++------ .../datasources/voicemail/VoicemailDataSource.java | 17 ++++++++----- .../android/dialer/phonelookup/PhoneLookup.java | 5 ++-- .../DialerBlockedNumberPhoneLookup.java | 4 ++-- .../SystemBlockedNumberPhoneLookup.java | 4 ++-- .../composite/CompositePhoneLookup.java | 13 +++++----- .../cp2/Cp2DefaultDirectoryPhoneLookup.java | 4 ++-- .../cp2/Cp2ExtendedDirectoryPhoneLookup.java | 4 ++-- .../dialer/phonelookup/spam/SpamPhoneLookup.java | 5 ++-- 13 files changed, 74 insertions(+), 66 deletions(-) diff --git a/java/com/android/dialer/calllog/CallLogFramework.java b/java/com/android/dialer/calllog/CallLogFramework.java index 365e4d7c0..936f2bbf6 100644 --- a/java/com/android/dialer/calllog/CallLogFramework.java +++ b/java/com/android/dialer/calllog/CallLogFramework.java @@ -63,7 +63,7 @@ public final class CallLogFramework { // TODO(zachh): Find a way to access Main#isNewUiEnabled without creating a circular dependency. if (ConfigProviderBindings.get(appContext).getBoolean("is_nui_shortcut_enabled", false)) { for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { - dataSource.registerContentObservers(appContext); + dataSource.registerContentObservers(); } } else { LogUtil.i("CallLogFramework.registerContentObservers", "not registering content observers"); @@ -80,7 +80,7 @@ public final class CallLogFramework { } for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { - dataSource.unregisterContentObservers(appContext); + dataSource.unregisterContentObservers(); } // Clear data only after all content observers have been disabled. diff --git a/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java b/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java index c399b05ea..32c278838 100644 --- a/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java +++ b/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java @@ -154,7 +154,7 @@ public class RefreshAnnotatedCallLogWorker { private ListenableFuture isDirty() { List> isDirtyFutures = new ArrayList<>(); for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { - ListenableFuture dataSourceDirty = dataSource.isDirty(appContext); + ListenableFuture dataSourceDirty = dataSource.isDirty(); isDirtyFutures.add(dataSourceDirty); String eventName = String.format(Metrics.IS_DIRTY_TEMPLATE, dataSource.getClass().getSimpleName()); @@ -172,7 +172,7 @@ public class RefreshAnnotatedCallLogWorker { // Start by filling the data sources--the system call log data source must go first! CallLogDataSource systemCallLogDataSource = dataSources.getSystemCallLogDataSource(); - ListenableFuture fillFuture = systemCallLogDataSource.fill(appContext, mutations); + ListenableFuture fillFuture = systemCallLogDataSource.fill(mutations); String systemEventName = eventNameForFill(systemCallLogDataSource, isBuilt); futureTimer.applyTiming(fillFuture, systemEventName); @@ -184,7 +184,7 @@ public class RefreshAnnotatedCallLogWorker { Futures.transformAsync( fillFuture, unused -> { - ListenableFuture dataSourceFuture = dataSource.fill(appContext, mutations); + ListenableFuture dataSourceFuture = dataSource.fill(mutations); String eventName = eventNameForFill(dataSource, isBuilt); futureTimer.applyTiming(dataSourceFuture, eventName); return dataSourceFuture; @@ -215,7 +215,7 @@ public class RefreshAnnotatedCallLogWorker { List> onSuccessfulFillFutures = new ArrayList<>(); for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { - ListenableFuture dataSourceFuture = dataSource.onSuccessfulFill(appContext); + ListenableFuture dataSourceFuture = dataSource.onSuccessfulFill(); onSuccessfulFillFutures.add(dataSourceFuture); String eventName = eventNameForOnSuccessfulFill(dataSource, isBuilt); futureTimer.applyTiming(dataSourceFuture, eventName); diff --git a/java/com/android/dialer/calllog/datasources/CallLogDataSource.java b/java/com/android/dialer/calllog/datasources/CallLogDataSource.java index fa3b6a9df..f6796c767 100644 --- a/java/com/android/dialer/calllog/datasources/CallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/CallLogDataSource.java @@ -17,7 +17,6 @@ package com.android.dialer.calllog.datasources; import android.content.ContentValues; -import android.content.Context; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract; @@ -32,18 +31,17 @@ import java.util.List; * always invoked. * *
    - *
  1. {@link #isDirty(Context)}: Invoked only if the framework doesn't yet know if a rebuild is + *
  2. {@link #isDirty()}: Invoked only if the framework doesn't yet know if a rebuild is * necessary. - *
  3. {@link #fill(Context, CallLogMutations)}: Invoked only if the framework determined a - * rebuild is necessary. - *
  4. {@link #onSuccessfulFill(Context)}: Invoked if and only if fill was previously called and - * the mutations provided by the previous fill operation succeeded in being applied. + *
  5. {@link #fill(CallLogMutations)}: Invoked only if the framework determined a rebuild is + * necessary. + *
  6. {@link #onSuccessfulFill()}: Invoked if and only if fill was previously called and the + * mutations provided by the previous fill operation succeeded in being applied. *
* - *

Because {@link #isDirty(Context)} is not always invoked, {@link #fill(Context, - * CallLogMutations)} shouldn't rely on any state saved during {@link #isDirty(Context)}. It - * is safe to assume that {@link #onSuccessfulFill(Context)} refers to the previous fill - * operation. + *

Because {@link #isDirty()} is not always invoked, {@link #fill(CallLogMutations)} shouldn't + * rely on any state saved during {@link #isDirty()}. It is safe to assume that {@link + * #onSuccessfulFill()} refers to the previous fill operation. * *

The same data source objects may be reused across multiple checkDirtyAndRebuild cycles, so * implementors should take care to clear any internal state at the start of a new cycle. @@ -65,7 +63,7 @@ public interface CallLogDataSource { * * @see CallLogDataSource class doc for complete lifecyle information */ - ListenableFuture isDirty(Context appContext); + ListenableFuture isDirty(); /** * Computes the set of mutations necessary to update the annotated call log with respect to this @@ -76,7 +74,7 @@ public interface CallLogDataSource { * contain inserts from the system call log, and these inserts should be modified by each data * source. */ - ListenableFuture fill(Context appContext, CallLogMutations mutations); + ListenableFuture fill(CallLogMutations mutations); /** * Called after database mutations have been applied to all data sources. This is useful for @@ -85,7 +83,7 @@ public interface CallLogDataSource { * * @see CallLogDataSource class doc for complete lifecyle information */ - ListenableFuture onSuccessfulFill(Context appContext); + ListenableFuture onSuccessfulFill(); /** * Combines raw annotated call log rows into a single coalesced row. @@ -104,10 +102,10 @@ public interface CallLogDataSource { ContentValues coalesce(List individualRowsSortedByTimestampDesc); @MainThread - void registerContentObservers(Context appContext); + void registerContentObservers(); @MainThread - void unregisterContentObservers(Context appContext); + void unregisterContentObservers(); /** * Clear any data written by this data source. This is called when the new call log framework has diff --git a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java index 615a457e3..0de987308 100644 --- a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java +++ b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java @@ -37,6 +37,7 @@ 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.Annotations.LightweightExecutor; +import com.android.dialer.inject.ApplicationContext; import com.android.dialer.phonelookup.PhoneLookup; import com.android.dialer.phonelookup.PhoneLookupInfo; import com.android.dialer.phonelookup.composite.CompositePhoneLookup; @@ -66,6 +67,7 @@ import javax.inject.Inject; */ public final class PhoneLookupDataSource implements CallLogDataSource { + private final Context appContext; private final CompositePhoneLookup compositePhoneLookup; private final ListeningExecutorService backgroundExecutorService; private final ListeningExecutorService lightweightExecutorService; @@ -73,8 +75,8 @@ public final class PhoneLookupDataSource implements CallLogDataSource { /** * Keyed by normalized number (the primary key for PhoneLookupHistory). * - *

This is state saved between the {@link #fill(Context, CallLogMutations)} and {@link - * #onSuccessfulFill(Context)} operations. + *

This is state saved between the {@link CallLogDataSource#fill(CallLogMutations)} and {@link + * CallLogDataSource#onSuccessfulFill()} operations. */ private final Map phoneLookupHistoryRowsToUpdate = new ArrayMap<>(); @@ -82,8 +84,8 @@ public final class PhoneLookupDataSource implements CallLogDataSource { * Normalized numbers (the primary key for PhoneLookupHistory) which should be deleted from * PhoneLookupHistory. * - *

This is state saved between the {@link #fill(Context, CallLogMutations)} and {@link - * #onSuccessfulFill(Context)} operations. + *

This is state saved between the {@link CallLogDataSource#fill(CallLogMutations)} and {@link + * CallLogDataSource#onSuccessfulFill()} operations. */ private final Set phoneLookupHistoryRowsToDelete = new ArraySet<>(); @@ -91,10 +93,12 @@ public final class PhoneLookupDataSource implements CallLogDataSource { @Inject PhoneLookupDataSource( + @ApplicationContext Context appContext, CompositePhoneLookup compositePhoneLookup, @BackgroundExecutor ListeningExecutorService backgroundExecutorService, @LightweightExecutor ListeningExecutorService lightweightExecutorService, PhoneLookupHistoryDatabaseHelper phoneLookupHistoryDatabaseHelper) { + this.appContext = appContext; this.compositePhoneLookup = compositePhoneLookup; this.backgroundExecutorService = backgroundExecutorService; this.lightweightExecutorService = lightweightExecutorService; @@ -102,7 +106,7 @@ public final class PhoneLookupDataSource implements CallLogDataSource { } @Override - public ListenableFuture isDirty(Context appContext) { + public ListenableFuture isDirty() { ListenableFuture> phoneNumbers = backgroundExecutorService.submit( () -> queryDistinctDialerPhoneNumbersFromAnnotatedCallLog(appContext)); @@ -139,7 +143,7 @@ public final class PhoneLookupDataSource implements CallLogDataSource { * */ @Override - public ListenableFuture fill(Context appContext, CallLogMutations mutations) { + public ListenableFuture fill(CallLogMutations mutations) { LogUtil.v( "PhoneLookupDataSource.fill", "processing mutations (inserts: %d, updates: %d, deletes: %d)", @@ -243,7 +247,7 @@ public final class PhoneLookupDataSource implements CallLogDataSource { } @Override - public ListenableFuture onSuccessfulFill(Context appContext) { + public ListenableFuture onSuccessfulFill() { // First update and/or delete the appropriate rows in PhoneLookupHistory. ListenableFuture writePhoneLookupHistory = backgroundExecutorService.submit(() -> writePhoneLookupHistory(appContext)); @@ -296,13 +300,13 @@ public final class PhoneLookupDataSource implements CallLogDataSource { @MainThread @Override - public void registerContentObservers(Context appContext) { - compositePhoneLookup.registerContentObservers(appContext); + public void registerContentObservers() { + compositePhoneLookup.registerContentObservers(); } @Override - public void unregisterContentObservers(Context appContext) { - compositePhoneLookup.unregisterContentObservers(appContext); + public void unregisterContentObservers() { + compositePhoneLookup.unregisterContentObservers(); } @Override diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java index e07996177..6fd19dd17 100644 --- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java @@ -52,6 +52,7 @@ import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.compat.android.provider.VoicemailCompat; +import com.android.dialer.inject.ApplicationContext; import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; import com.android.dialer.storage.Unencrypted; import com.android.dialer.telecom.TelecomUtil; @@ -79,6 +80,7 @@ public class SystemCallLogDataSource implements CallLogDataSource { @VisibleForTesting static final String PREF_LAST_TIMESTAMP_PROCESSED = "systemCallLogLastTimestampProcessed"; + private final Context appContext; private final ListeningExecutorService backgroundExecutorService; private final MarkDirtyObserver markDirtyObserver; private final SharedPreferences sharedPreferences; @@ -88,10 +90,12 @@ public class SystemCallLogDataSource implements CallLogDataSource { @Inject SystemCallLogDataSource( + @ApplicationContext Context appContext, @BackgroundExecutor ListeningExecutorService backgroundExecutorService, MarkDirtyObserver markDirtyObserver, @Unencrypted SharedPreferences sharedPreferences, AnnotatedCallLogDatabaseHelper annotatedCallLogDatabaseHelper) { + this.appContext = appContext; this.backgroundExecutorService = backgroundExecutorService; this.markDirtyObserver = markDirtyObserver; this.sharedPreferences = sharedPreferences; @@ -100,7 +104,7 @@ public class SystemCallLogDataSource implements CallLogDataSource { @MainThread @Override - public void registerContentObservers(Context appContext) { + public void registerContentObservers() { Assert.isMainThread(); LogUtil.enterBlock("SystemCallLogDataSource.registerContentObservers"); @@ -130,7 +134,7 @@ public class SystemCallLogDataSource implements CallLogDataSource { } @Override - public void unregisterContentObservers(Context appContext) { + public void unregisterContentObservers() { appContext.getContentResolver().unregisterContentObserver(markDirtyObserver); } @@ -151,17 +155,17 @@ public class SystemCallLogDataSource implements CallLogDataSource { } @Override - public ListenableFuture isDirty(Context appContext) { + public ListenableFuture isDirty() { return backgroundExecutorService.submit(this::isDirtyInternal); } @Override - public ListenableFuture fill(Context appContext, CallLogMutations mutations) { - return backgroundExecutorService.submit(() -> fillInternal(appContext, mutations)); + public ListenableFuture fill(CallLogMutations mutations) { + return backgroundExecutorService.submit(() -> fillInternal(mutations)); } @Override - public ListenableFuture onSuccessfulFill(Context appContext) { + public ListenableFuture onSuccessfulFill() { return backgroundExecutorService.submit(this::onSuccessfulFillInternal); } @@ -181,7 +185,7 @@ public class SystemCallLogDataSource implements CallLogDataSource { } @WorkerThread - private Void fillInternal(Context appContext, CallLogMutations mutations) { + private Void fillInternal(CallLogMutations mutations) { Assert.isWorkerThread(); lastTimestampProcessed = null; diff --git a/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java b/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java index 75c05139d..ab9288a1e 100644 --- a/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java +++ b/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java @@ -28,6 +28,7 @@ import com.android.dialer.calllog.datasources.CallLogMutations; import com.android.dialer.calllog.datasources.util.RowCombiner; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.compat.telephony.TelephonyManagerCompat; +import com.android.dialer.inject.ApplicationContext; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.util.PermissionsUtil; import com.google.common.util.concurrent.Futures; @@ -41,15 +42,19 @@ import javax.inject.Inject; /** Provide information for whether the call is a call to the voicemail inbox. */ public class VoicemailDataSource implements CallLogDataSource { + private final Context appContext; private final ListeningExecutorService backgroundExecutor; @Inject - VoicemailDataSource(@BackgroundExecutor ListeningExecutorService backgroundExecutor) { + VoicemailDataSource( + @ApplicationContext Context appContext, + @BackgroundExecutor ListeningExecutorService backgroundExecutor) { + this.appContext = appContext; this.backgroundExecutor = backgroundExecutor; } @Override - public ListenableFuture isDirty(Context appContext) { + public ListenableFuture isDirty() { // The isVoicemail status is immutable and permanent. The call will always show as "Voicemail" // even if the SIM is swapped. Dialing the row will result in some unexpected number after a SIM // swap but this is deemed acceptable. @@ -58,7 +63,7 @@ public class VoicemailDataSource implements CallLogDataSource { @Override @SuppressWarnings("missingPermission") - public ListenableFuture fill(Context appContext, CallLogMutations mutations) { + public ListenableFuture fill(CallLogMutations mutations) { if (!PermissionsUtil.hasReadPhoneStatePermissions(appContext)) { return Futures.immediateFuture(null); } @@ -94,7 +99,7 @@ public class VoicemailDataSource implements CallLogDataSource { } @Override - public ListenableFuture onSuccessfulFill(Context appContext) { + public ListenableFuture onSuccessfulFill() { return Futures.immediateFuture(null); } @@ -107,10 +112,10 @@ public class VoicemailDataSource implements CallLogDataSource { } @Override - public void registerContentObservers(Context appContext) {} + public void registerContentObservers() {} @Override - public void unregisterContentObservers(Context appContext) {} + public void unregisterContentObservers() {} @Override public ListenableFuture clearData() { diff --git a/java/com/android/dialer/phonelookup/PhoneLookup.java b/java/com/android/dialer/phonelookup/PhoneLookup.java index d4a1ddfbd..d11f023af 100644 --- a/java/com/android/dialer/phonelookup/PhoneLookup.java +++ b/java/com/android/dialer/phonelookup/PhoneLookup.java @@ -16,7 +16,6 @@ package com.android.dialer.phonelookup; -import android.content.Context; import android.support.annotation.MainThread; import com.android.dialer.DialerPhoneNumber; import com.google.common.collect.ImmutableMap; @@ -84,10 +83,10 @@ public interface PhoneLookup { ListenableFuture onSuccessfulBulkUpdate(); @MainThread - void registerContentObservers(Context appContext); + void registerContentObservers(); @MainThread - void unregisterContentObservers(Context appContext); + void unregisterContentObservers(); /** * Clear any data written by this lookup. This is called when the new call log framework has been diff --git a/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java b/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java index f5a249aed..ce879a995 100644 --- a/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java +++ b/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java @@ -169,7 +169,7 @@ public final class DialerBlockedNumberPhoneLookup implements PhoneLookup clearData() { diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2ExtendedDirectoryPhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2ExtendedDirectoryPhoneLookup.java index 9110aa71f..e497989c7 100644 --- a/java/com/android/dialer/phonelookup/cp2/Cp2ExtendedDirectoryPhoneLookup.java +++ b/java/com/android/dialer/phonelookup/cp2/Cp2ExtendedDirectoryPhoneLookup.java @@ -228,14 +228,14 @@ public final class Cp2ExtendedDirectoryPhoneLookup implements PhoneLookup clearData() { diff --git a/java/com/android/dialer/phonelookup/spam/SpamPhoneLookup.java b/java/com/android/dialer/phonelookup/spam/SpamPhoneLookup.java index 315f65819..6b77036cf 100644 --- a/java/com/android/dialer/phonelookup/spam/SpamPhoneLookup.java +++ b/java/com/android/dialer/phonelookup/spam/SpamPhoneLookup.java @@ -16,7 +16,6 @@ package com.android.dialer.phonelookup.spam; -import android.content.Context; import android.content.SharedPreferences; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; @@ -152,13 +151,13 @@ public final class SpamPhoneLookup implements PhoneLookup { } @Override - public void registerContentObservers(Context appContext) { + public void registerContentObservers() { // No content observer can be registered as Spam is not based on a content provider. // Each Spam implementation should be responsible for notifying any data changes. } @Override - public void unregisterContentObservers(Context appContext) {} + public void unregisterContentObservers() {} @Override public ListenableFuture clearData() { -- cgit v1.2.3 From deb440005181e1d18785e2474192142cf1681d54 Mon Sep 17 00:00:00 2001 From: uabdullah Date: Wed, 21 Mar 2018 15:30:16 -0700 Subject: Use SwitchPreferenceWithClickableSummary instead of SwitchPreference for VM Donation The learn more link needs to be in the summary of the switch preference, however having a hyperlink in the summary text view of a switch preference does not open the hyperlink. To do this we made our custom switch preference which allows the summary to be clicked. All other aspects of the switch preference remain the same. Bug: 74033229 Test: Unit test PiperOrigin-RevId: 189978676 Change-Id: I31e744f3545e576ee3f5ac4a8fee249e22835e19 --- .../dialer/common/preference/AndroidManifest.xml | 18 ++++ .../SwitchPreferenceWithClickableSummary.java | 104 +++++++++++++++++++++ .../dialer/common/preference/res/values/attrs.xml | 22 +++++ .../settings/VoicemailSettingsFragment.java | 65 +++++++++++-- .../voicemail/settings/res/values/strings.xml | 4 +- .../settings/res/xml/voicemail_settings.xml | 35 +++---- packages.mk | 1 + 7 files changed, 221 insertions(+), 28 deletions(-) create mode 100644 java/com/android/dialer/common/preference/AndroidManifest.xml create mode 100644 java/com/android/dialer/common/preference/SwitchPreferenceWithClickableSummary.java create mode 100644 java/com/android/dialer/common/preference/res/values/attrs.xml diff --git a/java/com/android/dialer/common/preference/AndroidManifest.xml b/java/com/android/dialer/common/preference/AndroidManifest.xml new file mode 100644 index 000000000..3e8062216 --- /dev/null +++ b/java/com/android/dialer/common/preference/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + diff --git a/java/com/android/dialer/common/preference/SwitchPreferenceWithClickableSummary.java b/java/com/android/dialer/common/preference/SwitchPreferenceWithClickableSummary.java new file mode 100644 index 000000000..7b3564ddc --- /dev/null +++ b/java/com/android/dialer/common/preference/SwitchPreferenceWithClickableSummary.java @@ -0,0 +1,104 @@ +/* + * 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 + */ + +package com.android.dialer.common.preference; + +import static android.support.v4.content.ContextCompat.startActivity; + +import android.content.Context; +import android.content.Intent; +import android.content.res.TypedArray; +import android.net.Uri; +import android.preference.SwitchPreference; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import com.android.dialer.common.Assert; + +/** + * Utility to allow the summary of a {@link SwitchPreference} to be clicked and opened via a browser + * to the specified {@link urlToOpen} attribute while maintaining all other aspects of a {@link + * SwitchPreference}. + * + *

Example usage: + * + *

+ *   
+ * 
+ */ +public class SwitchPreferenceWithClickableSummary extends SwitchPreference { + private final String urlToOpen; + + public SwitchPreferenceWithClickableSummary( + Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + TypedArray typedArray = + context.obtainStyledAttributes(attrs, R.styleable.SwitchPreferenceWithClickableSummary); + urlToOpen = + String.valueOf( + typedArray.getText(R.styleable.SwitchPreferenceWithClickableSummary_urlToOpen)); + } + + public SwitchPreferenceWithClickableSummary( + Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr, defStyleAttr); + TypedArray typedArray = + context.obtainStyledAttributes(attrs, R.styleable.SwitchPreferenceWithClickableSummary); + urlToOpen = + String.valueOf( + typedArray.getText(R.styleable.SwitchPreferenceWithClickableSummary_urlToOpen)); + } + + public SwitchPreferenceWithClickableSummary(Context context, AttributeSet attrs) { + super(context, attrs); + TypedArray typedArray = + context.obtainStyledAttributes(attrs, R.styleable.SwitchPreferenceWithClickableSummary); + urlToOpen = + String.valueOf( + typedArray.getText(R.styleable.SwitchPreferenceWithClickableSummary_urlToOpen)); + } + + public SwitchPreferenceWithClickableSummary(Context context) { + this(context, null); + } + + @Override + protected View onCreateView(ViewGroup parent) { + return super.onCreateView(parent); + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + Assert.checkArgument( + urlToOpen != null, + "must have a urlToOpen attribute when using SwitchPreferenceWithClickableSummary"); + view.findViewById(android.R.id.summary) + .setOnClickListener( + new OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlToOpen)); + startActivity(view.getContext(), intent, null); + } + }); + } +} diff --git a/java/com/android/dialer/common/preference/res/values/attrs.xml b/java/com/android/dialer/common/preference/res/values/attrs.xml new file mode 100644 index 000000000..c1d1de015 --- /dev/null +++ b/java/com/android/dialer/common/preference/res/values/attrs.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/java/com/android/dialer/voicemail/settings/VoicemailSettingsFragment.java b/java/com/android/dialer/voicemail/settings/VoicemailSettingsFragment.java index 53c14b795..2e76b70fe 100644 --- a/java/com/android/dialer/voicemail/settings/VoicemailSettingsFragment.java +++ b/java/com/android/dialer/voicemail/settings/VoicemailSettingsFragment.java @@ -25,6 +25,7 @@ import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.preference.SwitchPreference; import android.provider.Settings; +import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import android.telecom.PhoneAccount; @@ -34,14 +35,18 @@ import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; +import com.android.dialer.common.preference.SwitchPreferenceWithClickableSummary; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.notification.NotificationChannelManager; +import com.android.dialer.spannable.ContentWithLearnMoreSpanner; import com.android.dialer.telecom.TelecomUtil; import com.android.voicemail.VoicemailClient; import com.android.voicemail.VoicemailClient.ActivationStateListener; import com.android.voicemail.VoicemailComponent; import com.google.common.base.Optional; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * Fragment for voicemail settings. Requires {@link VoicemailClient#PARAM_PHONE_ACCOUNT_HANDLE} set @@ -63,19 +68,16 @@ public class VoicemailSettingsFragment extends PreferenceFragment private static final String TAG = "VmSettingsActivity"; @Nullable private PhoneAccountHandle phoneAccountHandle; - private VoicemailClient voicemailClient; - // Settings that are independent of the carrier configurations private Preference voicemailNotificationPreference; private PreferenceScreen advancedSettingsPreference; - // Settings that are supported by dialer only if the carrier configurations are valid. private SwitchPreference visualVoicemailPreference; private SwitchPreference voicemailAutoArchivePreference; private SwitchPreference transcribeVoicemailPreference; // Voicemail transcription analysis toggle - private SwitchPreference donateTranscribedVoicemailPreference; + private SwitchPreferenceWithClickableSummary donateTranscribedVoicemailPreference; private Preference voicemailChangePinPreference; @Override @@ -98,7 +100,7 @@ public class VoicemailSettingsFragment extends PreferenceFragment addPreferencesFromResource(R.xml.voicemail_settings); - initializePreferences(); + initializeXmlPreferences(); setupVisualVoicemailPreferences(); @@ -163,15 +165,28 @@ public class VoicemailSettingsFragment extends PreferenceFragment } private void showTranscriptionDonationEnabledPreferences() { - donateTranscribedVoicemailPreference.setOnPreferenceChangeListener(this); + donateTranscribedVoicemailPreference.setEnabled(true); donateTranscribedVoicemailPreference.setChecked( voicemailClient.isVoicemailDonationEnabled(getContext(), phoneAccountHandle)); + donateTranscribedVoicemailPreference.setOnPreferenceChangeListener(this); donateTranscribedVoicemailPreference.setSummary( - R.string.voicemail_donate_preference_summary_info); - donateTranscribedVoicemailPreference.setEnabled(true); + getVoicemailTranscriptionDonationInformationalText()); getPreferenceScreen().addPreference(donateTranscribedVoicemailPreference); } + /** + * Builds a spannable string containing the voicemail donation informational text containing the + * appropriate "Learn More" urls. + * + * @return The voicemail donation information text. + */ + private CharSequence getVoicemailTranscriptionDonationInformationalText() { + return new ContentWithLearnMoreSpanner(getContext()) + .create( + getContext().getString(R.string.voicemail_donate_preference_summary_info), + getContext().getString(R.string.donation_learn_more_url)); + } + private void removeAllTranscriptionPreferences() { getPreferenceScreen().removePreference(transcribeVoicemailPreference); getPreferenceScreen().removePreference(donateTranscribedVoicemailPreference); @@ -196,29 +211,38 @@ public class VoicemailSettingsFragment extends PreferenceFragment updateVoicemailSummaryMessage(); } - private void initializePreferences() { + /** The preferences that are present in the voicemail_settings.xml file are initialized here. */ + private void initializeXmlPreferences() { voicemailNotificationPreference = findPreference(getString(R.string.voicemail_notifications_key)); + voicemailNotificationPreference.setOrder(VMSettingOrdering.NOTIFICATIONS); advancedSettingsPreference = (PreferenceScreen) findPreference(getString(R.string.voicemail_advanced_settings_key)); + advancedSettingsPreference.setOrder(VMSettingOrdering.ADVANCED_SETTING); visualVoicemailPreference = (SwitchPreference) findPreference(getString(R.string.voicemail_visual_voicemail_key)); + visualVoicemailPreference.setOrder(VMSettingOrdering.VISUAL_VOICEMAIL); voicemailAutoArchivePreference = (SwitchPreference) findPreference(getString(R.string.voicemail_visual_voicemail_archive_key)); + voicemailAutoArchivePreference.setOrder(VMSettingOrdering.VOICEMAIL_AUTO_ARCHIVE); transcribeVoicemailPreference = (SwitchPreference) findPreference(getString(R.string.voicemail_visual_voicemail_transcription_key)); + transcribeVoicemailPreference.setOrder(VMSettingOrdering.VOICEMAIL_TRANSCRIPTION); donateTranscribedVoicemailPreference = - (SwitchPreference) + (SwitchPreferenceWithClickableSummary) findPreference(getString(R.string.voicemail_visual_voicemail_donation_key)); + donateTranscribedVoicemailPreference.setOrder( + VMSettingOrdering.VOICEMAIL_TRANSCRIPTION_DONATION); voicemailChangePinPreference = findPreference(getString(R.string.voicemail_change_pin_key)); + voicemailChangePinPreference.setOrder(VMSettingOrdering.VOICEMAIL_CHANGE_PIN); } /** Removes vvm settings since the carrier setup is not supported by Dialer */ @@ -462,4 +486,25 @@ public class VoicemailSettingsFragment extends PreferenceFragment builder.setCancelable(true); builder.show(); } + + /** The ordering in which to show the voicemail settings */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + VMSettingOrdering.NOTIFICATIONS, + VMSettingOrdering.VISUAL_VOICEMAIL, + VMSettingOrdering.VOICEMAIL_TRANSCRIPTION, + VMSettingOrdering.VOICEMAIL_TRANSCRIPTION_DONATION, + VMSettingOrdering.VOICEMAIL_CHANGE_PIN, + VMSettingOrdering.VOICEMAIL_AUTO_ARCHIVE, + VMSettingOrdering.ADVANCED_SETTING + }) + private @interface VMSettingOrdering { + int NOTIFICATIONS = 1; + int VISUAL_VOICEMAIL = 2; + int VOICEMAIL_TRANSCRIPTION = 3; + int VOICEMAIL_TRANSCRIPTION_DONATION = 4; + int VOICEMAIL_CHANGE_PIN = 5; + int VOICEMAIL_AUTO_ARCHIVE = 6; + int ADVANCED_SETTING = 7; + } } diff --git a/java/com/android/dialer/voicemail/settings/res/values/strings.xml b/java/com/android/dialer/voicemail/settings/res/values/strings.xml index db6309800..7df8a0192 100644 --- a/java/com/android/dialer/voicemail/settings/res/values/strings.xml +++ b/java/com/android/dialer/voicemail/settings/res/values/strings.xml @@ -119,9 +119,9 @@ Activating voicemail - Get transcripts of your voicemail using Google\'s transcription service + Get transcripts of your voicemail using Google\'s transcription service. - Let Google review your voicemail messages to improve transcription accuracy + Let Google review your voicemail messages to improve transcription accuracy. Your voicemail messages are stored anonymously. %1$s Turn off visual voicemail diff --git a/java/com/android/dialer/voicemail/settings/res/xml/voicemail_settings.xml b/java/com/android/dialer/voicemail/settings/res/xml/voicemail_settings.xml index 175a12740..e5af813b6 100644 --- a/java/com/android/dialer/voicemail/settings/res/xml/voicemail_settings.xml +++ b/java/com/android/dialer/voicemail/settings/res/xml/voicemail_settings.xml @@ -15,37 +15,40 @@ --> + xmlns:app="http://schemas.android.com/apk/res-auto" + android:title="@string/voicemail_settings_title"> " + android:key="@string/voicemail_visual_voicemail_key" + android:title="@string/voicemail_visual_voicemail_switch_title"/>" " + android:dependency="@string/voicemail_visual_voicemail_key" + android:key="@string/voicemail_visual_voicemail_archive_key" + android:title="@string/voicemail_visual_voicemail_auto_archive_switch_title"/>" " - " + + + android:key="@string/voicemail_change_pin_key" + android:title="@string/voicemail_change_pin_preference_title"/> - + android:key="@string/voicemail_advanced_settings_key" + android:title="@string/voicemail_advanced_settings_title"> + diff --git a/packages.mk b/packages.mk index 5e69a15dd..4ae490c38 100644 --- a/packages.mk +++ b/packages.mk @@ -27,6 +27,7 @@ LOCAL_AAPT_FLAGS := \ com.android.dialer.clipboard \ com.android.dialer.commandline \ com.android.dialer.common \ + com.android.dialer.common.preference \ com.android.dialer.configprovider \ com.android.dialer.contactphoto \ com.android.dialer.contactsfragment \ -- cgit v1.2.3