summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/view/RotationPolicy.java4
-rwxr-xr-xcore/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml4
-rw-r--r--services/java/com/android/server/RotationSwitchObserver.java163
-rw-r--r--services/java/com/android/server/SystemServer.java22
5 files changed, 194 insertions, 2 deletions
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 95130c8..a86c323 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -58,7 +58,9 @@ public final class RotationPolicy {
return isRotationLockToggleSupported(context) &&
Settings.System.getIntForUser(context.getContentResolver(),
Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0,
- UserHandle.USER_CURRENT) == 0;
+ UserHandle.USER_CURRENT) == 0 &&
+ !context.getResources().getBoolean(com.android
+ .internal.R.bool.config_hasRotationLockSwitch);
}
/**
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b571519..d590f67 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4055,4 +4055,7 @@
<!-- label for item that opens the profile choosing dialog -->
<string name="global_action_choose_profile">Profile</string>
+ <!-- Hardware Rotation lock string -->
+ <string name="toast_rotation_unlocked">Display rotation unlocked</string>
+ <string name="toast_rotation_locked">Display rotation locked</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c1131f7..2e63708 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1883,4 +1883,8 @@
<!-- Lock screen always show battery -->
<java-symbol type="string" name="lockscreen_discharging" />
+ <!-- HW rotation lock -->
+ <java-symbol type="string" name="toast_rotation_unlocked" />
+ <java-symbol type="string" name="toast_rotation_locked" />
+
</resources>
diff --git a/services/java/com/android/server/RotationSwitchObserver.java b/services/java/com/android/server/RotationSwitchObserver.java
new file mode 100644
index 0000000..a191433
--- /dev/null
+++ b/services/java/com/android/server/RotationSwitchObserver.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ */
+
+package com.android.server;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.UEventObserver;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+
+import android.widget.Toast;
+import android.view.IWindowManager;
+import android.os.ServiceManager;
+import android.os.RemoteException;
+import android.os.AsyncTask;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+/**
+ * <p>RotationLockObserver monitors for rotation lock switch state
+ */
+class RotationSwitchObserver extends UEventObserver {
+ private static final String TAG = RotationSwitchObserver.class
+ .getSimpleName();
+ private static final boolean LOG = true;
+
+ private static final String LOCK_UEVENT_MATCH =
+ "DEVPATH=/devices/virtual/switch/rotationlock";
+ private static final String LOCK_STATE_PATH =
+ "/sys/class/switch/rotationlock/state";
+
+ private static final int MSG_LOCK_STATE = 0;
+
+ private int mLockState;
+ private int mPreviousLockState;
+
+ private boolean mSystemReady;
+
+ private final Context mContext;
+
+ private boolean mAutoRotation;
+
+ public RotationSwitchObserver(Context context) {
+ mContext = context;
+ init(); // set initial status
+
+ startObserving(LOCK_UEVENT_MATCH);
+ }
+
+ @Override
+ public void onUEvent(UEventObserver.UEvent event) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Slog.v(TAG, "Switch UEVENT: " + event.toString());
+ }
+
+ synchronized (this) {
+ try {
+ int newState = Integer.parseInt(event.get("SWITCH_STATE"));
+ if (newState != mLockState) {
+ mPreviousLockState = mLockState;
+ mLockState = newState;
+ if (mSystemReady) {
+ update();
+ }
+ }
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "Could not parse switch state from event "
+ + event);
+ }
+ }
+ }
+
+ private final void init() {
+ char[] buffer = new char[1024];
+
+ try {
+ FileReader file = new FileReader(LOCK_STATE_PATH);
+ int len = file.read(buffer, 0, 1024);
+ file.close();
+ mPreviousLockState = mLockState =
+ Integer.valueOf((new String(buffer, 0, len)).trim());
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "This kernel does not have rotation switch support");
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "" , e);
+ } catch (IOException e) {
+ Slog.e(TAG, "" , e);
+ }
+ }
+
+ void systemReady() {
+ synchronized (this) {
+ mSystemReady = true;
+ }
+ }
+
+ private final void update() {
+ mHandler.sendEmptyMessage(MSG_LOCK_STATE);
+ }
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_LOCK_STATE:
+ synchronized (this) {
+ boolean autoRotate = mLockState == 0;
+ int toastId = autoRotate
+ ? com.android.internal.R.string.toast_rotation_unlocked
+ : com.android.internal.R.string.toast_rotation_locked;
+
+ setAutoRotation(autoRotate);
+
+ Toast.makeText(mContext, mContext.getString(toastId),
+ Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+ }
+ };
+
+ private void setAutoRotation(final boolean autorotate) {
+ mAutoRotation = autorotate;
+ AsyncTask.execute(new Runnable() {
+ public void run() {
+ try {
+ IWindowManager wm = IWindowManager.Stub.asInterface(
+ ServiceManager
+ .getService(Context.WINDOW_SERVICE));
+ if (autorotate) {
+ wm.thawRotation();
+ } else {
+ wm.freezeRotation(-1);
+ }
+ } catch (RemoteException exc) {
+ Log.w(TAG, "Unable to save auto-rotate setting");
+ }
+ }
+ });
+ }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a2d8355..9decd62 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -160,6 +160,7 @@ class ServerThread extends Thread {
WindowManagerService wm = null;
BluetoothManagerService bluetooth = null;
DockObserver dock = null;
+ RotationSwitchObserver rotateSwitch = null;
UsbService usb = null;
SerialService serial = null;
TwilightService twilight = null;
@@ -360,6 +361,9 @@ class ServerThread extends Thread {
Slog.e("System", "************ Failure starting core service", e);
}
+ boolean hasRotationLock = context.getResources().getBoolean(com.android
+ .internal.R.bool.config_hasRotationLockSwitch);
+
DevicePolicyManagerService devicePolicy = null;
StatusBarManagerService statusBar = null;
InputMethodManagerService imm = null;
@@ -659,7 +663,17 @@ class ServerThread extends Thread {
}
try {
- Slog.i(TAG, "Wired Accessory Manager");
+ if (hasRotationLock) {
+ Slog.i(TAG, "Rotation Switch Observer");
+ // Listen for switch changes
+ rotateSwitch = new RotationSwitchObserver(context);
+ }
+ } catch (Throwable e) {
+ reportWtf("starting RotationSwitchObserver", e);
+ }
+
+ try {
+ Slog.i(TAG, "Wired Accessory Observer");
// Listen for wired headset changes
inputManager.setWiredAccessoryCallbacks(
new WiredAccessoryManager(context, inputManager));
@@ -892,6 +906,7 @@ class ServerThread extends Thread {
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
final DockObserver dockF = dock;
+ final RotationSwitchObserver rotateSwitchF = rotateSwitch;
final UsbService usbF = usb;
final ThrottleService throttleF = throttle;
final TwilightService twilightF = twilight;
@@ -956,6 +971,11 @@ class ServerThread extends Thread {
reportWtf("making Dock Service ready", e);
}
try {
+ if (rotateSwitchF != null) rotateSwitchF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Rotation Switch Service ready", e);
+ }
+ try {
if (usbF != null) usbF.systemReady();
} catch (Throwable e) {
reportWtf("making USB Service ready", e);