diff options
| -rw-r--r-- | core/java/com/android/internal/view/RotationPolicy.java | 4 | ||||
| -rwxr-xr-x | core/res/res/values/strings.xml | 3 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 4 | ||||
| -rw-r--r-- | services/java/com/android/server/RotationSwitchObserver.java | 163 | ||||
| -rw-r--r-- | services/java/com/android/server/SystemServer.java | 22 |
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); |
