blob: 7fa0e5225960fe4e94eea7e5fe598e20301e86b0 [file] [log] [blame]
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -07001/*
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
17package com.android.launcher3;
18
19import android.app.Activity;
Sunny Goyal848cad52017-07-07 03:12:21 -070020import android.app.AlertDialog;
21import android.app.Dialog;
22import android.app.DialogFragment;
23import android.app.FragmentManager;
24import android.content.ComponentName;
Sunny Goyalf48e5922016-05-12 15:36:20 -070025import android.content.ContentResolver;
Sunny Goyal848cad52017-07-07 03:12:21 -070026import android.content.Context;
27import android.content.DialogInterface;
28import android.content.Intent;
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070029import android.os.Bundle;
Sunny Goyalca187462017-03-31 20:09:34 -070030import android.preference.ListPreference;
Rahul Chaturvedi799aa042015-06-01 21:26:41 -040031import android.preference.Preference;
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070032import android.preference.PreferenceFragment;
Sunny Goyalf48e5922016-05-12 15:36:20 -070033import android.provider.Settings;
Sunny Goyal3fbca152017-11-02 18:55:44 -070034import android.text.TextUtils;
35import android.view.LayoutInflater;
36import android.view.View;
37import android.view.ViewGroup;
38import android.widget.Adapter;
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070039
Sunny Goyalca187462017-03-31 20:09:34 -070040import com.android.launcher3.graphics.IconShapeOverride;
Sunny Goyal848cad52017-07-07 03:12:21 -070041import com.android.launcher3.notification.NotificationListener;
Tonyd48710c2017-07-27 23:23:58 -070042import com.android.launcher3.util.SettingsObserver;
Sunny Goyal848cad52017-07-07 03:12:21 -070043import com.android.launcher3.views.ButtonPreference;
Sunny Goyal3fbca152017-11-02 18:55:44 -070044import com.android.launcher3.views.HighlightableListView;
Sunny Goyalca187462017-03-31 20:09:34 -070045
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070046/**
Rahul Chaturvedi799aa042015-06-01 21:26:41 -040047 * Settings activity for Launcher. Currently implements the following setting: Allow rotation
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070048 */
49public class SettingsActivity extends Activity {
Tony Wickham2ab84822017-05-12 14:59:09 -070050
51 private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
Tonyd48710c2017-07-27 23:23:58 -070052 /** Hidden field Settings.Secure.NOTIFICATION_BADGING */
53 public static final String NOTIFICATION_BADGING = "notification_badging";
Sunny Goyal848cad52017-07-07 03:12:21 -070054 /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
55 private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
Tony Wickham2ab84822017-05-12 14:59:09 -070056
Sunny Goyal3fbca152017-11-02 18:55:44 -070057 private static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
58 private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;
59 private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
60
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070061 @Override
62 protected void onCreate(Bundle savedInstanceState) {
63 super.onCreate(savedInstanceState);
64
Mario Bertschler2de2d672017-06-30 18:51:46 -070065 if (savedInstanceState == null) {
66 // Display the fragment as the main content.
67 getFragmentManager().beginTransaction()
Sunny Goyal3fbca152017-11-02 18:55:44 -070068 .replace(android.R.id.content, getNewFragment())
Mario Bertschler2de2d672017-06-30 18:51:46 -070069 .commit();
70 }
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070071 }
72
Sunny Goyal3fbca152017-11-02 18:55:44 -070073 protected PreferenceFragment getNewFragment() {
74 return new LauncherSettingsFragment();
75 }
76
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070077 /**
78 * This fragment shows the launcher preferences.
79 */
Sunny Goyalf48e5922016-05-12 15:36:20 -070080 public static class LauncherSettingsFragment extends PreferenceFragment {
81
Tony Wickham2ab84822017-05-12 14:59:09 -070082 private IconBadgingObserver mIconBadgingObserver;
Sunny Goyalf48e5922016-05-12 15:36:20 -070083
Sunny Goyal3fbca152017-11-02 18:55:44 -070084 private String mPreferenceKey;
85 private boolean mPreferenceHighlighted = false;
86
87 @Override
88 public View onCreateView(LayoutInflater inflater, ViewGroup container,
89 Bundle savedInstanceState) {
90 return inflater.inflate(R.layout.launcher_preference, container, false);
91 }
92
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -070093 @Override
94 public void onCreate(Bundle savedInstanceState) {
95 super.onCreate(savedInstanceState);
Sunny Goyal3fbca152017-11-02 18:55:44 -070096 if (savedInstanceState != null) {
97 mPreferenceHighlighted = savedInstanceState.getBoolean(SAVE_HIGHLIGHTED_KEY);
98 }
99
Sunny Goyalf48e5922016-05-12 15:36:20 -0700100 getPreferenceManager().setSharedPreferencesName(LauncherFiles.SHARED_PREFERENCES_KEY);
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -0700101 addPreferencesFromResource(R.xml.launcher_preferences);
Sunny Goyal7779d622015-06-11 16:18:39 -0700102
Tony Wickham2ab84822017-05-12 14:59:09 -0700103 ContentResolver resolver = getActivity().getContentResolver();
104
Sunny Goyal848cad52017-07-07 03:12:21 -0700105 ButtonPreference iconBadgingPref =
106 (ButtonPreference) findPreference(ICON_BADGING_PREFERENCE_KEY);
Hyunyoung Songe24cb632017-09-11 11:18:03 -0700107 if (!Utilities.ATLEAST_OREO) {
Sunny Goyal4179e9b2017-03-08 14:25:09 -0800108 getPreferenceScreen().removePreference(
109 findPreference(SessionCommitReceiver.ADD_ICON_PREFERENCE_KEY));
Tony Wickham2ab84822017-05-12 14:59:09 -0700110 getPreferenceScreen().removePreference(iconBadgingPref);
Tony Wickhamc1385152017-08-14 14:31:03 -0700111 } else if (!getResources().getBoolean(R.bool.notification_badging_enabled)) {
112 getPreferenceScreen().removePreference(iconBadgingPref);
Tony Wickham2ab84822017-05-12 14:59:09 -0700113 } else {
114 // Listen to system notification badge settings while this UI is active.
Sunny Goyal848cad52017-07-07 03:12:21 -0700115 mIconBadgingObserver = new IconBadgingObserver(
116 iconBadgingPref, resolver, getFragmentManager());
Tonyd48710c2017-07-27 23:23:58 -0700117 mIconBadgingObserver.register(NOTIFICATION_BADGING, NOTIFICATION_ENABLED_LISTENERS);
Sunny Goyal4179e9b2017-03-08 14:25:09 -0800118 }
Sunny Goyalca187462017-03-31 20:09:34 -0700119
120 Preference iconShapeOverride = findPreference(IconShapeOverride.KEY_PREFERENCE);
121 if (iconShapeOverride != null) {
122 if (IconShapeOverride.isSupported(getActivity())) {
123 IconShapeOverride.handlePreferenceUi((ListPreference) iconShapeOverride);
124 } else {
125 getPreferenceScreen().removePreference(iconShapeOverride);
126 }
127 }
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -0700128 }
Rahul Chaturvedi799aa042015-06-01 21:26:41 -0400129
130 @Override
Sunny Goyal3fbca152017-11-02 18:55:44 -0700131 public void onSaveInstanceState(Bundle outState) {
132 super.onSaveInstanceState(outState);
133 outState.putBoolean(SAVE_HIGHLIGHTED_KEY, mPreferenceHighlighted);
134 }
135
136 @Override
137 public void onResume() {
138 super.onResume();
139
140 Intent intent = getActivity().getIntent();
141 mPreferenceKey = intent.getStringExtra(EXTRA_FRAGMENT_ARG_KEY);
142 if (isAdded() && !mPreferenceHighlighted && !TextUtils.isEmpty(mPreferenceKey)) {
143 getView().postDelayed(this::highlightPreference, DELAY_HIGHLIGHT_DURATION_MILLIS);
144 }
145 }
146
147 private void highlightPreference() {
148 HighlightableListView list = getView().findViewById(android.R.id.list);
149 Preference pref = findPreference(mPreferenceKey);
150 Adapter adapter = list.getAdapter();
151 if (adapter == null) {
152 return;
153 }
154
155 // Find the position
156 int position = -1;
157 for (int i = adapter.getCount() - 1; i >= 0; i--) {
158 if (pref == adapter.getItem(i)) {
159 position = i;
160 break;
161 }
162 }
163 list.highlightPosition(position);
164 mPreferenceHighlighted = true;
165 }
166
167 @Override
Sunny Goyalf48e5922016-05-12 15:36:20 -0700168 public void onDestroy() {
Tony Wickham2ab84822017-05-12 14:59:09 -0700169 if (mIconBadgingObserver != null) {
Tonyd48710c2017-07-27 23:23:58 -0700170 mIconBadgingObserver.unregister();
Tony Wickham2ab84822017-05-12 14:59:09 -0700171 mIconBadgingObserver = null;
172 }
Sunny Goyalf48e5922016-05-12 15:36:20 -0700173 super.onDestroy();
174 }
175 }
176
177 /**
Tony Wickham2ab84822017-05-12 14:59:09 -0700178 * Content observer which listens for system badging setting changes,
179 * and updates the launcher badging setting subtext accordingly.
180 */
Tonyd48710c2017-07-27 23:23:58 -0700181 private static class IconBadgingObserver extends SettingsObserver.Secure
Sunny Goyalb65e13c2017-08-01 11:04:15 -0700182 implements Preference.OnPreferenceClickListener {
Tony Wickham2ab84822017-05-12 14:59:09 -0700183
Sunny Goyal848cad52017-07-07 03:12:21 -0700184 private final ButtonPreference mBadgingPref;
Tony Wickham2ab84822017-05-12 14:59:09 -0700185 private final ContentResolver mResolver;
Sunny Goyal848cad52017-07-07 03:12:21 -0700186 private final FragmentManager mFragmentManager;
Tony Wickham2ab84822017-05-12 14:59:09 -0700187
Sunny Goyal848cad52017-07-07 03:12:21 -0700188 public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver,
189 FragmentManager fragmentManager) {
Tonyd48710c2017-07-27 23:23:58 -0700190 super(resolver);
Tony Wickham2ab84822017-05-12 14:59:09 -0700191 mBadgingPref = badgingPref;
192 mResolver = resolver;
Sunny Goyal848cad52017-07-07 03:12:21 -0700193 mFragmentManager = fragmentManager;
Tony Wickham2ab84822017-05-12 14:59:09 -0700194 }
195
196 @Override
Tonyd48710c2017-07-27 23:23:58 -0700197 public void onSettingChanged(boolean enabled) {
Sunny Goyal848cad52017-07-07 03:12:21 -0700198 int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off;
199
200 boolean serviceEnabled = true;
201 if (enabled) {
202 // Check if the listener is enabled or not.
203 String enabledListeners =
204 Settings.Secure.getString(mResolver, NOTIFICATION_ENABLED_LISTENERS);
205 ComponentName myListener =
206 new ComponentName(mBadgingPref.getContext(), NotificationListener.class);
207 serviceEnabled = enabledListeners != null &&
208 (enabledListeners.contains(myListener.flattenToString()) ||
209 enabledListeners.contains(myListener.flattenToShortString()));
210 if (!serviceEnabled) {
211 summary = R.string.title_missing_notification_access;
212 }
213 }
Sunny Goyalb65e13c2017-08-01 11:04:15 -0700214 mBadgingPref.setWidgetFrameVisible(!serviceEnabled);
215 mBadgingPref.setOnPreferenceClickListener(serviceEnabled ? null : this);
Sunny Goyal848cad52017-07-07 03:12:21 -0700216 mBadgingPref.setSummary(summary);
217
218 }
219
220 @Override
Sunny Goyalb65e13c2017-08-01 11:04:15 -0700221 public boolean onPreferenceClick(Preference preference) {
Sunny Goyal848cad52017-07-07 03:12:21 -0700222 new NotificationAccessConfirmation().show(mFragmentManager, "notification_access");
Sunny Goyalb65e13c2017-08-01 11:04:15 -0700223 return true;
Tony Wickham2ab84822017-05-12 14:59:09 -0700224 }
225 }
226
Sunny Goyal848cad52017-07-07 03:12:21 -0700227 public static class NotificationAccessConfirmation
228 extends DialogFragment implements DialogInterface.OnClickListener {
229
230 @Override
231 public Dialog onCreateDialog(Bundle savedInstanceState) {
232 final Context context = getActivity();
233 String msg = context.getString(R.string.msg_missing_notification_access,
234 context.getString(R.string.derived_app_name));
235 return new AlertDialog.Builder(context)
236 .setTitle(R.string.title_missing_notification_access)
237 .setMessage(msg)
238 .setNegativeButton(android.R.string.cancel, null)
239 .setPositiveButton(R.string.title_change_settings, this)
240 .create();
241 }
242
243 @Override
244 public void onClick(DialogInterface dialogInterface, int i) {
245 ComponentName cn = new ComponentName(getActivity(), NotificationListener.class);
246 Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
247 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
248 .putExtra(":settings:fragment_args_key", cn.flattenToString());
249 getActivity().startActivity(intent);
250 }
251 }
Rahul Chaturvedi7fc77ca2015-05-19 18:02:16 -0700252}