Home | History | Annotate | Download | only in am
      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 
     44     public AppTimeTracker(PendingIntent receiver) {
     45         mReceiver = receiver;
     46     }
     47 
     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 
     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 
     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 
     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 
    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