• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.settings.notification;
18 
19 import android.app.INotificationManager;
20 import android.app.NotificationManager;
21 import android.content.ComponentName;
22 import android.content.Context;
23 import android.media.AudioManager;
24 import android.os.Binder;
25 import android.os.ServiceManager;
26 import android.os.Vibrator;
27 import android.provider.DeviceConfig;
28 import android.util.Log;
29 
30 import com.android.internal.annotations.VisibleForTesting;
31 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
32 
33 import java.util.Objects;
34 
35 /**
36  * Shared functionality and interfaces for volume controllers whose state can change by ringer mode
37  */
38 public abstract class RingerModeAffectedVolumePreferenceController extends
39         VolumeSeekBarPreferenceController {
40 
41     private final String mTag;
42 
43     protected int mNormalIconId;
44     protected int mVibrateIconId;
45     protected int mSilentIconId;
46     protected int mMuteIcon;
47 
48     protected Vibrator mVibrator;
49     protected int mRingerMode = AudioManager.RINGER_MODE_NORMAL;
50     protected ComponentName mSuppressor;
51     protected boolean mSeparateNotification;
52     protected INotificationManager mNoMan;
53 
54     private static final boolean CONFIG_SEPARATE_NOTIFICATION_DEFAULT_VAL = false;
55 
RingerModeAffectedVolumePreferenceController(Context context, String key, String tag)56     public RingerModeAffectedVolumePreferenceController(Context context, String key, String tag) {
57         super(context, key);
58         mTag = tag;
59         mVibrator = mContext.getSystemService(Vibrator.class);
60         if (mVibrator != null && !mVibrator.hasVibrator()) {
61             mVibrator = null;
62         }
63     }
64 
updateEffectsSuppressor()65     protected void updateEffectsSuppressor() {
66         final ComponentName suppressor = NotificationManager.from(mContext).getEffectsSuppressor();
67         if (Objects.equals(suppressor, mSuppressor)) return;
68 
69         if (mNoMan == null) {
70             mNoMan = INotificationManager.Stub.asInterface(
71                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
72         }
73 
74         final int hints;
75         try {
76             hints = mNoMan.getHintsFromListenerNoToken();
77         } catch (android.os.RemoteException ex) {
78             Log.w(mTag, "updateEffectsSuppressor: " + ex.getMessage());
79             return;
80         }
81 
82         if (hintsMatch(hints)) {
83             mSuppressor = suppressor;
84             if (mPreference != null) {
85                 final String text = SuppressorHelper.getSuppressionText(mContext, suppressor);
86                 mPreference.setSuppressionText(text);
87             }
88         }
89     }
90 
91     @VisibleForTesting
setPreference(VolumeSeekBarPreference volumeSeekBarPreference)92     void setPreference(VolumeSeekBarPreference volumeSeekBarPreference) {
93         mPreference = volumeSeekBarPreference;
94     }
95 
96     @VisibleForTesting
setVibrator(Vibrator vibrator)97     void setVibrator(Vibrator vibrator) {
98         mVibrator = vibrator;
99     }
100 
101     @Override
isSliceable()102     public boolean isSliceable() {
103         return true;
104     }
105 
106     @Override
isPublicSlice()107     public boolean isPublicSlice() {
108         return true;
109     }
110 
111     @Override
useDynamicSliceSummary()112     public boolean useDynamicSliceSummary() {
113         return true;
114     }
115 
116     @Override
getMuteIcon()117     public int getMuteIcon() {
118         return mMuteIcon;
119     }
120 
isSeparateNotificationConfigEnabled()121     protected boolean isSeparateNotificationConfigEnabled() {
122         return Binder.withCleanCallingIdentity(()
123                 -> DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
124                 SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION,
125                 CONFIG_SEPARATE_NOTIFICATION_DEFAULT_VAL));
126     }
127 
128     /**
129      * side effect: updates the cached value of the config
130      * @return has the config changed?
131      */
readSeparateNotificationVolumeConfig()132     protected boolean readSeparateNotificationVolumeConfig() {
133         boolean newVal = isSeparateNotificationConfigEnabled();
134 
135         boolean valueUpdated = newVal != mSeparateNotification;
136         if (valueUpdated) {
137             mSeparateNotification = newVal;
138         }
139 
140         return valueUpdated;
141     }
142 
143     /**
144      * Updates UI Icon in response to ringer mode changes.
145      * @return whether the ringer mode has changed.
146      */
updateRingerMode()147     protected boolean updateRingerMode() {
148         final int ringerMode = mHelper.getRingerModeInternal();
149         if (mRingerMode == ringerMode) {
150             return false;
151         }
152         mRingerMode = ringerMode;
153         selectPreferenceIconState();
154         return true;
155     }
156 
157     /**
158      * Switching among normal/mute/vibrate
159      */
selectPreferenceIconState()160     protected void selectPreferenceIconState() {
161         if (mPreference != null) {
162             if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
163                 mPreference.showIcon(mNormalIconId);
164             } else {
165                 if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE && mVibrator != null) {
166                     mMuteIcon = mVibrateIconId;
167                 } else {
168                     mMuteIcon = mSilentIconId;
169                 }
170                 mPreference.showIcon(getMuteIcon());
171             }
172         }
173     }
174 
hintsMatch(int hints)175     protected abstract boolean hintsMatch(int hints);
176 
177 }
178