Add ATV KeyHandler
* Add a keyhandler to support Netflix, Youtube, Google Play,
HBO Max, Disney+, and Settings buttons on dopinder, sabrina,
wade.
* Use keycode instead of scancode, as dopinder/sabrina have
overlapping scancodes's for their buttons.
Co-authored-by: Aaron Kling <webgeek1234@gmail.com>
Change-Id: If4e227d03684bf62e19ee8ca10b699ff27827529
diff --git a/src/org/lineageos/lineageparts/atv/KeyHandler.java b/src/org/lineageos/lineageparts/atv/KeyHandler.java
new file mode 100644
index 0000000..bed2974
--- /dev/null
+++ b/src/org/lineageos/lineageparts/atv/KeyHandler.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 The LineageOS 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 org.lineageos.lineageparts.atv;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import com.android.internal.os.DeviceKeyHandler;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+public class KeyHandler implements DeviceKeyHandler {
+ private static final String TAG = KeyHandler.class.getSimpleName();
+ private static Map<Integer, String> KEYMAP;
+
+ private final Context mContext;
+
+ public KeyHandler(Context context) {
+ mContext = context;
+
+ int[] keycodes = mContext.getResources().getIntArray(
+ org.lineageos.platform.internal.R.array.keyhandler_keycodes);
+ String[] packages = mContext.getResources().getStringArray(
+ org.lineageos.platform.internal.R.array.keyhandler_packages);
+
+ KEYMAP = IntStream.range(0, keycodes.length).boxed()
+ .collect(Collectors.toMap(i -> keycodes[i], i -> packages[i]));
+ }
+
+ public KeyEvent handleKeyEvent(KeyEvent event) {
+ if (event.getAction() != KeyEvent.ACTION_UP || !hasSetupCompleted()) {
+ return event;
+ }
+
+ int keyCode = event.getKeyCode();
+ String targetName = KEYMAP.get(keyCode);
+
+ if (targetName != null) {
+ launchTarget(targetName);
+ return null;
+ }
+
+ return event;
+ }
+
+ private boolean hasSetupCompleted() {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.TV_USER_SETUP_COMPLETE, 0) != 0;
+ }
+
+ private void launchTarget(String targetName) {
+ // First try to look the name up as a package
+ Intent launchIntent = mContext.getPackageManager().getLaunchIntentForPackage(targetName);
+
+ // If it isn't an installed package, try as an intent
+ if (launchIntent == null) {
+ launchIntent = new Intent(targetName);
+ launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ if (mContext.getPackageManager().resolveService(launchIntent, 0) == null) {
+ launchIntent = null;
+ }
+ }
+
+ // If something resolved, run it; otherwise log a warning
+ if (launchIntent != null) {
+ mContext.startActivity(launchIntent);
+ } else {
+ Log.w(TAG, "Cannot launch " + targetName + ": package/intent not found.");
+ }
+ }
+}