import android.service.dreams.IDreamManager;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
+
+import cyanogenmod.hardware.CMHardwareManager;
+import cyanogenmod.providers.CMSettings;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
import com.android.server.statusbar.StatusBarManagerInternal;
-import dalvik.system.DexClassLoader;
-
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import cyanogenmod.providers.CMSettings;
+import dalvik.system.PathClassLoader;
/**
* WindowManagerPolicy implementation for the Android phone UI. This
boolean mNavigationBarLeftInLandscape = false; // Navigation bar left handed?
boolean mBootMessageNeedsHiding;
+
+ WindowState mKeyguardPanel;
+
+
KeyguardServiceDelegate mKeyguardDelegate;
final Runnable mWindowManagerDrawCallback = new Runnable() {
@Override
// During wakeup by volume keys, we still need to capture subsequent events
// until the key is released. This is required since the beep sound is produced
// post keypressed.
- boolean mVolumeWakeTriggered;
+ boolean mVolumeDownWakeTriggered;
+ boolean mVolumeUpWakeTriggered;
+ boolean mVolumeMuteWakeTriggered;
int mPointerLocationMode = 0; // guarded by mLock
boolean mVolBtnMusicControls;
boolean mIsLongPress;
- // Volume wake control flag
- boolean mVolumeWakeScreen;
-
PointerLocationView mPointerLocationView;
// The current size of the screen; really; extends into the overscan area of
boolean mWifiDisplayConnected = false;
int mWifiDisplayCustomRotation = -1;
+ private CMHardwareManager mCMHardware;
+
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.ACCELEROMETER_ROTATION_ANGLES), false, this,
UserHandle.USER_ALL);
- resolver.registerContentObserver(CMSettings.Secure.getUriFor(
- CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR), false, this,
+ resolver.registerContentObserver(CMSettings.Global.getUriFor(
+ CMSettings.Global.DEV_FORCE_SHOW_NAVBAR), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(CMSettings.System.getUriFor(
CMSettings.System.VOLBTN_MUSIC_CONTROLS), false, this,
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.ACCELEROMETER_ROTATION_ANGLES), false, this,
UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.DEV_FORCE_SHOW_NAVBAR), false, this,
- UserHandle.USER_ALL);
resolver.registerContentObserver(CMSettings.System.getUriFor(
CMSettings.System.NAVBAR_LEFT_IN_LANDSCAPE), false, this,
UserHandle.USER_ALL);
Runnable mBackLongPress = new Runnable() {
public void run() {
+ if (unpinActivity(false)) {
+ return;
+ }
try {
final Intent intent = new Intent(Intent.ACTION_MAIN);
String defaultHomePackage = "com.android.launcher";
mOrientationListener.setCurrentRotation(windowManager.getRotation());
} catch (RemoteException ex) { }
mSettingsObserver = new SettingsObserver(mHandler);
- mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context);
mUiMode = context.getResources().getInteger(
com.android.internal.R.integer.config_defaultUiModeType);
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());
+ PathClassLoader loader = new PathClassLoader(deviceKeyHandlerLib,
+ getClass().getClassLoader());
try {
Class<?> klass = loader.loadClass(deviceKeyHandlerClass);
Constructor<?> constructor = klass.getConstructor(Context.class);
+ deviceKeyHandlerLib, e);
}
}
-
}
private void updateKeyAssignments() {
updateWakeGestureListenerLp();
}
- boolean devForceNavbar = CMSettings.Secure.getIntForUser(resolver,
- CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR, 0, UserHandle.USER_CURRENT) == 1;
+ boolean devForceNavbar = CMSettings.Global.getIntForUser(resolver,
+ CMSettings.Global.DEV_FORCE_SHOW_NAVBAR, 0, UserHandle.USER_CURRENT) == 1;
if (devForceNavbar != mDevForceNavbar) {
mDevForceNavbar = devForceNavbar;
+ if (mCMHardware.isSupported(CMHardwareManager.FEATURE_KEY_DISABLE)) {
+ mCMHardware.set(CMHardwareManager.FEATURE_KEY_DISABLE, mDevForceNavbar);
+ }
}
mNavigationBarLeftInLandscape = CMSettings.System.getIntForUser(resolver,
permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW;
outAppOp[0] = AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
break;
+ case TYPE_KEYGUARD_PANEL:
+ permission =
+ org.cyanogenmod.platform.internal.Manifest.permission.THIRD_PARTY_KEYGUARD;
+ break;
default:
permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
}
case TYPE_VOLUME_OVERLAY:
case TYPE_PRIVATE_PRESENTATION:
case TYPE_DOCK_DIVIDER:
+ case TYPE_KEYGUARD_PANEL:
break;
}
// the safety window that shows behind keyguard while keyguard is starting
return 14;
case TYPE_STATUS_BAR_SUB_PANEL:
+ case TYPE_KEYGUARD_PANEL:
return 15;
case TYPE_STATUS_BAR:
return 16;
android.Manifest.permission.STATUS_BAR_SERVICE,
"PhoneWindowManager");
break;
+ case TYPE_KEYGUARD_PANEL:
+ mContext.enforceCallingOrSelfPermission(
+ org.cyanogenmod.platform.internal.Manifest.permission.THIRD_PARTY_KEYGUARD,
+ "PhoneWindowManager");
+ if (mKeyguardPanel != null) {
+ return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
+ }
+ mKeyguardPanel = win;
+ break;
case TYPE_KEYGUARD_SCRIM:
if (mKeyguardScrim != null) {
return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
} else if (mKeyguardScrim == win) {
Log.v(TAG, "Removing keyguard scrim");
mKeyguardScrim = null;
- } if (mNavigationBar == win) {
+ } else if (mNavigationBar == win) {
mNavigationBar = null;
mNavigationBarController.setWindow(null);
+ } else if (mKeyguardPanel == win) {
+ mKeyguardPanel = null;
}
}
if (isAlarmBoot && (keyCode == KeyEvent.KEYCODE_HOME
|| keyCode == KeyEvent.KEYCODE_SEARCH
|| keyCode == KeyEvent.KEYCODE_MENU
- || keyCode == KeyEvent.KEYCODE_APP_SWITCH)) {
+ || keyCode == KeyEvent.KEYCODE_APP_SWITCH
+ || keyCode == KeyEvent.KEYCODE_BACK)) {
return -1;
}
}
return -1;
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
- if (CMSettings.Secure.getInt(mContext.getContentResolver(),
+ if (unpinActivity(true) || CMSettings.Secure.getInt(mContext.getContentResolver(),
CMSettings.Secure.KILL_APP_LONGPRESS_BACK, 0) == 1) {
if (down && repeatCount == 0) {
mHandler.postDelayed(mBackLongPress, mBackKillTimeout);
return 0;
}
+ private boolean unpinActivity(boolean checkOnly) {
+ if (!hasNavigationBar()) {
+ try {
+ if (ActivityManagerNative.getDefault().isInLockTaskMode()) {
+ if (!checkOnly) {
+ ActivityManagerNative.getDefault().stopSystemLockTaskMode();
+ }
+ return true;
+ }
+ } catch (RemoteException e) {
+ // ignore
+ }
+ }
+ return false;
+ }
+
/** {@inheritDoc} */
@Override
public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0;
- // Specific device key handling
- if (mDeviceKeyHandler != null) {
- try {
- // The device only should consume known keys.
- if (mDeviceKeyHandler.handleKeyEvent(event)) {
- return null;
- }
- } catch (Exception e) {
- Slog.w(TAG, "Could not dispatch event to device key handler", e);
- }
- }
-
// Check for fallback actions specified by the key character map.
final FallbackAction fallbackAction;
if (initialDown) {
// gets everything, period.
if (attrs.type == TYPE_STATUS_BAR_PANEL
|| attrs.type == TYPE_STATUS_BAR_SUB_PANEL
- || attrs.type == TYPE_VOLUME_OVERLAY) {
+ || attrs.type == TYPE_VOLUME_OVERLAY
+ || attrs.type == TYPE_KEYGUARD_PANEL) {
pf.left = df.left = of.left = cf.left = hasNavBar
? mDockLeft : mUnrestrictedScreenLeft;
pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop;
mContext.sendBroadcastAsUser(errorIntent, UserHandle.CURRENT);
}
+ private void setVolumeWakeTriggered(final int keyCode, boolean triggered) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ mVolumeDownWakeTriggered = triggered;
+ break;
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ mVolumeUpWakeTriggered = triggered;
+ break;
+ case KeyEvent.KEYCODE_VOLUME_MUTE:
+ mVolumeMuteWakeTriggered = triggered;
+ break;
+ default:
+ Log.w(TAG, "setVolumeWakeTriggered: unexpected keyCode=" + keyCode);
+ }
+ }
+
+ private boolean getVolumeWakeTriggered(final int keyCode) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ return mVolumeDownWakeTriggered;
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ return mVolumeUpWakeTriggered;
+ case KeyEvent.KEYCODE_VOLUME_MUTE:
+ return mVolumeMuteWakeTriggered;
+ default:
+ Log.w(TAG, "getVolumeWakeTriggered: unexpected keyCode=" + keyCode);
+ return false;
+ }
+ }
+
/** {@inheritDoc} */
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
&& (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
&& event.getRepeatCount() == 0;
+ // Specific device key handling
+ if (mDeviceKeyHandler != null) {
+ try {
+ // The device only should consume known keys.
+ if (mDeviceKeyHandler.handleKeyEvent(event)) {
+ return 0;
+ }
+ } catch (Exception e) {
+ Slog.w(TAG, "Could not dispatch event to device key handler", e);
+ }
+ }
+
// Handle special keys.
switch (keyCode) {
case KeyEvent.KEYCODE_BACK: {
// Eat all down & up keys when using volume wake.
// This disables volume control, music control, and "beep" on key up.
if (isWakeKey && mVolumeWakeScreen) {
- mVolumeWakeTriggered = true;
+ setVolumeWakeTriggered(keyCode, true);
break;
- } else if (mVolumeWakeTriggered && !down) {
+ } else if (getVolumeWakeTriggered(keyCode) && !down) {
result &= ~ACTION_PASS_TO_USER;
- mVolumeWakeTriggered = false;
+ setVolumeWakeTriggered(keyCode, false);
break;
}
mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
mKeyguardDelegate.onSystemReady();
+ mCMHardware = CMHardwareManager.getInstance(mContext);
+ // Ensure observe happens in systemReady() since we need
+ // CMHardwareService to be up and running
+ mSettingsObserver.observe();
+
readCameraLensCoverState();
updateUiMode();
boolean bindKeyguardNow;