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 
instance()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 
FirstRunDetector(Profiler profiler)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      */
isFirstRun()53     public boolean isFirstRun() {
54         return mIsFirstRun;
55     }
56 
57     /**
58      * Return true if this is the first time the app was opened.
59      */
getTimeOfFirstRun()60     public long getTimeOfFirstRun() {
61         return mTimeOfFirstRun;
62     }
63 
64     /**
65      * Clear the first run flag.
66      */
clear()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      */
initializeTimeOfFirstRun(Context context)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 }