/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.am; import android.app.ActivityOptions; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.SystemClock; import android.util.ArrayMap; import android.util.MutableLong; import android.util.TimeUtils; import java.io.PrintWriter; /** * Tracks the time a user spent in an app. */ public class AppTimeTracker { private final PendingIntent mReceiver; private long mTotalTime; private final ArrayMap mPackageTimes = new ArrayMap<>(); private long mStartedTime; private String mStartedPackage; private MutableLong mStartedPackageTime; public AppTimeTracker(PendingIntent receiver) { mReceiver = receiver; } public void start(String packageName) { long now = SystemClock.elapsedRealtime(); if (mStartedTime == 0) { mStartedTime = now; } if (!packageName.equals(mStartedPackage)) { if (mStartedPackageTime != null) { long elapsedTime = now - mStartedTime; mStartedPackageTime.value += elapsedTime; mTotalTime += elapsedTime; } mStartedPackage = packageName; mStartedPackageTime = mPackageTimes.get(packageName); if (mStartedPackageTime == null) { mStartedPackageTime = new MutableLong(0); mPackageTimes.put(packageName, mStartedPackageTime); } } } public void stop() { if (mStartedTime != 0) { long elapsedTime = SystemClock.elapsedRealtime() - mStartedTime; mTotalTime += elapsedTime; if (mStartedPackageTime != null) { mStartedPackageTime.value += elapsedTime; } mStartedPackage = null; mStartedPackageTime = null; } } public void deliverResult(Context context) { stop(); Bundle extras = new Bundle(); extras.putLong(ActivityOptions.EXTRA_USAGE_TIME_REPORT, mTotalTime); Bundle pkgs = new Bundle(); for (int i=mPackageTimes.size()-1; i>=0; i--) { pkgs.putLong(mPackageTimes.keyAt(i), mPackageTimes.valueAt(i).value); } extras.putBundle(ActivityOptions.EXTRA_USAGE_TIME_REPORT_PACKAGES, pkgs); Intent fillinIntent = new Intent(); fillinIntent.putExtras(extras); try { mReceiver.send(context, 0, fillinIntent); } catch (PendingIntent.CanceledException e) { } } public void dumpWithHeader(PrintWriter pw, String prefix, boolean details) { pw.print(prefix); pw.print("AppTimeTracker #"); pw.print(Integer.toHexString(System.identityHashCode(this))); pw.println(":"); dump(pw, prefix + " ", details); } public void dump(PrintWriter pw, String prefix, boolean details) { pw.print(prefix); pw.print("mReceiver="); pw.println(mReceiver); pw.print(prefix); pw.print("mTotalTime="); TimeUtils.formatDuration(mTotalTime, pw); pw.println(); for (int i = 0; i < mPackageTimes.size(); i++) { pw.print(prefix); pw.print("mPackageTime:"); pw.print(mPackageTimes.keyAt(i)); pw.print("="); TimeUtils.formatDuration(mPackageTimes.valueAt(i).value, pw); pw.println(); } if (details && mStartedTime != 0) { pw.print(prefix); pw.print("mStartedTime="); TimeUtils.formatDuration(SystemClock.elapsedRealtime(), mStartedTime, pw); pw.println(); pw.print(prefix); pw.print("mStartedPackage="); pw.println(mStartedPackage); } } }