13516800b611a79339a3c188332d13a26e9086b09Adam Lesinski/**
23516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Copyright (C) 2014 The Android Open Source Project
33516800b611a79339a3c188332d13a26e9086b09Adam Lesinski *
43516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); you may not
53516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * use this file except in compliance with the License. You may obtain a copy
63516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * of the License at
73516800b611a79339a3c188332d13a26e9086b09Adam Lesinski *
83516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0
93516800b611a79339a3c188332d13a26e9086b09Adam Lesinski *
103516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Unless required by applicable law or agreed to in writing, software
113516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
123516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
133516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * License for the specific language governing permissions and limitations
143516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * under the License.
153516800b611a79339a3c188332d13a26e9086b09Adam Lesinski */
163516800b611a79339a3c188332d13a26e9086b09Adam Lesinskipackage com.android.server.usage;
173516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
187f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport android.app.usage.ConfigurationStats;
1960aa35b756707a16d310c222a36edbcef9d56ed4Suprabh Shuklaimport android.app.usage.EventList;
20ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackbornimport android.app.usage.EventStats;
213516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.TimeSparseArray;
223516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.UsageEvents;
233516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.UsageStats;
247f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport android.content.res.Configuration;
253516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.util.ArrayMap;
269d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinskiimport android.util.ArraySet;
273516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
28ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackbornimport java.util.List;
29ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn
303516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiclass IntervalStats {
313516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    public long beginTime;
323516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    public long endTime;
333516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    public long lastTimeSaved;
343378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    public final EventTracker interactiveTracker = new EventTracker();
353378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    public final EventTracker nonInteractiveTracker = new EventTracker();
363378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    public final EventTracker keyguardShownTracker = new EventTracker();
373378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    public final EventTracker keyguardHiddenTracker = new EventTracker();
3837a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski    public final ArrayMap<String, UsageStats> packageStats = new ArrayMap<>();
397f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    public final ArrayMap<Configuration, ConfigurationStats> configurations = new ArrayMap<>();
407f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    public Configuration activeConfiguration;
4160aa35b756707a16d310c222a36edbcef9d56ed4Suprabh Shukla    public EventList events;
423516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
439d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski    // A string cache. This is important as when we're parsing XML files, we don't want to
449d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski    // keep hundreds of strings that have the same contents. We will read the string
459d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski    // and only keep it if it's not in the cache. The GC will take care of the
469d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski    // strings that had identical copies in the cache.
479d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski    private final ArraySet<String> mStringCache = new ArraySet<>();
483516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
493378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    public static final class EventTracker {
503378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        public long curStartTime;
513378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        public long lastEventTime;
523378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        public long duration;
533378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        public int count;
543378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn
553378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        public void commitTime(long timeStamp) {
563378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            if (curStartTime != 0) {
573378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                duration += timeStamp - duration;
583378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                curStartTime = 0;
593378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            }
603378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        }
613378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn
623378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        public void update(long timeStamp) {
633378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            if (curStartTime == 0) {
643378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                // If we aren't already running, time to bump the count.
653378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                count++;
663378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            }
673378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            commitTime(timeStamp);
683378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            curStartTime = timeStamp;
693378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            lastEventTime = timeStamp;
703378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        }
713378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn
723378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        void addToEventStats(List<EventStats> out, int event, long beginTime, long endTime) {
733378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            if (count != 0 || duration != 0) {
743378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                EventStats ev = new EventStats();
753378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                ev.mEventType = event;
763378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                ev.mCount = count;
773378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                ev.mTotalTime = duration;
783378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                ev.mLastEventTime = lastEventTime;
793378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                ev.mBeginTimeStamp = beginTime;
803378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                ev.mEndTimeStamp = endTime;
813378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                out.add(ev);
823378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn            }
833378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        }
843378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn
853378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    }
863378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn
877f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    /**
887f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski     * Gets the UsageStats object for the given package, or creates one and adds it internally.
897f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski     */
903516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    UsageStats getOrCreateUsageStats(String packageName) {
9137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski        UsageStats usageStats = packageStats.get(packageName);
923516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        if (usageStats == null) {
933516800b611a79339a3c188332d13a26e9086b09Adam Lesinski            usageStats = new UsageStats();
947f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            usageStats.mPackageName = getCachedStringRef(packageName);
953516800b611a79339a3c188332d13a26e9086b09Adam Lesinski            usageStats.mBeginTimeStamp = beginTime;
963516800b611a79339a3c188332d13a26e9086b09Adam Lesinski            usageStats.mEndTimeStamp = endTime;
9737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski            packageStats.put(usageStats.mPackageName, usageStats);
983516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        }
993516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        return usageStats;
1003516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    }
1013516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
1027f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    /**
1037f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski     * Gets the ConfigurationStats object for the given configuration, or creates one and adds it
1047f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski     * internally.
1057f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski     */
1067f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    ConfigurationStats getOrCreateConfigurationStats(Configuration config) {
1077f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        ConfigurationStats configStats = configurations.get(config);
1087f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        if (configStats == null) {
1097f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            configStats = new ConfigurationStats();
1107f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            configStats.mBeginTimeStamp = beginTime;
1117f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            configStats.mEndTimeStamp = endTime;
1127f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            configStats.mConfiguration = config;
1137f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            configurations.put(config, configStats);
1147f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        }
1157f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        return configStats;
1167f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    }
1177f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski
1187f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    /**
1197f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski     * Builds a UsageEvents.Event, but does not add it internally.
1207f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski     */
1217f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    UsageEvents.Event buildEvent(String packageName, String className) {
1227f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        UsageEvents.Event event = new UsageEvents.Event();
1237f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        event.mPackage = getCachedStringRef(packageName);
1247f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        if (className != null) {
1257f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            event.mClass = getCachedStringRef(className);
1267f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        }
1277f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        return event;
1287f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    }
1297f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski
130978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski    private boolean isStatefulEvent(int eventType) {
131978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski        switch (eventType) {
132978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski            case UsageEvents.Event.MOVE_TO_FOREGROUND:
133978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski            case UsageEvents.Event.MOVE_TO_BACKGROUND:
134978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski            case UsageEvents.Event.END_OF_DAY:
135978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski            case UsageEvents.Event.CONTINUE_PREVIOUS_DAY:
136978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski                return true;
137978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski        }
138978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski        return false;
139978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski    }
140978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski
141bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani    /**
142bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani     * Returns whether the event type is one caused by user visible
143bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani     * interaction. Excludes those that are internally generated.
144bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani     * @param eventType
145bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani     * @return
146bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani     */
147bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani    private boolean isUserVisibleEvent(int eventType) {
148bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani        return eventType != UsageEvents.Event.SYSTEM_INTERACTION
149bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani                && eventType != UsageEvents.Event.STANDBY_BUCKET_CHANGED;
150bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani    }
151bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani
1523516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    void update(String packageName, long timeStamp, int eventType) {
1533516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        UsageStats usageStats = getOrCreateUsageStats(packageName);
1543516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
1553516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        // TODO(adamlesinski): Ensure that we recover from incorrect event sequences
1563516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        // like double MOVE_TO_BACKGROUND, etc.
1573516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        if (eventType == UsageEvents.Event.MOVE_TO_BACKGROUND ||
1583516800b611a79339a3c188332d13a26e9086b09Adam Lesinski                eventType == UsageEvents.Event.END_OF_DAY) {
1593516800b611a79339a3c188332d13a26e9086b09Adam Lesinski            if (usageStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND ||
1603516800b611a79339a3c188332d13a26e9086b09Adam Lesinski                    usageStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) {
1613516800b611a79339a3c188332d13a26e9086b09Adam Lesinski                usageStats.mTotalTimeInForeground += timeStamp - usageStats.mLastTimeUsed;
1623516800b611a79339a3c188332d13a26e9086b09Adam Lesinski            }
1633516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        }
164978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski
165978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski        if (isStatefulEvent(eventType)) {
166978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski            usageStats.mLastEvent = eventType;
167978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski        }
168978a1ed5aa2752cd36ff51df91d2d2d8be2171d9Adam Lesinski
169bfc4bf5febe3d97d3f51206c9ead2f7d2b05e700Amith Yamasani        if (isUserVisibleEvent(eventType)) {
170c8e8729244d75584ce71a74d29c452fe538a22c5Adam Lesinski            usageStats.mLastTimeUsed = timeStamp;
171c8e8729244d75584ce71a74d29c452fe538a22c5Adam Lesinski        }
1723516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        usageStats.mEndTimeStamp = timeStamp;
1737f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski
1747f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        if (eventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
1757f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            usageStats.mLaunchCount += 1;
1767f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        }
1777f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski
1787f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        endTime = timeStamp;
1797f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    }
1807f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski
18153b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li    void updateChooserCounts(String packageName, String category, String action) {
18253b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        UsageStats usageStats = getOrCreateUsageStats(packageName);
18353b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        if (usageStats.mChooserCounts == null) {
18453b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li            usageStats.mChooserCounts = new ArrayMap<>();
18553b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        }
18653b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        ArrayMap<String, Integer> chooserCounts;
18753b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        final int idx = usageStats.mChooserCounts.indexOfKey(action);
18853b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        if (idx < 0) {
18953b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li            chooserCounts = new ArrayMap<>();
19053b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li            usageStats.mChooserCounts.put(action, chooserCounts);
19153b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        } else {
19253b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li            chooserCounts = usageStats.mChooserCounts.valueAt(idx);
19353b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        }
19453b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        int currentCount = chooserCounts.getOrDefault(category, 0);
19553b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li        chooserCounts.put(category, currentCount + 1);
19653b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li    }
19753b4314ad9b43b1890cbd765b896ccb0f005fdebKang Li
1987f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski    void updateConfigurationStats(Configuration config, long timeStamp) {
1997f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        if (activeConfiguration != null) {
2007f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            ConfigurationStats activeStats = configurations.get(activeConfiguration);
2017f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            activeStats.mTotalTimeActive += timeStamp - activeStats.mLastTimeActive;
2027f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            activeStats.mLastTimeActive = timeStamp - 1;
2037f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        }
2047f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski
2057f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        if (config != null) {
2067f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            ConfigurationStats configStats = getOrCreateConfigurationStats(config);
2077f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            configStats.mLastTimeActive = timeStamp;
2087f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            configStats.mActivationCount += 1;
2097f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski            activeConfiguration = configStats.mConfiguration;
2107f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski        }
2117f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski
2123516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        endTime = timeStamp;
2133516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    }
2143516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
215bc813eb26e3027856114a26312e36e4bad86bd86Amith Yamasani    void incrementAppLaunchCount(String packageName) {
216bc813eb26e3027856114a26312e36e4bad86bd86Amith Yamasani        UsageStats usageStats = getOrCreateUsageStats(packageName);
217bc813eb26e3027856114a26312e36e4bad86bd86Amith Yamasani        usageStats.mAppLaunchCount += 1;
218bc813eb26e3027856114a26312e36e4bad86bd86Amith Yamasani    }
219bc813eb26e3027856114a26312e36e4bad86bd86Amith Yamasani
220ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    void commitTime(long timeStamp) {
2213378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        interactiveTracker.commitTime(timeStamp);
2223378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        nonInteractiveTracker.commitTime(timeStamp);
2233378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        keyguardShownTracker.commitTime(timeStamp);
2243378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        keyguardHiddenTracker.commitTime(timeStamp);
225ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    }
226ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn
227ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    void updateScreenInteractive(long timeStamp) {
2283378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        interactiveTracker.update(timeStamp);
2293378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        nonInteractiveTracker.commitTime(timeStamp);
230ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    }
231ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn
232ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    void updateScreenNonInteractive(long timeStamp) {
2333378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        nonInteractiveTracker.update(timeStamp);
2343378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        interactiveTracker.commitTime(timeStamp);
235ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    }
236ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn
2373378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    void updateKeyguardShown(long timeStamp) {
2383378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        keyguardShownTracker.update(timeStamp);
2393378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        keyguardHiddenTracker.commitTime(timeStamp);
2403378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    }
2413378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn
2423378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn    void updateKeyguardHidden(long timeStamp) {
2433378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        keyguardHiddenTracker.update(timeStamp);
2443378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        keyguardShownTracker.commitTime(timeStamp);
245ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    }
246ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn
247ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    void addEventStatsTo(List<EventStats> out) {
2483378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        interactiveTracker.addToEventStats(out, UsageEvents.Event.SCREEN_INTERACTIVE,
2493378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                beginTime, endTime);
2503378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        nonInteractiveTracker.addToEventStats(out, UsageEvents.Event.SCREEN_NON_INTERACTIVE,
2513378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                beginTime, endTime);
2523378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        keyguardShownTracker.addToEventStats(out, UsageEvents.Event.KEYGUARD_SHOWN,
2533378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                beginTime, endTime);
2543378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn        keyguardHiddenTracker.addToEventStats(out, UsageEvents.Event.KEYGUARD_HIDDEN,
2553378aa9f88101d77bc52c1a00b257c752bd8c193Dianne Hackborn                beginTime, endTime);
256ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn    }
257ced54398cc0dfd2f782153560c2ffd0eb8743045Dianne Hackborn
2589d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski    private String getCachedStringRef(String str) {
2599d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski        final int index = mStringCache.indexOf(str);
2609d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski        if (index < 0) {
2619d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski            mStringCache.add(str);
2629d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski            return str;
2639d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski        }
2649d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski        return mStringCache.valueAt(index);
2659d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski    }
2663516800b611a79339a3c188332d13a26e9086b09Adam Lesinski}
267