Initial checkin: optional permissions sample code

This is an initial checkin of a small demonstration program
which demonstrates how optional permissions can be used.
This app can do three things, which require permissions:

* Vibrate the device (android.permission.VIBRATE)
* Access the internet (android.permission.INTERNET)
* Get the phone number (android.permission.READ_PHONE_STATE)

At install time, this app has zero permissions.  However, the app can
request that the user grant permissions, based on pressing the "Prompt"
button. The user can then choose to allow or deny the permissions.

Known bugs and limitations:
* Once a permission is granted, it currently cannot be revoked by the
application nor the user.
* Due to the way it's implemented, the INTERNET permission requires a
restart of the application. That isn't in the sample code.
* Getting the device phone number doesn't make sense for a tablet.

This code was mostly written by klyubin@google.com with heavy
modification by myself.

Change-Id: I620db52c4a1f10ac7aa604ba34f77f7ec03af023
diff --git a/samples/OptionalPermissions/Android.mk b/samples/OptionalPermissions/Android.mk
new file mode 100644
index 0000000..758a7ea
--- /dev/null
+++ b/samples/OptionalPermissions/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := OptionalPermissions
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/samples/OptionalPermissions/AndroidManifest.xml b/samples/OptionalPermissions/AndroidManifest.xml
new file mode 100644
index 0000000..668de5b
--- /dev/null
+++ b/samples/OptionalPermissions/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.permdemo"
+    android:versionCode="3" android:versionName="0.03">
+
+    <uses-permission android:name="android.permission.VIBRATE" android:required="false" />
+    <uses-permission android:name="android.permission.INTERNET" android:required="false" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false" />
+
+    <application
+        android:label="@string/app_name"
+        android:allowBackup="true">
+
+        <activity android:name=".MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".PrefsActivity"/>
+    </application>
+
+</manifest>
+
diff --git a/samples/OptionalPermissions/res/values/strings.xml b/samples/OptionalPermissions/res/values/strings.xml
new file mode 100644
index 0000000..6688947
--- /dev/null
+++ b/samples/OptionalPermissions/res/values/strings.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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">
+
+    <!-- Name of the application -->
+    <string name="app_name">Permissions Demo</string>
+
+    <string name="category_vibrate">Vibrate</string>
+    <string name="category_internet">Internet</string>
+    <string name="category_phone_state">Phone state &amp; identity</string>
+    <string name="category_all">All</string>
+
+
+    <string name="vibrate_do_pref_title">Vibrate</string>
+    <string name="vibrate_do_pref_summary">Vibrate Android</string>
+    <string name="vibrate_prompt_pref_title">Prompt</string>
+    <string name="vibrate_prompt_pref_summary">Prompt for the VIBRATE permission</string>
+    <string name="vibrate_status_pref_title">Status</string>
+
+    <string name="internet_do_pref_title">Get time from google.com</string>
+    <string name="internet_do_pref_summary">Get current time from https://www.google.com</string>
+    <string name="internet_prompt_pref_title">Prompt</string>
+    <string name="internet_prompt_pref_summary">Prompt for the INTERNET permission</string>
+    <string name="internet_status_pref_title">Status</string>
+
+    <string name="phone_state_do_pref_title">Show phone number</string>
+    <string name="phone_state_do_pref_summary">Read this Android\'s phone number</string>
+    <string name="phone_state_prompt_pref_title">Prompt</string>
+    <string name="phone_state_prompt_pref_summary">Prompt for the READ_PHONE_STATE permission</string>
+    <string name="phone_state_status_pref_title">Status</string>
+
+    <string name="all_prompt_pref_title">Prompt</string>
+    <string name="all_prompt_pref_summary">Prompt for all of the above permissions</string>
+
+    <string name="toast_permission_grant_approved">Granted</string>
+    <string name="toast_permission_grant_denied">Denied</string>
+    <string name="toast_permission_grant_revoked">Revoked</string>
+
+    <string name="vibrate_feature_not_available">
+        Vibrate feature not available on this Android
+    </string>
+
+    <string name="telephony_feature_not_available">
+        Telephony feature not available on this Android
+    </string>
+
+    <string name="exception_dialog_title">Exception caught</string>
+
+    <string name="get_time_progress_dialog_message">Getting current time from Google&#8230;</string>
+
+    <string name="permission_status_granted">GRANTED</string>
+    <string name="permission_status_not_granted">NOT GRANTED</string>
+
+</resources>
diff --git a/samples/OptionalPermissions/res/xml/preference_headers.xml b/samples/OptionalPermissions/res/xml/preference_headers.xml
new file mode 100644
index 0000000..4f9a64d
--- /dev/null
+++ b/samples/OptionalPermissions/res/xml/preference_headers.xml
@@ -0,0 +1,19 @@
+<!-- Copyright (C) 2013 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.
+-->
+
+<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+    <header android:fragment="com.google.android.apps.permdemo.PrefsFragment"
+            android:title="Preferences" />
+</preference-headers>
diff --git a/samples/OptionalPermissions/res/xml/preferences.xml b/samples/OptionalPermissions/res/xml/preferences.xml
new file mode 100644
index 0000000..7fe6dd3
--- /dev/null
+++ b/samples/OptionalPermissions/res/xml/preferences.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <PreferenceCategory
+            android:title="@string/category_vibrate">
+        <Preference
+                android:key="vibrate_do"
+                android:persistent="false"
+                android:title="@string/vibrate_do_pref_title"
+                android:summary="@string/vibrate_do_pref_summary" />
+        <Preference
+                android:key="vibrate_prompt"
+                android:persistent="false"
+                android:title="@string/vibrate_prompt_pref_title"
+                android:summary="@string/vibrate_prompt_pref_summary" />
+        <Preference
+                android:key="vibrate_status"
+                android:persistent="false"
+                android:enabled="false"
+                android:shouldDisableView="false"
+                android:title="@string/vibrate_status_pref_title" />
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/category_internet">
+        <Preference
+                android:key="internet_do"
+                android:persistent="false"
+                android:title="@string/internet_do_pref_title"
+                android:summary="@string/internet_do_pref_summary" />
+        <Preference
+                android:key="internet_prompt"
+                android:persistent="false"
+                android:title="@string/internet_prompt_pref_title"
+                android:summary="@string/internet_prompt_pref_summary" />
+        <Preference
+                android:key="internet_status"
+                android:persistent="false"
+                android:enabled="false"
+                android:shouldDisableView="false"
+                android:title="@string/internet_status_pref_title" />
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/category_phone_state">
+        <Preference
+                android:key="phone_state_do"
+                android:persistent="false"
+                android:title="@string/phone_state_do_pref_title"
+                android:summary="@string/phone_state_do_pref_summary" />
+        <Preference
+                android:key="phone_state_prompt"
+                android:persistent="false"
+                android:title="@string/phone_state_prompt_pref_title"
+                android:summary="@string/phone_state_prompt_pref_summary" />
+        <Preference
+                android:key="phone_state_status"
+                android:persistent="false"
+                android:enabled="false"
+                android:shouldDisableView="false"
+                android:title="@string/phone_state_status_pref_title" />
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/category_all">
+        <Preference
+                android:key="all_prompt"
+                android:persistent="false"
+                android:title="@string/all_prompt_pref_title"
+                android:summary="@string/all_prompt_pref_summary" />
+    </PreferenceCategory>
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/samples/OptionalPermissions/src/com/example/android/permdemo/MainActivity.java b/samples/OptionalPermissions/src/com/example/android/permdemo/MainActivity.java
new file mode 100644
index 0000000..c68689c
--- /dev/null
+++ b/samples/OptionalPermissions/src/com/example/android/permdemo/MainActivity.java
@@ -0,0 +1,53 @@
+/*
+** Copyright 2013, 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.
+*/
+
+package com.example.android.permdemo;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class MainActivity extends Activity {
+    private static final int REQUEST_CODE_PREFS = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        startActivityForResult(
+                new Intent(this, PrefsActivity.class)
+                        .putExtra(PreferenceActivity.EXTRA_NO_HEADERS, true)
+                        .putExtra(
+                                PreferenceActivity.EXTRA_SHOW_FRAGMENT,
+                                PrefsFragment.class.getName()),
+                REQUEST_CODE_PREFS);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case REQUEST_CODE_PREFS:
+                // The PrefsActivity we launched has finished.
+                finish();
+                break;
+            default:
+                super.onActivityResult(requestCode, resultCode, data);
+                break;
+        }
+    }
+
+}
diff --git a/samples/OptionalPermissions/src/com/example/android/permdemo/PrefsActivity.java b/samples/OptionalPermissions/src/com/example/android/permdemo/PrefsActivity.java
new file mode 100644
index 0000000..eff4d28
--- /dev/null
+++ b/samples/OptionalPermissions/src/com/example/android/permdemo/PrefsActivity.java
@@ -0,0 +1,37 @@
+/*
+** Copyright 2013, 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.
+*/
+
+package com.example.android.permdemo;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+import java.util.List;
+
+public class PrefsActivity extends PreferenceActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    /**
+     * Populate the activity with the top-level headers.
+     */
+    @Override
+    public void onBuildHeaders(List<Header> target) {
+        loadHeadersFromResource(R.xml.preference_headers, target);
+    }
+}
diff --git a/samples/OptionalPermissions/src/com/example/android/permdemo/PrefsFragment.java b/samples/OptionalPermissions/src/com/example/android/permdemo/PrefsFragment.java
new file mode 100644
index 0000000..d37f6fa
--- /dev/null
+++ b/samples/OptionalPermissions/src/com/example/android/permdemo/PrefsFragment.java
@@ -0,0 +1,331 @@
+/*
+** Copyright 2013, 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.
+*/
+
+package com.example.android.permdemo;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.telephony.TelephonyManager;
+import android.text.format.DateFormat;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Date;
+
+public class PrefsFragment extends PreferenceFragment {
+
+    private static final int REQUEST_CODE_PROMPT_PERMISSIONS = 1;
+
+    private static final String[] ALL_PERMISSIONS = {
+            android.Manifest.permission.VIBRATE,
+            android.Manifest.permission.INTERNET,
+            android.Manifest.permission.READ_PHONE_STATE,
+    };
+
+    private Preference mVibrateStatusPreference;
+    private Preference mInternetStatusPreference;
+    private Preference mPhoneStateStatusPreference;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.preferences);
+
+        findPreference("vibrate_do").setOnPreferenceClickListener(
+                new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                onVibrateActionClicked();
+                return false;
+            }
+        });
+        findPreference("vibrate_prompt").setOnPreferenceClickListener(
+                new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                onPromptPermissionsClicked(android.Manifest.permission.VIBRATE);
+                return false;
+            }
+        });
+
+        findPreference("internet_do").setOnPreferenceClickListener(
+                new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                onInternetActionClicked();
+                return false;
+            }
+        });
+        findPreference("internet_prompt").setOnPreferenceClickListener(
+                new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                onPromptPermissionsClicked(android.Manifest.permission.INTERNET);
+                return false;
+            }
+        });
+
+        findPreference("phone_state_do").setOnPreferenceClickListener(
+                new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                onReadPhoneStateActionClicked();
+                return false;
+            }
+        });
+        findPreference("phone_state_prompt").setOnPreferenceClickListener(
+                new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                onPromptPermissionsClicked(android.Manifest.permission.READ_PHONE_STATE);
+                return false;
+            }
+        });
+
+        findPreference("all_prompt").setOnPreferenceClickListener(
+                new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                onPromptPermissionsClicked(ALL_PERMISSIONS);
+                return false;
+            }
+        });
+
+        mVibrateStatusPreference = findPreference("vibrate_status");
+        mInternetStatusPreference = findPreference("internet_status");
+        mPhoneStateStatusPreference = findPreference("phone_state_status");
+        refreshPermissionsStatus();
+    }
+
+    private void onVibrateActionClicked() {
+        Vibrator vibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
+        if (vibrator == null) {
+            Toast.makeText(
+                    getActivity(),
+                    R.string.vibrate_feature_not_available,
+                    Toast.LENGTH_LONG).show();
+            return;
+        }
+        try {
+            vibrator.vibrate(300);
+        } catch (Exception e) {
+            displayException(e);
+        }
+    }
+
+    private void onInternetActionClicked() {
+        new AsyncTask<Void, Void, Object>() {
+            private ProgressDialog mProgressDialog;
+
+            @Override
+            protected void onPreExecute() {
+                mProgressDialog = ProgressDialog.show(
+                        getActivity(),
+                        null,
+                        getString(R.string.get_time_progress_dialog_message),
+                        true, // indeterminate progress
+                        true, // cancelable
+                        new DialogInterface.OnCancelListener() {
+                            @Override
+                            public void onCancel(DialogInterface dialog) {
+                                // Cancel this AsyncTask
+                                cancel(true);
+                            }
+                        });
+                super.onPreExecute();
+            }
+
+            @Override
+            protected Object doInBackground(Void... params) {
+                HttpURLConnection connection = null;
+                Date date;
+                try {
+                    connection =
+                            (HttpURLConnection) new URL("https://www.google.com").openConnection();
+                    connection.setDefaultUseCaches(false);
+                    connection.setInstanceFollowRedirects(false);
+                    connection.setRequestMethod("HEAD");
+
+                    // Force the request to fail if there's no Internet connectivity
+                    connection.getResponseCode();
+
+                    long timeMillis = connection.getDate();
+                    if (timeMillis == 0) {
+                        throw new IOException("No time returned by the server");
+                    }
+                    date = new Date(timeMillis);
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                    return t;
+                } finally {
+                    if (connection != null) {
+                        connection.disconnect();
+                    }
+                }
+
+                return date;
+            }
+
+            @Override
+            protected void onPostExecute(Object result) {
+                if (getActivity().isFinishing()) {
+                    // The Activity is already finishing/finished -- no need to display the date
+                    return;
+                }
+
+                dismissProgressDialog();
+
+                if (result instanceof Throwable) {
+                    displayException((Throwable) result);
+                    return;
+                }
+
+                Date date = (Date) result;
+                String formattedDate = DateFormat.getDateFormat(getActivity()).format(date)
+                        + " " + DateFormat.getTimeFormat(getActivity()).format(date);
+                new AlertDialog.Builder(getActivity())
+                        .setMessage(formattedDate)
+                        .setPositiveButton(android.R.string.ok, null)
+                        .show();
+            }
+
+            @Override
+            protected void onCancelled() {
+                dismissProgressDialog();
+                super.onCancelled();
+            }
+
+            private void dismissProgressDialog() {
+                if (mProgressDialog != null) {
+                    mProgressDialog.dismiss();
+                    mProgressDialog = null;
+                }
+            }
+
+        }.execute((Void[]) null);
+    }
+
+    private void onReadPhoneStateActionClicked() {
+        TelephonyManager telephonyManager =
+                (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
+        if (telephonyManager == null) {
+            Toast.makeText(
+                    getActivity(),
+                    R.string.telephony_feature_not_available,
+                    Toast.LENGTH_LONG).show();
+            return;
+        }
+
+        String phoneNumber;
+        try {
+            phoneNumber = telephonyManager.getLine1Number();
+        } catch (Exception e) {
+            displayException(e);
+            return;
+        }
+
+        new AlertDialog.Builder(getActivity())
+                .setMessage("Phone number: " + phoneNumber)
+                .setPositiveButton(android.R.string.ok, null)
+                .show();
+    }
+
+    private void onPromptPermissionsClicked(String... permissions) {
+        Intent i = getActivity().getApplication()
+                .getPackageManager().buildPermissionRequestIntent(permissions);
+        startActivityForResult(i, REQUEST_CODE_PROMPT_PERMISSIONS);
+    }
+
+    private void onGrantPermissionsResult(boolean granted) {
+        if (granted) {
+            displayPermissionsGrantApprovedToast();
+        } else {
+            displayPermissionsGrantDeniedToast();
+        }
+        refreshPermissionsStatus();
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case REQUEST_CODE_PROMPT_PERMISSIONS:
+                onGrantPermissionsResult(resultCode == Activity.RESULT_OK);
+                break;
+            default:
+                super.onActivityResult(requestCode, resultCode, data);
+                break;
+        }
+    }
+
+    private void displayException(Throwable exception) {
+        new AlertDialog.Builder(getActivity())
+                .setTitle(R.string.exception_dialog_title)
+                .setMessage(exception.toString())
+                .setPositiveButton(android.R.string.ok, null)
+                .show();
+    }
+
+    private void displayPermissionsGrantApprovedToast() {
+        Toast.makeText(
+                getActivity(),
+                R.string.toast_permission_grant_approved,
+                Toast.LENGTH_SHORT).show();
+    }
+
+    private void displayPermissionsGrantDeniedToast() {
+        Toast.makeText(
+                getActivity(),
+                R.string.toast_permission_grant_denied,
+                Toast.LENGTH_SHORT).show();
+    }
+
+    private void refreshPermissionsStatus() {
+        mVibrateStatusPreference.setSummary(
+                hasPermission(android.Manifest.permission.VIBRATE)
+                ? R.string.permission_status_granted : R.string.permission_status_not_granted);
+        mInternetStatusPreference.setSummary(
+                hasPermission(android.Manifest.permission.INTERNET)
+                ? R.string.permission_status_granted : R.string.permission_status_not_granted);
+        mPhoneStateStatusPreference.setSummary(
+                hasPermission(
+                        android.Manifest.permission.READ_PHONE_STATE)
+                ? R.string.permission_status_granted : R.string.permission_status_not_granted);
+    }
+
+    private boolean hasPermission(String permission) {
+        long identity = Binder.clearCallingIdentity();
+        try {
+            return getActivity().getApplicationContext()
+                .checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+}