summaryrefslogtreecommitdiff
path: root/src/com/android/phone/CallTime.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/phone/CallTime.java')
-rw-r--r--src/com/android/phone/CallTime.java231
1 files changed, 231 insertions, 0 deletions
diff --git a/src/com/android/phone/CallTime.java b/src/com/android/phone/CallTime.java
new file mode 100644
index 00000000..92c7972d
--- /dev/null
+++ b/src/com/android/phone/CallTime.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2006 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.phone;
+
+import android.content.Context;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.SystemClock;
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.Connection;
+import android.util.Log;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Helper class used to keep track of various "elapsed time" indications
+ * in the Phone app, and also to start and stop tracing / profiling.
+ */
+public class CallTime extends Handler {
+ private static final String LOG_TAG = "PHONE/CallTime";
+ private static final boolean DBG = false;
+ /* package */ static final boolean PROFILE = true;
+
+ private static final int PROFILE_STATE_NONE = 0;
+ private static final int PROFILE_STATE_READY = 1;
+ private static final int PROFILE_STATE_RUNNING = 2;
+
+ private static int sProfileState = PROFILE_STATE_NONE;
+
+ private Call mCall;
+ private long mLastReportedTime;
+ private boolean mTimerRunning;
+ private long mInterval;
+ private PeriodicTimerCallback mTimerCallback;
+ private OnTickListener mListener;
+
+ interface OnTickListener {
+ void onTickForCallTimeElapsed(long timeElapsed);
+ }
+
+ public CallTime(OnTickListener listener) {
+ mListener = listener;
+ mTimerCallback = new PeriodicTimerCallback();
+ }
+
+ /**
+ * Sets the call timer to "active call" mode, where the timer will
+ * periodically update the UI to show how long the specified call
+ * has been active.
+ *
+ * After calling this you should also call reset() and
+ * periodicUpdateTimer() to get the timer started.
+ */
+ /* package */ void setActiveCallMode(Call call) {
+ if (DBG) log("setActiveCallMode(" + call + ")...");
+ mCall = call;
+
+ // How frequently should we update the UI?
+ mInterval = 1000; // once per second
+ }
+
+ /* package */ void reset() {
+ if (DBG) log("reset()...");
+ mLastReportedTime = SystemClock.uptimeMillis() - mInterval;
+ }
+
+ /* package */ void periodicUpdateTimer() {
+ if (!mTimerRunning) {
+ mTimerRunning = true;
+
+ long now = SystemClock.uptimeMillis();
+ long nextReport = mLastReportedTime + mInterval;
+
+ while (now >= nextReport) {
+ nextReport += mInterval;
+ }
+
+ if (DBG) log("periodicUpdateTimer() @ " + nextReport);
+ postAtTime(mTimerCallback, nextReport);
+ mLastReportedTime = nextReport;
+
+ if (mCall != null) {
+ Call.State state = mCall.getState();
+
+ if (state == Call.State.ACTIVE) {
+ updateElapsedTime(mCall);
+ }
+ }
+
+ if (PROFILE && isTraceReady()) {
+ startTrace();
+ }
+ } else {
+ if (DBG) log("periodicUpdateTimer: timer already running, bail");
+ }
+ }
+
+ /* package */ void cancelTimer() {
+ if (DBG) log("cancelTimer()...");
+ removeCallbacks(mTimerCallback);
+ mTimerRunning = false;
+ }
+
+ private void updateElapsedTime(Call call) {
+ if (mListener != null) {
+ long duration = getCallDuration(call);
+ mListener.onTickForCallTimeElapsed(duration / 1000);
+ }
+ }
+
+ /**
+ * Returns a "call duration" value for the specified Call, in msec,
+ * suitable for display in the UI.
+ */
+ /* package */ static long getCallDuration(Call call) {
+ long duration = 0;
+ List connections = call.getConnections();
+ int count = connections.size();
+ Connection c;
+
+ if (count == 1) {
+ c = (Connection) connections.get(0);
+ //duration = (state == Call.State.ACTIVE
+ // ? c.getDurationMillis() : c.getHoldDurationMillis());
+ duration = c.getDurationMillis();
+ } else {
+ for (int i = 0; i < count; i++) {
+ c = (Connection) connections.get(i);
+ //long t = (state == Call.State.ACTIVE
+ // ? c.getDurationMillis() : c.getHoldDurationMillis());
+ long t = c.getDurationMillis();
+ if (t > duration) {
+ duration = t;
+ }
+ }
+ }
+
+ if (DBG) log("updateElapsedTime, count=" + count + ", duration=" + duration);
+ return duration;
+ }
+
+ private static void log(String msg) {
+ Log.d(LOG_TAG, "[CallTime] " + msg);
+ }
+
+ private class PeriodicTimerCallback implements Runnable {
+ PeriodicTimerCallback() {
+
+ }
+
+ public void run() {
+ if (PROFILE && isTraceRunning()) {
+ stopTrace();
+ }
+
+ mTimerRunning = false;
+ periodicUpdateTimer();
+ }
+ }
+
+ static void setTraceReady() {
+ if (sProfileState == PROFILE_STATE_NONE) {
+ sProfileState = PROFILE_STATE_READY;
+ log("trace ready...");
+ } else {
+ log("current trace state = " + sProfileState);
+ }
+ }
+
+ boolean isTraceReady() {
+ return sProfileState == PROFILE_STATE_READY;
+ }
+
+ boolean isTraceRunning() {
+ return sProfileState == PROFILE_STATE_RUNNING;
+ }
+
+ void startTrace() {
+ if (PROFILE & sProfileState == PROFILE_STATE_READY) {
+ // For now, we move away from temp directory in favor of
+ // the application's data directory to store the trace
+ // information (/data/data/com.android.phone).
+ File file = PhoneGlobals.getInstance().getDir ("phoneTrace", Context.MODE_PRIVATE);
+ if (file.exists() == false) {
+ file.mkdirs();
+ }
+ String baseName = file.getPath() + File.separator + "callstate";
+ String dataFile = baseName + ".data";
+ String keyFile = baseName + ".key";
+
+ file = new File(dataFile);
+ if (file.exists() == true) {
+ file.delete();
+ }
+
+ file = new File(keyFile);
+ if (file.exists() == true) {
+ file.delete();
+ }
+
+ sProfileState = PROFILE_STATE_RUNNING;
+ log("startTrace");
+ Debug.startMethodTracing(baseName, 8 * 1024 * 1024);
+ }
+ }
+
+ void stopTrace() {
+ if (PROFILE) {
+ if (sProfileState == PROFILE_STATE_RUNNING) {
+ sProfileState = PROFILE_STATE_NONE;
+ log("stopTrace");
+ Debug.stopMethodTracing();
+ }
+ }
+ }
+}