Home | History | Annotate | Download | only in utils
      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 
     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