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

Commit 208c21d2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add bubble confirmation prompt" into qt-dev

parents f32d29b7 19e2473b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -7788,9 +7788,9 @@
    <!-- Title of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=NONE] -->
    <string name="bubbles_feature_disabled_dialog_title">Turn on bubbles</string>
    <!-- Description of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=NONE] -->
    <string name="bubbles_feature_disabled_dialog_text">Before you can turn on bubbles for this app, you need to turn on bubbles for your device</string>
    <string name="bubbles_feature_disabled_dialog_text">To turn on bubbles for this app, first you need to turn them on for your device. This affects other apps in which you previously turned on bubbles.</string>
    <!-- Button of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=60]-->
    <string name="bubbles_feature_disabled_button_go_to_bubbles">Go to Bubbles</string>
    <string name="bubbles_feature_disabled_button_approve">Turn on for device</string>
    <!-- Button to cancel out of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=60] -->
    <string name="bubbles_feature_disabled_button_cancel">Cancel</string>
+22 −12
Original line number Diff line number Diff line
@@ -18,22 +18,23 @@ package com.android.settings.notification;

import android.app.settings.SettingsEnums;
import android.content.Context;
import android.provider.SearchIndexableResource;
import android.text.TextUtils;
import android.util.Log;

import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable;

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

@SearchIndexable
public class AppBubbleNotificationSettings extends NotificationSettingsBase {
public class AppBubbleNotificationSettings extends NotificationSettingsBase implements
        GlobalBubblePermissionObserverMixin.Listener {
    private static final String TAG = "AppBubNotiSettings";
    private GlobalBubblePermissionObserverMixin mObserverMixin;

    @Override
    public int getMetricsCategory() {
@@ -64,6 +65,11 @@ public class AppBubbleNotificationSettings extends NotificationSettingsBase {
        return controllers;
    }

    @Override
    public void onGlobalBubblePermissionChanged() {
        updatePreferenceStates();
    }

    @Override
    public void onResume() {
        super.onResume();
@@ -79,19 +85,23 @@ public class AppBubbleNotificationSettings extends NotificationSettingsBase {
            controller.displayPreference(getPreferenceScreen());
        }
        updatePreferenceStates();

        mObserverMixin = new GlobalBubblePermissionObserverMixin(getContext(), this);
        mObserverMixin.onStart();
    }

    /**
     * For Search.
     */
    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
    @Override
    public void onPause() {
        mObserverMixin.onStop();
        super.onPause();
    }

    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider() {

                @Override
                public List<SearchIndexableResource> getXmlResourcesToIndex(
                        Context context, boolean enabled) {
                    final SearchIndexableResource sir = new SearchIndexableResource(context);
                    sir.xmlResId = R.xml.app_bubble_notification_settings;
                    return Arrays.asList(sir);
                protected boolean isPageSearchEnabled(Context context) {
                    return false;
                }

                @Override
+52 −8
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.RestrictedSwitchPreference;

import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;

public class BubblePreferenceController extends NotificationPreferenceController
@@ -35,10 +36,18 @@ public class BubblePreferenceController extends NotificationPreferenceController
    private static final int SYSTEM_WIDE_ON = 1;
    private static final int SYSTEM_WIDE_OFF = 0;

    private FragmentManager mFragmentManager;

    public BubblePreferenceController(Context context, NotificationBackend backend) {
        super(context, backend);
    }

    public BubblePreferenceController(Context context, FragmentManager fragmentManager,
            NotificationBackend backend) {
        super(context, backend);
        mFragmentManager = fragmentManager;
    }

    @Override
    public String getPreferenceKey() {
        return KEY;
@@ -52,11 +61,11 @@ public class BubblePreferenceController extends NotificationPreferenceController
        if (mAppRow == null && mChannel == null) {
            return false;
        }
        if (mChannel != null) {
            if (Settings.Secure.getInt(mContext.getContentResolver(),
                    NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_OFF) {
                return false;
            }
        if (mChannel != null) {
            if (isDefaultChannel()) {
                return true;
            } else {
@@ -74,7 +83,9 @@ public class BubblePreferenceController extends NotificationPreferenceController
                pref.setChecked(mChannel.canBubble());
                pref.setEnabled(isChannelConfigurable() && !pref.isDisabledByAdmin());
            } else {
                pref.setChecked(mAppRow.allowBubbles);
                pref.setChecked(mAppRow.allowBubbles
                        && Settings.Secure.getInt(mContext.getContentResolver(),
                        NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_ON);
                pref.setSummary(mContext.getString(
                        R.string.bubbles_app_toggle_summary, mAppRow.label));
            }
@@ -87,11 +98,44 @@ public class BubblePreferenceController extends NotificationPreferenceController
        if (mChannel != null) {
            mChannel.setAllowBubbles(value);
            saveChannel();
            return true;
        } else if (mAppRow != null) {
            RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
            // if the global setting is off, toggling app level permission requires extra
            // confirmation
            if (Settings.Secure.getInt(mContext.getContentResolver(),
                    NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_OFF
                    && !pref.isChecked()) {
                new BubbleWarningDialogFragment()
                        .setPkgInfo(mAppRow.pkg, mAppRow.uid)
                        .show(mFragmentManager, "dialog");
                return false;
            } else {
                mAppRow.allowBubbles = value;
                mBackend.setAllowBubbles(mAppRow.pkg, mAppRow.uid, value);
            }
        }
        return true;
    }

    // Used in app level prompt that confirms the user is ok with turning on bubbles
    // globally. If they aren't, undo what
    public static void revertBubblesApproval(Context mContext, String pkg, int uid) {
        NotificationBackend backend = new NotificationBackend();
        backend.setAllowBubbles(pkg, uid, false);
        // changing the global settings will cause the observer on the host page to reload
        // correct preference state
        Settings.Secure.putInt(mContext.getContentResolver(),
                NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF);
    }

    // Apply global bubbles approval
    public static void applyBubblesApproval(Context mContext, String pkg, int uid) {
        NotificationBackend backend = new NotificationBackend();
        backend.setAllowBubbles(pkg, uid, true);
        // changing the global settings will cause the observer on the host page to reload
        // correct preference state
        Settings.Secure.putInt(mContext.getContentResolver(),
                NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
    }
}
+7 −5
Original line number Diff line number Diff line
@@ -52,11 +52,11 @@ public class BubbleSummaryPreferenceController extends NotificationPreferenceCon
        if (mAppRow == null && mChannel == null) {
            return false;
        }
        if (mChannel != null) {
            if (Settings.Secure.getInt(mContext.getContentResolver(),
                    NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_OFF) {
                return false;
            }
        if (mChannel != null) {
            if (isDefaultChannel()) {
                return true;
            } else {
@@ -91,7 +91,9 @@ public class BubbleSummaryPreferenceController extends NotificationPreferenceCon
            if (mChannel != null) {
                canBubble |= mChannel.canBubble();
            } else {
               canBubble |= mAppRow.allowBubbles;
               canBubble |= mAppRow.allowBubbles
                       && (Settings.Secure.getInt(mContext.getContentResolver(),
                       NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON) == SYSTEM_WIDE_ON);
            }
        }
        return mContext.getString(canBubble ? R.string.switch_on_text : R.string.switch_off_text);
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.settings.notification;

import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.os.Bundle;

import androidx.appcompat.app.AlertDialog;

import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;

public class BubbleWarningDialogFragment extends InstrumentedDialogFragment {
    static final String KEY_PKG = "p";
    static final String KEY_UID = "u";


    @Override
    public int getMetricsCategory() {
        return SettingsEnums.DIALOG_APP_BUBBLE_SETTINGS;
    }

    public BubbleWarningDialogFragment setPkgInfo(String pkg, int uid) {
        Bundle args = new Bundle();
        args.putString(KEY_PKG, pkg);
        args.putInt(KEY_UID, uid);
        setArguments(args);
        return this;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final Bundle args = getArguments();
        final String pkg = args.getString(KEY_PKG);
        final int uid = args.getInt(KEY_UID);

        final String title =
                getResources().getString(R.string.bubbles_feature_disabled_dialog_title);
        final String summary = getResources()
                .getString(R.string.bubbles_feature_disabled_dialog_text);
        return new AlertDialog.Builder(getContext())
                .setMessage(summary)
                .setTitle(title)
                .setCancelable(true)
                .setPositiveButton(R.string.bubbles_feature_disabled_button_approve,
                        (dialog, id) ->
                                BubblePreferenceController.applyBubblesApproval(
                                        getContext(), pkg, uid))
                .setNegativeButton(R.string.bubbles_feature_disabled_button_cancel,
                        (dialog, id) ->
                                BubblePreferenceController.revertBubblesApproval(
                                        getContext(), pkg, uid))
                .create();
    }
}
Loading