1/** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import Audio from '@ohos.multimedia.audio'; 17import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil'; 18import { SubHeader } from '../../../../../../common/component/src/main/ets/default/textComponent'; 19import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData'; 20import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent'; 21import { registerObserver, RingerModel, VolumeModel } from '../model/volumeControlImpl/VolumeControlModel'; 22 23const VOLUME_MIN_VALUE = 0; 24const VOLUME_MAX_VALUE = 15; 25 26/** 27 * Volume control 28 */ 29@Entry 30@Component 31export struct VolumeControl { 32 private TAG = ConfigData.TAG + ' VolumeControl '; 33 34 build() { 35 Column() { 36 GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) { 37 Column() { 38 //head 39 HeadComponent({ headName: $r('app.string.volumeControlTab') }); 40 41 SubHeader({ titleContent: $r('app.string.soundMode') }); 42 43 // sound mode 44 AudioRingerModeComponent(); 45 46 SubHeader({ titleContent: $r('app.string.volumeControl') }); 47 48 // volume control 49 VolumeControlComponent(); 50 } 51 .useSizeType({ 52 sm: { span: 4, offset: 0 }, 53 md: { span: 6, offset: 1 }, 54 lg: { span: 8, offset: 2 } 55 }) 56 } 57 .width(ConfigData.WH_100_100) 58 .height(ConfigData.WH_100_100) 59 } 60 .backgroundColor($r("sys.color.ohos_id_color_sub_background")) 61 .width(ConfigData.WH_100_100) 62 .height(ConfigData.WH_100_100) 63 } 64 65 aboutToAppear() { 66 LogUtil.info(`${this.TAG} aboutToAppear in`); 67 registerObserver(); 68 LogUtil.info(`${this.TAG} aboutToAppear out`); 69 } 70} 71 72/** 73 * AudioRingerMode component 74 */ 75@Component 76struct AudioRingerModeComponent { 77 @StorageLink('ringerModeNormal') ringerModeNormal: boolean = false; 78 @StorageLink('ringerModeSilent') ringerModeSilent: boolean = false; 79 private ringerSilentModel: RingerModel = new RingerModel(Audio.AudioRingMode.RINGER_MODE_SILENT); 80 private ringerNormalModel: RingerModel = new RingerModel(Audio.AudioRingMode.RINGER_MODE_NORMAL); 81 private TAG = ConfigData.TAG + ' AudioRingerModeComponent '; 82 83 build() { 84 Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceAround }) { 85 Row() { 86 Blank() 87 88 AudioRingerModeItem({ 89 checked: $ringerModeNormal, 90 audioRingerModel: this.ringerNormalModel, 91 image: $r("app.media.ic_ring"), 92 text: $r('app.string.soundModeSound') 93 }); 94 95 Blank() 96 97 Divider() 98 .vertical(true) 99 .margin({ bottom: 14 }) 100 .color($r('sys.color.ohos_id_color_list_separator')) 101 102 Blank() 103 104 AudioRingerModeItem({ 105 checked: $ringerModeSilent, 106 audioRingerModel: this.ringerSilentModel, 107 image: $r("app.media.ic_ring_off"), 108 text: $r('app.string.soundModeSilent') 109 }); 110 111 Blank() 112 } 113 .width(ConfigData.WH_100_100) 114 } 115 .borderRadius($r('app.float.radius_24')) 116 .backgroundColor($r("sys.color.ohos_id_color_foreground_contrary")) 117 .width(ConfigData.WH_100_100) 118 .height($r('app.float.wh_value_119')) 119 .padding({ 120 top: $r('app.float.distance_14'), 121 bottom: $r('app.float.distance_2') 122 }) 123 } 124 125 aboutToAppear() { 126 LogUtil.info(`${this.TAG} aboutToAppear in`); 127 LogUtil.info(`${this.TAG} aboutToAppear out`); 128 } 129} 130 131/** 132 * AudioRingerMode item 133 */ 134@Component 135struct AudioRingerModeItem { 136 @Link checked: boolean; 137 private audioRingerModel: RingerModel | null = null; 138 private image: Resource | null = null; 139 private text: string | Resource = ''; 140 141 build() { 142 Column() { 143 Image(this.image) 144 .width($r('app.float.wh_value_24')) 145 .height($r('app.float.wh_value_24')) 146 .objectFit(ImageFit.Contain) 147 .fillColor($r("sys.color.ohos_fa_icon_secondary")) 148 149 Text(this.text) 150 .fontColor($r("app.color.font_color_182431")) 151 .fontSize($r("sys.float.ohos_id_text_size_body2")) 152 .lineHeight($r("app.float.lineHeight_19")) 153 .fontWeight(FontWeight.Regular) 154 .textAlign(TextAlign.Center) 155 .margin({ top: $r('app.float.distance_8') }); 156 157 Radio({ value: '', group: '' }) 158 .width($r('app.float.wh_value_24')) 159 .height($r('app.float.wh_value_24')) 160 .margin({ top: $r('app.float.distance_4') }) 161 .checked(this.checked) 162 .onChange((vue) => { 163 if (vue) { 164 this.audioRingerModel?.setRingerMode(); 165 } 166 }) 167 } 168 .alignItems(HorizontalAlign.Center) 169 .onClick(() => { 170 LogUtil.info(ConfigData.TAG + 'AudioRingerModeItem : item is clicked'); 171 this.audioRingerModel?.setRingerMode(); 172 }); 173 } 174} 175 176/** 177 * Volume control component 178 */ 179@Component 180struct VolumeControlComponent { 181 @StorageLink('volume_ringtone') volumeRingTone: number = 2; 182 @StorageLink('volume_media') volumeMedia: number = 2; 183 @StorageLink('volume_voicecall') volumeVoiceCall: number = 2; 184 private voiceCallModel: VolumeModel = new VolumeModel(Audio.AudioVolumeType.VOICE_CALL); 185 private ringtoneModel: VolumeModel = new VolumeModel(Audio.AudioVolumeType.RINGTONE); 186 private mediaModel: VolumeModel = new VolumeModel(Audio.AudioVolumeType.MEDIA); 187 private TAG = ConfigData.TAG + ' VolumeControlComponent '; 188 189 build() { 190 Column() { 191 VolumeControlItem({ 192 image: this.volumeRingTone === 0 ? $r("app.media.ic_ring_off") : $r("app.media.ic_ring"), 193 volumeValue: $volumeRingTone, 194 volumeModel: this.ringtoneModel, 195 text: $r("app.string.volumeControlRing") }) 196 197 VolumeControlItem({ 198 image: this.volumeMedia === 0 ? $r("app.media.ic_media_off") : $r("app.media.ic_media"), 199 volumeValue: $volumeMedia, 200 volumeModel: this.mediaModel, 201 text: $r("app.string.volumeControlMedia") }) 202 203 VolumeControlItem({ 204 image: $r("app.media.ic_call"), 205 volumeValue: $volumeVoiceCall, 206 volumeModel: this.voiceCallModel, 207 text: $r("app.string.volumeControlCall") }) 208 } 209 .width(ConfigData.WH_100_100) 210 .borderRadius($r('app.float.radius_24')) 211 .backgroundColor($r("sys.color.ohos_id_color_foreground_contrary")) 212 .padding($r('app.float.distance_12')) 213 } 214 215 aboutToAppear(): void { 216 LogUtil.info(`${this.TAG} aboutToAppear in`); 217 LogUtil.info(`${this.TAG} aboutToAppear out`); 218 let volumeGroupManager = Audio.getAudioManager().getVolumeManager(); 219 volumeGroupManager.on('volumeChange', (data) => { 220 LogUtil.info(`${this.TAG} volumeType: ${data.volumeType} volume: ${data.volume}`); 221 if (data.volumeType === Audio.AudioVolumeType.RINGTONE) { 222 AppStorage.SetOrCreate('volume_ringtone', data.volume); 223 this.volumeRingTone = data.volume; 224 } else if (data.volumeType === Audio.AudioVolumeType.VOICE_CALL) { 225 AppStorage.SetOrCreate('volume_voicecall', data.volume); 226 } else if (data.volumeType === Audio.AudioVolumeType.MEDIA) { 227 AppStorage.SetOrCreate('volume_media', data.volume); 228 } 229 }) 230 } 231} 232 233/** 234 * Volume control item 235 */ 236@Component 237struct VolumeControlItem { 238 @Link volumeValue: number; 239 private volumeModel: VolumeModel | null = null; 240 private image: Resource | null = null; 241 private text: string | Resource = ''; 242 243 build() { 244 Column() { 245 Row() { 246 Image(this.image) 247 .width($r('app.float.wh_value_20')) 248 .height($r('app.float.wh_value_20')) 249 .fillColor($r("sys.color.ohos_fa_icon_secondary")) 250 .objectFit(ImageFit.Contain) 251 252 Text(this.text) 253 .fontSize($r("app.float.font_16")) 254 .lineHeight($r("app.float.lineHeight_22")) 255 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 256 .textAlign(TextAlign.Start) 257 .margin({ left: $r('app.float.distance_12') }) 258 .width(ConfigData.WH_100_100); 259 } 260 .margin({ bottom: $r('app.float.distance_1') }) 261 .width(ConfigData.WH_100_100) 262 .align(Alignment.Center); 263 264 Slider({ 265 value: this.volumeValue, 266 min: VOLUME_MIN_VALUE, 267 max: VOLUME_MAX_VALUE, 268 style: SliderStyle.InSet 269 }) 270 .selectedColor($r('app.color.font_color_007DFF')) 271 .blockColor(Color.White) 272 .height($r('app.float.wh_value_40')) 273 .width(ConfigData.WH_100_100) 274 .onChange((value: number) => { 275 this.volumeModel?.setVolume(value); 276 }); 277 } 278 .margin({ top: $r("app.float.distance_12") }) 279 .width(ConfigData.WH_100_100); 280 } 281}