Skip to content

Commit

Permalink
Merge pull request #38 from yosemiteyss/feat/get-audio-stream
Browse files Browse the repository at this point in the history
feat: add get android audio stream and ios audio session category methods
  • Loading branch information
yosemiteyss authored Mar 30, 2023
2 parents 2fdce74 + 36d4b0b commit f5d70a6
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ object MethodName {
const val RAISE_VOLUME = "raiseVolume"
const val LOWER_VOLUME = "lowerVolume"
const val SET_ANDROID_AUDIO_STREAM = "setAndroidAudioStream"
const val GET_ANDROID_AUDIO_STREAM = "getAndroidAudioStream"
const val GET_MUTE = "getMute"
const val SET_MUTE = "setMute"
const val TOGGLE_MUTE = "toggleMute"
Expand All @@ -30,6 +31,7 @@ object ErrorCode {
const val SET_MUTE = "1006"
const val TOGGLE_MUTE = "1007"
const val SET_ANDROID_AUDIO_STREAM = "1008"
const val GET_ANDROID_AUDIO_STREAM = "1010"
}

object ErrorMessage {
Expand All @@ -42,4 +44,5 @@ object ErrorMessage {
const val SET_MUTE = "Failed to set mute"
const val TOGGLE_MUTE = "Failed to toggle mute"
const val SET_ANDROID_AUDIO_STREAM = "Failed to set audio stream"
const val GET_ANDROID_AUDIO_STREAM = "Failed to get audio stream"
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ class FlutterVolumeControllerPlugin : FlutterPlugin, ActivityAware, MethodCallHa
)
}
}
MethodName.GET_ANDROID_AUDIO_STREAM -> {
try {
val audioStream = getActivityAudioStream()
result.success(audioStream?.ordinal)
} catch (e: Exception) {
result.error(
ErrorCode.GET_ANDROID_AUDIO_STREAM,
ErrorMessage.GET_ANDROID_AUDIO_STREAM,
e.message
)
}
}
else -> {
result.notImplemented()
}
Expand Down Expand Up @@ -224,6 +236,10 @@ class FlutterVolumeControllerPlugin : FlutterPlugin, ActivityAware, MethodCallHa
observedStream = audioStream
}

private fun getActivityAudioStream(): AudioStream? {
return AudioStream.values().firstOrNull { it.streamType == activity?.volumeControlStream }
}

private fun resumeActivityAudioStream() {
activity?.volumeControlStream = observedStream.streamType
}
Expand Down
18 changes: 4 additions & 14 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
# flutter_volume_controller_example

Demonstrates how to use the flutter_volume_controller plugin.

## Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)

For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
## Run integration test
```
flutter test integration_test/main_test.dart
```
27 changes: 25 additions & 2 deletions example/integration_test/main_test.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:io';

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
import 'package:integration_test/integration_test.dart';
Expand Down Expand Up @@ -83,9 +85,30 @@ void main() {
expect(actual, target);
});

/// TODO: add test for [FlutterVolumeController.setAndroidAudioStream].
if (Platform.isAndroid) {
testWidgets('should set android audio stream', (tester) async {
const target = AudioStream.music;

await FlutterVolumeController.setAndroidAudioStream(stream: target);
await _insertDelay();

final actual = await FlutterVolumeController.getAndroidAudioStream();
expect(actual, target);
});
}

/// TODO: add test for [FlutterVolumeController.setIOSAudioSessionCategory].
if (Platform.isIOS) {
testWidgets('should set ios audio session category', (tester) async {
const target = AudioSessionCategory.playback;

await FlutterVolumeController.setIOSAudioSessionCategory(
category: target);
await _insertDelay();

final actual = await FlutterVolumeController.getIOSAudioSessionCategory();
expect(actual, target);
});
}

testWidgets('should receive volume event after adding listener',
(tester) async {
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: ec7bdfce9f82e8314b94d9cd1cfee2974a0e1c97

COCOAPODS: 1.11.2
COCOAPODS: 1.11.3
26 changes: 24 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class _HomeState extends State<Home> {
},
),
),
if (Platform.isAndroid)
if (Platform.isAndroid) ...[
Center(
child: ElevatedButton(
child: const Text('Switch audio stream'),
Expand All @@ -85,7 +85,18 @@ class _HomeState extends State<Home> {
},
),
),
if (Platform.isIOS)
Center(
child: ElevatedButton(
child: const Text('Get audio stream'),
onPressed: () async {
final stream =
await FlutterVolumeController.getAndroidAudioStream();
_showSnackBar('Audio stream: $stream');
},
),
),
],
if (Platform.isIOS) ...[
Center(
child: ElevatedButton(
child: const Text('Switch audio session category'),
Expand All @@ -102,6 +113,17 @@ class _HomeState extends State<Home> {
},
),
),
Center(
child: ElevatedButton(
child: const Text('Get audio session category'),
onPressed: () async {
final category = await FlutterVolumeController
.getIOSAudioSessionCategory();
_showSnackBar('Audio session category: $category');
},
),
),
],
Center(
child: ElevatedButton(
child: const Text('Get Volume'),
Expand Down
6 changes: 3 additions & 3 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b"
sha256: c224ac897bed083dabf11f238dd11a239809b446740be0c2044608c50029ffdf
url: "https://pub.dev"
source: hosted
version: "2.0.7"
version: "2.0.9"
flutter_test:
dependency: "direct dev"
description: flutter
Expand Down Expand Up @@ -288,4 +288,4 @@ packages:
version: "3.0.1"
sdks:
dart: ">=2.18.0 <3.0.0"
flutter: ">=2.8.0"
flutter: ">=3.0.0"
3 changes: 3 additions & 0 deletions ios/Classes/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct MethodName {
static let raiseVolume = "raiseVolume"
static let lowerVolume = "lowerVolume"
static let setIOSAudioSessionCategory = "setIOSAudioSessionCategory"
static let getIOSAudioSessionCategory = "getIOSAudioSessionCategory"
static let getMute = "getMute"
static let setMute = "setMute"
static let toggleMute = "toggleMute"
Expand All @@ -35,6 +36,7 @@ struct ErrorCode {
static let setMute = "1006"
static let toggleMute = "1007"
static let setIOSAudioSessionCategory = "1009"
static let getIOSAudioSessionCategory = "1011"
}

struct ErrorMessage {
Expand All @@ -47,4 +49,5 @@ struct ErrorMessage {
static let setMute = "Failed to set mute"
static let toggleMute = "Failed to toggle mute"
static let setIOSAudioSessionCategory = "Failed to set audio session category"
static let getIOSAudioSessionCategory = "Failed to get audio session category"
}
6 changes: 6 additions & 0 deletions ios/Classes/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,9 @@ extension AVAudioSession {
try setActive(true)
}
}

extension CaseIterable where Self: Equatable {
var ordinal: Self.AllCases.Index {
return Self.allCases.firstIndex(of: self)!
}
}
7 changes: 7 additions & 0 deletions ios/Classes/SwiftFlutterVolumeControllerPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ public class SwiftFlutterVolumeControllerPlugin: NSObject, FlutterPlugin {
} catch {
result(FlutterError(code: ErrorCode.setIOSAudioSessionCategory, message: ErrorMessage.setIOSAudioSessionCategory, details: error.localizedDescription))
}
case MethodName.getIOSAudioSessionCategory:
do {
let category = try SwiftFlutterVolumeControllerPlugin.volumeController.getAudioSessionCategory()
result(category?.ordinal)
} catch {
result(FlutterError(code: ErrorCode.getIOSAudioSessionCategory, message: ErrorMessage.getIOSAudioSessionCategory, details: error.localizedDescription))
}
default:
result(FlutterMethodNotImplemented)
}
Expand Down
5 changes: 5 additions & 0 deletions ios/Classes/VolumeController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ class VolumeController {
currentCategory = category.categoryType
}

func getAudioSessionCategory() throws -> AudioSessionCategory? {
try audioSession.setActive(true)
return AudioSessionCategory.allCases.first { category in category.categoryType == audioSession.category }
}

func resumeAudioSession() throws {
try audioSession.activate(with: currentCategory)
}
Expand Down
6 changes: 6 additions & 0 deletions lib/src/constants.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
class MethodName {
const MethodName._();

static const String getVolume = 'getVolume';
static const String setVolume = 'setVolume';
static const String raiseVolume = 'raiseVolume';
static const String lowerVolume = 'lowerVolume';
static const String setAndroidAudioStream = 'setAndroidAudioStream';
static const String getAndroidAudioStream = 'getAndroidAudioStream';
static const String setIOSAudioSessionCategory = 'setIOSAudioSessionCategory';
static const String getIOSAudioSessionCategory = 'getIOSAudioSessionCategory';
static const String getMute = 'getMute';
static const String setMute = 'setMute';
static const String toggleMute = 'toggleMute';
}

class MethodArg {
const MethodArg._();

static const String volume = 'volume';
static const String step = 'step';
static const String showSystemUI = 'showSystemUI';
Expand Down
22 changes: 22 additions & 0 deletions lib/src/flutter_volume_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,17 @@ class FlutterVolumeController {
}
}

/// Get the current audio stream on Android.
static Future<AudioStream?> getAndroidAudioStream() async {
if (Platform.isAndroid) {
final index = await methodChannel
.invokeMethod<int>(MethodName.getAndroidAudioStream);
return index != null ? AudioStream.values[index] : null;
}

return null;
}

/// Set the default audio session category on iOS.
/// Adjusts to a different set of audio behaviors.
/// Use [category] to set the audio session category type on iOS.
Expand All @@ -189,6 +200,17 @@ class FlutterVolumeController {
}
}

/// Get the current audio session category on IOS.
static Future<AudioSessionCategory?> getIOSAudioSessionCategory() async {
if (Platform.isIOS) {
final index = await methodChannel
.invokeMethod<int>(MethodName.getIOSAudioSessionCategory);
return index != null ? AudioSessionCategory.values[index] : null;
}

return null;
}

/// Listen for volume changes.
/// Use [emitOnStart] to control whether volume value should be emitted
/// immediately right after the listener is attached.
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_plugin_android_lifecycle: ^2.0.7
flutter_plugin_android_lifecycle: ^2.0.9

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit f5d70a6

Please sign in to comment.