• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.inputmethod.latin.utils;
18 
19 import android.content.Context;
20 import android.content.SharedPreferences;
21 import android.provider.Settings;
22 import android.provider.Settings.SettingNotFoundException;
23 import android.text.TextUtils;
24 import android.util.Log;
25 
26 import com.android.inputmethod.annotations.UsedForTesting;
27 import com.android.inputmethod.latin.R;
28 
29 import java.util.concurrent.TimeUnit;
30 
31 public final class ImportantNoticeUtils {
32     private static final String TAG = ImportantNoticeUtils.class.getSimpleName();
33 
34     // {@link SharedPreferences} name to save the last important notice version that has been
35     // displayed to users.
36     private static final String PREFERENCE_NAME = "important_notice_pref";
37     @UsedForTesting
38     static final String KEY_IMPORTANT_NOTICE_VERSION = "important_notice_version";
39     @UsedForTesting
40     static final String KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE =
41             "timestamp_of_first_important_notice";
42     @UsedForTesting
43     static final long TIMEOUT_OF_IMPORTANT_NOTICE = TimeUnit.HOURS.toMillis(23);
44     public static final int VERSION_TO_ENABLE_PERSONALIZED_SUGGESTIONS = 1;
45 
46     // Copy of the hidden {@link Settings.Secure#USER_SETUP_COMPLETE} settings key.
47     // The value is zero until each multiuser completes system setup wizard.
48     // Caveat: This is a hidden API.
49     private static final String Settings_Secure_USER_SETUP_COMPLETE = "user_setup_complete";
50     private static final int USER_SETUP_IS_NOT_COMPLETE = 0;
51 
ImportantNoticeUtils()52     private ImportantNoticeUtils() {
53         // This utility class is not publicly instantiable.
54     }
55 
isInSystemSetupWizard(final Context context)56     private static boolean isInSystemSetupWizard(final Context context) {
57         try {
58             final int userSetupComplete = Settings.Secure.getInt(
59                     context.getContentResolver(), Settings_Secure_USER_SETUP_COMPLETE);
60             return userSetupComplete == USER_SETUP_IS_NOT_COMPLETE;
61         } catch (final SettingNotFoundException e) {
62             Log.w(TAG, "Can't find settings in Settings.Secure: key="
63                     + Settings_Secure_USER_SETUP_COMPLETE);
64             return false;
65         }
66     }
67 
68     @UsedForTesting
getImportantNoticePreferences(final Context context)69     static SharedPreferences getImportantNoticePreferences(final Context context) {
70         return context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
71     }
72 
73     @UsedForTesting
getCurrentImportantNoticeVersion(final Context context)74     static int getCurrentImportantNoticeVersion(final Context context) {
75         return context.getResources().getInteger(R.integer.config_important_notice_version);
76     }
77 
78     @UsedForTesting
getLastImportantNoticeVersion(final Context context)79     static int getLastImportantNoticeVersion(final Context context) {
80         return getImportantNoticePreferences(context).getInt(KEY_IMPORTANT_NOTICE_VERSION, 0);
81     }
82 
getNextImportantNoticeVersion(final Context context)83     public static int getNextImportantNoticeVersion(final Context context) {
84         return getLastImportantNoticeVersion(context) + 1;
85     }
86 
hasNewImportantNotice(final Context context)87     private static boolean hasNewImportantNotice(final Context context) {
88         final int lastVersion = getLastImportantNoticeVersion(context);
89         return getCurrentImportantNoticeVersion(context) > lastVersion;
90     }
91 
92     @UsedForTesting
hasTimeoutPassed(final Context context, final long currentTimeInMillis)93     static boolean hasTimeoutPassed(final Context context, final long currentTimeInMillis) {
94         final SharedPreferences prefs = getImportantNoticePreferences(context);
95         if (!prefs.contains(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)) {
96             prefs.edit()
97                     .putLong(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE, currentTimeInMillis)
98                     .apply();
99         }
100         final long firstDisplayTimeInMillis = prefs.getLong(
101                 KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE, currentTimeInMillis);
102         final long elapsedTime = currentTimeInMillis - firstDisplayTimeInMillis;
103         return elapsedTime >= TIMEOUT_OF_IMPORTANT_NOTICE;
104     }
105 
shouldShowImportantNotice(final Context context)106     public static boolean shouldShowImportantNotice(final Context context) {
107         if (!hasNewImportantNotice(context)) {
108             return false;
109         }
110         final String importantNoticeTitle = getNextImportantNoticeTitle(context);
111         if (TextUtils.isEmpty(importantNoticeTitle)) {
112             return false;
113         }
114         if (isInSystemSetupWizard(context)) {
115             return false;
116         }
117         if (hasTimeoutPassed(context, System.currentTimeMillis())) {
118             updateLastImportantNoticeVersion(context);
119             return false;
120         }
121         return true;
122     }
123 
updateLastImportantNoticeVersion(final Context context)124     public static void updateLastImportantNoticeVersion(final Context context) {
125         getImportantNoticePreferences(context)
126                 .edit()
127                 .putInt(KEY_IMPORTANT_NOTICE_VERSION, getNextImportantNoticeVersion(context))
128                 .remove(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)
129                 .apply();
130     }
131 
getNextImportantNoticeTitle(final Context context)132     public static String getNextImportantNoticeTitle(final Context context) {
133         final int nextVersion = getNextImportantNoticeVersion(context);
134         final String[] importantNoticeTitleArray = context.getResources().getStringArray(
135                 R.array.important_notice_title_array);
136         if (nextVersion > 0 && nextVersion < importantNoticeTitleArray.length) {
137             return importantNoticeTitleArray[nextVersion];
138         }
139         return null;
140     }
141 
getNextImportantNoticeContents(final Context context)142     public static String getNextImportantNoticeContents(final Context context) {
143         final int nextVersion = getNextImportantNoticeVersion(context);
144         final String[] importantNoticeContentsArray = context.getResources().getStringArray(
145                 R.array.important_notice_contents_array);
146         if (nextVersion > 0 && nextVersion < importantNoticeContentsArray.length) {
147             return importantNoticeContentsArray[nextVersion];
148         }
149         return null;
150     }
151 }
152