Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8355dc05 authored by Tony Wickham's avatar Tony Wickham
Browse files

[automerger] Unbind notification listener when badging is disabled am: d48710c2

Change-Id: Icb4da18efc0e0c3ac009e90a314c9ff27189ba11
parents 30284965 d48710c2
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.launcher3;

import android.content.ComponentName;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
@@ -28,13 +29,17 @@ import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dynamicui.ExtractionUtils;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.util.ConfigMonitor;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.SettingsObserver;
import com.android.launcher3.util.TestingUtils;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;

public class LauncherAppState {

    public static final boolean PROFILE_STARTUP = FeatureFlags.IS_DOGFOOD_BUILD;
@@ -47,7 +52,7 @@ public class LauncherAppState {
    private final IconCache mIconCache;
    private final WidgetPreviewLoader mWidgetCache;
    private final InvariantDeviceProfile mInvariantDeviceProfile;

    private final SettingsObserver mNotificationBadgingObserver;

    public static LauncherAppState getInstance(final Context context) {
        if (INSTANCE == null) {
@@ -117,6 +122,23 @@ public class LauncherAppState {
        new ConfigMonitor(mContext).register();

        ExtractionUtils.startColorExtractionServiceIfNecessary(mContext);

        if (!mContext.getResources().getBoolean(R.bool.notification_badging_enabled)) {
            mNotificationBadgingObserver = null;
        } else {
            // Register an observer to rebind the notification listener when badging is re-enabled.
            mNotificationBadgingObserver = new SettingsObserver.Secure(
                    mContext.getContentResolver()) {
                @Override
                public void onSettingChanged(boolean isNotificationBadgingEnabled) {
                    if (isNotificationBadgingEnabled) {
                        NotificationListener.requestRebind(new ComponentName(
                                mContext, NotificationListener.class));
                    }
                }
            };
            mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
        }
    }

    /**
@@ -127,6 +149,9 @@ public class LauncherAppState {
        final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext);
        launcherApps.removeOnAppsChangedCallback(mModel);
        PackageInstallerCompat.getInstance(mContext).onStop();
        if (mNotificationBadgingObserver != null) {
            mNotificationBadgingObserver.unregister();
        }
    }

    LauncherModel setLauncher(Launcher launcher) {
+13 −29
Original line number Diff line number Diff line
@@ -26,17 +26,15 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.ContentObserver;
import android.os.Bundle;
import android.os.Handler;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.provider.Settings;
import android.provider.Settings.System;

import com.android.launcher3.graphics.IconShapeOverride;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.util.SettingsObserver;
import com.android.launcher3.views.ButtonPreference;

/**
@@ -45,8 +43,8 @@ import com.android.launcher3.views.ButtonPreference;
public class SettingsActivity extends Activity {

    private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
    // TODO: use Settings.Secure.NOTIFICATION_BADGING
    private static final String NOTIFICATION_BADGING = "notification_badging";
    /** Hidden field Settings.Secure.NOTIFICATION_BADGING */
    public static final String NOTIFICATION_BADGING = "notification_badging";
    /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
    private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";

@@ -88,12 +86,9 @@ public class SettingsActivity extends Activity {

                // Register a content observer to listen for system setting changes while
                // this UI is active.
                resolver.registerContentObserver(
                        Settings.System.getUriFor(System.ACCELEROMETER_ROTATION),
                        false, mRotationLockObserver);
                mRotationLockObserver.register(Settings.System.ACCELEROMETER_ROTATION);

                // Initialize the UI once
                mRotationLockObserver.onChange(true);
                rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity()));
            }

@@ -107,13 +102,7 @@ public class SettingsActivity extends Activity {
                // Listen to system notification badge settings while this UI is active.
                mIconBadgingObserver = new IconBadgingObserver(
                        iconBadgingPref, resolver, getFragmentManager());
                resolver.registerContentObserver(
                        Settings.Secure.getUriFor(NOTIFICATION_BADGING),
                        false, mIconBadgingObserver);
                resolver.registerContentObserver(
                        Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS),
                        false, mIconBadgingObserver);
                mIconBadgingObserver.onChange(true);
                mIconBadgingObserver.register(NOTIFICATION_BADGING, NOTIFICATION_ENABLED_LISTENERS);
            }

            Preference iconShapeOverride = findPreference(IconShapeOverride.KEY_PREFERENCE);
@@ -129,11 +118,11 @@ public class SettingsActivity extends Activity {
        @Override
        public void onDestroy() {
            if (mRotationLockObserver != null) {
                getActivity().getContentResolver().unregisterContentObserver(mRotationLockObserver);
                mRotationLockObserver.unregister();
                mRotationLockObserver = null;
            }
            if (mIconBadgingObserver != null) {
                getActivity().getContentResolver().unregisterContentObserver(mIconBadgingObserver);
                mIconBadgingObserver.unregister();
                mIconBadgingObserver = null;
            }
            super.onDestroy();
@@ -144,22 +133,18 @@ public class SettingsActivity extends Activity {
     * Content observer which listens for system auto-rotate setting changes, and enables/disables
     * the launcher rotation setting accordingly.
     */
    private static class SystemDisplayRotationLockObserver extends ContentObserver {
    private static class SystemDisplayRotationLockObserver extends SettingsObserver.System {

        private final Preference mRotationPref;
        private final ContentResolver mResolver;

        public SystemDisplayRotationLockObserver(
                Preference rotationPref, ContentResolver resolver) {
            super(new Handler());
            super(resolver);
            mRotationPref = rotationPref;
            mResolver = resolver;
        }

        @Override
        public void onChange(boolean selfChange) {
            boolean enabled = Settings.System.getInt(mResolver,
                    Settings.System.ACCELEROMETER_ROTATION, 1) == 1;
        public void onSettingChanged(boolean enabled) {
            mRotationPref.setEnabled(enabled);
            mRotationPref.setSummary(enabled
                    ? R.string.allow_rotation_desc : R.string.allow_rotation_blocked_desc);
@@ -170,7 +155,7 @@ public class SettingsActivity extends Activity {
     * Content observer which listens for system badging setting changes,
     * and updates the launcher badging setting subtext accordingly.
     */
    private static class IconBadgingObserver extends ContentObserver
    private static class IconBadgingObserver extends SettingsObserver.Secure
            implements Preference.OnPreferenceClickListener {

        private final ButtonPreference mBadgingPref;
@@ -179,15 +164,14 @@ public class SettingsActivity extends Activity {

        public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver,
                FragmentManager fragmentManager) {
            super(new Handler());
            super(resolver);
            mBadgingPref = badgingPref;
            mResolver = resolver;
            mFragmentManager = fragmentManager;
        }

        @Override
        public void onChange(boolean selfChange) {
            boolean enabled = Settings.Secure.getInt(mResolver, NOTIFICATION_BADGING, 1) == 1;
        public void onSettingChanged(boolean enabled) {
            int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off;

            boolean serviceEnabled = true;
+37 −3
Original line number Diff line number Diff line
@@ -30,15 +30,20 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;

import com.android.launcher3.LauncherModel;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.SettingsObserver;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;

/**
 * A {@link NotificationListenerService} that sends updates to its
 * {@link NotificationsChangedListener} when notifications are posted or canceled,
@@ -57,12 +62,14 @@ public class NotificationListener extends NotificationListenerService {
    private static NotificationListener sNotificationListenerInstance = null;
    private static NotificationsChangedListener sNotificationsChangedListener;
    private static boolean sIsConnected;
    private static boolean sIsCreated;

    private final Handler mWorkerHandler;
    private final Handler mUiHandler;

    private final Ranking mTempRanking = new Ranking();

    private SettingsObserver mNotificationBadgingObserver;

    private final Handler.Callback mWorkerCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
@@ -130,6 +137,28 @@ public class NotificationListener extends NotificationListenerService {
        sNotificationListenerInstance = this;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sIsCreated = true;
        mNotificationBadgingObserver = new SettingsObserver.Secure(getContentResolver()) {
            @Override
            public void onSettingChanged(boolean isNotificationBadgingEnabled) {
                if (!isNotificationBadgingEnabled) {
                    requestUnbind();
                }
            }
        };
        mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        sIsCreated = false;
        mNotificationBadgingObserver.unregister();
    }

    public static @Nullable NotificationListener getInstanceIfConnected() {
        return sIsConnected ? sNotificationListenerInstance : null;
    }
@@ -143,6 +172,11 @@ public class NotificationListener extends NotificationListenerService {
        NotificationListener notificationListener = getInstanceIfConnected();
        if (notificationListener != null) {
            notificationListener.onNotificationFullRefresh();
        } else if (!sIsCreated && sNotificationsChangedListener != null) {
            // User turned off badging globally, so we unbound this service;
            // tell the listener that there are no notifications to remove dots.
            sNotificationsChangedListener.onNotificationFullRefresh(
                    Collections.<StatusBarNotification>emptyList());
        }
    }

+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.android.launcher3.util;

import android.content.ContentResolver;
import android.database.ContentObserver;
import android.os.Handler;
import android.provider.Settings;

public interface SettingsObserver {

    /**
     * Registers the content observer to call {@link #onSettingChanged(boolean)} when any of the
     * passed settings change. The value passed to onSettingChanged() is based on the key setting.
     */
    void register(String keySetting, String ... dependentSettings);
    void unregister();
    void onSettingChanged(boolean keySettingEnabled);


    abstract class Secure extends ContentObserver implements SettingsObserver {
        private ContentResolver mResolver;
        private String mKeySetting;

        public Secure(ContentResolver resolver) {
            super(new Handler());
            mResolver = resolver;
        }

        @Override
        public void register(String keySetting, String ... dependentSettings) {
            mKeySetting = keySetting;
            mResolver.registerContentObserver(
                    Settings.Secure.getUriFor(mKeySetting), false, this);
            for (String setting : dependentSettings) {
                mResolver.registerContentObserver(
                        Settings.Secure.getUriFor(setting), false, this);
            }
            onChange(true);
        }

        @Override
        public void unregister() {
            mResolver.unregisterContentObserver(this);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            onSettingChanged(Settings.Secure.getInt(mResolver, mKeySetting, 1) == 1);
        }
    }

    abstract class System extends ContentObserver implements SettingsObserver {
        private ContentResolver mResolver;
        private String mKeySetting;

        public System(ContentResolver resolver) {
            super(new Handler());
            mResolver = resolver;
        }

        @Override
        public void register(String keySetting, String ... dependentSettings) {
            mKeySetting = keySetting;
            mResolver.registerContentObserver(
                    Settings.System.getUriFor(mKeySetting), false, this);
            for (String setting : dependentSettings) {
                mResolver.registerContentObserver(
                        Settings.System.getUriFor(setting), false, this);
            }
            onChange(true);
        }

        @Override
        public void unregister() {
            mResolver.unregisterContentObserver(this);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            onSettingChanged(Settings.System.getInt(mResolver, mKeySetting, 1) == 1);
        }
    }
}