Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a97f582 authored by Hyunyoung Song's avatar Hyunyoung Song Committed by Android (Google) Code Review
Browse files

Merge "ItemInfo supports lite proto builder (1/n)" into ub-launcher3-master

parents 1c45e888 7ac0ef1c
Loading
Loading
Loading
Loading
+108 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.
 */
syntax = "proto2";

option java_package = "com.android.launcher3.logger";
option java_outer_classname = "LauncherAtom";

//
// ItemInfos
message ItemInfo {
  oneof Item {
    Application application = 1;
    Task task= 2;
    Shortcut shortcut = 3;
    Widget widget = 4;
  }
  // When used for launch event, stores the global predictive rank
  optional int32 rank = 5;

  // Stores whether the Item belows to non primary user
  optional bool is_work = 6;

  // Item can be child node to parent container or parent containers (nested)
  oneof Container {
    WorkspaceContainer workspace = 7;
    HotseatContainer hotseat = 8;
    FolderContainer folder = 9;
  }
  // Stores the origin of the Item
  optional Origin source = 10;
}

enum Origin {
  UNKNOWN = 0;
  DEFAULT_LAYOUT = 1;       // icon automatically placed in workspace, folder, hotseat
  BACKUP_RESTORE = 2;       // icon layout restored from backup
  PINITEM = 3;              // from another app (e.g., Chrome's "Add to Home screen")
  ALLAPPS_ATOZ = 4;         // within launcher surface, all aps a-z
  WIDGETS = 5;              // within launcher, widgets tray
  ADD_TO_HOMESCREEN = 6;    // play install + launcher home setting
  ALLAPPS_PREDICTION = 7;   // from prediction bar in all apps container
  HOTSEAT_PREDICTION = 8;   // from prediction bar in hotseat container
}

// Main app icons
message Application {
  optional string package_name = 1;
  optional string component_name = 2;
}

// Legacy shortcuts and shortcuts handled by ShortcutManager
message Shortcut {
  optional string shortcut_name = 1;
}

// AppWidgets handled by AppWidgetManager
message Widget {
  optional int32 span_x = 1;
  optional int32 span_y = 2;
  optional int32 app_widget_id = 3;
  optional string package_name = 4; // only populated during snapshot if from workspace
  optional string component_name = 5; // only populated during snapshot if from workspace
}

// Tasks handled by PackageManager
message Task {
  optional string package_name = 1;
  optional string component_name = 2;
  optional int32 index = 3;
}

//////////////////////////////////////////////
// Containers

message WorkspaceContainer {
  optional int32 page_index = 1; // range [-1, l], 0 is the index of the main homescreen
  optional int32 grid_x = 2;     // [0, m], m varies based on the display density and resolution
  optional int32 grid_y = 3;     // [0, n], n varies based on the display density and resolution
}

message HotseatContainer {
  optional int32 index = 1;
}

message FolderContainer {
  optional int32 page_index = 1;
  optional int32 grid_x = 2;
  optional int32 grid_y = 3;
  oneof Container {
    WorkspaceContainer workspace = 4;
    HotseatContainer hotseat = 5;
  }
}

+11 −7
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_DISMISS_SWIPE_UP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_SWIPE_DOWN;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
@@ -1183,13 +1185,13 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
                verticalFactor * secondaryTaskDimension).setDuration(duration), LINEAR, sp);
    }

    private void removeTask(Task task, int index, EndState endState) {
        if (task != null) {
            ActivityManagerWrapper.getInstance().removeTask(task.key.id);
            ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
    private void removeTask(TaskView taskView, int index, EndState endState) {
        if (taskView.getTask() != null) {
            ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id);
            ComponentKey compKey = TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key);
            mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
                    endState.logAction, Direction.UP, index, componentKey);
            mActivity.getStatsLogManager().logTaskDismiss(this, componentKey);
                    endState.logAction, Direction.UP, index, compKey);
            mActivity.getStatsLogManager().log(TASK_DISMISS_SWIPE_UP, taskView.buildProto());
        }
    }

@@ -1284,7 +1286,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
            private void onEnd(EndState endState) {
                if (endState.isSuccess) {
                    if (shouldRemoveTask) {
                        removeTask(taskView.getTask(), draggedIndex, endState);
                        removeTask(taskView, draggedIndex, endState);
                    }

                    int pageToSnapTo = mCurrentPage;
@@ -1733,6 +1735,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
                    mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
                            endState.logAction, Direction.DOWN, indexOfChild(tv),
                            TaskUtils.getLaunchComponentKeyForTask(task.key));
                    mActivity.getStatsLogManager().log(TASK_LAUNCH_SWIPE_DOWN, tv.buildProto()
                    );
                }
            } else {
                onTaskLaunched(false);
+16 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_TAP;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -43,6 +44,7 @@ import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Process;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
@@ -59,6 +61,7 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.states.RotationHelper;
@@ -68,6 +71,7 @@ import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.ViewPool.Reusable;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.TaskIconCache;
@@ -217,8 +221,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
            mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
                    Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
                    TaskUtils.getLaunchComponentKeyForTask(getTask().key));
            mActivity.getStatsLogManager().logTaskLaunch(getRecentsView(),
                    TaskUtils.getLaunchComponentKeyForTask(getTask().key));
            mActivity.getStatsLogManager().log(TASK_LAUNCH_TAP, buildProto());
        });
        mCornerRadius = TaskCornerRadius.get(context);
        mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context.getResources());
@@ -229,6 +232,17 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
        setOutlineProvider(mOutlineProvider);
    }

    /* Builds proto for logging */
    protected LauncherAtom.ItemInfo buildProto() {
        ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(getTask().key);
        LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
        itemBuilder.setIsWork(componentKey.user != Process.myUserHandle());
        itemBuilder.setTask(LauncherAtom.Task.newBuilder()
                .setComponentName(componentKey.componentName.flattenToShortString())
                .setIndex(getRecentsView().indexOfChild(this)));
        return itemBuilder.build();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
+45 −196
Original line number Diff line number Diff line
@@ -18,36 +18,22 @@ package com.android.quickstep.logging;

import static android.stats.launcher.nano.Launcher.ALLAPPS;
import static android.stats.launcher.nano.Launcher.BACKGROUND;
import static android.stats.launcher.nano.Launcher.DISMISS_TASK;
import static android.stats.launcher.nano.Launcher.HOME;
import static android.stats.launcher.nano.Launcher.LAUNCH_APP;
import static android.stats.launcher.nano.Launcher.LAUNCH_TASK;
import static android.stats.launcher.nano.Launcher.OVERVIEW;

import static com.android.launcher3.logging.UserEventDispatcher.makeTargetsList;

import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.stats.launcher.nano.Launcher;
import android.stats.launcher.nano.LauncherExtension;
import android.stats.launcher.nano.LauncherTarget;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

import com.android.launcher3.FolderInfo;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogUtils;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
import com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ComponentKey;
import com.android.systemui.shared.system.SysUiStatsLog;

import com.google.protobuf.nano.MessageNano;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.util.IntSparseArrayMap;

import java.util.ArrayList;

@@ -62,196 +48,59 @@ import java.util.ArrayList;
public class StatsLogCompatManager extends StatsLogManager {

    private static final int SUPPORTED_TARGET_DEPTH = 2;
    private static final String TAG = "StatsLogCompatManager";
    private static final String TAG = "StatsLog";
    private static final boolean DEBUG = false;
    private static Context sContext;

    public StatsLogCompatManager(Context context) {
        sContext = context;
    }

    @Override
    public void logAppLaunch(View v, Intent intent, @Nullable UserHandle userHandle) {
        LauncherExtension ext = new LauncherExtension();
        ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH];
        int srcState = mStateProvider.getCurrentState();
        fillInLauncherExtension(v, ext);
        if (ext.srcTarget[0] != null) {
            ext.srcTarget[0].item = LauncherTarget.APP_ICON;
        }
        SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_EVENT, LAUNCH_APP, srcState,
                BACKGROUND /* dstState */, MessageNano.toByteArray(ext), true);
    }

    @Override
    public void logTaskLaunch(View v, ComponentKey componentKey) {
        LauncherExtension ext = new LauncherExtension();
        ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH];
        int srcState = OVERVIEW;
        fillInLauncherExtension(v, ext);
        SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_EVENT, LAUNCH_TASK, srcState,
                BACKGROUND /* dstState */, MessageNano.toByteArray(ext), true);
    }

    @Override
    public void logTaskDismiss(View v, ComponentKey componentKey) {
        LauncherExtension ext = new LauncherExtension();
        ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH];
        int srcState = OVERVIEW;
        fillInLauncherExtension(v, ext);
        SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_EVENT, DISMISS_TASK, srcState,
                BACKGROUND /* dstState */, MessageNano.toByteArray(ext), true);
    public void log(LauncherEvent eventId, LauncherAtom.ItemInfo item) {
        // Call StatsLog method
    }

    @Override
    public void logSwipeOnContainer(boolean isSwipingToLeft, int pageId) {
        LauncherExtension ext = new LauncherExtension();
        ext.srcTarget = new LauncherTarget[1];
        int srcState = mStateProvider.getCurrentState();
        fillInLauncherExtensionWithPageId(ext, pageId);
        int launcherAction = isSwipingToLeft ? Launcher.SWIPE_LEFT : Launcher.SWIPE_RIGHT;
        SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_EVENT, launcherAction, srcState, srcState,
                MessageNano.toByteArray(ext), true);
    }

    public static boolean fillInLauncherExtension(View v, LauncherExtension extension) {
        if (DEBUG) {
            Log.d(TAG, "fillInLauncherExtension");
        }

        StatsLogUtils.LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(v);
        if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
            if (DEBUG) {
                Log.d(TAG, "View or provider is null, or view doesn't have an ItemInfo tag.");
            }

            return false;
        }
        Target child = new Target();
        ArrayList<Target> targets = makeTargetsList(child);
        targets.add(child);
        provider.fillInLogContainerData((ItemInfo) v.getTag(), child, targets);

        int maxDepth = Math.min(SUPPORTED_TARGET_DEPTH, targets.size());
        extension.srcTarget = new LauncherTarget[maxDepth];
        for (int i = 0; i < maxDepth; i++) {
            extension.srcTarget[i] = new LauncherTarget();
            copy(targets.get(i), extension.srcTarget[i]);
        }
        return true;
    }

    public static boolean fillInLauncherExtensionWithPageId(LauncherExtension ext, int pageId) {
        if (DEBUG) {
            Log.d(TAG, "fillInLauncherExtensionWithPageId, pageId = " + pageId);
    public void verify() {
        if (!(StatsLogUtils.LAUNCHER_STATE_ALLAPPS == ALLAPPS
                && StatsLogUtils.LAUNCHER_STATE_BACKGROUND == BACKGROUND
                && StatsLogUtils.LAUNCHER_STATE_OVERVIEW == OVERVIEW
                && StatsLogUtils.LAUNCHER_STATE_HOME == HOME)) {
            throw new IllegalStateException(
                    "StatsLogUtil constants doesn't match enums in launcher.proto");
        }

        Target target = new Target();
        target.pageIndex = pageId;
        ext.srcTarget[0] = new LauncherTarget();
        copy(target, ext.srcTarget[0]);
        return true;
    }

    private static void copy(Target src, LauncherTarget dst) {
        if (DEBUG) {
            Log.d(TAG, "copy target information from clearcut Target to LauncherTarget.");
    /**
     * Logs the workspace layout information on the model thread.
     */
    public void logSnapshot() {
        LauncherAppState.getInstance(sContext).getModel().enqueueModelUpdateTask(
                new SnapshotWorker());
    }

        // Fill in type
        switch (src.type) {
            case Target.Type.ITEM:
                dst.type = LauncherTarget.ITEM_TYPE;
                break;
            case Target.Type.CONTROL:
                dst.type = LauncherTarget.CONTROL_TYPE;
                break;
            case Target.Type.CONTAINER:
                dst.type = LauncherTarget.CONTAINER_TYPE;
                break;
            default:
                dst.type = LauncherTarget.NONE;
                break;
        }
    private class SnapshotWorker extends BaseModelUpdateTask {
        @Override
        public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
            IntSparseArrayMap<FolderInfo> folders = dataModel.folders.clone();
            ArrayList<ItemInfo> workspaceItems = (ArrayList) dataModel.workspaceItems.clone();
            ArrayList<LauncherAppWidgetInfo> appWidgets = (ArrayList) dataModel.appWidgets.clone();

        // Fill in item
        switch (src.itemType) {
            case ItemType.APP_ICON:
                dst.item = LauncherTarget.APP_ICON;
                break;
            case ItemType.SHORTCUT:
                dst.item = LauncherTarget.SHORTCUT;
                break;
            case ItemType.WIDGET:
                dst.item = LauncherTarget.WIDGET;
                break;
            case ItemType.FOLDER_ICON:
                dst.item = LauncherTarget.FOLDER_ICON;
                break;
            case ItemType.DEEPSHORTCUT:
                dst.item = LauncherTarget.DEEPSHORTCUT;
                break;
            case ItemType.SEARCHBOX:
                dst.item = LauncherTarget.SEARCHBOX;
                break;
            case ItemType.EDITTEXT:
                dst.item = LauncherTarget.EDITTEXT;
                break;
            case ItemType.NOTIFICATION:
                dst.item = LauncherTarget.NOTIFICATION;
                break;
            case ItemType.TASK:
                dst.item = LauncherTarget.TASK;
                break;
            default:
                dst.item = LauncherTarget.DEFAULT_ITEM;
                break;
            for (ItemInfo info : workspaceItems) {
                LauncherAtom.ItemInfo atomInfo = info.buildProto(null, null);
                // call StatsLog method
            }

        // Fill in container
        switch (src.containerType) {
            case ContainerType.HOTSEAT:
                dst.container = LauncherTarget.HOTSEAT;
                break;
            case ContainerType.FOLDER:
                dst.container = LauncherTarget.FOLDER;
                break;
            case ContainerType.PREDICTION:
                dst.container = LauncherTarget.PREDICTION;
                break;
            case ContainerType.SEARCHRESULT:
                dst.container = LauncherTarget.SEARCHRESULT;
                break;
            default:
                dst.container = LauncherTarget.DEFAULT_CONTAINER;
                break;
            for (FolderInfo fInfo : folders) {
                for (ItemInfo info : fInfo.contents) {
                    LauncherAtom.ItemInfo atomInfo = info.buildProto(null, fInfo);
                    // call StatsLog method
                }

        // Fill in control
        switch (src.controlType) {
            case ControlType.UNINSTALL_TARGET:
                dst.control = LauncherTarget.UNINSTALL;
                break;
            case ControlType.REMOVE_TARGET:
                dst.control = LauncherTarget.REMOVE;
                break;
            default:
                dst.control = LauncherTarget.DEFAULT_CONTROL;
                break;
            }

        // Fill in other fields
        dst.pageId = src.pageIndex;
        dst.gridX = src.gridX;
        dst.gridY = src.gridY;
            for (ItemInfo info : appWidgets) {
                LauncherAtom.ItemInfo atomInfo = info.buildProto(null, null);
                // call StatsLog method
            }

    @Override
    public void verify() {
        if (!(StatsLogUtils.LAUNCHER_STATE_ALLAPPS == ALLAPPS
                && StatsLogUtils.LAUNCHER_STATE_BACKGROUND == BACKGROUND
                && StatsLogUtils.LAUNCHER_STATE_OVERVIEW == OVERVIEW
                && StatsLogUtils.LAUNCHER_STATE_HOME == HOME)) {
            throw new IllegalStateException(
                    "StatsLogUtil constants doesn't match enums in launcher.proto");
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.launcher3;

import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.APP_LAUNCH_TAP;
import static com.android.launcher3.util.DefaultDisplay.CHANGE_ROTATION;

import android.app.ActivityOptions;
@@ -181,7 +182,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
                        sourceContainer);
            }
            getUserEventDispatcher().logAppLaunch(v, intent, user);
            getStatsLogManager().logAppLaunch(v, intent, user);
            getStatsLogManager().log(APP_LAUNCH_TAP, item.buildProto(null, null));
            return true;
        } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Loading