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

Commit 93d46d42 authored by Alexander Hofbauer's avatar Alexander Hofbauer
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.
parent 1145152e
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
@@ -792,4 +792,10 @@

    <!-- True if the Sym key should open the InputMethodPicker (default) -->
    <bool name="config_symKeyShowsImePicker">true</bool>

    <!-- Path to the library that contains the device specifiy key handler -->
    <string name="config_deviceKeyHandlerLib"></string>

    <!-- Name of that key handler class -->
    <string name="config_deviceKeyHandlerClass"></string>
</resources>
+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;
@@ -59,12 +60,15 @@ import android.provider.Settings;

import com.android.internal.R;
import com.android.internal.app.ShutdownThread;
import com.android.internal.os.DeviceKeyHandler;
import com.android.internal.policy.PolicyManager;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.telephony.ITelephony;
import com.android.internal.view.BaseInputHandler;
import com.android.internal.widget.PointerLocationView;

import dalvik.system.DexClassLoader;

import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
@@ -143,6 +147,7 @@ import java.io.FileDescriptor;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

@@ -255,6 +260,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
@@ -930,6 +937,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.equals("") && !deviceKeyHandlerClass.equals("")) {
            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, "Loaded device key handler");
            } catch (Exception e) {
                Slog.d(TAG, "Could not instantiate device key handler "
                        + deviceKeyHandlerClass + " from class "
                        + deviceKeyHandlerLib, e);
            }
        }
    }

    public void setInitialDisplaySize(int width, int height) {
@@ -1828,6 +1859,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH);
        }

        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;
    }