• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.ActivityThread;
20 import android.app.NotificationManager;
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.media.AudioManager;
26 import android.os.Binder;
27 import android.os.Handler;
28 import android.os.Looper;
29 import android.os.Message;
30 import android.provider.DeviceConfig;
31 import android.service.notification.NotificationListenerService;
32 
33 import androidx.lifecycle.OnLifecycleEvent;
34 
35 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
36 import com.android.settings.R;
37 import com.android.settingslib.core.lifecycle.Lifecycle;
38 
39 import java.util.Set;
40 
41 /**
42  * This slider represents both ring and notification
43  */
44 public class RingVolumePreferenceController extends
45         RingerModeAffectedVolumePreferenceController {
46 
47     private static final String KEY_RING_VOLUME = "ring_volume";
48     private static final String TAG = "RingVolumePreferenceController";
49 
50     private final RingReceiver mReceiver = new RingReceiver();
51     private final H mHandler = new H();
52 
RingVolumePreferenceController(Context context)53     public RingVolumePreferenceController(Context context) {
54         this(context, KEY_RING_VOLUME);
55     }
56 
RingVolumePreferenceController(Context context, String key)57     public RingVolumePreferenceController(Context context, String key) {
58         super(context, key, TAG);
59 
60         mNormalIconId = R.drawable.ic_notifications;
61         mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
62         mSilentIconId = R.drawable.ic_notifications_off_24dp;
63 
64         mSeparateNotification = isSeparateNotificationConfigEnabled();
65         updateRingerMode();
66     }
67 
68     /**
69      * As the responsibility of this slider changes, so should its title & icon
70      */
onDeviceConfigChange(DeviceConfig.Properties properties)71     private void onDeviceConfigChange(DeviceConfig.Properties properties) {
72         Set<String> changeSet = properties.getKeyset();
73         if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
74             boolean valueUpdated = readSeparateNotificationVolumeConfig();
75             if (valueUpdated) {
76                 updateEffectsSuppressor();
77                 selectPreferenceIconState();
78             }
79         }
80     }
81 
82     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
83     @Override
onResume()84     public void onResume() {
85         super.onResume();
86         mReceiver.register(true);
87         readSeparateNotificationVolumeConfig();
88         Binder.withCleanCallingIdentity(()
89                 -> DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
90                 ActivityThread.currentApplication().getMainExecutor(), this::onDeviceConfigChange));
91         updateEffectsSuppressor();
92         selectPreferenceIconState();
93 
94         if (mPreference != null) {
95             mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
96         }
97     }
98 
99     @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
100     @Override
onPause()101     public void onPause() {
102         super.onPause();
103         mReceiver.register(false);
104         Binder.withCleanCallingIdentity(() ->
105                 DeviceConfig.removeOnPropertiesChangedListener(this::onDeviceConfigChange));
106     }
107 
108     @Override
getPreferenceKey()109     public String getPreferenceKey() {
110         return KEY_RING_VOLUME;
111     }
112 
113     @Override
getAvailabilityStatus()114     public int getAvailabilityStatus() {
115         boolean separateNotification = isSeparateNotificationConfigEnabled();
116         return !separateNotification && !mHelper.isSingleVolume()
117                 ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
118     }
119 
120     @Override
getAudioStream()121     public int getAudioStream() {
122         return AudioManager.STREAM_RING;
123     }
124 
125     @Override
hintsMatch(int hints)126     protected boolean hintsMatch(int hints) {
127         boolean notificationSeparated = isSeparateNotificationConfigEnabled();
128         return (hints & NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS) != 0
129                 || (hints & NotificationListenerService.HINT_HOST_DISABLE_EFFECTS) != 0
130                 || ((hints & NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS)
131                 != 0 && !notificationSeparated);
132     }
133 
134 
135     private final class H extends Handler {
136         private static final int UPDATE_EFFECTS_SUPPRESSOR = 1;
137         private static final int UPDATE_RINGER_MODE = 2;
138 
H()139         private H() {
140             super(Looper.getMainLooper());
141         }
142 
143         @Override
handleMessage(Message msg)144         public void handleMessage(Message msg) {
145             switch (msg.what) {
146                 case UPDATE_EFFECTS_SUPPRESSOR:
147                     updateEffectsSuppressor();
148                     break;
149                 case UPDATE_RINGER_MODE:
150                     updateRingerMode();
151                     break;
152             }
153         }
154     }
155 
156     private class RingReceiver extends BroadcastReceiver {
157         private boolean mRegistered;
158 
register(boolean register)159         public void register(boolean register) {
160             if (mRegistered == register) return;
161             if (register) {
162                 final IntentFilter filter = new IntentFilter();
163                 filter.addAction(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
164                 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
165                 mContext.registerReceiver(this, filter);
166             } else {
167                 mContext.unregisterReceiver(this);
168             }
169             mRegistered = register;
170         }
171 
172         @Override
onReceive(Context context, Intent intent)173         public void onReceive(Context context, Intent intent) {
174             final String action = intent.getAction();
175             if (NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED.equals(action)) {
176                 mHandler.sendEmptyMessage(H.UPDATE_EFFECTS_SUPPRESSOR);
177             } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
178                 mHandler.sendEmptyMessage(H.UPDATE_RINGER_MODE);
179             }
180         }
181     }
182 
183 }
184