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

Commit 862f89d4 authored by Alexander Hofbauer's avatar Alexander Hofbauer Committed by Aaron Echols
Browse files

Dispatch keys to a device specific key handler

Injects a device key handler into the input path to handle additional
keys (as found on some docks with a hardware keyboard).

Configurable via overlay settings config_deviceKeyHandlerLib and
config_deviceKeyHandlerClass.

Change-Id: I6678c89c7530fdb1d4d516ba4f1d2c9e30ce79a4

Conflicts:
	core/res/res/values/symbols.xml
parent cd9db1c8
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The CyanogenMod 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 com.android.internal.os;

import android.view.KeyEvent;

public interface DeviceKeyHandler {
    public static final int KEYEVENT_CAUGHT = -1;
    public static final int KEYEVENT_UNCAUGHT = 0;

    public int handleKeyEvent(KeyEvent event);
}
+6 −0
Original line number Diff line number Diff line
@@ -1100,6 +1100,12 @@
         legacy USB manager should be started. -->
    <string name="config_legacyUmsLunFile">/sys/devices/platform/usb_mass_storage/lun0/file</string>

    <!-- Path to the library that contains a device specific key handler -->
    <string name="config_deviceKeyHandlerLib" translatable="false"></string>

    <!-- Name of that key handler class -->
    <string name="config_deviceKeyHandlerClass" translatable="false"></string>

    <!-- If a dock provides a lid switch, that lid can be removed. This
         setting is used to determine, whether lidOpenRotation has to be
         applied. -->
+2 −0
Original line number Diff line number Diff line
@@ -1840,6 +1840,8 @@
  <java-symbol type="bool" name="config_hasRemovableLid" />
  <java-symbol type="bool" name="config_hasDockBattery" />
  <java-symbol type="bool" name="config_noDelayInATwoDP" />
  <java-symbol type="string" name="config_deviceKeyHandlerLib" />
  <java-symbol type="string" name="config_deviceKeyHandlerClass" />

  <!-- Telephony -->
  <java-symbol type="bool" name="config_smsSamsungCdmaAlternateMessageIDEncoding" />
+39 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
@@ -67,6 +68,7 @@ import android.provider.Settings;

import com.android.internal.R;
import com.android.internal.app.ThemeUtils;
import com.android.internal.os.DeviceKeyHandler;
import com.android.internal.policy.PolicyManager;
import com.android.internal.policy.impl.keyguard.KeyguardViewManager;
import com.android.internal.policy.impl.keyguard.KeyguardViewMediator;
@@ -74,6 +76,8 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.telephony.ITelephony;
import com.android.internal.widget.PointerLocationView;

import dalvik.system.DexClassLoader;

import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
@@ -166,6 +170,7 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.lang.reflect.Constructor;

/**
 * WindowManagerPolicy implementation for the Android phone UI.  This
@@ -254,6 +259,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR);
    }

    DeviceKeyHandler mDeviceKeyHandler;

    /**
     * Lock protecting internal state.  Must not call out into window
     * manager with lock held.  (This lock will be acquired in places
@@ -1198,6 +1205,30 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        } else {
            screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
        }

        String deviceKeyHandlerLib = mContext.getResources().getString(
                com.android.internal.R.string.config_deviceKeyHandlerLib);

        String deviceKeyHandlerClass = mContext.getResources().getString(
                com.android.internal.R.string.config_deviceKeyHandlerClass);

        if (!deviceKeyHandlerLib.isEmpty() && !deviceKeyHandlerClass.isEmpty()) {
            DexClassLoader loader =  new DexClassLoader(deviceKeyHandlerLib,
                    new ContextWrapper(mContext).getCacheDir().getAbsolutePath(),
                    null,
                    ClassLoader.getSystemClassLoader());
            try {
                Class<?> klass = loader.loadClass(deviceKeyHandlerClass);
                Constructor<?> constructor = klass.getConstructor(Context.class);
                mDeviceKeyHandler = (DeviceKeyHandler) constructor.newInstance(
                        mContext);
                Slog.d(TAG, "Device key handler loaded");
            } catch (Exception e) {
                Slog.d(TAG, "Could not instantiate device key handler "
                        + deviceKeyHandlerClass + " from class "
                        + deviceKeyHandlerLib, e);
            }
        }
    }

    public void setInitialDisplaySize(Display display, int width, int height, int density) {
@@ -2496,6 +2527,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return -1;
        }

        if (mDeviceKeyHandler != null) {
            try {
                return mDeviceKeyHandler.handleKeyEvent(event);
            } catch (Exception e) {
                Slog.d(TAG, "Could not dispatch event to device key handler", e);
            }
        }

        // Let the application handle the key.
        return 0;
    }