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.server.am; 18 19 import android.app.ActivityOptions; 20 import android.app.PendingIntent; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.os.Bundle; 24 import android.os.SystemClock; 25 import android.util.ArrayMap; 26 import android.util.MutableLong; 27 import android.util.TimeUtils; 28 29 import java.io.PrintWriter; 30 31 /** 32 * Tracks the time a user spent in an app. 33 */ 34 public class AppTimeTracker { 35 private final PendingIntent mReceiver; 36 37 private long mTotalTime; 38 private final ArrayMap<String, MutableLong> mPackageTimes = new ArrayMap<>(); 39 40 private long mStartedTime; 41 private String mStartedPackage; 42 private MutableLong mStartedPackageTime; 43 AppTimeTracker(PendingIntent receiver)44 public AppTimeTracker(PendingIntent receiver) { 45 mReceiver = receiver; 46 } 47 start(String packageName)48 public void start(String packageName) { 49 long now = SystemClock.elapsedRealtime(); 50 if (mStartedTime == 0) { 51 mStartedTime = now; 52 } 53 if (!packageName.equals(mStartedPackage)) { 54 if (mStartedPackageTime != null) { 55 long elapsedTime = now - mStartedTime; 56 mStartedPackageTime.value += elapsedTime; 57 mTotalTime += elapsedTime; 58 } 59 mStartedPackage = packageName; 60 mStartedPackageTime = mPackageTimes.get(packageName); 61 if (mStartedPackageTime == null) { 62 mStartedPackageTime = new MutableLong(0); 63 mPackageTimes.put(packageName, mStartedPackageTime); 64 } 65 } 66 } 67 stop()68 public void stop() { 69 if (mStartedTime != 0) { 70 long elapsedTime = SystemClock.elapsedRealtime() - mStartedTime; 71 mTotalTime += elapsedTime; 72 if (mStartedPackageTime != null) { 73 mStartedPackageTime.value += elapsedTime; 74 } 75 mStartedPackage = null; 76 mStartedPackageTime = null; 77 } 78 } 79 deliverResult(Context context)80 public void deliverResult(Context context) { 81 stop(); 82 Bundle extras = new Bundle(); 83 extras.putLong(ActivityOptions.EXTRA_USAGE_TIME_REPORT, mTotalTime); 84 Bundle pkgs = new Bundle(); 85 for (int i=mPackageTimes.size()-1; i>=0; i--) { 86 pkgs.putLong(mPackageTimes.keyAt(i), mPackageTimes.valueAt(i).value); 87 } 88 extras.putBundle(ActivityOptions.EXTRA_USAGE_TIME_REPORT_PACKAGES, pkgs); 89 Intent fillinIntent = new Intent(); 90 fillinIntent.putExtras(extras); 91 try { 92 mReceiver.send(context, 0, fillinIntent); 93 } catch (PendingIntent.CanceledException e) { 94 } 95 } 96 dumpWithHeader(PrintWriter pw, String prefix, boolean details)97 public void dumpWithHeader(PrintWriter pw, String prefix, boolean details) { 98 pw.print(prefix); pw.print("AppTimeTracker #"); 99 pw.print(Integer.toHexString(System.identityHashCode(this))); 100 pw.println(":"); 101 dump(pw, prefix + " ", details); 102 } 103 dump(PrintWriter pw, String prefix, boolean details)104 public void dump(PrintWriter pw, String prefix, boolean details) { 105 pw.print(prefix); pw.print("mReceiver="); pw.println(mReceiver); 106 pw.print(prefix); pw.print("mTotalTime="); 107 TimeUtils.formatDuration(mTotalTime, pw); 108 pw.println(); 109 for (int i = 0; i < mPackageTimes.size(); i++) { 110 pw.print(prefix); pw.print("mPackageTime:"); pw.print(mPackageTimes.keyAt(i)); 111 pw.print("="); 112 TimeUtils.formatDuration(mPackageTimes.valueAt(i).value, pw); 113 pw.println(); 114 } 115 if (details && mStartedTime != 0) { 116 pw.print(prefix); pw.print("mStartedTime="); 117 TimeUtils.formatDuration(SystemClock.elapsedRealtime(), mStartedTime, pw); 118 pw.println(); 119 pw.print(prefix); pw.print("mStartedPackage="); pw.println(mStartedPackage); 120 } 121 } 122 } 123