diff --git a/api/current.xml b/api/current.xml index c7cddac27f1b5..9173afd5339d8 100644 --- a/api/current.xml +++ b/api/current.xml @@ -161089,6 +161089,17 @@ visibility="public" > + + + + 0 diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index 9ac832b31e7b7..593edc8865913 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -61,7 +61,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' // is properly propagated through your change. Not doing so will result in a loss of user // settings. - private static final int DATABASE_VERSION = 59; + private static final int DATABASE_VERSION = 60; private Context mContext; @@ -775,6 +775,23 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 59; } + if (upgradeVersion == 59) { + // Persistence for the rotation lock feature. + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT INTO system(name,value)" + + " VALUES(?,?);"); + loadBooleanSetting(stmt, Settings.System.USER_ROTATION, + R.integer.def_user_rotation); // should be zero degrees + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } + upgradeVersion = 60; + } + // *** Remember to update DATABASE_VERSION above! if (upgradeVersion != currentVersion) { diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png b/packages/SystemUI/res/drawable-land-mdpi/ic_sysbar_rotate_off.png similarity index 100% rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png rename to packages/SystemUI/res/drawable-land-mdpi/ic_sysbar_rotate_off.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off.png new file mode 100644 index 0000000000000..9e6793ad434a5 Binary files /dev/null and b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off.png differ diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png b/packages/SystemUI/res/drawable-port-mdpi/ic_sysbar_rotate_off.png similarity index 100% rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png rename to packages/SystemUI/res/drawable-port-mdpi/ic_sysbar_rotate_off.png diff --git a/packages/SystemUI/res/values-land/strings.xml b/packages/SystemUI/res/values-land/strings.xml new file mode 100644 index 0000000000000..e05e36b585454 --- /dev/null +++ b/packages/SystemUI/res/values-land/strings.xml @@ -0,0 +1,23 @@ + + + + + Screen is now locked in landscape orientation. + diff --git a/packages/SystemUI/res/values-port/strings.xml b/packages/SystemUI/res/values-port/strings.xml new file mode 100644 index 0000000000000..d3ab67bb7863c --- /dev/null +++ b/packages/SystemUI/res/values-port/strings.xml @@ -0,0 +1,23 @@ + + + + + Screen is now locked in portrait orientation. + diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 701aa9ff15066..f34dc22a449d7 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -84,5 +84,11 @@ --> No recent applications. + + Screen will rotate automatically. + + Screen rotation is now locked. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java index a0f5be635ecca..b4a9d760cbe42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java @@ -55,6 +55,7 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.IWindowManager; import android.view.WindowManager; import android.view.WindowManagerImpl; import android.widget.Button; @@ -74,6 +75,8 @@ import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.cdma.EriInfo; import com.android.internal.telephony.cdma.TtyIntent; +import com.android.server.WindowManagerService; + import com.android.systemui.statusbar.*; import com.android.systemui.R; @@ -102,6 +105,8 @@ public class SystemPanel extends LinearLayout implements StatusBarPanel { private TextView mBatteryText; private TextView mSignalText; + private final IWindowManager mWM; + private final AudioManager mAudioManager; private final WifiManager mWifiManager; private final TelephonyManager mPhone; @@ -397,6 +402,11 @@ public class SystemPanel extends LinearLayout implements StatusBarPanel { public SystemPanel(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + // our mighty overlord + mWM = IWindowManager.Stub.asInterface( + ServiceManager.getService("window")); + + // get notified of phone state changes TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); @@ -437,6 +447,7 @@ public class SystemPanel extends LinearLayout implements StatusBarPanel { }); mSoundButton = (ImageButton)findViewById(R.id.sound); + mSoundButton.setAlpha(getSilentMode() ? 0x7F : 0xFF); mSoundButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { setSilentMode(!getSilentMode()); @@ -444,9 +455,22 @@ public class SystemPanel extends LinearLayout implements StatusBarPanel { } }); mOrientationButton = (ImageButton)findViewById(R.id.orientation); + mOrientationButton.setImageResource( + getAutoRotate() + ? R.drawable.ic_sysbar_rotate_on + : R.drawable.ic_sysbar_rotate_off); mOrientationButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - Toast.makeText(getContext(), "Orientation control not implemented; please adjust neck angle.", Toast.LENGTH_SHORT).show(); + setAutoRotate(!getAutoRotate()); + mOrientationButton.setImageResource( + getAutoRotate() + ? R.drawable.ic_sysbar_rotate_on + : R.drawable.ic_sysbar_rotate_off); + Toast.makeText(getContext(), + getAutoRotate() + ? R.string.toast_rotation_free + : R.string.toast_rotation_locked, + Toast.LENGTH_SHORT).show(); } }); @@ -709,4 +733,31 @@ public class SystemPanel extends LinearLayout implements StatusBarPanel { ? R.drawable.sysbar_toggle_bg_on : R.drawable.sysbar_toggle_bg_off); } + + void setAutoRotate(boolean rot) { + try { + ContentResolver cr = getContext().getContentResolver(); + if (rot) { + mWM.thawRotation(); + } else { + mWM.freezeRotation(); + } + } catch (android.os.RemoteException exc) { + } + } + + boolean getAutoRotate() { + ContentResolver cr = getContext().getContentResolver(); + return 1 == Settings.System.getInt(cr, + Settings.System.ACCELEROMETER_ROTATION, + 1); + } + + int getDisplayRotation() { + try { + return mWM.getRotation(); + } catch (android.os.RemoteException exc) { + return 0; + } + } } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index af1bf59c26f73..2f2f943401596 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -230,6 +230,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mLidOpenRotation; int mCarDockRotation; int mDeskDockRotation; + + int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE; + int mUserRotation = Surface.ROTATION_0; + boolean mCarDockEnablesAccelerometer; boolean mDeskDockEnablesAccelerometer; int mLidKeyboardAccessibility; @@ -335,6 +339,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.ACCELEROMETER_ROTATION), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.USER_ROTATION), false, this); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_OFF_TIMEOUT), false, this); resolver.registerContentObserver(Settings.System.getUriFor( @@ -678,10 +684,20 @@ public class PhoneWindowManager implements WindowManagerPolicy { "fancy_rotation_anim", 0) != 0 ? 0x80 : 0; int accelerometerDefault = Settings.System.getInt(resolver, Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION); + + // set up rotation lock state + mUserRotationMode = (mAccelerometerDefault == 0) + ? WindowManagerPolicy.USER_ROTATION_LOCKED + : WindowManagerPolicy.USER_ROTATION_FREE; + mUserRotation = Settings.System.getInt(resolver, + Settings.System.USER_ROTATION, + Surface.ROTATION_0); + if (mAccelerometerDefault != accelerometerDefault) { mAccelerometerDefault = accelerometerDefault; updateOrientationListenerLp(); } + if (mSystemReady) { int pointerLocation = Settings.System.getInt(resolver, Settings.System.POINTER_LOCATION, 0); @@ -2280,6 +2296,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { return mCarDockRotation; } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) { return mDeskDockRotation; + } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { + return mUserRotation; } else { if (useSensorForOrientationLp(orientation)) { return mOrientationListener.getCurrentRotation(lastRotation); @@ -2323,6 +2341,26 @@ public class PhoneWindowManager implements WindowManagerPolicy { return sensorRotation == mPortraitRotation || sensorRotation == mUpsideDownRotation; } + + // User rotation: to be used when all else fails in assigning an orientation to the device + public void setUserRotationMode(int mode, int rot) { + ContentResolver res = mContext.getContentResolver(); + mUserRotationMode = mode; + if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) { + mUserRotation = rot; + Settings.System.putInt(res, + Settings.System.ACCELEROMETER_ROTATION, + 0); + Settings.System.putInt(res, + Settings.System.USER_ROTATION, + rot); + } else { + Settings.System.putInt(res, + Settings.System.ACCELEROMETER_ROTATION, + 1); + } + } + public boolean detectSafeMode() { try { int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU); diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index dbc7f480ce49c..41b3da681cf74 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -4842,6 +4842,26 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void freezeRotation() { + if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, + "setRotation()")) { + throw new SecurityException("Requires SET_ORIENTATION permission"); + } + + mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation); + setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0); + } + + public void thawRotation() { + if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, + "setRotation()")) { + throw new SecurityException("Requires SET_ORIENTATION permission"); + } + + mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0); + setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0); + } + public void setRotation(int rotation, boolean alwaysSendConfiguration, int animFlags) { if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,