Use a broadcast receiver instead of a settings observer.

Settings observer doesn't work if a setting is modified in another
process, hence we instead register a receiver which listens for a signal
from the settings process that the rotation preference has changed.

Change-Id: I570e3c67bb64a32347e84ca00a8ac31d9010eac3
This commit is contained in:
Rahul Chaturvedi
2015-06-01 21:26:41 -04:00
parent 091f0ffd92
commit 799aa04f2f
5 changed files with 67 additions and 29 deletions

View File

@@ -44,6 +44,10 @@
android:name="com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS"
android:protectionLevel="signature"
/>
<permission
android:name="com.android.launcher3.permission.RECEIVE_UPDATE_ORIENTATION_BROADCASTS"
android:protectionLevel="signature"
/>
<permission
android:name="com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST"
android:protectionLevel="signatureOrSystem" />
@@ -62,6 +66,7 @@
<uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher3.permission.WRITE_SETTINGS" />
<uses-permission android:name="com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS" />
<uses-permission android:name="com.android.launcher3.permission.RECEIVE_UPDATE_ORIENTATION_BROADCASTS" />
<uses-permission android:name="com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST" />
<application
@@ -152,7 +157,8 @@
<activity
android:name="com.android.launcher3.SettingsActivity"
android:label="@string/settings_button_text"
android:autoRemoveFromRecents="true">
android:autoRemoveFromRecents="true"
android:process=":settings_process">
</activity>
<!-- Debugging tools -->

View File

@@ -27,6 +27,9 @@
<!-- Permission to receive the com.android.launcher3.action.LAUNCH intent -->
<string name="receive_launch_broadcasts_permission" translatable="false">com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS</string>
<!-- Permission to receive the com.android.launcher3.SCREEN_ORIENTATION_PREF_CHANGED intent -->
<string name="receive_update_orientation_broadcasts_permission" translatable="false">com.android.launcher3.permission.RECEIVE_UPDATE_ORIENTATION_BROADCASTS</string>
<!-- Permission to receive the com.android.launcher3.action.FIRST_LOAD_COMPLETE intent -->
<string name="receive_first_load_broadcast_permission" translatable="false">com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST</string>

View File

@@ -403,22 +403,34 @@ public class Launcher extends Activity
FocusIndicatorView mFocusHandler;
@Thunk boolean mRotationEnabled = false;
private boolean mPreferenceObserverRegistered = false;
private boolean mScreenOrientationSettingReceiverRegistered = false;
final private SharedPreferences.OnSharedPreferenceChangeListener mSettingsObserver =
new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (Utilities.ALLOW_ROTATION_PREFERENCE_KEY.equals(key)) {
if (mRotationEnabled = sharedPreferences.getBoolean(
Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false)) {
unlockScreenOrientation(true);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
final private BroadcastReceiver mScreenOrientationSettingReceiver =
new BroadcastReceiver() {
@Thunk Runnable mUpdateOrientationRunnable = new Runnable() {
public void run() {
setOrientation();
}
};
@Override
public void onReceive(Context context, Intent intent) {
mRotationEnabled = intent.getBooleanExtra(
Utilities.SCREEN_ROTATION_SETTING_EXTRA, false);
if (!waitUntilResume(mUpdateOrientationRunnable, true)) {
setOrientation();
}
}
}
};
@Thunk void setOrientation() {
if (mRotationEnabled) {
unlockScreenOrientation(true);
} else {
setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
};
}
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -520,16 +532,18 @@ public class Launcher extends Activity
// In case we are on a device with locked rotation, we should look at preferences to check
// if the user has specifically allowed rotation.
if (!mRotationEnabled) {
getSharedPreferences(LauncherFiles.ROTATION_PREF_FILE,
Context.MODE_MULTI_PROCESS).registerOnSharedPreferenceChangeListener(
mSettingsObserver);
mPreferenceObserverRegistered = true;
String updateOrientationBroadcastPermission = getResources().getString(
R.string.receive_update_orientation_broadcasts_permission);
registerReceiver(mScreenOrientationSettingReceiver,
new IntentFilter(Utilities.SCREEN_ROTATION_SETTING_INTENT),
updateOrientationBroadcastPermission, null);
mScreenOrientationSettingReceiverRegistered = true;
mRotationEnabled = Utilities.isAllowRotationPrefEnabled(getApplicationContext());
}
// On large interfaces, or on devices that a user has specifically enabled screen rotation,
// we want the screen to auto-rotate based on the current orientation
unlockScreenOrientation(true);
setOrientation();
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onCreate(savedInstanceState);
@@ -2016,11 +2030,9 @@ public class Launcher extends Activity
public void onDestroy() {
super.onDestroy();
if (mPreferenceObserverRegistered) {
getSharedPreferences(LauncherFiles.ROTATION_PREF_FILE,
Context.MODE_MULTI_PROCESS).unregisterOnSharedPreferenceChangeListener(
mSettingsObserver);
mPreferenceObserverRegistered = false;
if (mScreenOrientationSettingReceiverRegistered) {
unregisterReceiver(mScreenOrientationSettingReceiver);
mScreenOrientationSettingReceiverRegistered = false;
}
// Remove all pending runnables
@@ -3663,7 +3675,7 @@ public class Launcher extends Activity
*
* @return {@code true} if we are currently paused. The caller might be able to skip some work
*/
private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {
@Thunk boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {
if (mPaused) {
if (LOGD) Log.d(TAG, "Deferring update until onResume");
if (deletePreviousRunnables) {

View File

@@ -18,12 +18,14 @@ package com.android.launcher3;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
/**
* Settings activity for Launcher. Currently implements the following setting:
* LockToPortrait
* Settings activity for Launcher. Currently implements the following setting: Allow rotation
*/
public class SettingsActivity extends Activity {
@Override
@@ -41,13 +43,25 @@ public class SettingsActivity extends Activity {
*/
@SuppressWarnings("WeakerAccess")
public static class LauncherSettingsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE);
getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);
getPreferenceManager().setSharedPreferencesName(LauncherFiles.ROTATION_PREF_FILE);
addPreferencesFromResource(R.xml.launcher_preferences);
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
boolean allowRotation = getPreferenceManager().getSharedPreferences().getBoolean(
Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false);
Intent rotationSetting = new Intent(Utilities.SCREEN_ROTATION_SETTING_INTENT);
String launchBroadcastPermission = getResources().getString(
R.string.receive_update_orientation_broadcasts_permission);
rotationSetting.putExtra(Utilities.SCREEN_ROTATION_SETTING_EXTRA, allowRotation);
getActivity().sendBroadcast(rotationSetting, launchBroadcastPermission);
return true;
}
}
}

View File

@@ -93,6 +93,9 @@ public final class Utilities {
private static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
public static final String SCREEN_ROTATION_SETTING_INTENT =
"come.android.launcher3.SCREEN_ORIENTATION_PREF_CHANGED";
public static final String SCREEN_ROTATION_SETTING_EXTRA = "screenRotationPref";
public static boolean isPropertyEnabled(String propertyName) {
return Log.isLoggable(propertyName, Log.VERBOSE);