/* * Copyright (C) 2011 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.providers.contacts; import com.google.android.collect.Lists; import android.database.Cursor; import android.net.Uri; import android.util.Log; import java.util.List; /** * Cursor wrapper that handles tracking time taken before query result came back and how long * the cursor was open before it was closed. */ public class InstrumentedCursorWrapper extends CrossProcessCursorWrapper { /** * Static list of active cursors. */ private static List<InstrumentedCursorWrapper> mActiveCursors = Lists.newArrayList(); /** * Time (ms since epoch) when the cursor was created. */ private long mCreationTime; /** * Milliseconds after creation at which the query completed (triggered by a getCount or * any method that moves the cursor). */ private long mTimeToQuery; /** * The URI being queried in this cursor. */ private Uri mUri; /** * Log tag to use. */ private String mTag; public InstrumentedCursorWrapper(Cursor cursor, Uri uri, String tag) { super(cursor); mCreationTime = System.currentTimeMillis(); mUri = uri; mTag = tag; mActiveCursors.add(this); } @Override public int getCount() { int count = super.getCount(); logQueryTime(); return count; } @Override public boolean moveToFirst() { boolean result = super.moveToFirst(); logQueryTime(); return result; } @Override public boolean moveToLast() { boolean result = super.moveToLast(); logQueryTime(); return result; } @Override public boolean move(int offset) { boolean result = super.move(offset); logQueryTime(); return result; } @Override public boolean moveToPosition(int position) { boolean result = super.moveToPosition(position); logQueryTime(); return result; } @Override public boolean moveToNext() { boolean result = super.moveToNext(); logQueryTime(); return result; } @Override public boolean moveToPrevious() { boolean result = super.moveToPrevious(); logQueryTime(); return result; } @Override public void close() { super.close(); long timeToClose = System.currentTimeMillis() - mCreationTime; Log.v(mTag, timeToClose + "ms to close for URI " + mUri + " (" + (timeToClose - mTimeToQuery) + "ms since query complete)"); mActiveCursors.remove(this); Log.v(mTag, mActiveCursors.size() + " cursors still open"); } private void logQueryTime() { if (mTimeToQuery == 0) { mTimeToQuery = System.currentTimeMillis() - mCreationTime; Log.v(mTag, mTimeToQuery + "ms to query URI " + mUri); } } }