diff options
Diffstat (limited to 'java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java')
-rw-r--r-- | java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java b/java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java new file mode 100644 index 000000000..45395a71f --- /dev/null +++ b/java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2016 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.incallui.answer.impl.hint; + +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.preference.PreferenceManager; +import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; +import com.android.dialer.common.Assert; +import com.android.dialer.common.ConfigProvider; +import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.common.LogUtil; +import com.android.incallui.util.AccessibilityUtil; +import java.util.Calendar; + +/** + * Selects a AnswerHint to show. If there's no suitable hints {@link EmptyAnswerHint} will be used, + * which does nothing. + */ +public class AnswerHintFactory { + + private static final String CONFIG_ANSWER_HINT_ANSWERED_THRESHOLD_KEY = + "answer_hint_answered_threshold"; + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + static final String CONFIG_ANSWER_HINT_WHITELISTED_DEVICES_KEY = + "answer_hint_whitelisted_devices"; + // Most popular devices released before NDR1 is whitelisted. Their user are likely to have seen + // the legacy UI. + private static final String DEFAULT_WHITELISTED_DEVICES_CSV = + "/hammerhead//bullhead//angler//shamu//gm4g//gm4g_s//AQ4501//gce_x86_phone//gm4gtkc_s/" + + "/Sparkle_V//Mi-498//AQ4502//imobileiq2//A65//H940//m8_google//m0xx//A10//ctih220/" + + "/Mi438S//bacon/"; + + @VisibleForTesting + static final String ANSWERED_COUNT_PREFERENCE_KEY = "answer_hint_answered_count"; + + private final EventPayloadLoader eventPayloadLoader; + + public AnswerHintFactory(@NonNull EventPayloadLoader eventPayloadLoader) { + this.eventPayloadLoader = Assert.isNotNull(eventPayloadLoader); + } + + @NonNull + public AnswerHint create(Context context, long puckUpDuration, long puckUpDelay) { + + if (shouldShowAnswerHint( + context, + ConfigProviderBindings.get(context), + getDeviceProtectedPreferences(context), + Build.PRODUCT)) { + return new DotAnswerHint(context, puckUpDuration, puckUpDelay); + } + + // Display the event answer hint if the payload is available. + Drawable eventPayload = + eventPayloadLoader.loadPayload( + context, System.currentTimeMillis(), Calendar.getInstance().getTimeZone()); + if (eventPayload != null) { + return new EventAnswerHint(context, eventPayload, puckUpDuration, puckUpDelay); + } + + return new EmptyAnswerHint(); + } + + public static void increaseAnsweredCount(Context context) { + SharedPreferences sharedPreferences = getDeviceProtectedPreferences(context); + int answeredCount = sharedPreferences.getInt(ANSWERED_COUNT_PREFERENCE_KEY, 0); + sharedPreferences.edit().putInt(ANSWERED_COUNT_PREFERENCE_KEY, answeredCount + 1).apply(); + } + + @VisibleForTesting + static boolean shouldShowAnswerHint( + Context context, + ConfigProvider configProvider, + SharedPreferences sharedPreferences, + String device) { + if (AccessibilityUtil.isTouchExplorationEnabled(context)) { + return false; + } + // Devices that has the legacy dialer installed are whitelisted as they are likely to go through + // a UX change during updates. + if (!isDeviceWhitelisted(device, configProvider)) { + return false; + } + + // If the user has gone through the process a few times we can assume they have learnt the + // method. + int answeredCount = sharedPreferences.getInt(ANSWERED_COUNT_PREFERENCE_KEY, 0); + long threshold = configProvider.getLong(CONFIG_ANSWER_HINT_ANSWERED_THRESHOLD_KEY, 3); + LogUtil.i( + "AnswerHintFactory.shouldShowAnswerHint", + "answerCount: %d, threshold: %d", + answeredCount, + threshold); + return answeredCount < threshold; + } + + /** + * @param device should be the value of{@link Build#PRODUCT}. + * @param configProvider should provide a list of devices quoted with '/' concatenated to a + * string. + */ + private static boolean isDeviceWhitelisted(String device, ConfigProvider configProvider) { + return configProvider + .getString(CONFIG_ANSWER_HINT_WHITELISTED_DEVICES_KEY, DEFAULT_WHITELISTED_DEVICES_CSV) + .contains("/" + device + "/"); + } + + private static SharedPreferences getDeviceProtectedPreferences(Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + return PreferenceManager.getDefaultSharedPreferences(context); + } + return PreferenceManager.getDefaultSharedPreferences( + context.createDeviceProtectedStorageContext()); + } +} |