/* * Copyright (C) 2012 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.launcher3; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; import java.io.*; import java.util.ArrayList; public class Stats { private static final boolean DEBUG_BROADCASTS = false; private static final String TAG = "Launcher3/Stats"; private static final boolean LOCAL_LAUNCH_LOG = true; public static final String ACTION_LAUNCH = "com.android.launcher3.action.LAUNCH"; public static final String PERM_LAUNCH = "com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS"; public static final String EXTRA_INTENT = "intent"; public static final String EXTRA_CONTAINER = "container"; public static final String EXTRA_SCREEN = "screen"; public static final String EXTRA_CELLX = "cellX"; public static final String EXTRA_CELLY = "cellY"; private static final String LOG_FILE_NAME = "launches.log"; private static final int LOG_VERSION = 1; private static final int LOG_TAG_VERSION = 0x1; private static final int LOG_TAG_LAUNCH = 0x1000; private static final String STATS_FILE_NAME = "stats.log"; private static final int STATS_VERSION = 1; private static final int INITIAL_STATS_SIZE = 100; // TODO: delayed/batched writes private static final boolean FLUSH_IMMEDIATELY = true; private final Launcher mLauncher; DataOutputStream mLog; ArrayList mIntents; ArrayList mHistogram; public Stats(Launcher launcher) { mLauncher = launcher; loadStats(); if (LOCAL_LAUNCH_LOG) { try { mLog = new DataOutputStream(mLauncher.openFileOutput(LOG_FILE_NAME, Context.MODE_APPEND)); mLog.writeInt(LOG_TAG_VERSION); mLog.writeInt(LOG_VERSION); } catch (FileNotFoundException e) { Log.e(TAG, "unable to create stats log: " + e); mLog = null; } catch (IOException e) { Log.e(TAG, "unable to write to stats log: " + e); mLog = null; } } if (DEBUG_BROADCASTS) { launcher.registerReceiver( new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { android.util.Log.v("Stats", "got broadcast: " + intent + " for launched intent: " + intent.getStringExtra(EXTRA_INTENT)); } }, new IntentFilter(ACTION_LAUNCH), PERM_LAUNCH, null ); } } public void incrementLaunch(String intentStr) { int pos = mIntents.indexOf(intentStr); if (pos < 0) { mIntents.add(intentStr); mHistogram.add(1); } else { mHistogram.set(pos, mHistogram.get(pos) + 1); } } public void recordLaunch(Intent intent) { recordLaunch(intent, null); } public void recordLaunch(Intent intent, ShortcutInfo shortcut) { intent = new Intent(intent); intent.setSourceBounds(null); final String flat = intent.toUri(0); Intent broadcastIntent = new Intent(ACTION_LAUNCH).putExtra(EXTRA_INTENT, flat); if (shortcut != null) { broadcastIntent.putExtra(EXTRA_CONTAINER, shortcut.container) .putExtra(EXTRA_SCREEN, shortcut.screenId) .putExtra(EXTRA_CELLX, shortcut.cellX) .putExtra(EXTRA_CELLY, shortcut.cellY); } mLauncher.sendBroadcast(broadcastIntent, PERM_LAUNCH); incrementLaunch(flat); if (FLUSH_IMMEDIATELY) { saveStats(); } if (LOCAL_LAUNCH_LOG && mLog != null) { try { mLog.writeInt(LOG_TAG_LAUNCH); mLog.writeLong(System.currentTimeMillis()); if (shortcut == null) { mLog.writeShort(0); mLog.writeShort(0); mLog.writeShort(0); mLog.writeShort(0); } else { mLog.writeShort((short) shortcut.container); mLog.writeShort((short) shortcut.screenId); mLog.writeShort((short) shortcut.cellX); mLog.writeShort((short) shortcut.cellY); } mLog.writeUTF(flat); if (FLUSH_IMMEDIATELY) { mLog.flush(); // TODO: delayed writes } } catch (IOException e) { e.printStackTrace(); } } } private void saveStats() { DataOutputStream stats = null; try { stats = new DataOutputStream(mLauncher.openFileOutput(STATS_FILE_NAME + ".tmp", Context.MODE_PRIVATE)); stats.writeInt(STATS_VERSION); final int N = mHistogram.size(); stats.writeInt(N); for (int i=0; i(INITIAL_STATS_SIZE); mHistogram = new ArrayList(INITIAL_STATS_SIZE); DataInputStream stats = null; try { stats = new DataInputStream(mLauncher.openFileInput(STATS_FILE_NAME)); final int version = stats.readInt(); if (version == STATS_VERSION) { final int N = stats.readInt(); for (int i=0; i