Merge "Rotation lock."

This commit is contained in:
Daniel Sandler
2010-11-04 14:15:56 -07:00
committed by Android (Google) Code Review
15 changed files with 234 additions and 2 deletions

View File

@@ -161089,6 +161089,17 @@
visibility="public"
>
</field>
<field name="USER_ROTATION"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;user_rotation&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="USE_GOOGLE_MAIL"
type="java.lang.String"
transient="false"

View File

@@ -1572,6 +1572,16 @@ public final class Settings {
*/
public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
/**
* Default screen rotation when no other policy applies.
* When {@link #ACCELEROMETER_ROTATION} is zero and no on-screen Activity expresses a
* preference, this rotation value will be used. Must be one of the
* {@link android.view.Surface#ROTATION_0 Surface rotation constants}.
*
* @see Display#getRotation
*/
public static final String USER_ROTATION = "user_rotation";
/**
* Whether the audible DTMF tones are played by the dialer when dialing. The value is
* boolean (1 or 0).
@@ -1806,6 +1816,7 @@ public final class Settings {
TIME_12_24,
DATE_FORMAT,
ACCELEROMETER_ROTATION,
USER_ROTATION,
DTMF_TONE_WHEN_DIALING,
DTMF_TONE_TYPE_WHEN_DIALING,
EMERGENCY_TONE,

View File

@@ -156,4 +156,17 @@ interface IWindowManager
* calls back when it changes.
*/
int watchRotation(IRotationWatcher watcher);
/**
* Lock the device orientation to the current rotation. Sensor input will
* be ignored until thawRotation() is called.
* @hide
*/
void freezeRotation();
/**
* Release the orientation lock imposed by freezeRotation().
* @hide
*/
void thawRotation();
}

View File

@@ -362,6 +362,13 @@ public interface WindowManagerPolicy {
* modify the rotation.
*/
public final int USE_LAST_ROTATION = -1000;
/** When not otherwise specified by the activity's screenOrientation, rotation should be
* determined by the system (that is, using sensors). */
public final int USER_ROTATION_FREE = 0;
/** When not otherwise specified by the activity's screenOrientation, rotation is set by
* the user. */
public final int USER_ROTATION_LOCKED = 1;
/**
* Perform initialization of the policy.
@@ -787,4 +794,14 @@ public interface WindowManagerPolicy {
* Return false to disable key repeat events from being generated.
*/
public boolean allowKeyRepeat();
/**
* Inform the policy that the user has chosen a preferred orientation ("rotation lock").
*
* @param mode One of {@link WindowManagerPolicy#USER_ROTATION_LOCKED} or
* {@link * WindowManagerPolicy#USER_ROTATION_FREE}.
* @param rotation One of {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
* {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
*/
public void setUserRotationMode(int mode, int rotation);
}

View File

@@ -103,4 +103,6 @@
0x120016=0x03050601:0x03040501:0x03030401:0x03020301:0x03070301:0x03010301:0x03000301;
</string>
<!-- Default for Settings.System.USER_ROTATION -->
<integer name="def_user_rotation">0</integer>
</resources>

View File

@@ -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) {

View File

Before

Width:  |  Height:  |  Size: 595 B

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

View File

Before

Width:  |  Height:  |  Size: 616 B

After

Width:  |  Height:  |  Size: 616 B

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/**
* Copyright (c) 2010, 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.
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Rotation lock toast text: shown when rotation lock is turned on in landscape orientation.
-->
<string name="toast_rotation_locked">Screen is now locked in landscape orientation.</string>
</resources>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/**
* Copyright (c) 2010, 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.
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Rotation lock toast text: shown when rotation lock is turned on in portrait orientation.
-->
<string name="toast_rotation_locked">Screen is now locked in portrait orientation.</string>
</resources>

View File

@@ -84,5 +84,11 @@
-->
<string name="recent_tasks_empty">No recent applications.</string>
<!-- Rotation lock toast text: shown when rotation lock is turned off (and the screen will
auto-rotate based on the accelerometer). -->
<string name="toast_rotation_free">Screen will rotate automatically.</string>
<!-- Rotation lock toast text: shown when rotation lock is turned on and the orientation is
undefined. -->
<string name="toast_rotation_locked">Screen rotation is now locked.</string>
</resources>

View File

@@ -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;
}
}
}

View File

@@ -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);

View File

@@ -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,