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

Commit 3f4654f4 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari Committed by Android (Google) Code Review
Browse files

Merge changes I7100a77e,I48e6c5ff into main

* changes:
  KeyGestureEvent support to launch applications
  Pipe current user to InputManagerService
parents 5d49bf2c 9ffdddac
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -26,4 +26,10 @@ parcelable AidlKeyGestureEvent {
    int action;
    int displayId;
    int flags;

    // App launch parameters: only set when gestureType = KEY_GESTURE_TYPE_LAUNCH_APPLICATION
    String appLaunchCategory;
    String appLaunchRole;
    String appLaunchPackageName;
    String appLaunchClassName;
}
+176 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 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 android.hardware.input;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.text.TextUtils;

import java.util.Objects;

/**
 * Provides data for launching an application.
 *
 * @hide
 */
public interface AppLaunchData {

    /** Creates AppLaunchData for the provided category */
    @NonNull
    static AppLaunchData createLaunchDataForCategory(@NonNull String category) {
        return new CategoryData(category);
    }

    /** Creates AppLaunchData for the provided role */
    @NonNull
    static AppLaunchData createLaunchDataForRole(@NonNull String role) {
        return new RoleData(role);
    }

    /** Creates AppLaunchData for the target package name and class name */
    @NonNull
    static AppLaunchData createLaunchDataForComponent(@NonNull String packageName,
            @NonNull String className) {
        return new ComponentData(packageName, className);
    }

    @Nullable
    static AppLaunchData createLaunchData(@Nullable String category, @Nullable String role,
            @Nullable String packageName, @Nullable String className) {
        if (!TextUtils.isEmpty(category)) {
            return new CategoryData(category);
        }
        if (!TextUtils.isEmpty(role)) {
            return new RoleData(role);
        }
        if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) {
            return new ComponentData(packageName, className);
        }
        return null;
    }

    /** Intent category based app launch data */
    class CategoryData implements AppLaunchData {
        @NonNull
        private final String mCategory;
        public CategoryData(@NonNull String category) {
            mCategory = category;
        }

        @NonNull
        public String getCategory() {
            return mCategory;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof CategoryData that)) return false;
            return Objects.equals(mCategory, that.mCategory);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mCategory);
        }

        @Override
        public String toString() {
            return "CategoryData{" +
                    "mCategory='" + mCategory + '\'' +
                    '}';
        }
    }

    /** Role based app launch data */
    class RoleData implements AppLaunchData {
        @NonNull
        private final String mRole;
        public RoleData(@NonNull String role) {
            mRole = role;
        }

        @NonNull
        public String getRole() {
            return mRole;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof RoleData roleData)) return false;
            return Objects.equals(mRole, roleData.mRole);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mRole);
        }

        @Override
        public String toString() {
            return "RoleData{" +
                    "mRole='" + mRole + '\'' +
                    '}';
        }
    }

    /** Target application launch data */
    class ComponentData implements AppLaunchData {
        @NonNull
        private final String mPackageName;

        @NonNull
        private final String mClassName;

        public ComponentData(@NonNull String packageName, @NonNull String className) {
            mPackageName = packageName;
            mClassName = className;
        }

        @NonNull
        public String getPackageName() {
            return mPackageName;
        }

        @NonNull
        public String getClassName() {
            return mClassName;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof ComponentData that)) return false;
            return Objects.equals(mPackageName, that.mPackageName) && Objects.equals(
                    mClassName, that.mClassName);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mPackageName, mClassName);
        }

        @Override
        public String toString() {
            return "ComponentData{" +
                    "mPackageName='" + mPackageName + '\'' +
                    ", mClassName='" + mClassName + '\'' +
                    '}';
        }
    }
}
+141 −9
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package android.hardware.input;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.role.RoleManager;
import android.content.Intent;
import android.view.Display;
import android.view.KeyCharacterMap;

@@ -26,6 +28,7 @@ import com.android.internal.util.FrameworkStatsLog;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * Provides information about the keyboard gesture event being triggered by an external keyboard.
@@ -37,6 +40,9 @@ public final class KeyGestureEvent {
    @NonNull
    private AidlKeyGestureEvent mKeyGestureEvent;

    private static final int LOG_EVENT_UNSPECIFIED =
            FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;

    public static final int KEY_GESTURE_TYPE_UNSPECIFIED = 0;
    public static final int KEY_GESTURE_TYPE_HOME = 1;
    public static final int KEY_GESTURE_TYPE_RECENT_APPS = 2;
@@ -76,6 +82,8 @@ public final class KeyGestureEvent {
    public static final int KEY_GESTURE_TYPE_SLEEP = 36;
    public static final int KEY_GESTURE_TYPE_WAKEUP = 37;
    public static final int KEY_GESTURE_TYPE_MEDIA_KEY = 38;
    // TODO(b/280423320): Remove "LAUNCH_DEFAULT_..." gestures and rely on launch intent to find
    //  the correct logging event.
    public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER = 39;
    public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL = 40;
    public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS = 41;
@@ -88,7 +96,7 @@ public final class KeyGestureEvent {
    public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES = 48;
    public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER = 49;
    public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS = 50;
    public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME = 51;
    public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION = 51;
    public static final int KEY_GESTURE_TYPE_DESKTOP_MODE = 52;
    public static final int KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION = 53;
    public static final int KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER = 54;
@@ -166,7 +174,7 @@ public final class KeyGestureEvent {
            KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES,
            KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER,
            KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS,
            KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME,
            KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
            KEY_GESTURE_TYPE_DESKTOP_MODE,
            KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION,
            KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER,
@@ -210,6 +218,8 @@ public final class KeyGestureEvent {
        private int mAction = KeyGestureEvent.ACTION_GESTURE_COMPLETE;
        private int mDisplayId = Display.DEFAULT_DISPLAY;
        private int mFlags = 0;
        @Nullable
        private AppLaunchData mAppLaunchData = null;

        /**
         * @see KeyGestureEvent#getDeviceId()
@@ -267,6 +277,14 @@ public final class KeyGestureEvent {
            return this;
        }

        /**
         * @see KeyGestureEvent#getAppLaunchData()
         */
        public Builder setAppLaunchData(@NonNull AppLaunchData appLaunchData) {
            mAppLaunchData = appLaunchData;
            return this;
        }

        /**
         * Build {@link KeyGestureEvent}
         */
@@ -279,6 +297,21 @@ public final class KeyGestureEvent {
            event.action = mAction;
            event.displayId = mDisplayId;
            event.flags = mFlags;
            if (mAppLaunchData != null) {
                if (mAppLaunchData instanceof AppLaunchData.CategoryData) {
                    event.appLaunchCategory =
                            ((AppLaunchData.CategoryData) mAppLaunchData).getCategory();
                } else if (mAppLaunchData instanceof AppLaunchData.RoleData) {
                    event.appLaunchRole = ((AppLaunchData.RoleData) mAppLaunchData).getRole();
                } else if (mAppLaunchData instanceof AppLaunchData.ComponentData) {
                    event.appLaunchPackageName =
                            ((AppLaunchData.ComponentData) mAppLaunchData).getPackageName();
                    event.appLaunchClassName =
                            ((AppLaunchData.ComponentData) mAppLaunchData).getClassName();
                } else {
                    throw new IllegalArgumentException("AppLaunchData type is invalid!");
                }
            }
            return new KeyGestureEvent(event);
        }
    }
@@ -315,6 +348,27 @@ public final class KeyGestureEvent {
        return (mKeyGestureEvent.flags & FLAG_CANCELLED) != 0;
    }

    public int getLogEvent() {
        if (getKeyGestureType() == KEY_GESTURE_TYPE_LAUNCH_APPLICATION) {
            return getLogEventFromLaunchAppData(getAppLaunchData());
        }
        return keyGestureTypeToLogEvent(getKeyGestureType());
    }

    /**
     * @return Launch app data associated with the event, only if key gesture type is
     * {@code KEY_GESTURE_TYPE_LAUNCH_APPLICATION}
     */
    @Nullable
    public AppLaunchData getAppLaunchData() {
        if (mKeyGestureEvent.gestureType != KEY_GESTURE_TYPE_LAUNCH_APPLICATION) {
            return null;
        }
        return AppLaunchData.createLaunchData(mKeyGestureEvent.appLaunchCategory,
                mKeyGestureEvent.appLaunchRole, mKeyGestureEvent.appLaunchPackageName,
                mKeyGestureEvent.appLaunchClassName);
    }

    @Override
    public String toString() {
        return "KeyGestureEvent { "
@@ -324,7 +378,8 @@ public final class KeyGestureEvent {
                + "keyGestureType = " + keyGestureTypeToString(mKeyGestureEvent.gestureType) + ", "
                + "action = " + mKeyGestureEvent.action + ", "
                + "displayId = " + mKeyGestureEvent.displayId + ", "
                + "flags = " + mKeyGestureEvent.flags
                + "flags = " + mKeyGestureEvent.flags + ", "
                + "appLaunchData = " + getAppLaunchData()
                + " }";
    }

@@ -339,7 +394,11 @@ public final class KeyGestureEvent {
                && mKeyGestureEvent.gestureType == that.mKeyGestureEvent.gestureType
                && mKeyGestureEvent.action == that.mKeyGestureEvent.action
                && mKeyGestureEvent.displayId == that.mKeyGestureEvent.displayId
                && mKeyGestureEvent.flags == that.mKeyGestureEvent.flags;
                && mKeyGestureEvent.flags == that.mKeyGestureEvent.flags
                && Objects.equals(mKeyGestureEvent.appLaunchCategory, that.mKeyGestureEvent.appLaunchCategory)
                && Objects.equals(mKeyGestureEvent.appLaunchRole, that.mKeyGestureEvent.appLaunchRole)
                && Objects.equals(mKeyGestureEvent.appLaunchPackageName, that.mKeyGestureEvent.appLaunchPackageName)
                && Objects.equals(mKeyGestureEvent.appLaunchClassName, that.mKeyGestureEvent.appLaunchClassName);
    }

    @Override
@@ -352,13 +411,21 @@ public final class KeyGestureEvent {
        _hash = 31 * _hash + mKeyGestureEvent.action;
        _hash = 31 * _hash + mKeyGestureEvent.displayId;
        _hash = 31 * _hash + mKeyGestureEvent.flags;
        _hash = 31 * _hash + (mKeyGestureEvent.appLaunchCategory != null
                ? mKeyGestureEvent.appLaunchCategory.hashCode() : 0);
        _hash = 31 * _hash + (mKeyGestureEvent.appLaunchRole != null
                ? mKeyGestureEvent.appLaunchRole.hashCode() : 0);
        _hash = 31 * _hash + (mKeyGestureEvent.appLaunchPackageName != null
                ? mKeyGestureEvent.appLaunchPackageName.hashCode() : 0);
        _hash = 31 * _hash + (mKeyGestureEvent.appLaunchClassName != null
                ? mKeyGestureEvent.appLaunchClassName.hashCode() : 0);
        return _hash;
    }

    /**
     * Convert KeyGestureEvent type to corresponding log event got KeyboardSystemsEvent
     */
    public static int keyGestureTypeToLogEvent(@KeyGestureType int value) {
    private static int keyGestureTypeToLogEvent(@KeyGestureType int value) {
        switch (value) {
            case KEY_GESTURE_TYPE_HOME:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME;
@@ -460,14 +527,79 @@ public final class KeyGestureEvent {
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER;
            case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS;
            case KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME:
            case KEY_GESTURE_TYPE_LAUNCH_APPLICATION:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME;
            case KEY_GESTURE_TYPE_DESKTOP_MODE:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE;
            case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION;
            default:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;
                return LOG_EVENT_UNSPECIFIED;
        }
    }

    /**
     * Find Log event type corresponding to app launch data.
     * Returns {@code LOG_EVENT_UNSPECIFIED} if no matching event found
     */
    private static int getLogEventFromLaunchAppData(@Nullable AppLaunchData data) {
        if (data == null) {
            return LOG_EVENT_UNSPECIFIED;
        }
        if (data instanceof AppLaunchData.CategoryData) {
            return getLogEventFromSelectorCategory(
                    ((AppLaunchData.CategoryData) data).getCategory());
        } else if (data instanceof AppLaunchData.RoleData) {
            return getLogEventFromRole(((AppLaunchData.RoleData) data).getRole());
        } else if (data instanceof AppLaunchData.ComponentData) {
            return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME;
        } else {
            throw new IllegalArgumentException("AppLaunchData type is invalid!");
        }
    }

    private static int getLogEventFromSelectorCategory(@NonNull String category) {
        switch (category) {
            case Intent.CATEGORY_APP_BROWSER:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER;
            case Intent.CATEGORY_APP_EMAIL:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_EMAIL;
            case Intent.CATEGORY_APP_CONTACTS:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CONTACTS;
            case Intent.CATEGORY_APP_CALENDAR:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALENDAR;
            case Intent.CATEGORY_APP_CALCULATOR:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALCULATOR;
            case Intent.CATEGORY_APP_MUSIC:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MUSIC;
            case Intent.CATEGORY_APP_MAPS:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MAPS;
            case Intent.CATEGORY_APP_MESSAGING:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING;
            case Intent.CATEGORY_APP_GALLERY:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_GALLERY;
            case Intent.CATEGORY_APP_FILES:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FILES;
            case Intent.CATEGORY_APP_WEATHER:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER;
            case Intent.CATEGORY_APP_FITNESS:
                return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS;
            default:
                return LOG_EVENT_UNSPECIFIED;
        }
    }

    /**
     * Find Log event corresponding to the provide system role name.
     * Returns {@code LOG_EVENT_UNSPECIFIED} if no matching event found.
     */
    private static int getLogEventFromRole(@NonNull String role) {
        if (RoleManager.ROLE_BROWSER.equals(role)) {
            return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER;
        } else if (RoleManager.ROLE_SMS.equals(role)) {
            return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING;
        } else {
            return LOG_EVENT_UNSPECIFIED;
        }
    }

@@ -577,8 +709,8 @@ public final class KeyGestureEvent {
                return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER";
            case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS:
                return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS";
            case KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME:
                return "KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME";
            case KEY_GESTURE_TYPE_LAUNCH_APPLICATION:
                return "KEY_GESTURE_TYPE_LAUNCH_APPLICATION";
            case KEY_GESTURE_TYPE_DESKTOP_MODE:
                return "KEY_GESTURE_TYPE_DESKTOP_MODE";
            case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION:
+7 −0
Original line number Diff line number Diff line
@@ -127,6 +127,13 @@ public abstract class InputManagerInternal {
     */
    public abstract void notifyInputMethodConnectionActive(boolean connectionIsActive);

    /**
     * Notify user id changes to input.
     *
     * TODO(b/362473586): Cleanup after input shifts to Lifecycle with user change callbacks
     */
    public abstract void setCurrentUser(@UserIdInt int newUserId);

    /** Callback interface for notifications relating to the lid switch. */
    public interface LidSwitchCallback {
        /**
+15 −0
Original line number Diff line number Diff line
@@ -175,6 +175,7 @@ public class InputManagerService extends IInputManager.Stub
    private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1;
    private static final int MSG_RELOAD_DEVICE_ALIASES = 2;
    private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 3;
    private static final int MSG_CURRENT_USER_CHANGED = 4;

    private static final int DEFAULT_VIBRATION_MAGNITUDE = 192;
    private static final AdditionalDisplayInputProperties
@@ -184,6 +185,8 @@ public class InputManagerService extends IInputManager.Stub

    private final Context mContext;
    private final InputManagerHandler mHandler;
    @UserIdInt
    private int mCurrentUserId = UserHandle.USER_SYSTEM;
    private DisplayManagerInternal mDisplayManagerInternal;

    private WindowManagerInternal mWindowManagerInternal;
@@ -2982,6 +2985,10 @@ public class InputManagerService extends IInputManager.Stub
        mKeyGestureController.unregisterKeyGestureHandler(handler, Binder.getCallingPid());
    }

    private void handleCurrentUserChanged(@UserIdInt int userId) {
        mCurrentUserId = userId;
    }

    /**
     * Callback interface implemented by the Window Manager.
     */
@@ -3150,6 +3157,9 @@ public class InputManagerService extends IInputManager.Stub
                    boolean inTabletMode = (boolean) args.arg1;
                    deliverTabletModeChanged(whenNanos, inTabletMode);
                    break;
                case MSG_CURRENT_USER_CHANGED:
                    handleCurrentUserChanged((int) msg.obj);
                    break;
            }
        }
    }
@@ -3512,6 +3522,11 @@ public class InputManagerService extends IInputManager.Stub
            InputManagerService.this.setAccessibilityPointerIconScaleFactor(displayId, scaleFactor);
        }

        @Override
        public void setCurrentUser(@UserIdInt int newUserId) {
            mHandler.obtainMessage(MSG_CURRENT_USER_CHANGED, newUserId).sendToTarget();
        }

        @Override
        public boolean setKernelWakeEnabled(int deviceId, boolean enabled) {
            return mNative.setKernelWakeEnabled(deviceId, enabled);
Loading