704
735
g_free (real_lang);
740
const std::array<std::pair<std::string,UpDeviceKind>,UP_DEVICE_KIND_LAST> kinds = {
741
std::make_pair("unknown", UP_DEVICE_KIND_UNKNOWN),
742
std::make_pair("line-power", UP_DEVICE_KIND_LINE_POWER),
743
std::make_pair("battery", UP_DEVICE_KIND_BATTERY),
744
std::make_pair("ups", UP_DEVICE_KIND_UPS),
745
std::make_pair("monitor", UP_DEVICE_KIND_MONITOR),
746
std::make_pair("mouse", UP_DEVICE_KIND_MOUSE),
747
std::make_pair("keyboard", UP_DEVICE_KIND_KEYBOARD),
748
std::make_pair("pda", UP_DEVICE_KIND_PDA),
749
std::make_pair("phone", UP_DEVICE_KIND_PHONE),
750
std::make_pair("media-player", UP_DEVICE_KIND_MEDIA_PLAYER),
751
std::make_pair("tablet", UP_DEVICE_KIND_TABLET),
752
std::make_pair("computer", UP_DEVICE_KIND_COMPUTER)
754
const std::string& kind2str(UpDeviceKind kind)
759
[kind](decltype(kinds[0])& i){return i.second==kind;}
762
UpDeviceKind str2kind(const std::string& str)
767
[str](decltype(kinds[0])& i){return i.first==str;}
774
const std::array<std::pair<std::string,UpDeviceState>,UP_DEVICE_STATE_LAST> states =
776
std::make_pair("unknown", UP_DEVICE_STATE_UNKNOWN),
777
std::make_pair("charging", UP_DEVICE_STATE_CHARGING),
778
std::make_pair("discharging", UP_DEVICE_STATE_DISCHARGING),
779
std::make_pair("empty", UP_DEVICE_STATE_EMPTY),
780
std::make_pair("charged", UP_DEVICE_STATE_FULLY_CHARGED),
781
std::make_pair("pending-charge", UP_DEVICE_STATE_PENDING_CHARGE),
782
std::make_pair("pending-discharge", UP_DEVICE_STATE_PENDING_DISCHARGE)
784
const std::string& state2str(UpDeviceState state)
789
[state](decltype(states[0])& i){return i.second==state;}
792
UpDeviceState str2state(const std::string& str)
797
[str](decltype(states[0])& i){return i.first==str;}
804
std::string device2str(IndicatorPowerDevice* device)
806
std::ostringstream o;
807
const auto path = indicator_power_device_get_object_path(device);
809
o << kind2str(indicator_power_device_get_kind(device))
810
<< ' ' << state2str(indicator_power_device_get_state(device))
811
<< ' ' << indicator_power_device_get_time(device)<<'m'
812
<< ' ' << int(ceil(indicator_power_device_get_percentage(device)))<<'%'
813
<< ' ' << (path ? path : "nopath");
818
IndicatorPowerDevice* str2device(const std::string& str)
820
auto tokens = g_strsplit(str.c_str(), " ", 0);
821
g_assert(5u == g_strv_length(tokens));
822
const auto kind = str2kind(tokens[0]);
823
const auto state = str2state(tokens[1]);
824
const time_t time = atoi(tokens[2]);
825
const double pct = strtod(tokens[3],nullptr);
826
const char* path = !g_strcmp0(tokens[4],"nopath") ? nullptr : tokens[4];
827
auto ret = indicator_power_device_new(path, kind, pct, state, time);
707
833
/* If a device has multiple batteries and uses only one of them at a time,
708
834
they should be presented as separate items inside the battery menu,
709
835
but everywhere else they should be aggregated (bug 880881).
714
840
should be the the maximum of the times for all those that are charging. */
715
841
TEST_F(DeviceTest, ChoosePrimary)
726
const Description descriptions[] = {
727
{ "/some/path/d0", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 10, 60.0 }, // 0
728
{ "/some/path/d1", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 20, 80.0 }, // 1
729
{ "/some/path/d2", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 30, 100.0 }, // 2
731
{ "/some/path/c0", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 10, 60.0 }, // 3
732
{ "/some/path/c1", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 20, 80.0 }, // 4
733
{ "/some/path/c2", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 30, 100.0 }, // 5
735
{ "/some/path/f0", UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_FULLY_CHARGED, 0, 100.0 }, // 6
736
{ "/some/path/m0", UP_DEVICE_KIND_MOUSE, UP_DEVICE_STATE_DISCHARGING, 20, 80.0 }, // 7
737
{ "/some/path/m1", UP_DEVICE_KIND_MOUSE, UP_DEVICE_STATE_FULLY_CHARGED, 0, 100.0 }, // 8
738
{ "/some/path/pw", UP_DEVICE_KIND_LINE_POWER, UP_DEVICE_STATE_UNKNOWN, 0, 0.0 } // 9
741
std::vector<IndicatorPowerDevice*> devices;
742
for(const auto& desc : descriptions)
743
devices.push_back(indicator_power_device_new(desc.path, desc.kind, desc.percentage, desc.state, time_t(desc.time)));
746
std::vector<unsigned int> device_indices;
747
Description expected;
844
std::string description;
845
std::string expected;
846
std::vector<std::string> devices;
750
{ { 0 }, descriptions[0] }, // 1 discharging
751
{ { 0, 1 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 20, 70.0 } }, // 2 discharging
752
{ { 1, 2 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 30, 90.0 } }, // 2 discharging
753
{ { 0, 1, 2 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 30, 80.0 } }, // 3 discharging
755
{ { 3 }, descriptions[3] }, // 1 charging
756
{ { 3, 4 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 20, 70.0 } }, // 2 charging
757
{ { 4, 5 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 30, 90.0 } }, // 2 charging
758
{ { 3, 4, 5 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 30, 80.0 } }, // 3 charging
760
{ { 6 }, descriptions[6] }, // 1 charged
761
{ { 6, 0 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 10, 80.0 } }, // 1 charged, 1 discharging
762
{ { 6, 3 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_CHARGING, 10, 80.0 } }, // 1 charged, 1 charging
763
{ { 6, 0, 3 }, { nullptr, UP_DEVICE_KIND_BATTERY, UP_DEVICE_STATE_DISCHARGING, 10, 73.3 } }, // 1 charged, 1 charging, 1 discharging
765
{ { 0, 7 }, descriptions[0] }, // 1 discharging battery, 1 discharging mouse. pick the one with the least time left.
766
{ { 2, 7 }, descriptions[7] }, // 1 discharging battery, 1 discharging mouse. pick the one with the least time left.
768
{ { 0, 8 }, descriptions[0] }, // 1 discharging battery, 1 fully-charged mouse. pick the one that's discharging.
769
{ { 6, 7 }, descriptions[7] }, // 1 discharging mouse, 1 fully-charged battery. pick the one that's discharging.
771
{ { 0, 9 }, descriptions[0] }, // everything comes before power lines
772
{ { 3, 9 }, descriptions[3] },
773
{ { 7, 9 }, descriptions[7] }
849
"one discharging battery",
850
"battery discharging 10m 60% bat01",
851
{ "battery discharging 10m 60% bat01" }
854
"merge two discharging batteries",
855
"battery discharging 20m 70% nopath",
856
{ "battery discharging 10m 60% bat01", "battery discharging 20m 80% bat02" }
859
"merge two other discharging batteries",
860
"battery discharging 30m 90% nopath",
861
{ "battery discharging 20m 80% bat01", "battery discharging 30m 100% bat02" }
864
"merge three discharging batteries",
865
"battery discharging 30m 80% nopath",
866
{ "battery discharging 10m 60% bat01", "battery discharging 20m 80% bat02", "battery discharging 30m 100% bat03" }
869
"one charging battery",
870
"battery charging 10m 60% bat01",
871
{ "battery charging 10m 60% bat01" }
874
"merge two charging batteries",
875
"battery charging 20m 70% nopath",
876
{ "battery charging 10m 60% bat01", "battery charging 20m 80% bat02" }
879
"merge two other charging batteries",
880
"battery charging 30m 90% nopath",
881
{ "battery charging 20m 80% bat01", "battery charging 30m 100% bat02" }
884
"merge three charging batteries",
885
"battery charging 30m 80% nopath",
886
{ "battery charging 10m 60% bat01", "battery charging 20m 80% bat02", "battery charging 30m 100% bat03" }
889
"one charged battery",
890
"battery charged 0m 100% bat01",
891
{ "battery charged 0m 100% bat01" }
894
"merge one charged, one discharging",
895
"battery discharging 10m 80% nopath",
896
{ "battery charged 0m 100% bat01", "battery discharging 10m 60% bat02" }
899
"merged one charged, one charging",
900
"battery charging 10m 80% nopath",
901
{ "battery charged 0m 100% bat01", "battery charging 10m 60% bat02" }
904
"merged one charged, one charging, one discharging",
905
"battery discharging 10m 74% nopath",
906
{ "battery charged 0m 100% bat01", "battery charging 10m 60% bat02", "battery discharging 10m 60% bat03" }
909
"one discharging mouse and one discharging battery. pick the one with the least time left",
910
"battery discharging 10m 60% bat01",
911
{ "battery discharging 10m 60% bat01", "mouse discharging 20m 80% mouse01" }
914
"one discharging mouse and a different discharging battery. pick the one with the least time left",
915
"mouse discharging 20m 80% mouse01",
916
{ "battery discharging 30m 100% bat01", "mouse discharging 20m 80% mouse01" }
919
"everything comes before power lines #1",
920
"battery discharging 10m 60% bat01",
921
{ "battery discharging 10m 60% bat01", "line-power unknown 0m 0% lp01" }
924
"everything comes before power lines #2",
925
"battery charging 10m 60% bat01",
926
{ "battery charging 10m 60% bat01", "line-power unknown 0m 0% lp01" }
929
"everything comes before power lines #2",
930
"mouse discharging 20m 80% mouse01",
931
{ "mouse discharging 20m 80% mouse01", "line-power unknown 0m 0% lp01" }
934
// https://bugs.launchpad.net/ubuntu/+source/indicator-power/+bug/1470080/comments/10
935
"don't select a device with unknown state when we have another device with a known state...",
936
"battery charged 0m 100% bat01",
937
{ "battery charged 0m 100% bat01", "phone unknown 0m 61% phone01" }
940
// https://bugs.launchpad.net/ubuntu/+source/indicator-power/+bug/1470080/comments/10
941
"...but do select the unknown state device if nothing else is available",
942
"phone unknown 0m 61% phone01",
943
{ "phone unknown 0m 61% phone01" }
776
947
for(const auto& test : tests)
778
const auto& x = test.expected;
780
GList * device_glist = nullptr;
781
for(const auto& i : test.device_indices)
782
device_glist = g_list_append(device_glist, devices[i]);
949
// build the device list
950
GList* device_glist {};
951
for (const auto& description : test.devices)
952
device_glist = g_list_append(device_glist, str2device(description));
784
955
auto primary = indicator_power_service_choose_primary_device(device_glist);
785
EXPECT_STREQ(x.path, indicator_power_device_get_object_path(primary));
786
EXPECT_EQ(x.kind, indicator_power_device_get_kind(primary));
787
EXPECT_EQ(x.state, indicator_power_device_get_state(primary));
788
EXPECT_EQ(x.time, indicator_power_device_get_time(primary));
789
EXPECT_EQ(int(ceil(x.percentage)), int(ceil(indicator_power_device_get_percentage(primary))));
790
g_object_unref(primary);
956
EXPECT_EQ(test.expected, device2str(primary));
957
g_clear_object(&primary);
792
959
// reverse the list and repeat the test
793
960
// to confirm that list order doesn't matter
794
device_glist = g_list_reverse (device_glist);
795
primary = indicator_power_service_choose_primary_device (device_glist);
796
EXPECT_STREQ(x.path, indicator_power_device_get_object_path(primary));
797
EXPECT_EQ(x.kind, indicator_power_device_get_kind(primary));
798
EXPECT_EQ(x.state, indicator_power_device_get_state(primary));
799
EXPECT_EQ(x.time, indicator_power_device_get_time(primary));
800
EXPECT_EQ(int(ceil(x.percentage)), int(ceil(indicator_power_device_get_percentage(primary))));
801
g_object_unref(primary);
961
device_glist = g_list_reverse(device_glist);
962
primary = indicator_power_service_choose_primary_device(device_glist);
963
EXPECT_EQ(test.expected, device2str(primary));
964
g_clear_object(&primary);
804
g_list_free(device_glist);
967
g_list_free_full(device_glist, g_object_unref);
807
for (auto& device : devices)
808
g_object_unref (device);