1 /* 2 * Copyright (C) 2015 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.camera.app; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.preference.PreferenceManager; 22 23 import com.android.camera.stats.profiler.Profile; 24 import com.android.camera.stats.profiler.Profiler; 25 import com.android.camera.stats.profiler.Profilers; 26 27 public class FirstRunDetector { 28 private static final long UNKNOWN = -1; 29 // Default SharedPreferences key for when the application was first used. 30 private static final String CLIENT_FIRST_USE_TIME = "client_first_use_time_millis"; 31 32 private static class Singleton { 33 private static final FirstRunDetector INSTANCE = new FirstRunDetector( 34 Profilers.instance().guard()); 35 } 36 37 public static FirstRunDetector instance() { 38 return Singleton.INSTANCE; 39 } 40 41 private final Profile mProfile; 42 private long mTimeOfFirstRun; 43 /** Flag set to true if and only if first run of application is detected. */ 44 private boolean mIsFirstRun = false; 45 46 private FirstRunDetector(Profiler profiler) { 47 mProfile = profiler.create("FirstRunDetector getTimeOfFirstRun"); 48 } 49 50 /** 51 * Return true if this is the first time the app was opened. 52 */ 53 public boolean isFirstRun() { 54 return mIsFirstRun; 55 } 56 57 /** 58 * Return true if this is the first time the app was opened. 59 */ 60 public long getTimeOfFirstRun() { 61 return mTimeOfFirstRun; 62 } 63 64 /** 65 * Clear the first run flag. 66 */ 67 public void clear() { 68 mIsFirstRun = false; 69 } 70 71 /** 72 * Returns time the app was first used, or UNKNOWN if the 73 * client is too old. This could be moved a separate utility class. 74 * 75 * @param context Application context. 76 */ 77 public void initializeTimeOfFirstRun(Context context) { 78 mProfile.start(); 79 80 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); 81 mProfile.mark("PreferenceManager.getDefaultSharedPreferences"); 82 83 // Read time of first installation. 84 long timeOfFirstUseMillis = preferences.getLong(CLIENT_FIRST_USE_TIME, 0); 85 mProfile.mark("preferences.getLong"); 86 87 // Write installation time if not set. 88 if (timeOfFirstUseMillis == 0) { 89 SharedPreferences cameraPrefs = context.getSharedPreferences( 90 context.getPackageName() + "_preferences_camera", Context.MODE_PRIVATE); 91 mProfile.mark("getSharedPreferences"); 92 93 // If we can find previous Shared Preferences, this is not a new install. 94 boolean isUpgrade = cameraPrefs.getAll().size() > 0 || preferences.getAll().size() > 0; 95 96 // Preference CLIENT_FIRST_USE_TIME is set to UNKNOWN for preference 97 // upgrades and the actual first use time for new installs. We call 98 // System.currentTimeMillis() to match the log timebase. 99 timeOfFirstUseMillis = isUpgrade ? UNKNOWN : System.currentTimeMillis(); 100 preferences.edit().putLong(CLIENT_FIRST_USE_TIME, timeOfFirstUseMillis).apply(); 101 mProfile.mark("preferences.edit()"); 102 103 if (!isUpgrade) { 104 mIsFirstRun = true; 105 } 106 } 107 mTimeOfFirstRun = timeOfFirstUseMillis; 108 mProfile.stop(); 109 } 110 }