Merge "Add global key configuration file" into jb-mr2-dev
This commit is contained in:
@ -2578,6 +2578,14 @@ public class Intent implements Parcelable, Cloneable {
|
||||
public static final String ACTION_SHOW_BRIGHTNESS_DIALOG =
|
||||
"android.intent.action.SHOW_BRIGHTNESS_DIALOG";
|
||||
|
||||
/**
|
||||
* Broadcast Action: A global button was pressed. Includes a single
|
||||
* extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that
|
||||
* caused the broadcast.
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON";
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
// Standard intent categories (see addCategory()).
|
||||
|
@ -1142,6 +1142,7 @@
|
||||
<java-symbol type="xml" name="time_zones_by_country" />
|
||||
<java-symbol type="xml" name="sms_short_codes" />
|
||||
<java-symbol type="xml" name="audio_assets" />
|
||||
<java-symbol type="xml" name="global_keys" />
|
||||
|
||||
<java-symbol type="raw" name="accessibility_gestures" />
|
||||
<java-symbol type="raw" name="incognito_mode_start_page" />
|
||||
|
31
core/res/res/xml/global_keys.xml
Normal file
31
core/res/res/xml/global_keys.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2013, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!-- Mapping of keycodes to components which will be handled globally.
|
||||
Modify this file to add global keys.
|
||||
A global key will NOT go to the foreground application and instead only ever be sent via targeted
|
||||
broadcast to the specified component. The action of the intent will be
|
||||
android.intent.action.GLOBAL_BUTTON and the KeyEvent will be included in the intent as
|
||||
android.intent.extra.KEY_EVENT.
|
||||
-->
|
||||
|
||||
<global_keys version="1">
|
||||
<!-- Example format: keyCode = keycode to handle globally. component = component which will handle this key. -->
|
||||
<!-- <key keyCode="KEYCODE_VOLUME_UP" component="com.android.example.keys/.VolumeKeyHandler" /> -->
|
||||
</global_keys>
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
*
|
||||
* 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.policy.impl;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.android.internal.util.XmlUtils;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Stores a mapping of global keys.
|
||||
* <p>
|
||||
* A global key will NOT go to the foreground application and instead only ever be sent via targeted
|
||||
* broadcast to the specified component. The action of the intent will be
|
||||
* {@link Intent#ACTION_GLOBAL_BUTTON} and the KeyEvent will be included in the intent with
|
||||
* {@link Intent#EXTRA_KEY_EVENT}.
|
||||
*/
|
||||
final class GlobalKeyManager {
|
||||
|
||||
private static final String TAG = "GlobalKeyManager";
|
||||
|
||||
private static final String TAG_GLOBAL_KEYS = "global_keys";
|
||||
private static final String ATTR_VERSION = "version";
|
||||
private static final String TAG_KEY = "key";
|
||||
private static final String ATTR_KEY_CODE = "keyCode";
|
||||
private static final String ATTR_COMPONENT = "component";
|
||||
|
||||
private static final int GLOBAL_KEY_FILE_VERSION = 1;
|
||||
|
||||
private SparseArray<ComponentName> mKeyMapping;
|
||||
|
||||
public GlobalKeyManager(Context context) {
|
||||
mKeyMapping = new SparseArray<ComponentName>();
|
||||
loadGlobalKeys(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts an intent if the keycode is part of the global key mapping.
|
||||
*
|
||||
* @param context context used to broadcast the event
|
||||
* @param keyCode keyCode which triggered this function
|
||||
* @param event keyEvent which trigged this function
|
||||
* @return {@code true} if this was handled
|
||||
*/
|
||||
boolean handleGlobalKey(Context context, int keyCode, KeyEvent event) {
|
||||
if (mKeyMapping.size() > 0) {
|
||||
ComponentName component = mKeyMapping.get(keyCode);
|
||||
if (component != null) {
|
||||
Intent intent = new Intent(Intent.ACTION_GLOBAL_BUTTON)
|
||||
.setComponent(component)
|
||||
.putExtra(Intent.EXTRA_KEY_EVENT, event);
|
||||
context.sendBroadcastAsUser(intent, UserHandle.CURRENT, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the key will be handled globally.
|
||||
*/
|
||||
boolean shouldHandleGlobalKey(int keyCode, KeyEvent event) {
|
||||
return mKeyMapping.get(keyCode) != null;
|
||||
}
|
||||
|
||||
private void loadGlobalKeys(Context context) {
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
parser = context.getResources().getXml(com.android.internal.R.xml.global_keys);
|
||||
XmlUtils.beginDocument(parser, TAG_GLOBAL_KEYS);
|
||||
int version = parser.getAttributeIntValue(null, ATTR_VERSION, 0);
|
||||
if (GLOBAL_KEY_FILE_VERSION == version) {
|
||||
while (true) {
|
||||
XmlUtils.nextElement(parser);
|
||||
String element = parser.getName();
|
||||
if (element == null) {
|
||||
break;
|
||||
}
|
||||
if (TAG_KEY.equals(element)) {
|
||||
String keyCodeName = parser.getAttributeValue(null, ATTR_KEY_CODE);
|
||||
String componentName = parser.getAttributeValue(null, ATTR_COMPONENT);
|
||||
int keyCode = KeyEvent.keyCodeFromString(keyCodeName);
|
||||
if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
|
||||
mKeyMapping.put(keyCode, ComponentName.unflattenFromString(
|
||||
componentName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Resources.NotFoundException e) {
|
||||
Log.w(TAG, "global keys file not found", e);
|
||||
} catch (XmlPullParserException e) {
|
||||
Log.w(TAG, "XML parser exception reading global keys file", e);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "I/O exception reading global keys file", e);
|
||||
} finally {
|
||||
if (parser != null) {
|
||||
parser.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -441,6 +441,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
PowerManager.WakeLock mBroadcastWakeLock;
|
||||
boolean mHavePendingMediaKeyRepeatWithWakeLock;
|
||||
|
||||
// Maps global key codes to the components that will handle them.
|
||||
private GlobalKeyManager mGlobalKeyManager;
|
||||
|
||||
// Fallback actions by key code.
|
||||
private final SparseArray<KeyCharacterMap.FallbackAction> mFallbackActions =
|
||||
new SparseArray<KeyCharacterMap.FallbackAction>();
|
||||
@ -898,6 +901,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mScreenshotChordEnabled = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_enableScreenshotChord);
|
||||
|
||||
mGlobalKeyManager = new GlobalKeyManager(mContext);
|
||||
|
||||
// Controls rotation and the like.
|
||||
initializeHdmiState();
|
||||
|
||||
@ -2140,6 +2145,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Let the application handle the key.
|
||||
return 0;
|
||||
}
|
||||
@ -3585,6 +3594,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
// If the key would be handled globally, just return the result, don't worry about special
|
||||
// key processing.
|
||||
if (mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Handle special keys.
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
||||
|
Reference in New Issue
Block a user