ImportantNoticeUtils.java revision be4e0d0e3921af3d575f745cb356704974362baf
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
17package com.android.inputmethod.latin.utils;
18
19import android.content.Context;
20import android.content.SharedPreferences;
21import android.provider.Settings;
22import android.provider.Settings.SettingNotFoundException;
23import android.text.TextUtils;
24import android.util.Log;
25
26import com.android.inputmethod.annotations.UsedForTesting;
27import com.android.inputmethod.latin.R;
28
29import java.util.concurrent.TimeUnit;
30
31public 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
52    private ImportantNoticeUtils() {
53        // This utility class is not publicly instantiable.
54    }
55
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
69    static SharedPreferences getImportantNoticePreferences(final Context context) {
70        return context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
71    }
72
73    @UsedForTesting
74    static int getCurrentImportantNoticeVersion(final Context context) {
75        return context.getResources().getInteger(R.integer.config_important_notice_version);
76    }
77
78    @UsedForTesting
79    static int getLastImportantNoticeVersion(final Context context) {
80        return getImportantNoticePreferences(context).getInt(KEY_IMPORTANT_NOTICE_VERSION, 0);
81    }
82
83    public static int getNextImportantNoticeVersion(final Context context) {
84        return getLastImportantNoticeVersion(context) + 1;
85    }
86
87    private static boolean hasNewImportantNotice(final Context context) {
88        final int lastVersion = getLastImportantNoticeVersion(context);
89        return getCurrentImportantNoticeVersion(context) > lastVersion;
90    }
91
92    @UsedForTesting
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
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
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
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
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