summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYorke Lee <yorkelee@google.com>2015-07-24 12:27:46 -0700
committerYorke Lee <yorkelee@google.com>2015-07-24 12:52:02 -0700
commit5f6c901ad062cd7d88db09b555e28ee354ca66c6 (patch)
tree204db626234e773f39461181ba0c0b8a3388f428 /src
parenta0018a3f788f381313ee5c5f2b15ddce8d7ec5d1 (diff)
Protect against lack of WRITE_SYSTEM_SETTINGS AppOp
Guard the following entry points with checks against the AppOp 1) Launch of SoundSettingsFragment Fallback: Send to system sound settings instead 2) onResume of SoundSettingsFragment (this can happen if the AppOp is toggled by the user in the background) Fallback: Return to main Dialer settings instead 3) Toggling of various perferences (this can happen in monkey tests) Fallback: Show toast, ignore settings chance Bug: 22660372 Change-Id: Ief5d74166d35a9718ea664f378f6930e777f2923
Diffstat (limited to 'src')
-rw-r--r--src/com/android/dialer/settings/DefaultRingtonePreference.java12
-rw-r--r--src/com/android/dialer/settings/DialerSettingsActivity.java34
-rw-r--r--src/com/android/dialer/settings/SoundSettingsFragment.java27
3 files changed, 64 insertions, 9 deletions
diff --git a/src/com/android/dialer/settings/DefaultRingtonePreference.java b/src/com/android/dialer/settings/DefaultRingtonePreference.java
index c12e7175a..f2648cb66 100644
--- a/src/com/android/dialer/settings/DefaultRingtonePreference.java
+++ b/src/com/android/dialer/settings/DefaultRingtonePreference.java
@@ -16,12 +16,17 @@
package com.android.dialer.settings;
+import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.RingtonePreference;
import android.util.AttributeSet;
+import android.widget.Toast;
+
+import com.android.contacts.common.util.PermissionsUtil;
+import com.android.dialer.R;
/**
* RingtonePreference which doesn't show default ringtone setting.
@@ -44,6 +49,13 @@ public class DefaultRingtonePreference extends RingtonePreference {
@Override
protected void onSaveRingtone(Uri ringtoneUri) {
+ if (!PermissionsUtil.hasAppOp(getContext(), AppOpsManager.OPSTR_WRITE_SETTINGS)) {
+ Toast.makeText(
+ getContext(),
+ getContext().getResources().getString(R.string.toast_cannot_write_system_settings),
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
RingtoneManager.setActualDefaultRingtoneUri(getContext(), getRingtoneType(), ringtoneUri);
}
diff --git a/src/com/android/dialer/settings/DialerSettingsActivity.java b/src/com/android/dialer/settings/DialerSettingsActivity.java
index d54053b40..abf854c08 100644
--- a/src/com/android/dialer/settings/DialerSettingsActivity.java
+++ b/src/com/android/dialer/settings/DialerSettingsActivity.java
@@ -1,23 +1,22 @@
package com.android.dialer.settings;
-import com.google.common.collect.Lists;
-
-import android.content.ComponentName;
+import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
-import android.os.UserHandle;
+import android.os.Process;
import android.os.UserManager;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
-import android.preference.PreferenceActivity.Header;
+import android.provider.Settings;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
-import android.text.TextUtils;
+import android.util.Log;
import android.view.MenuItem;
+import android.widget.Toast;
-import com.android.dialer.DialtactsActivity;
+import com.android.contacts.common.util.PermissionsUtil;
import com.android.dialer.R;
import java.util.List;
@@ -26,8 +25,6 @@ public class DialerSettingsActivity extends PreferenceActivity {
protected SharedPreferences mPreferences;
- private static final int OWNER_HANDLE_ID = 0;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -44,6 +41,7 @@ public class DialerSettingsActivity extends PreferenceActivity {
Header soundSettingsHeader = new Header();
soundSettingsHeader.titleRes = R.string.sounds_and_vibration_title;
soundSettingsHeader.fragment = SoundSettingsFragment.class.getName();
+ soundSettingsHeader.id = R.id.settings_header_sounds_and_vibration;
target.add(soundSettingsHeader);
Header quickResponseSettingsHeader = new Header();
@@ -91,6 +89,24 @@ public class DialerSettingsActivity extends PreferenceActivity {
}
@Override
+ public void onHeaderClick(Header header, int position) {
+ if (header.id == R.id.settings_header_sounds_and_vibration) {
+ // If we don't have the AppOp to write to system settings, go to system sound settings
+ // instead. Otherwise, perform the super implementation (which launches our own
+ // preference fragment.
+ if (!PermissionsUtil.hasAppOp(this, AppOpsManager.OPSTR_WRITE_SETTINGS)) {
+ Toast.makeText(
+ this,
+ getResources().getString(R.string.toast_cannot_write_system_settings),
+ Toast.LENGTH_SHORT).show();
+ startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS));
+ return;
+ }
+ }
+ super.onHeaderClick(header, position);
+ }
+
+ @Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
diff --git a/src/com/android/dialer/settings/SoundSettingsFragment.java b/src/com/android/dialer/settings/SoundSettingsFragment.java
index 7fc9394f8..1dedcaaff 100644
--- a/src/com/android/dialer/settings/SoundSettingsFragment.java
+++ b/src/com/android/dialer/settings/SoundSettingsFragment.java
@@ -16,7 +16,9 @@
package com.android.dialer.settings;
+import android.app.AppOpsManager;
import android.content.Context;
+import android.content.Intent;
import android.media.RingtoneManager;
import android.os.Bundle;
import android.os.Handler;
@@ -30,7 +32,10 @@ import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
+import android.view.MenuItem;
+import android.widget.Toast;
+import com.android.contacts.common.util.PermissionsUtil;
import com.android.dialer.R;
import com.android.phone.common.util.SettingsUtil;
@@ -127,6 +132,13 @@ public class SoundSettingsFragment extends PreferenceFragment
public void onResume() {
super.onResume();
+ if (!PermissionsUtil.hasAppOp(getContext(), AppOpsManager.OPSTR_WRITE_SETTINGS)) {
+ // If the user launches this setting fragment, then toggles the WRITE_SYSTEM_SETTINGS
+ // AppOp, then close the fragment since there is nothing useful to do.
+ getActivity().onBackPressed();
+ return;
+ }
+
if (mVibrateWhenRinging != null) {
mVibrateWhenRinging.setChecked(shouldVibrateWhenRinging());
}
@@ -143,6 +155,14 @@ public class SoundSettingsFragment extends PreferenceFragment
*/
@Override
public boolean onPreferenceChange(Preference preference, Object objValue) {
+ if (!PermissionsUtil.hasAppOp(getContext(), AppOpsManager.OPSTR_WRITE_SETTINGS)) {
+ // A user shouldn't be able to get here, but this protects against monkey crashes.
+ Toast.makeText(
+ getContext(),
+ getResources().getString(R.string.toast_cannot_write_system_settings),
+ Toast.LENGTH_SHORT).show();
+ return true;
+ }
if (preference == mVibrateWhenRinging) {
boolean doVibrate = (Boolean) objValue;
Settings.System.putInt(getActivity().getContentResolver(),
@@ -161,6 +181,13 @@ public class SoundSettingsFragment extends PreferenceFragment
*/
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ if (!PermissionsUtil.hasAppOp(getContext(), AppOpsManager.OPSTR_WRITE_SETTINGS)) {
+ Toast.makeText(
+ getContext(),
+ getResources().getString(R.string.toast_cannot_write_system_settings),
+ Toast.LENGTH_SHORT).show();
+ return true;
+ }
if (preference == mPlayDtmfTone) {
Settings.System.putInt(getActivity().getContentResolver(),
Settings.System.DTMF_TONE_WHEN_DIALING,