Fix crash on rotation
Load app/channel data early so that any open dialogs can be properly
reconstructed. Never call done on an entityheadercontroller with
an activity that's not yet started.
Test: robotests
Change-Id: Ib2b9f8f1985ef038959062204aaceff686f4ebcf
Fixes: 74114917
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e87951b..af565d6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2743,6 +2743,7 @@
<!-- Show channel-level notification settings (channel passed in as extras) -->
<activity android:name="Settings$ChannelNotificationSettingsActivity"
+ android:label="@string/notification_channel_title"
android:exported="true">
<intent-filter android:priority="1">
<action android:name="android.settings.CHANNEL_NOTIFICATION_SETTINGS" />
diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml
index 2d5dc57..3ddfac5 100644
--- a/res/xml/app_notification_settings.xml
+++ b/res/xml/app_notification_settings.xml
@@ -31,15 +31,32 @@
<!-- Channels/Channel groups added here -->
+ <!-- Importance toggle -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="allow_sound"
+ android:title="@string/allow_interruption"
+ android:summary="@string/allow_interruption_summary" />
+
+ <!-- Visibility Override -->
+ <com.android.settings.RestrictedListPreference
+ android:key="visibility_override"
+ android:title="@string/app_notification_visibility_override_title"/>
+
<!-- Show badge -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="badge"
android:title="@string/notification_badge_title"
android:order="501"
settings:useAdditionalSummary="true"
- settings:allowDividerAbove="true"
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
+ <!-- Bypass DND -->
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="bypass_dnd"
+ android:title="@string/app_notification_override_dnd_title"
+ android:summary="@string/app_notification_override_dnd_summary"
+ settings:useAdditionalSummary="true"/>
+
<Preference
android:key="app_link"
android:title="@string/app_settings_link"
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index 9d0398d..01001fa 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -14,9 +14,12 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:settings="http://schemas.android.com/apk/res-auto"
- settings:initialExpandedChildrenCount="3">
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="channel_settings"
+ android:title="@string/notification_channel_title"
+ settings:initialExpandedChildrenCount="3" >
<com.android.settings.applications.LayoutPreference
android:key="pref_app_header"
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 6776931..2bc2489 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -68,10 +68,7 @@
mDynamicPreferences.clear();
}
- if (mShowLegacyChannelConfig) {
- addPreferencesFromResource(R.xml.channel_notification_settings);
- } else {
- addPreferencesFromResource(R.xml.app_notification_settings);
+ if (!mShowLegacyChannelConfig) {
// Load channel settings
new AsyncTask<Void, Void, Void>() {
@Override
@@ -106,7 +103,7 @@
@Override
protected int getPreferenceScreenResId() {
- return R.xml.notification_settings;
+ return R.xml.app_notification_settings;
}
@Override
diff --git a/src/com/android/settings/notification/HeaderPreferenceController.java b/src/com/android/settings/notification/HeaderPreferenceController.java
index d5e289b..c6f6a80 100644
--- a/src/com/android/settings/notification/HeaderPreferenceController.java
+++ b/src/com/android/settings/notification/HeaderPreferenceController.java
@@ -18,6 +18,8 @@
import static com.android.settings.widget.EntityHeaderController.PREF_KEY_APP_HEADER;
+import android.arch.lifecycle.LifecycleObserver;
+import android.arch.lifecycle.OnLifecycleEvent;
import android.content.Context;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.Preference;
@@ -30,13 +32,16 @@
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.events.OnStart;
import java.util.Objects;
public class HeaderPreferenceController extends NotificationPreferenceController
- implements PreferenceControllerMixin {
+ implements PreferenceControllerMixin, LifecycleObserver {
private final PreferenceFragment mFragment;
+ private EntityHeaderController mHeaderController;
public HeaderPreferenceController(Context context, PreferenceFragment fragment) {
super(context, null);
@@ -57,10 +62,9 @@
public void updateState(Preference preference) {
if (mAppRow != null && mFragment != null) {
LayoutPreference pref = (LayoutPreference) preference;
- EntityHeaderController controller = EntityHeaderController
- .newInstance(mFragment.getActivity(), mFragment,
- pref.findViewById(R.id.entity_header));
- pref = controller.setIcon(mAppRow.icon)
+ mHeaderController = EntityHeaderController.newInstance(
+ mFragment.getActivity(), mFragment, pref.findViewById(R.id.entity_header));
+ pref = mHeaderController.setIcon(mAppRow.icon)
.setLabel(getLabel())
.setSummary(getSummary())
.setPackageName(mAppRow.pkg)
@@ -68,7 +72,7 @@
.setButtonActions(EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
EntityHeaderController.ActionType.ACTION_NONE)
.setHasAppInfoLink(true)
- .done(mFragment.getActivity(), mContext);
+ .done(null, mContext);
pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
}
}
@@ -101,4 +105,11 @@
return "";
}
}
+
+ @OnLifecycleEvent(Lifecycle.Event.ON_START)
+ public void onStart() {
+ if (mHeaderController != null) {
+ mHeaderController.styleActionBar(mFragment.getActivity());
+ }
+ }
}
diff --git a/src/com/android/settings/notification/NotificationPreferenceController.java b/src/com/android/settings/notification/NotificationPreferenceController.java
index 1a65351..1e477c4 100644
--- a/src/com/android/settings/notification/NotificationPreferenceController.java
+++ b/src/com/android/settings/notification/NotificationPreferenceController.java
@@ -96,7 +96,7 @@
if (preference != null) {
mPreference = preference;
}
- if (this instanceof Preference.OnPreferenceChangeListener) {
+ if (mPreference != null && this instanceof Preference.OnPreferenceChangeListener) {
mPreference.setOnPreferenceChangeListener(
(Preference.OnPreferenceChangeListener) this);
}
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index 7eb0ba4..faf6fb3 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -20,6 +20,7 @@
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -81,28 +82,25 @@
protected List<Preference> mDynamicPreferences = new ArrayList<>();
protected ImportanceListener mImportanceListener = new ImportanceListener();
+ protected Intent mIntent;
+ protected Bundle mArgs;
+
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ public void onAttach(Context context) {
+ super.onAttach(context);
mContext = getActivity();
- Intent intent = getActivity().getIntent();
- Bundle args = getArguments();
- if (DEBUG) Log.d(TAG, "onCreate getIntent()=" + intent);
- if (intent == null && args == null) {
- Log.w(TAG, "No intent");
- toastAndFinish();
- return;
- }
+ mIntent = getActivity().getIntent();
+ mArgs = getArguments();
mPm = getPackageManager();
mNm = NotificationManager.from(mContext);
- mPkg = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_NAME)
- ? args.getString(AppInfoBase.ARG_PACKAGE_NAME)
- : intent.getStringExtra(Settings.EXTRA_APP_PACKAGE);
- mUid = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_UID)
- ? args.getInt(AppInfoBase.ARG_PACKAGE_UID)
- : intent.getIntExtra(Settings.EXTRA_APP_UID, -1);
+ mPkg = mArgs != null && mArgs.containsKey(AppInfoBase.ARG_PACKAGE_NAME)
+ ? mArgs.getString(AppInfoBase.ARG_PACKAGE_NAME)
+ : mIntent.getStringExtra(Settings.EXTRA_APP_PACKAGE);
+ mUid = mArgs != null && mArgs.containsKey(AppInfoBase.ARG_PACKAGE_UID)
+ ? mArgs.getInt(AppInfoBase.ARG_PACKAGE_UID)
+ : mIntent.getIntExtra(Settings.EXTRA_APP_UID, -1);
if (mUid < 0) {
try {
@@ -113,13 +111,38 @@
mPkgInfo = findPackageInfo(mPkg, mUid);
+ mUserId = UserHandle.getUserId(mUid);
+ mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended(
+ mContext, mPkg, mUserId);
+
+ loadChannel();
+ loadAppRow();
+ loadChannelGroup();
+ collectConfigActivities();
+
+ getLifecycle().addObserver(use(HeaderPreferenceController.class));
+
+ for (NotificationPreferenceController controller : mControllers) {
+ controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (mIntent == null && mArgs == null) {
+ Log.w(TAG, "No intent");
+ toastAndFinish();
+ return;
+ }
+
if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
Log.w(TAG, "Missing package or uid or packageinfo");
toastAndFinish();
return;
}
- mUserId = UserHandle.getUserId(mUid);
startListeningToPackageRemove();
}
@@ -132,18 +155,26 @@
@Override
public void onResume() {
super.onResume();
- if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
+ if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null || mAppRow == null) {
Log.w(TAG, "Missing package or uid or packageinfo");
finish();
return;
}
- mAppRow = mBackend.loadAppRow(mContext, mPm, mPkgInfo);
+ // Reload app, channel, etc onResume in case they've changed. A little wasteful if we've
+ // just done onAttach but better than making every preference controller reload all
+ // the data
+ loadAppRow();
if (mAppRow == null) {
Log.w(TAG, "Can't load package");
finish();
return;
}
+ loadChannel();
+ loadChannelGroup();
collectConfigActivities();
+ }
+
+ private void loadChannel() {
Intent intent = getActivity().getIntent();
String channelId = intent != null ? intent.getStringExtra(Settings.EXTRA_CHANNEL_ID) : null;
if (channelId == null && intent != null) {
@@ -151,12 +182,13 @@
channelId = args != null ? args.getString(Settings.EXTRA_CHANNEL_ID) : null;
}
mChannel = mBackend.getChannel(mPkg, mUid, channelId);
+ }
- NotificationChannelGroup group = null;
+ private void loadAppRow() {
+ mAppRow = mBackend.loadAppRow(mContext, mPm, mPkgInfo);
+ }
- mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended(
- mContext, mPkg, mUserId);
-
+ private void loadChannelGroup() {
mShowLegacyChannelConfig = mBackend.onlyHasDefaultChannel(mAppRow.pkg, mAppRow.uid)
|| (mChannel != null
&& NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId()));
@@ -166,7 +198,7 @@
mAppRow.pkg, mAppRow.uid, NotificationChannel.DEFAULT_CHANNEL_ID);
}
if (mChannel != null && !TextUtils.isEmpty(mChannel.getGroup())) {
- group = mBackend.getGroup(mPkg, mUid, mChannel.getGroup());
+ NotificationChannelGroup group = mBackend.getGroup(mPkg, mUid, mChannel.getGroup());
if (group != null) {
mChannelGroup = group;
}