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.incallui.answer.impl.hint; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.graphics.drawable.Drawable; 22 import android.os.Build; 23 import android.support.annotation.NonNull; 24 import android.support.annotation.VisibleForTesting; 25 import com.android.dialer.common.Assert; 26 import com.android.dialer.common.ConfigProvider; 27 import com.android.dialer.common.ConfigProviderBindings; 28 import com.android.dialer.common.LogUtil; 29 import com.android.dialer.util.DialerUtils; 30 import com.android.incallui.util.AccessibilityUtil; 31 32 /** 33 * Selects a AnswerHint to show. If there's no suitable hints {@link EmptyAnswerHint} will be used, 34 * which does nothing. 35 */ 36 public class AnswerHintFactory { 37 38 private static final String CONFIG_ANSWER_HINT_ANSWERED_THRESHOLD_KEY = 39 "answer_hint_answered_threshold"; 40 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) 41 static final String CONFIG_ANSWER_HINT_WHITELISTED_DEVICES_KEY = 42 "answer_hint_whitelisted_devices"; 43 // Most popular devices released before NDR1 is whitelisted. Their user are likely to have seen 44 // the legacy UI. 45 private static final String DEFAULT_WHITELISTED_DEVICES_CSV = 46 "/hammerhead//bullhead//angler//shamu//gm4g//gm4g_s//AQ4501//gce_x86_phone//gm4gtkc_s/" 47 + "/Sparkle_V//Mi-498//AQ4502//imobileiq2//A65//H940//m8_google//m0xx//A10//ctih220/" 48 + "/Mi438S//bacon/"; 49 50 @VisibleForTesting 51 static final String ANSWERED_COUNT_PREFERENCE_KEY = "answer_hint_answered_count"; 52 53 private final PawImageLoader pawImageLoader; 54 55 public AnswerHintFactory(@NonNull PawImageLoader pawImageLoader) { 56 this.pawImageLoader = Assert.isNotNull(pawImageLoader); 57 } 58 59 @NonNull 60 public AnswerHint create(Context context, long puckUpDuration, long puckUpDelay) { 61 62 if (shouldShowAnswerHint( 63 context, 64 ConfigProviderBindings.get(context), 65 DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(context), 66 Build.PRODUCT)) { 67 return new DotAnswerHint(context, puckUpDuration, puckUpDelay); 68 } 69 70 // Display the event answer hint if the payload is available. 71 Drawable eventPayload = pawImageLoader.loadPayload(context); 72 if (eventPayload != null) { 73 return new PawAnswerHint(context, eventPayload, puckUpDuration, puckUpDelay); 74 } 75 76 return new EmptyAnswerHint(); 77 } 78 79 public static void increaseAnsweredCount(Context context) { 80 SharedPreferences sharedPreferences = 81 DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(context); 82 int answeredCount = sharedPreferences.getInt(ANSWERED_COUNT_PREFERENCE_KEY, 0); 83 sharedPreferences.edit().putInt(ANSWERED_COUNT_PREFERENCE_KEY, answeredCount + 1).apply(); 84 } 85 86 @VisibleForTesting 87 static boolean shouldShowAnswerHint( 88 Context context, 89 ConfigProvider configProvider, 90 SharedPreferences sharedPreferences, 91 String device) { 92 if (AccessibilityUtil.isTouchExplorationEnabled(context)) { 93 return false; 94 } 95 // Devices that has the legacy dialer installed are whitelisted as they are likely to go through 96 // a UX change during updates. 97 if (!isDeviceWhitelisted(device, configProvider)) { 98 return false; 99 } 100 101 // If the user has gone through the process a few times we can assume they have learnt the 102 // method. 103 int answeredCount = sharedPreferences.getInt(ANSWERED_COUNT_PREFERENCE_KEY, 0); 104 long threshold = configProvider.getLong(CONFIG_ANSWER_HINT_ANSWERED_THRESHOLD_KEY, 3); 105 LogUtil.i( 106 "AnswerHintFactory.shouldShowAnswerHint", 107 "answerCount: %d, threshold: %d", 108 answeredCount, 109 threshold); 110 return answeredCount < threshold; 111 } 112 113 /** 114 * @param device should be the value of{@link Build#PRODUCT}. 115 * @param configProvider should provide a list of devices quoted with '/' concatenated to a 116 * string. 117 */ 118 private static boolean isDeviceWhitelisted(String device, ConfigProvider configProvider) { 119 return configProvider 120 .getString(CONFIG_ANSWER_HINT_WHITELISTED_DEVICES_KEY, DEFAULT_WHITELISTED_DEVICES_CSV) 121 .contains("/" + device + "/"); 122 } 123 } 124