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,