1cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria/*
2cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * Copyright (C) 2017 The Android Open Source Project
3cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria *
4cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * Licensed under the Apache License, Version 2.0 (the "License");
5cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * you may not use this file except in compliance with the License.
6cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * You may obtain a copy of the License at
7cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria *
8cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria *      http://www.apache.org/licenses/LICENSE-2.0
9cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria *
10cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * Unless required by applicable law or agreed to in writing, software
11cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * distributed under the License is distributed on an "AS IS" BASIS,
12cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * See the License for the specific language governing permissions and
14cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria * limitations under the License.
15cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria */
16564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariapackage androidx.work.impl.constraints.trackers;
17cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
18cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport static org.hamcrest.CoreMatchers.is;
19cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport static org.hamcrest.MatcherAssert.assertThat;
201b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarinimport static org.hamcrest.core.IsNull.nullValue;
2147bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagarimport static org.mockito.ArgumentMatchers.any;
22cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport static org.mockito.ArgumentMatchers.anyBoolean;
2347bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagarimport static org.mockito.ArgumentMatchers.isNull;
24cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport static org.mockito.Mockito.mock;
25cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport static org.mockito.Mockito.never;
2647bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagarimport static org.mockito.Mockito.times;
27cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport static org.mockito.Mockito.verify;
2847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagarimport static org.mockito.Mockito.verifyNoMoreInteractions;
2947bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagarimport static org.mockito.Mockito.when;
30cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
31cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport android.annotation.TargetApi;
3247bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagarimport android.content.BroadcastReceiver;
3347bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagarimport android.content.Context;
34cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport android.content.Intent;
35cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport android.content.IntentFilter;
36cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport android.os.BatteryManager;
3747bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagarimport android.os.Build;
38cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport android.support.test.InstrumentationRegistry;
39cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport android.support.test.filters.SdkSuppress;
40cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport android.support.test.filters.SmallTest;
41cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport android.support.test.runner.AndroidJUnit4;
42cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
43b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Katariaimport androidx.work.impl.constraints.ConstraintListener;
44b5728f4e1a4b3f4f1fabf033b1363ca6b1cffdefSumir Kataria
45cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport org.junit.Before;
46cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport org.junit.Test;
47cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariaimport org.junit.runner.RunWith;
48cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
49cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria@RunWith(AndroidJUnit4.class)
50cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Katariapublic class BatteryChargingTrackerTest {
51cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
52cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    private BatteryChargingTracker mTracker;
53a0d0d16f358a6cd71033a9d12c934c1c90b07973Xyan Bhatnagar    private ConstraintListener<Boolean> mListener;
5447bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    private Context mMockContext;
55cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
56cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @Before
57cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    public void setUp() {
5847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mMockContext = mock(Context.class);
5947bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
6047bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar
6147bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mTracker = new BatteryChargingTracker(mMockContext);
62a0d0d16f358a6cd71033a9d12c934c1c90b07973Xyan Bhatnagar        mListener = mock(ConstraintListener.class);
63cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    }
64cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
6547bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    private void mockContextReturns(Intent expectedIntent) {
6647bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        when(mMockContext.registerReceiver((BroadcastReceiver) isNull(),
6747bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar                any(IntentFilter.class))).thenReturn(expectedIntent);
6847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    }
6947bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar
7047bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    private Intent createBatteryChangedIntent(boolean charging) {
7147bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
7247bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        if (Build.VERSION.SDK_INT >= 23) {
7347bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar            int status = charging ? BatteryManager.BATTERY_STATUS_CHARGING
7447bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar                    : BatteryManager.BATTERY_STATUS_DISCHARGING;
7547bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar            intent.putExtra(BatteryManager.EXTRA_STATUS, status);
7647bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        } else {
7747bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar            int plugged = charging ? 1 : 0;
7847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar            intent.putExtra(BatteryManager.EXTRA_PLUGGED, plugged);
7947bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        }
8047bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        return intent;
8147bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    }
8247bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar
8347bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    private Intent createChargingIntent(boolean charging) {
8447bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        return new Intent(
8547bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar                charging ? Intent.ACTION_POWER_CONNECTED : Intent.ACTION_POWER_DISCONNECTED);
8647bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    }
8747bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar
8847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    @TargetApi(23)
8947bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    private Intent createChargingIntent_afterApi23(boolean charging) {
9047bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        return new Intent(
9147bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar                charging ? BatteryManager.ACTION_CHARGING : BatteryManager.ACTION_DISCHARGING);
9247bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    }
9347bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar
94cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @Test
951b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @SmallTest
9647bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    public void testGetInitialState_nullIntent() {
9747bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mockContextReturns(null);
9847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        assertThat(mTracker.getInitialState(), is(nullValue()));
991b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    }
1001b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin
1011b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @Test
1021b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @SmallTest
10347bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    public void testGetInitialState_chargingIntent() {
10447bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mockContextReturns(createBatteryChangedIntent(true));
10547bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        assertThat(mTracker.getInitialState(), is(true));
1061b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    }
1071b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin
1081b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @Test
1091b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @SmallTest
11047bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar    public void testGetInitialState_dischargingIntent() {
11147bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mockContextReturns(createBatteryChangedIntent(false));
11247bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        assertThat(mTracker.getInitialState(), is(false));
1131b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    }
1141b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin
1151b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @Test
1161b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @SmallTest
117cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @SdkSuppress(maxSdkVersion = 22)
118cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    public void testGetIntentFilter_beforeApi23() {
119cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria        IntentFilter intentFilter = mTracker.getIntentFilter();
1203ad5665594d01ed7acefbb0b502547079be44c7cXyan Bhatnagar        assertThat(intentFilter.hasAction(Intent.ACTION_POWER_CONNECTED), is(true));
1213ad5665594d01ed7acefbb0b502547079be44c7cXyan Bhatnagar        assertThat(intentFilter.hasAction(Intent.ACTION_POWER_DISCONNECTED), is(true));
1223ad5665594d01ed7acefbb0b502547079be44c7cXyan Bhatnagar        assertThat(intentFilter.countActions(), is(2));
123cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    }
124cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
125cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @Test
1261b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @SmallTest
127cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @SdkSuppress(minSdkVersion = 23)
128cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    public void testGetIntentFilter_afterApi23() {
129cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria        IntentFilter intentFilter = mTracker.getIntentFilter();
130cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria        assertThat(intentFilter.hasAction(BatteryManager.ACTION_CHARGING), is(true));
131cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria        assertThat(intentFilter.hasAction(BatteryManager.ACTION_DISCHARGING), is(true));
132cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria        assertThat(intentFilter.countActions(), is(2));
133cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    }
134cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
135cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @Test
1361b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @SmallTest
137ea3c3af4150c20d63d0aaaa721b3304baae254c6Jan Clarin    public void testOnBroadcastReceive_invalidIntentAction_doesNotNotifyListeners() {
13847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mockContextReturns(createBatteryChangedIntent(true));
13947bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mTracker.addListener(mListener);
14047bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        verify(mListener).onConstraintChanged(true);
14147bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar
142ea3c3af4150c20d63d0aaaa721b3304baae254c6Jan Clarin        mTracker.onBroadcastReceive(
143cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria                InstrumentationRegistry.getTargetContext(),
144ea3c3af4150c20d63d0aaaa721b3304baae254c6Jan Clarin                new Intent("INVALID"));
14547bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        verifyNoMoreInteractions(mListener);
146cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    }
147cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
148cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @Test
1491b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @SmallTest
150cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @SdkSuppress(maxSdkVersion = 22)
151ea3c3af4150c20d63d0aaaa721b3304baae254c6Jan Clarin    public void testOnBroadcastReceive_notifiesListeners_beforeApi23() {
15247bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mockContextReturns(createBatteryChangedIntent(false));
15347bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mTracker.addListener(mListener);
154a0d0d16f358a6cd71033a9d12c934c1c90b07973Xyan Bhatnagar        verify(mListener).onConstraintChanged(false);
15547bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar
15647bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mTracker.onBroadcastReceive(mMockContext, createChargingIntent(true));
15747bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        verify(mListener).onConstraintChanged(true);
15847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mTracker.onBroadcastReceive(mMockContext, createChargingIntent(false));
15947bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        verify(mListener, times(2)).onConstraintChanged(false);
160cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    }
161cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria
162cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @Test
1631b58a02b857bf59a52a702dd30f31db9a152f19bJan Clarin    @SmallTest
164cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    @SdkSuppress(minSdkVersion = 23)
165ea3c3af4150c20d63d0aaaa721b3304baae254c6Jan Clarin    public void testOnBroadcastReceive_notifiesListeners_afterApi23() {
16647bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mockContextReturns(null);
16747bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mTracker.addListener(mListener);
16847bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        verify(mListener, never()).onConstraintChanged(anyBoolean());
16947bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar
17047bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mTracker.onBroadcastReceive(mMockContext, createChargingIntent_afterApi23(true));
171a0d0d16f358a6cd71033a9d12c934c1c90b07973Xyan Bhatnagar        verify(mListener).onConstraintChanged(true);
17247bc9f58bf013dcb40ba1ee33f72c196d5e3001aXyan Bhatnagar        mTracker.onBroadcastReceive(mMockContext, createChargingIntent_afterApi23(false));
173a0d0d16f358a6cd71033a9d12c934c1c90b07973Xyan Bhatnagar        verify(mListener).onConstraintChanged(false);
174cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria    }
175cac53d44f27fcf13aab265cac19bc574ac44aae3Sumir Kataria}
176