/* * Copyright (c) 2015. The CyanogenMod 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.stats; import android.content.Context; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.text.TextUtils; import android.util.Log; import com.android.launcher3.stats.internal.db.DatabaseHelper; import com.android.launcher3.stats.internal.model.TrackingEvent; /** *
 *     Utility class made specifically for Launcher related events
 * 
*/ public class LauncherStats { // Constants private static final String TAG = LauncherStats.class.getSimpleName(); private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final int MSG_STORE_EVENT = 1000; public static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; public static final String ORIGIN_HOMESCREEN = "homescreen"; public static final String ORIGIN_APPDRAWER = "appdrawer"; public static final String ORIGIN_TREB_LONGPRESS = "trebuchet_longpress"; public static final String ORIGIN_CHOOSER = "theme_chooser"; public static final String ORIGIN_SETTINGS = "settings"; public static final String ORIGIN_DRAG_DROP = "drag_drop"; public static final String ORIGIN_FOLDER = "folder"; private static void log(String msg) throws IllegalArgumentException { if (TextUtils.isEmpty(msg)) { throw new IllegalArgumentException("'msg' cannot be null or empty!"); } if (DEBUG) { Log.d(TAG, msg); } } private static void loge(String msg) throws IllegalArgumentException { if (TextUtils.isEmpty(msg)) { throw new IllegalArgumentException("'msg' cannot be null or empty!"); } Log.e(TAG, msg); } /** *
     *     This is a thread responsible for writing events to a database
     * 
* * @see {@link HandlerThread} */ private static class WriteHandlerThread extends HandlerThread { public WriteHandlerThread() { super(WriteHandlerThread.class.getSimpleName()); } } /** *
     *     Handler for issuing db writes
     * 
* * @see {@link Handler} */ private static class WriteHandler extends Handler { public WriteHandler() { super(sHandlerThread.getLooper()); } @Override public void handleMessage(Message msg) { log("Handling message: " + msg.what); switch (msg.what) { case MSG_STORE_EVENT: handleStoreEvent((TrackingEvent) msg.obj); break; default: super.handleMessage(msg); } } } // Instance private static LauncherStats sInstance = null; // Members private static WriteHandlerThread sHandlerThread; private static WriteHandler sWriteHandler; private static DatabaseHelper sDatabaseHelper; /** * Send a message to the handler to store event data * * @param trackingEvent {@link TrackingEvent} */ protected void sendStoreEventMessage(TrackingEvent trackingEvent) { log("Sending tracking event to handler: " + trackingEvent); Message msg = new Message(); msg.what = MSG_STORE_EVENT; msg.obj = trackingEvent; sWriteHandler.sendMessage(msg); } /** * Handle the storing work * * @param trackingEvent {@link TrackingEvent} */ private static void handleStoreEvent(TrackingEvent trackingEvent) { log("Handling store event: " + trackingEvent); if (trackingEvent != null) { sDatabaseHelper.writeEvent(trackingEvent); } else { loge("Tracking event was null!"); } } /** * Used only for overlay extensions */ protected LauncherStats() { } /** * Constructor * * @param context {@link Context} not null! * @throws IllegalArgumentException {@link IllegalArgumentException} */ private LauncherStats(Context context) throws IllegalArgumentException { if (context == null) { throw new IllegalArgumentException("'context' cannot be null!"); } sDatabaseHelper = new DatabaseHelper(context); sHandlerThread = new WriteHandlerThread(); sHandlerThread.start(); sWriteHandler = new WriteHandler(); } /** * Gets a singleton instance of the stats utility * * @param context {@link Context} not null! * @return {@link LauncherStats} * @throws IllegalArgumentException {@link IllegalArgumentException} */ public static LauncherStats getInstance(Context context) throws IllegalArgumentException { if (sInstance == null) { sInstance = new LauncherStats(context); } return sInstance; } /** * Interface for posting a new widget add event * * @param pkg {@link String} package name of widget * @throws IllegalArgumentException {@link IllegalArgumentException} */ public void sendWidgetAddEvent(String pkg) throws IllegalArgumentException { if (TextUtils.isEmpty(pkg)) { throw new IllegalArgumentException("'pkg' cannot be null!"); } TrackingEvent trackingEvent = new TrackingEvent(TrackingEvent.Category.WIDGET_ADD); trackingEvent.setMetaData(TrackingEvent.KEY_PACKAGE, pkg); sendStoreEventMessage(trackingEvent); } /** * Interface for posting a new widget removal event * * @param pkg {@link String} package name of widget * @throws IllegalArgumentException {@link IllegalArgumentException} */ public void sendWidgetRemoveEvent(String pkg) throws IllegalArgumentException { if (TextUtils.isEmpty(pkg)) { throw new IllegalArgumentException("'pkg' cannot be null!"); } TrackingEvent trackingEvent = new TrackingEvent(TrackingEvent.Category.WIDGET_REMOVE); trackingEvent.setMetaData(TrackingEvent.KEY_PACKAGE, pkg); sendStoreEventMessage(trackingEvent); } /** * Interface for posting an app launch event * * @param origin {@link String} origin of application launch * @param pkg {@link String} package of app launched * @throws IllegalArgumentException {@link IllegalArgumentException} */ public void sendAppLaunchEvent(String origin, String pkg) throws IllegalArgumentException { if (TextUtils.isEmpty(origin)) { throw new IllegalArgumentException("'origin' cannot be null!"); } if (TextUtils.isEmpty(pkg)) { throw new IllegalArgumentException("'pkg' cannot be null!"); } TrackingEvent trackingEvent = new TrackingEvent(TrackingEvent.Category.APP_LAUNCH); trackingEvent.setMetaData(TrackingEvent.KEY_ORIGIN, origin); trackingEvent.setMetaData(TrackingEvent.KEY_PACKAGE, pkg); sendStoreEventMessage(trackingEvent); } /** * Interface for sending a "settings opened" event * * @param origin {@link String} origin of the event */ public void sendSettingsOpenedEvent(String origin) { TrackingEvent trackingEvent = new TrackingEvent(TrackingEvent.Category.SETTINGS_OPEN); trackingEvent.setMetaData(TrackingEvent.KEY_ORIGIN, origin); sendStoreEventMessage(trackingEvent); } /** * Interface for sending a "wallpaper changed" event * * @param origin {@link String} origin of the event */ public void sendWallpaperChangedEvent(String origin) { TrackingEvent trackingEvent = new TrackingEvent(TrackingEvent.Category.WALLPAPER_CHANGE); trackingEvent.setMetaData(TrackingEvent.KEY_ORIGIN, origin); sendStoreEventMessage(trackingEvent); } }