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

Commit e3cc8914 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4949382 from 8cb78fcb to pi-qpr1-release

Change-Id: I95d0db4e6b6035249937c06338ae5a8093fa5d94
parents 23fe45f5 8cb78fcb
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1748,7 +1748,8 @@ public final class SQLiteDatabase extends SQLiteClosable {
        executeSql(sql, bindArgs);
    }

    private int executeSql(String sql, Object[] bindArgs) throws SQLException {
    /** {@hide} */
    public int executeSql(String sql, Object[] bindArgs) throws SQLException {
        acquireReference();
        try {
            final int statementType = DatabaseUtils.getSqlStatementType(sql);
+234 −34
Original line number Diff line number Diff line
@@ -16,17 +16,25 @@

package android.database.sqlite;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.os.Build;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;

import libcore.util.EmptyArray;

import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;

@@ -95,9 +103,6 @@ public class SQLiteQueryBuilder
        if (mWhereClause == null) {
            mWhereClause = new StringBuilder(inWhere.length() + 16);
        }
        if (mWhereClause.length() == 0) {
            mWhereClause.append('(');
        }
        mWhereClause.append(inWhere);
    }

@@ -115,9 +120,6 @@ public class SQLiteQueryBuilder
        if (mWhereClause == null) {
            mWhereClause = new StringBuilder(inWhere.length() + 16);
        }
        if (mWhereClause.length() == 0) {
            mWhereClause.append('(');
        }
        DatabaseUtils.appendEscapedSQLString(mWhereClause, inWhere);
    }

@@ -376,6 +378,11 @@ public class SQLiteQueryBuilder
            return null;
        }

        final String sql;
        final String unwrappedSql = buildQuery(
                projectionIn, selection, groupBy, having,
                sortOrder, limit);

        if (mStrict && selection != null && selection.length() > 0) {
            // Validate the user-supplied selection to detect syntactic anomalies
            // in the selection string that could indicate a SQL injection attempt.
@@ -384,24 +391,166 @@ public class SQLiteQueryBuilder
            // originally specified. An attacker cannot create an expression that
            // would escape the SQL expression while maintaining balanced parentheses
            // in both the wrapped and original forms.
            String sqlForValidation = buildQuery(projectionIn, "(" + selection + ")", groupBy,

            // NOTE: The ordering of the below operations is important; we must
            // execute the wrapped query to ensure the untrusted clause has been
            // fully isolated.

            // Validate the unwrapped query
            db.validateSql(unwrappedSql, cancellationSignal); // will throw if query is invalid

            // Execute wrapped query for extra protection
            final String wrappedSql = buildQuery(projectionIn, wrap(selection), groupBy,
                    having, sortOrder, limit);
            db.validateSql(sqlForValidation, cancellationSignal); // will throw if query is invalid
            sql = wrappedSql;
        } else {
            // Execute unwrapped query
            sql = unwrappedSql;
        }

        String sql = buildQuery(
                projectionIn, selection, groupBy, having,
                sortOrder, limit);

        final String[] sqlArgs = selectionArgs;
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Performing query: " + sql);
            if (Build.IS_DEBUGGABLE) {
                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
            } else {
                Log.d(TAG, sql);
            }
        }
        return db.rawQueryWithFactory(
                mFactory, sql, selectionArgs,
                mFactory, sql, sqlArgs,
                SQLiteDatabase.findEditTable(mTables),
                cancellationSignal); // will throw if query is invalid
    }

    /**
     * Perform an update by combining all current settings and the
     * information passed into this method.
     *
     * @param db the database to update on
     * @param selection A filter declaring which rows to return,
     *   formatted as an SQL WHERE clause (excluding the WHERE
     *   itself). Passing null will return all rows for the given URL.
     * @param selectionArgs You may include ?s in selection, which
     *   will be replaced by the values from selectionArgs, in order
     *   that they appear in the selection. The values will be bound
     *   as Strings.
     * @return the number of rows updated
     * @hide
     */
    public int update(@NonNull SQLiteDatabase db, @NonNull ContentValues values,
            @Nullable String selection, @Nullable String[] selectionArgs) {
        Objects.requireNonNull(mTables, "No tables defined");
        Objects.requireNonNull(db, "No database defined");
        Objects.requireNonNull(values, "No values defined");

        final String sql;
        final String unwrappedSql = buildUpdate(values, selection);

        if (mStrict) {
            // Validate the user-supplied selection to detect syntactic anomalies
            // in the selection string that could indicate a SQL injection attempt.
            // The idea is to ensure that the selection clause is a valid SQL expression
            // by compiling it twice: once wrapped in parentheses and once as
            // originally specified. An attacker cannot create an expression that
            // would escape the SQL expression while maintaining balanced parentheses
            // in both the wrapped and original forms.

            // NOTE: The ordering of the below operations is important; we must
            // execute the wrapped query to ensure the untrusted clause has been
            // fully isolated.

            // Validate the unwrapped query
            db.validateSql(unwrappedSql, null); // will throw if query is invalid

            // Execute wrapped query for extra protection
            final String wrappedSql = buildUpdate(values, wrap(selection));
            sql = wrappedSql;
        } else {
            // Execute unwrapped query
            sql = unwrappedSql;
        }

        if (selectionArgs == null) {
            selectionArgs = EmptyArray.STRING;
        }
        final String[] rawKeys = values.keySet().toArray(EmptyArray.STRING);
        final int valuesLength = rawKeys.length;
        final Object[] sqlArgs = new Object[valuesLength + selectionArgs.length];
        for (int i = 0; i < sqlArgs.length; i++) {
            if (i < valuesLength) {
                sqlArgs[i] = values.get(rawKeys[i]);
            } else {
                sqlArgs[i] = selectionArgs[i - valuesLength];
            }
        }
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            if (Build.IS_DEBUGGABLE) {
                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
            } else {
                Log.d(TAG, sql);
            }
        }
        return db.executeSql(sql, sqlArgs);
    }

    /**
     * Perform a delete by combining all current settings and the
     * information passed into this method.
     *
     * @param db the database to delete on
     * @param selection A filter declaring which rows to return,
     *   formatted as an SQL WHERE clause (excluding the WHERE
     *   itself). Passing null will return all rows for the given URL.
     * @param selectionArgs You may include ?s in selection, which
     *   will be replaced by the values from selectionArgs, in order
     *   that they appear in the selection. The values will be bound
     *   as Strings.
     * @return the number of rows deleted
     * @hide
     */
    public int delete(@NonNull SQLiteDatabase db, @Nullable String selection,
            @Nullable String[] selectionArgs) {
        Objects.requireNonNull(mTables, "No tables defined");
        Objects.requireNonNull(db, "No database defined");

        final String sql;
        final String unwrappedSql = buildDelete(selection);

        if (mStrict) {
            // Validate the user-supplied selection to detect syntactic anomalies
            // in the selection string that could indicate a SQL injection attempt.
            // The idea is to ensure that the selection clause is a valid SQL expression
            // by compiling it twice: once wrapped in parentheses and once as
            // originally specified. An attacker cannot create an expression that
            // would escape the SQL expression while maintaining balanced parentheses
            // in both the wrapped and original forms.

            // NOTE: The ordering of the below operations is important; we must
            // execute the wrapped query to ensure the untrusted clause has been
            // fully isolated.

            // Validate the unwrapped query
            db.validateSql(unwrappedSql, null); // will throw if query is invalid

            // Execute wrapped query for extra protection
            final String wrappedSql = buildDelete(wrap(selection));
            sql = wrappedSql;
        } else {
            // Execute unwrapped query
            sql = unwrappedSql;
        }

        final String[] sqlArgs = selectionArgs;
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            if (Build.IS_DEBUGGABLE) {
                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
            } else {
                Log.d(TAG, sql);
            }
        }
        return db.executeSql(sql, sqlArgs);
    }

    /**
     * Construct a SELECT statement suitable for use in a group of
     * SELECT statements that will be joined through UNION operators
@@ -434,28 +583,10 @@ public class SQLiteQueryBuilder
            String[] projectionIn, String selection, String groupBy,
            String having, String sortOrder, String limit) {
        String[] projection = computeProjection(projectionIn);

        StringBuilder where = new StringBuilder();
        boolean hasBaseWhereClause = mWhereClause != null && mWhereClause.length() > 0;

        if (hasBaseWhereClause) {
            where.append(mWhereClause.toString());
            where.append(')');
        }

        // Tack on the user's selection, if present.
        if (selection != null && selection.length() > 0) {
            if (hasBaseWhereClause) {
                where.append(" AND ");
            }

            where.append('(');
            where.append(selection);
            where.append(')');
        }
        String where = computeWhere(selection);

        return buildQueryString(
                mDistinct, mTables, projection, where.toString(),
                mDistinct, mTables, projection, where,
                groupBy, having, sortOrder, limit);
    }

@@ -472,6 +603,42 @@ public class SQLiteQueryBuilder
        return buildQuery(projectionIn, selection, groupBy, having, sortOrder, limit);
    }

    /** {@hide} */
    public String buildUpdate(ContentValues values, String selection) {
        if (values == null || values.size() == 0) {
            throw new IllegalArgumentException("Empty values");
        }

        StringBuilder sql = new StringBuilder(120);
        sql.append("UPDATE ");
        sql.append(mTables);
        sql.append(" SET ");

        final String[] rawKeys = values.keySet().toArray(EmptyArray.STRING);
        for (int i = 0; i < rawKeys.length; i++) {
            if (i > 0) {
                sql.append(',');
            }
            sql.append(rawKeys[i]);
            sql.append("=?");
        }

        final String where = computeWhere(selection);
        appendClause(sql, " WHERE ", where);
        return sql.toString();
    }

    /** {@hide} */
    public String buildDelete(String selection) {
        StringBuilder sql = new StringBuilder(120);
        sql.append("DELETE FROM ");
        sql.append(mTables);

        final String where = computeWhere(selection);
        appendClause(sql, " WHERE ", where);
        return sql.toString();
    }

    /**
     * Construct a SELECT statement suitable for use in a group of
     * SELECT statements that will be joined through UNION operators
@@ -645,4 +812,37 @@ public class SQLiteQueryBuilder
        }
        return null;
    }

    private @Nullable String computeWhere(@Nullable String selection) {
        final boolean hasInternal = !TextUtils.isEmpty(mWhereClause);
        final boolean hasExternal = !TextUtils.isEmpty(selection);

        if (hasInternal || hasExternal) {
            final StringBuilder where = new StringBuilder();
            if (hasInternal) {
                where.append('(').append(mWhereClause).append(')');
            }
            if (hasInternal && hasExternal) {
                where.append(" AND ");
            }
            if (hasExternal) {
                where.append('(').append(selection).append(')');
            }
            return where.toString();
        } else {
            return null;
        }
    }

    /**
     * Wrap given argument in parenthesis, unless it's {@code null} or
     * {@code ()}, in which case return it verbatim.
     */
    private @Nullable String wrap(@Nullable String arg) {
        if (TextUtils.isEmpty(arg)) {
            return arg;
        } else {
            return "(" + arg + ")";
        }
    }
}
+9 −0
Original line number Diff line number Diff line
@@ -10509,6 +10509,15 @@ public final class Settings {
         */
        public static final String ACTIVITY_MANAGER_CONSTANTS = "activity_manager_constants";
        /**
         * Feature flag to enable or disable the activity starts logging feature.
         * Type: int (0 for false, 1 for true)
         * Default: 0
         * @hide
         */
        public static final String ACTIVITY_STARTS_LOGGING_ENABLED
                = "activity_starts_logging_enabled";
        /**
         * App ops specific settings.
         * This is encoded as a key=value list, separated by commas. Ex:
+1 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ public class SettingsBackupTest {
    private static final Set<String> BACKUP_BLACKLISTED_GLOBAL_SETTINGS =
            newHashSet(
                    Settings.Global.ACTIVITY_MANAGER_CONSTANTS,
                    Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED,
                    Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED,
                    Settings.Global.ADB_ENABLED,
                    Settings.Global.ADD_USERS_WHEN_LOCKED,
+299 −0
Original line number Diff line number Diff line
@@ -6130,6 +6130,305 @@ message MetricsEvent {
    // CATEGORY: NOTIFICATION
    NOTIFICATION_INTERRUPTION = 1501;

    // OPEN: Settings
    // CATEGORY: SETTINGS
    // OS: Q
    SETTINGS_HOMEPAGE = 1502;

    // OPEN: Settings > Create shortcut(widget)
    // CATEGORY: SETTINGS
    // OS: Q
    SETTINGS_CREATE_SHORTCUT = 1503;

    // ACTION: Authenticate using fingerprint
    // CATEGORY: SETTINGS
    // OS: Q
    ACTION_FACE_AUTH = 1504;

    // ACTION: Add fingerprint > Enroll fingerprint
    // CATEGORY: SETTINGS
    // OS: Q
    ACTION_FACE_ENROLL = 1505;

    // OPEN: Face Enroll introduction
    // CATEGORY: SETTINGS
    // OS: Q
    FACE_ENROLL_INTRO = 1506;

    // OPEN: Face Enroll introduction
    // CATEGORY: SETTINGS
    // OS: Q
    FACE_ENROLL_ENROLLING = 1507;

    // OPEN: Face Enroll introduction
    // CATEGORY: SETTINGS
    // OS: Q
    FACE_ENROLL_FINISHED = 1508;

    // OPEN: Face Enroll sidecar
    // CATEGORY: SETTINGS
    // OS: Q
    FACE_ENROLL_SIDECAR = 1509;

    // OPEN: Settings > Add face > Error dialog
    // OS: Q
    DIALOG_FACE_ERROR = 1510;

    // OPEN: Settings > Security > Face
    // CATEGORY: SETTINGS
    // OS: Q
    FACE = 1511;

    // OPEN: Settings > Acessibility > HearingAid pairing instructions dialog
    // CATEGORY: SETTINGS
    // OS: Q
    DIALOG_ACCESSIBILITY_HEARINGAID = 1512;

    // ACTION: Activity start
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    ACTION_ACTIVITY_START = 1513;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Calling UID
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_CALLING_UID = 1514;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Calling package name
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_CALLING_PACKAGE_NAME = 1515;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Calling UID proc state
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_CALLING_UID_PROC_STATE = 1516;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Calling UID has any visible window
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW = 1517;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Real calling UID
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_REAL_CALLING_UID = 1518;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Real calling UID proc state
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_REAL_CALLING_UID_PROC_STATE = 1519;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Real calling UID has any visible window
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW = 1520;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Target UID
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_TARGET_UID = 1521;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Target UID package name
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_TARGET_PACKAGE_NAME = 1522;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Target UID proc state
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_TARGET_UID_PROC_STATE = 1523;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Target UID has any visible window
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW = 1524;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Target doze whitelist tag
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_TARGET_WHITELIST_TAG = 1525;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Target short component name
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_TARGET_SHORT_COMPONENT_NAME = 1526;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Coming from pending intent
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_COMING_FROM_PENDING_INTENT = 1527;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Intent action
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_INTENT_ACTION = 1528;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Caller app process record process name
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_PROCESS_NAME = 1529;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Caller app process record current proc state
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_CUR_PROC_STATE = 1530;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Caller app process record has client activities
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES = 1531;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Caller app process record has foreground services
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES = 1532;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Caller app process record has foreground activities
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES = 1533;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Caller app process record has top UI
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_HAS_TOP_UI = 1534;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Caller app process record has overlay UI
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_HAS_OVERLAY_UI = 1535;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Caller app process record pending UI clean
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_PENDING_UI_CLEAN = 1536;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Millis since caller app's process record last interaction event
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT = 1537;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Millis since caller app's process record fg interaction
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION = 1538;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Millis since caller app's process record last became unimportant
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT = 1539;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record launch mode
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_LAUNCH_MODE = 1540;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record target activity
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY = 1541;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record flags
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_FLAGS = 1542;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record real activity
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_REAL_ACTIVITY = 1543;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record short component name
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME = 1544;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record process name
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_PROCESS_NAME = 1545;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record is fullscreen
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_IS_FULLSCREEN = 1546;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record is no display
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY = 1547;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Millis since activity was last visible
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE = 1548;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record's resultTo packageName
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME = 1549;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record's resultTo shortComponentName
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME = 1550;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record is visible
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_IS_VISIBLE = 1551;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Activity record is visible ignoring keyguard
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD = 1552;

    // Tagged data for ACTION_ACTIVITY_START.
    // FIELD: Millis since activity's last launch
    // CATEGORY: OTHER
    // OS: Q (will also ship in PQ1A)
    FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH = 1553;

    // ---- End Q Constants, all Q constants go above this line ----

    // Add new aosp constants above this line.
Loading