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

Commit 03b97318 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz Committed by Android (Google) Code Review
Browse files

Merge changes from topic "UsageStats2Proto"

* changes:
  Pool Package and Class names when writing UsageStats to disk
  Upgrade UsageStatsDatabase from XML to Protobuf
parents 222b7569 c90bc15d
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -28,9 +28,13 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
import android.util.proto.WireTypeMismatchException;
import android.view.DisplayInfo;

import java.io.IOException;

/**
 * Class that contains windowing configuration/state for other objects that contain windows directly
 * or indirectly. E.g. Activities, Task, Displays, ...
@@ -510,6 +514,38 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        protoOutputStream.end(token);
    }

    /**
     * Read from a protocol buffer input stream.
     * Protocol buffer message definition at {@link android.app.WindowConfigurationProto}
     *
     * @param proto   Stream to read the WindowConfiguration object from.
     * @param fieldId Field Id of the WindowConfiguration as defined in the parent message
     * @hide
     */
    public void readFromProto(ProtoInputStream proto, long fieldId)
            throws IOException, WireTypeMismatchException {
        final long token = proto.start(fieldId);
        try {
            while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                switch (proto.getFieldNumber()) {
                    case (int) APP_BOUNDS:
                        mAppBounds = new Rect();
                        mAppBounds.readFromProto(proto, APP_BOUNDS);
                        break;
                    case (int) WINDOWING_MODE:
                        mWindowingMode = proto.readInt(WINDOWING_MODE);
                        break;
                    case (int) ACTIVITY_TYPE:
                        mActivityType = proto.readInt(ACTIVITY_TYPE);
                        break;
                }
            }
        } finally {
            // Let caller handle any exceptions
            proto.end(token);
        }
    }

    /**
     * Returns true if the activities associated with this window configuration display a shadow
     * around their border.
+12 −0
Original line number Diff line number Diff line
@@ -165,6 +165,12 @@ public final class UsageEvents implements Parcelable {
         */
        public static final int KEYGUARD_HIDDEN = 18;

        /**
         * Keep in sync with the greatest event type value.
         * @hide
         */
        public static final int MAX_EVENT_TYPE = 18;

        /** @hide */
        public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;

@@ -175,6 +181,12 @@ public final class UsageEvents implements Parcelable {
        @Retention(RetentionPolicy.SOURCE)
        public @interface EventFlags {}

        /**
         * Bitwise OR all valid flag constants to create this constant.
         * @hide
         */
        public static final int VALID_FLAG_BITS = FLAG_IS_PACKAGE_INSTANT_APP;

        /**
         * {@hide}
         */
+132 −2
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.WindowConfiguration;
import android.content.LocaleProto;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.Config;
import android.os.Build;
@@ -54,7 +55,9 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
import android.util.proto.WireTypeMismatchException;
import android.view.View;

import com.android.internal.util.XmlUtils;
@@ -67,6 +70,7 @@ import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
@@ -1086,12 +1090,14 @@ public final class Configuration implements Parcelable, Comparable<Configuration
    /**
     * Write to a protocol buffer output stream.
     * Protocol buffer message definition at {@link android.content.ConfigurationProto}
     * Has the option to ignore fields that don't need to be persisted to disk.
     *
     * @param protoOutputStream Stream to write the Configuration object to.
     * @param fieldId           Field Id of the Configuration as defined in the parent message
     * @param persisted         Note if this proto will be persisted to disk
     * @hide
     */
    public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
    public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean persisted) {
        final long token = protoOutputStream.start(fieldId);
        protoOutputStream.write(FONT_SCALE, fontScale);
        protoOutputStream.write(MCC, mcc);
@@ -1113,12 +1119,136 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        protoOutputStream.write(SCREEN_HEIGHT_DP, screenHeightDp);
        protoOutputStream.write(SMALLEST_SCREEN_WIDTH_DP, smallestScreenWidthDp);
        protoOutputStream.write(DENSITY_DPI, densityDpi);
        if (windowConfiguration != null) {
        // For persistence, we do not care about window configuration
        if (!persisted && windowConfiguration != null) {
            windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION);
        }
        protoOutputStream.end(token);
    }

    /**
     * Write to a protocol buffer output stream.
     * Protocol buffer message definition at {@link android.content.ConfigurationProto}
     *
     * @param protoOutputStream Stream to write the Configuration object to.
     * @param fieldId           Field Id of the Configuration as defined in the parent message
     * @hide
     */
    public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
        writeToProto(protoOutputStream, fieldId, false);
    }

    /**
     * Read from a protocol buffer output stream.
     * Protocol buffer message definition at {@link android.content.ConfigurationProto}
     *
     * @param protoInputStream Stream to read the Configuration object from.
     * @param fieldId          Field Id of the Configuration as defined in the parent message
     * @hide
     */
    public void readFromProto(ProtoInputStream protoInputStream, long fieldId) throws IOException {
        final long token = protoInputStream.start(fieldId);
        final List<Locale> list = new ArrayList();
        try {
            while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                switch (protoInputStream.getFieldNumber()) {
                    case (int) FONT_SCALE:
                        fontScale = protoInputStream.readFloat(FONT_SCALE);
                        break;
                    case (int) MCC:
                        mcc = protoInputStream.readInt(MCC);
                        break;
                    case (int) MNC:
                        mnc = protoInputStream.readInt(MNC);
                        break;
                    case (int) LOCALES:
                        // Parse the Locale here to handle all the repeated Locales
                        // The LocaleList will be created when the message is completed
                        final long localeToken = protoInputStream.start(LOCALES);
                        String language = "";
                        String country = "";
                        String variant = "";
                        try {
                            while (protoInputStream.nextField()
                                    != ProtoInputStream.NO_MORE_FIELDS) {
                                switch (protoInputStream.getFieldNumber()) {
                                    case (int) LocaleProto.LANGUAGE:
                                        language = protoInputStream.readString(
                                                LocaleProto.LANGUAGE);
                                        break;
                                    case (int) LocaleProto.COUNTRY:
                                        country = protoInputStream.readString(LocaleProto.COUNTRY);
                                        break;
                                    case (int) LocaleProto.VARIANT:
                                        variant = protoInputStream.readString(LocaleProto.VARIANT);
                                        break;
                                }
                            }
                        } catch (WireTypeMismatchException wtme) {
                            // rethrow for caller deal with
                            throw wtme;
                        } finally {
                            protoInputStream.end(localeToken);
                            list.add(new Locale(language, country, variant));
                        }
                        break;
                    case (int) SCREEN_LAYOUT:
                        screenLayout = protoInputStream.readInt(SCREEN_LAYOUT);
                        break;
                    case (int) COLOR_MODE:
                        colorMode = protoInputStream.readInt(COLOR_MODE);
                        break;
                    case (int) TOUCHSCREEN:
                        touchscreen = protoInputStream.readInt(TOUCHSCREEN);
                        break;
                    case (int) KEYBOARD:
                        keyboard = protoInputStream.readInt(KEYBOARD);
                        break;
                    case (int) KEYBOARD_HIDDEN:
                        keyboardHidden = protoInputStream.readInt(KEYBOARD_HIDDEN);
                        break;
                    case (int) HARD_KEYBOARD_HIDDEN:
                        hardKeyboardHidden = protoInputStream.readInt(HARD_KEYBOARD_HIDDEN);
                        break;
                    case (int) NAVIGATION:
                        navigation = protoInputStream.readInt(NAVIGATION);
                        break;
                    case (int) NAVIGATION_HIDDEN:
                        navigationHidden = protoInputStream.readInt(NAVIGATION_HIDDEN);
                        break;
                    case (int) ORIENTATION:
                        orientation = protoInputStream.readInt(ORIENTATION);
                        break;
                    case (int) UI_MODE:
                        uiMode = protoInputStream.readInt(UI_MODE);
                        break;
                    case (int) SCREEN_WIDTH_DP:
                        screenWidthDp = protoInputStream.readInt(SCREEN_WIDTH_DP);
                        break;
                    case (int) SCREEN_HEIGHT_DP:
                        screenHeightDp = protoInputStream.readInt(SCREEN_HEIGHT_DP);
                        break;
                    case (int) SMALLEST_SCREEN_WIDTH_DP:
                        smallestScreenWidthDp = protoInputStream.readInt(SMALLEST_SCREEN_WIDTH_DP);
                        break;
                    case (int) DENSITY_DPI:
                        densityDpi = protoInputStream.readInt(DENSITY_DPI);
                        break;
                    case (int) WINDOW_CONFIGURATION:
                        windowConfiguration.readFromProto(protoInputStream, WINDOW_CONFIGURATION);
                        break;
                }
            }
        } finally {
            // Let caller handle any exceptions
            if (list.size() > 0) {
                //Create the LocaleList from the collected Locales
                setLocales(new LocaleList(list.toArray(new Locale[list.size()])));
            }
            protoInputStream.end(token);
        }
    }

    /**
     * Write full {@link android.content.ResourcesConfigurationProto} to protocol buffer output
     * stream.
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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";
package com.android.server.usage;
import "frameworks/base/core/proto/android/content/configuration.proto";
import "frameworks/base/libs/incident/proto/android/privacy.proto";

option java_multiple_files = true;

message IntervalStatsProto {
  message StringPool {
    optional int32 size = 1;
    repeated string strings = 2;
  }

  message CountAndTime {
    optional int32 count = 1;
    optional int64 time_ms = 2;
  }

  // Stores the relevant information from a UsageStats
  message UsageStats {
    message ChooserAction {
      message CategoryCount {
        optional string name = 1;
        optional int32 count = 3;
      }
      optional string name = 1;
      repeated CategoryCount counts = 3;
    }
    optional string package = 1;
    // package_index contains the index + 1 of the package name in the string pool
    optional int32 package_index = 2;
    optional int64 last_time_active_ms = 3;
    optional int64 total_time_active_ms = 4;
    optional int32 last_event = 5;
    optional int32 app_launch_count = 6;
    repeated ChooserAction chooser_actions = 7;
  }

  // Stores the relevant information an IntervalStats will have about a Configuration
  message Configuration {
    optional .android.content.ConfigurationProto config = 1;
    optional int64 last_time_active_ms = 2;
    optional int64 total_time_active_ms = 3;
    optional int32 count = 4;
    optional bool active = 5;
  }

  // Stores the relevant information from a UsageEvents.Event
  message Event {
    optional string package = 1;
    // package_index contains the index + 1 of the package name in the string pool
    optional int32 package_index = 2;
    optional string class = 3;
    // class_index contains the index + 1 of the class name in the string pool
    optional int32 class_index = 4;
    optional int64 time_ms = 5;
    optional int32 flags = 6;
    optional int32 type = 7;
    optional .android.content.ConfigurationProto config = 8;
    optional string shortcut_id = 9;
    optional int32 standby_bucket = 11;
    optional string notification_channel = 12;
    // notification_channel_index contains the index + 1 of the channel name in the string pool
    optional int32 notification_channel_index = 13;
  }

  // The following fields contain supplemental data used to build IntervalStats, such as a string
  // pool.
  optional int64 end_time_ms = 1;
  // stringpool contains all the package and class names used by UsageStats and Event
  // They will hold a number that is equal to the index + 1 of their string in the pool
  optional StringPool stringpool = 2;

  // The following fields contain aggregated usage stats data
  optional CountAndTime interactive = 10;
  optional CountAndTime non_interactive = 11;
  optional CountAndTime keyguard_shown = 12;
  optional CountAndTime keyguard_hidden = 13;

  // The following fields contain listed usage stats data
  repeated UsageStats packages = 20;
  repeated Configuration configurations = 21;
  repeated Event event_log = 22;
}
+37 −0
Original line number Diff line number Diff line
@@ -23,8 +23,11 @@ import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
import android.util.proto.WireTypeMismatchException;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -231,6 +234,40 @@ public final class Rect implements Parcelable {
        protoOutputStream.end(token);
    }

    /**
     * Read from a protocol buffer input stream.
     * Protocol buffer message definition at {@link android.graphics.RectProto}
     *
     * @param proto     Stream to read the Rect object from.
     * @param fieldId   Field Id of the Rect as defined in the parent message
     * @hide
     */
    public void readFromProto(@NonNull ProtoInputStream proto, long fieldId) throws IOException,
            WireTypeMismatchException {
        final long token = proto.start(fieldId);
        try {
            while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                switch (proto.getFieldNumber()) {
                    case (int) RectProto.LEFT:
                        left = proto.readInt(RectProto.LEFT);
                        break;
                    case (int) RectProto.TOP:
                        top = proto.readInt(RectProto.TOP);
                        break;
                    case (int) RectProto.RIGHT:
                        right = proto.readInt(RectProto.RIGHT);
                        break;
                    case (int) RectProto.BOTTOM:
                        bottom = proto.readInt(RectProto.BOTTOM);
                        break;
                }
            }
        } finally {
            // Let caller handle any exceptions
            proto.end(token);
        }
    }

    /**
     * Returns true if the rectangle is empty (left >= right or top >= bottom)
     */
Loading