Skip to content

Commit

Permalink
Merge pull request #4 from PuntitOwO/auto-pip
Browse files Browse the repository at this point in the history
0.7.0: Auto PIP feature
  • Loading branch information
PuntitOwO authored Jul 19, 2022
2 parents 442ead7 + af5a95a commit cd35b81
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.7.0

* Automatic pip method implemented for Android S.
* Bugfix: [Issue #2](https://github.com/PuntitOwO/simple_pip_mode_flutter/issues/2)

## 0.6.0

* Callback enabling process simplified:
Expand Down
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,30 @@ class MyWidget extends StatelessWidget {
}
```

## Setting automatic pip mode

Import `simple_pip.dart` file and call `setAutoPipMode` method.
This needs at least API level 31.

```dart
import 'package:simple_pip_mode/simple_pip.dart';
class MyWidget extends StatelessWidget {
Widget build(BuildContext context) {
return IconButton(
icon: Icon(Icons.picture_in_picture),
onPressed: () => SimplePip().setAutoPipMode(),
);
}
}
```

This way, when user presses home (or uses home gesture), the app enters PIP mode automatically.

## Enabling callbacks

There's two ways of enabling callbacks:
* [Activity wrapper](#activity-wrapper) (New in 0.6.0!)
* [Activity wrapper](#activity-wrapper) (Recommended!)
* [Callback helper](#callback-helper)

### Activity wrapper
Expand Down Expand Up @@ -164,6 +184,15 @@ class MyWidget extends StatelessWidget {
```
You can also pass callbacks directly to `PipWidget`.

# Notes

## Multi-platform apps

Every `SimplePip` method calls android native code, so make sure you only make a call to a `SimplePip` method when running in an Android device.
This includes `SimplePip.isPipAvailable`.

Calling `SimplePip` methods on a non-Android device will raise a `MissingPluginException` error.

# Contribute

I'm currently working on more features, so issues and pull requests are appreciated!
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class SimplePipModePlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
)
} else if (call.method == "isPipActivated") {
result.success(activity.isInPictureInPictureMode)
} else if (call.method == "isAutoPipAvailable") {
result.success(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
} else if (call.method == "enterPipMode") {
val aspectRatio = call.argument<List<Int>>("aspectRatio")
val autoEnter = call.argument<Boolean>("autoEnter")
Expand All @@ -65,6 +67,22 @@ class SimplePipModePlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
result.success(
activity.enterPictureInPictureMode(params.build())
)
} else if (call.method == "setAutoPipMode") {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val aspectRatio = call.argument<List<Int>>("aspectRatio")
val seamlessResize = call.argument<Boolean>("seamlessResize")
// TODO(add actions)
var params = PictureInPictureParams.Builder()
.setAspectRatio(Rational(aspectRatio!![0], aspectRatio[1]))
.setAutoEnterEnabled(true)
.setSeamlessResizeEnabled(seamlessResize!!)

activity.setPictureInPictureParams(params.build())

result.success(true)
} else {
result.error("NotImplemented", "System Version less than Android S found", "Expected Android S or newer.")
}
} else {
result.notImplemented()
}
Expand All @@ -75,15 +93,13 @@ class SimplePipModePlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
}

override fun onDetachedFromActivityForConfigChanges() {
TODO("Not yet implemented")
}

override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
activity = binding.activity
}

override fun onDetachedFromActivity() {
TODO("Not yet implemented")
}

}
26 changes: 26 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class ExampleApp extends StatefulWidget {
class _ExampleAppState extends State<ExampleApp> {
bool pipAvailable = false;
List<int> aspectRatio = aspectRatios.first;
bool autoPipAvailable = false;
bool autoPipSwitch = false;
late SimplePip pip;

@override
Expand All @@ -43,8 +45,10 @@ class _ExampleAppState extends State<ExampleApp> {
/// Checks if system supports PIP mode
Future<void> requestPipAvailability() async {
var isAvailable = await SimplePip.isPipAvailable;
var isAutoPipAvailable = await SimplePip.isAutoPipAvailable;
setState(() {
pipAvailable = isAvailable;
autoPipAvailable = isAutoPipAvailable;
});
}

Expand All @@ -69,6 +73,12 @@ class _ExampleAppState extends State<ExampleApp> {
value: aspectRatio,
onChanged: (List<int>? newValue) {
if (newValue == null) return;
if (autoPipSwitch) {
pip.setAutoPipMode(
aspectRatio: newValue,
seamlessResize: true,
);
}
setState(() {
aspectRatio = newValue;
});
Expand All @@ -82,6 +92,22 @@ class _ExampleAppState extends State<ExampleApp> {
)
.toList(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Auto Enter (Android S): '),
Switch(
value: autoPipSwitch,
onChanged: autoPipAvailable
? (newValue) {
setState(() {
autoPipSwitch = newValue;
});
}
: null,
),
],
),
IconButton(
onPressed: pipAvailable
? () => pip.enterPipMode(
Expand Down
22 changes: 22 additions & 0 deletions lib/simple_pip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ class SimplePip {
return isAvailable ?? false;
}

/// Whether the device supports AutoEnter PIP parameter (Android S)
static Future<bool> get isAutoPipAvailable async {
final bool? isAvailable = await _channel.invokeMethod('isAutoPipAvailable');
return isAvailable ?? false;
}

/// Whether the app is currently in PIP mode.
static Future<bool> get isPipActivated async {
final bool? isActivated = await _channel.invokeMethod('isPipActivated');
Expand Down Expand Up @@ -46,6 +52,22 @@ class SimplePip {
return enteredSuccessfully ?? false;
}

/// Request setting automatic PIP mode.
/// Android 12 (Android S, API level 31) or newer required.
Future<bool> setAutoPipMode({
aspectRatio = const [16, 9],
seamlessResize = false,
}) async {
Map params = {
'aspectRatio': aspectRatio,
'autoEnter': true,
'seamlessResize': seamlessResize,
};
final bool? setSuccessfully =
await _channel.invokeMethod('setAutoPipMode', params);
return setSuccessfully ?? false;
}

SimplePip({this.onPipEntered, this.onPipExited}) {
if (onPipEntered != null || onPipExited != null) {
_channel.setMethodCallHandler(
Expand Down
3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: simple_pip_mode
description: A complete Picture-In-Picutre mode plugin (Android support only)
version: 0.6.0
version: 0.7.0
repository: https://github.com/PuntitOwO/simple_pip_mode_flutter
homepage: https://puntito.cl/pip

environment:
sdk: ">=2.16.0 <3.0.0"
Expand Down

0 comments on commit cd35b81

Please sign in to comment.