Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 161aed2

Browse files
authored
[battery_platform_interface] Introduce package. (#2975)
1 parent 2f33166 commit 161aed2

File tree

8 files changed

+254
-0
lines changed

8 files changed

+254
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 1.0.0
2+
3+
- Initial open-source release.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
//
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions are
5+
// met:
6+
//
7+
// * Redistributions of source code must retain the above copyright
8+
// notice, this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above
10+
// copyright notice, this list of conditions and the following disclaimer
11+
// in the documentation and/or other materials provided with the
12+
// distribution.
13+
// * Neither the name of Google Inc. nor the names of its
14+
// contributors may be used to endorse or promote products derived from
15+
// this software without specific prior written permission.
16+
//
17+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# battery_platform_interface
2+
3+
A common platform interface for the [`battery`][1] plugin.
4+
5+
This interface allows platform-specific implementations of the `battery`
6+
plugin, as well as the plugin itself, to ensure they are supporting the
7+
same interface.
8+
9+
# Usage
10+
11+
To implement a new platform-specific implementation of `battery`, extend
12+
[`BatteryPlatform`][2] with an implementation that performs the
13+
platform-specific behavior, and when you register your plugin, set the default
14+
`BatteryPlatform` by calling
15+
`BatteryPlatform.instance = MyPlatformBattery()`.
16+
17+
# Note on breaking changes
18+
19+
Strongly prefer non-breaking changes (such as adding a method to the interface)
20+
over breaking changes for this package.
21+
22+
See https://flutter.dev/go/platform-interface-breaking-changes for a discussion
23+
on why a less-clean interface is preferable to a breaking change.
24+
25+
[1]: ../battery
26+
[2]: lib/battery_platform_interface.dart
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
7+
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
8+
9+
import 'method_channel/method_channel_battery.dart';
10+
import 'enums/battery_state.dart';
11+
12+
export 'enums/battery_state.dart';
13+
14+
/// The interface that implementations of battery must implement.
15+
///
16+
/// Platform implementations should extend this class rather than implement it as `battery`
17+
/// does not consider newly added methods to be breaking changes. Extending this class
18+
/// (using `extends`) ensures that the subclass will get the default implementation, while
19+
/// platform implementations that `implements` this interface will be broken by newly added
20+
/// [BatteryPlatform] methods.
21+
abstract class BatteryPlatform extends PlatformInterface {
22+
/// Constructs a BatteryPlatform.
23+
BatteryPlatform() : super(token: _token);
24+
25+
static final Object _token = Object();
26+
27+
static BatteryPlatform _instance = MethodChannelBattery();
28+
29+
/// The default instance of [BatteryPlatform] to use.
30+
///
31+
/// Defaults to [MethodChannelBattery].
32+
static BatteryPlatform get instance => _instance;
33+
34+
/// Platform-specific plugins should set this with their own platform-specific
35+
/// class that extends [BatteryPlatform] when they register themselves.
36+
static set instance(BatteryPlatform instance) {
37+
PlatformInterface.verifyToken(instance, _token);
38+
_instance = instance;
39+
}
40+
41+
/// Gets the battery level from device.
42+
Future<int> batteryLevel() {
43+
throw UnimplementedError('batteryLevel() has not been implemented.');
44+
}
45+
46+
/// gets battery state from device.
47+
Stream<BatteryState> onBatteryStateChanged() {
48+
throw UnimplementedError(
49+
'onBatteryStateChanged() has not been implemented.');
50+
}
51+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// Indicates the current battery state.
2+
enum BatteryState {
3+
/// The battery is completely full of energy.
4+
full,
5+
6+
/// The battery is currently storing energy.
7+
charging,
8+
9+
/// The battery is currently losing energy.
10+
discharging
11+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import 'dart:async';
2+
3+
import 'package:flutter/services.dart';
4+
import 'package:meta/meta.dart';
5+
6+
import 'package:battery_platform_interface/battery_platform_interface.dart';
7+
8+
import '../battery_platform_interface.dart';
9+
10+
/// An implementation of [BatteryPlatform] that uses method channels.
11+
class MethodChannelBattery extends BatteryPlatform {
12+
/// The method channel used to interact with the native platform.
13+
@visibleForTesting
14+
MethodChannel channel = MethodChannel('plugins.flutter.io/battery');
15+
16+
/// The event channel used to interact with the native platform.
17+
@visibleForTesting
18+
EventChannel eventChannel = EventChannel('plugins.flutter.io/charging');
19+
20+
/// Method channel for getting battery level.
21+
Future<int> batteryLevel() async {
22+
return (await channel.invokeMethod('getBatteryLevel')).toInt();
23+
}
24+
25+
/// Stream variable for storing battery state.
26+
Stream<BatteryState> _onBatteryStateChanged;
27+
28+
/// Event channel for getting battery change state.
29+
Stream<BatteryState> onBatteryStateChanged() {
30+
if (_onBatteryStateChanged == null) {
31+
_onBatteryStateChanged = eventChannel
32+
.receiveBroadcastStream()
33+
.map((dynamic event) => _parseBatteryState(event));
34+
}
35+
return _onBatteryStateChanged;
36+
}
37+
}
38+
39+
/// Method for parsing battery state.
40+
BatteryState _parseBatteryState(String state) {
41+
switch (state) {
42+
case 'full':
43+
return BatteryState.full;
44+
case 'charging':
45+
return BatteryState.charging;
46+
case 'discharging':
47+
return BatteryState.discharging;
48+
default:
49+
throw ArgumentError('$state is not a valid BatteryState.');
50+
}
51+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: battery_platform_interface
2+
description: A common platform interface for the battery plugin.
3+
homepage: https://github.com/flutter/plugins/tree/master/packages/battery
4+
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
5+
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
6+
version: 1.0.0
7+
8+
dependencies:
9+
flutter:
10+
sdk: flutter
11+
meta: ^1.1.8
12+
plugin_platform_interface: ^1.0.2
13+
14+
dev_dependencies:
15+
flutter_test:
16+
sdk: flutter
17+
mockito: ^4.1.1
18+
pedantic: ^1.8.0
19+
20+
environment:
21+
sdk: ">=2.7.0 <3.0.0"
22+
flutter: ">=1.9.1+hotfix.4 <2.0.0"
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/services.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
8+
import 'package:battery_platform_interface/battery_platform_interface.dart';
9+
10+
import 'package:battery_platform_interface/method_channel/method_channel_battery.dart';
11+
12+
void main() {
13+
TestWidgetsFlutterBinding.ensureInitialized();
14+
15+
group("$MethodChannelBattery", () {
16+
MethodChannelBattery methodChannelBattery;
17+
18+
setUp(() async {
19+
methodChannelBattery = MethodChannelBattery();
20+
21+
methodChannelBattery.channel
22+
.setMockMethodCallHandler((MethodCall methodCall) async {
23+
switch (methodCall.method) {
24+
case 'getBatteryLevel':
25+
return 90;
26+
default:
27+
return null;
28+
}
29+
});
30+
31+
MethodChannel(methodChannelBattery.eventChannel.name)
32+
.setMockMethodCallHandler((MethodCall methodCall) async {
33+
switch (methodCall.method) {
34+
case 'listen':
35+
await ServicesBinding.instance.defaultBinaryMessenger
36+
.handlePlatformMessage(
37+
methodChannelBattery.eventChannel.name,
38+
methodChannelBattery.eventChannel.codec
39+
.encodeSuccessEnvelope('full'),
40+
(_) {},
41+
);
42+
break;
43+
case 'cancel':
44+
default:
45+
return null;
46+
}
47+
});
48+
});
49+
50+
/// Test for batetry level call.
51+
test("getBatteryLevel", () async {
52+
final int result = await methodChannelBattery.batteryLevel();
53+
expect(result, 90);
54+
});
55+
56+
/// Test for battery changed state call.
57+
test("onBatteryChanged", () async {
58+
final BatteryState result =
59+
await methodChannelBattery.onBatteryStateChanged().first;
60+
expect(result, BatteryState.full);
61+
});
62+
});
63+
}

0 commit comments

Comments
 (0)