Home | History | Annotate | Download | only in launcher3
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.launcher3;
     18 
     19 import android.app.Activity;
     20 import android.app.AlertDialog;
     21 import android.app.Dialog;
     22 import android.app.DialogFragment;
     23 import android.app.FragmentManager;
     24 import android.content.ComponentName;
     25 import android.content.ContentResolver;
     26 import android.content.Context;
     27 import android.content.DialogInterface;
     28 import android.content.Intent;
     29 import android.os.Bundle;
     30 import android.preference.ListPreference;
     31 import android.preference.Preference;
     32 import android.preference.PreferenceFragment;
     33 import android.provider.Settings;
     34 
     35 import com.android.launcher3.graphics.IconShapeOverride;
     36 import com.android.launcher3.notification.NotificationListener;
     37 import com.android.launcher3.util.SettingsObserver;
     38 import com.android.launcher3.views.ButtonPreference;
     39 
     40 /**
     41  * Settings activity for Launcher. Currently implements the following setting: Allow rotation
     42  */
     43 public class SettingsActivity extends Activity {
     44 
     45     private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
     46     /** Hidden field Settings.Secure.NOTIFICATION_BADGING */
     47     public static final String NOTIFICATION_BADGING = "notification_badging";
     48     /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
     49     private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
     50 
     51     @Override
     52     protected void onCreate(Bundle savedInstanceState) {
     53         super.onCreate(savedInstanceState);
     54 
     55         if (savedInstanceState == null) {
     56             // Display the fragment as the main content.
     57             getFragmentManager().beginTransaction()
     58                     .replace(android.R.id.content, new LauncherSettingsFragment())
     59                     .commit();
     60         }
     61     }
     62 
     63     /**
     64      * This fragment shows the launcher preferences.
     65      */
     66     public static class LauncherSettingsFragment extends PreferenceFragment {
     67 
     68         private SystemDisplayRotationLockObserver mRotationLockObserver;
     69         private IconBadgingObserver mIconBadgingObserver;
     70 
     71         @Override
     72         public void onCreate(Bundle savedInstanceState) {
     73             super.onCreate(savedInstanceState);
     74             getPreferenceManager().setSharedPreferencesName(LauncherFiles.SHARED_PREFERENCES_KEY);
     75             addPreferencesFromResource(R.xml.launcher_preferences);
     76 
     77             ContentResolver resolver = getActivity().getContentResolver();
     78 
     79             // Setup allow rotation preference
     80             Preference rotationPref = findPreference(Utilities.ALLOW_ROTATION_PREFERENCE_KEY);
     81             if (getResources().getBoolean(R.bool.allow_rotation)) {
     82                 // Launcher supports rotation by default. No need to show this setting.
     83                 getPreferenceScreen().removePreference(rotationPref);
     84             } else {
     85                 mRotationLockObserver = new SystemDisplayRotationLockObserver(rotationPref, resolver);
     86 
     87                 // Register a content observer to listen for system setting changes while
     88                 // this UI is active.
     89                 mRotationLockObserver.register(Settings.System.ACCELEROMETER_ROTATION);
     90 
     91                 // Initialize the UI once
     92                 rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity()));
     93             }
     94 
     95             ButtonPreference iconBadgingPref =
     96                     (ButtonPreference) findPreference(ICON_BADGING_PREFERENCE_KEY);
     97             if (!Utilities.ATLEAST_OREO) {
     98                 getPreferenceScreen().removePreference(
     99                         findPreference(SessionCommitReceiver.ADD_ICON_PREFERENCE_KEY));
    100                 getPreferenceScreen().removePreference(iconBadgingPref);
    101             } else if (!getResources().getBoolean(R.bool.notification_badging_enabled)) {
    102                 getPreferenceScreen().removePreference(iconBadgingPref);
    103             } else {
    104                 // Listen to system notification badge settings while this UI is active.
    105                 mIconBadgingObserver = new IconBadgingObserver(
    106                         iconBadgingPref, resolver, getFragmentManager());
    107                 mIconBadgingObserver.register(NOTIFICATION_BADGING, NOTIFICATION_ENABLED_LISTENERS);
    108             }
    109 
    110             Preference iconShapeOverride = findPreference(IconShapeOverride.KEY_PREFERENCE);
    111             if (iconShapeOverride != null) {
    112                 if (IconShapeOverride.isSupported(getActivity())) {
    113                     IconShapeOverride.handlePreferenceUi((ListPreference) iconShapeOverride);
    114                 } else {
    115                     getPreferenceScreen().removePreference(iconShapeOverride);
    116                 }
    117             }
    118         }
    119 
    120         @Override
    121         public void onDestroy() {
    122             if (mRotationLockObserver != null) {
    123                 mRotationLockObserver.unregister();
    124                 mRotationLockObserver = null;
    125             }
    126             if (mIconBadgingObserver != null) {
    127                 mIconBadgingObserver.unregister();
    128                 mIconBadgingObserver = null;
    129             }
    130             super.onDestroy();
    131         }
    132     }
    133 
    134     /**
    135      * Content observer which listens for system auto-rotate setting changes, and enables/disables
    136      * the launcher rotation setting accordingly.
    137      */
    138     private static class SystemDisplayRotationLockObserver extends SettingsObserver.System {
    139 
    140         private final Preference mRotationPref;
    141 
    142         public SystemDisplayRotationLockObserver(
    143                 Preference rotationPref, ContentResolver resolver) {
    144             super(resolver);
    145             mRotationPref = rotationPref;
    146         }
    147 
    148         @Override
    149         public void onSettingChanged(boolean enabled) {
    150             mRotationPref.setEnabled(enabled);
    151             mRotationPref.setSummary(enabled
    152                     ? R.string.allow_rotation_desc : R.string.allow_rotation_blocked_desc);
    153         }
    154     }
    155 
    156     /**
    157      * Content observer which listens for system badging setting changes,
    158      * and updates the launcher badging setting subtext accordingly.
    159      */
    160     private static class IconBadgingObserver extends SettingsObserver.Secure
    161             implements Preference.OnPreferenceClickListener {
    162 
    163         private final ButtonPreference mBadgingPref;
    164         private final ContentResolver mResolver;
    165         private final FragmentManager mFragmentManager;
    166 
    167         public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver,
    168                 FragmentManager fragmentManager) {
    169             super(resolver);
    170             mBadgingPref = badgingPref;
    171             mResolver = resolver;
    172             mFragmentManager = fragmentManager;
    173         }
    174 
    175         @Override
    176         public void onSettingChanged(boolean enabled) {
    177             int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off;
    178 
    179             boolean serviceEnabled = true;
    180             if (enabled) {
    181                 // Check if the listener is enabled or not.
    182                 String enabledListeners =
    183                         Settings.Secure.getString(mResolver, NOTIFICATION_ENABLED_LISTENERS);
    184                 ComponentName myListener =
    185                         new ComponentName(mBadgingPref.getContext(), NotificationListener.class);
    186                 serviceEnabled = enabledListeners != null &&
    187                         (enabledListeners.contains(myListener.flattenToString()) ||
    188                                 enabledListeners.contains(myListener.flattenToShortString()));
    189                 if (!serviceEnabled) {
    190                     summary = R.string.title_missing_notification_access;
    191                 }
    192             }
    193             mBadgingPref.setWidgetFrameVisible(!serviceEnabled);
    194             mBadgingPref.setOnPreferenceClickListener(serviceEnabled ? null : this);
    195             mBadgingPref.setSummary(summary);
    196 
    197         }
    198 
    199         @Override
    200         public boolean onPreferenceClick(Preference preference) {
    201             new NotificationAccessConfirmation().show(mFragmentManager, "notification_access");
    202             return true;
    203         }
    204     }
    205 
    206     public static class NotificationAccessConfirmation
    207             extends DialogFragment implements DialogInterface.OnClickListener {
    208 
    209         @Override
    210         public Dialog onCreateDialog(Bundle savedInstanceState) {
    211             final Context context = getActivity();
    212             String msg = context.getString(R.string.msg_missing_notification_access,
    213                     context.getString(R.string.derived_app_name));
    214             return new AlertDialog.Builder(context)
    215                     .setTitle(R.string.title_missing_notification_access)
    216                     .setMessage(msg)
    217                     .setNegativeButton(android.R.string.cancel, null)
    218                     .setPositiveButton(R.string.title_change_settings, this)
    219                     .create();
    220         }
    221 
    222         @Override
    223         public void onClick(DialogInterface dialogInterface, int i) {
    224             ComponentName cn = new ComponentName(getActivity(), NotificationListener.class);
    225             Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
    226                     .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    227                     .putExtra(":settings:fragment_args_key", cn.flattenToString());
    228             getActivity().startActivity(intent);
    229         }
    230     }
    231 }
    232