19599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey/*
29599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project
39599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey *
49599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
59599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * you may not use this file except in compliance with the License.
69599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * You may obtain a copy of the License at
79599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey *
89599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
99599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey *
109599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
119599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
129599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * See the License for the specific language governing permissions and
149599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * limitations under the License.
159599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey */
169599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
179599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeypackage com.android.server;
189599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
19b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.ACTION_UID_REMOVED;
20b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.EXTRA_UID;
21961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
2221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI;
23af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkeyimport static android.net.NetworkPolicy.LIMIT_DISABLED;
24af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkeyimport static android.net.NetworkPolicy.WARNING_DISABLED;
259599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_NONE;
26fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
279599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
28fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
29cd2ca4038a027315832c38c68be5076000bc4b53Jeff Sharkeyimport static android.net.NetworkPolicyManager.computeLastCycleBoundary;
30af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkeyimport static android.net.NetworkPolicyManager.computeNextCycleBoundary;
31241dde2306202e7655fdf41d5381f2874e47e108Jeff Sharkeyimport static android.net.TrafficStats.KB_IN_BYTES;
32241dde2306202e7655fdf41d5381f2874e47e108Jeff Sharkeyimport static android.net.TrafficStats.MB_IN_BYTES;
33af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS;
3441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static android.text.format.DateUtils.MINUTE_IN_MILLIS;
359bf3150cfae03421c9dd237b46657714859d871cJeff Sharkeyimport static android.text.format.Time.TIMEZONE_UTC;
3641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
3741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
3841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
392ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkeyimport static org.easymock.EasyMock.anyInt;
400cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkeyimport static org.easymock.EasyMock.anyLong;
41fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static org.easymock.EasyMock.aryEq;
429599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport static org.easymock.EasyMock.capture;
439599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport static org.easymock.EasyMock.createMock;
449599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport static org.easymock.EasyMock.eq;
459599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport static org.easymock.EasyMock.expect;
469599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport static org.easymock.EasyMock.expectLastCall;
472ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkeyimport static org.easymock.EasyMock.isA;
489599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
499599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.app.IActivityManager;
502ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkeyimport android.app.INotificationManager;
519599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.app.IProcessObserver;
5241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport android.app.Notification;
539599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.content.Intent;
544414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport android.content.pm.PackageInfo;
559599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.content.pm.PackageManager;
564414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport android.content.pm.Signature;
57cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkeyimport android.content.pm.UserInfo;
589599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.net.ConnectivityManager;
5921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.IConnectivityManager;
6041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport android.net.INetworkManagementEventObserver;
619599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.net.INetworkPolicyListener;
6275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService;
6321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.LinkProperties;
6421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkInfo;
6521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkInfo.DetailedState;
6621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkPolicy;
6721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkState;
6821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkStats;
691b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkTemplate;
709599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.os.Binder;
7150fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharmaimport android.os.INetworkManagementService;
729599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.os.IPowerManager;
73163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport android.os.MessageQueue.IdleHandler;
74cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkeyimport android.os.UserId;
759599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.test.AndroidTestCase;
769599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.test.mock.MockPackageManager;
779599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.test.suitebuilder.annotation.LargeTest;
789599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.test.suitebuilder.annotation.Suppress;
7921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.text.format.Time;
8021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.TrustedTime;
819599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
829599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport com.android.server.net.NetworkPolicyManagerService;
834414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport com.google.common.util.concurrent.AbstractFuture;
849599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
859599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport org.easymock.Capture;
869599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport org.easymock.EasyMock;
874414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport org.easymock.IAnswer;
889599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
8921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.File;
90cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkeyimport java.util.ArrayList;
91af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkeyimport java.util.LinkedHashSet;
92cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkeyimport java.util.List;
934414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport java.util.concurrent.ExecutionException;
949599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport java.util.concurrent.Future;
954414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport java.util.concurrent.TimeUnit;
964414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport java.util.concurrent.TimeoutException;
97163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport java.util.logging.Handler;
989599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
998e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkeyimport libcore.io.IoUtils;
1008e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
1019599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey/**
1029599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * Tests for {@link NetworkPolicyManagerService}.
1039599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey */
1049599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey@LargeTest
1059599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeypublic class NetworkPolicyManagerServiceTest extends AndroidTestCase {
1069599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private static final String TAG = "NetworkPolicyManagerServiceTest";
1079599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
10821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static final long TEST_START = 1194220800000L;
10921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static final String TEST_IFACE = "test0";
110e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    private static final String TEST_SSID = "AndroidAP";
11121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
112e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi(TEST_SSID);
1131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1149599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private BroadcastInterceptingContext mServiceContext;
11521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private File mPolicyDir;
1169599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1179599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private IActivityManager mActivityManager;
1189599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private IPowerManager mPowerManager;
11975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private INetworkStatsService mStatsService;
12041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private INetworkManagementService mNetworkManager;
1219599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private INetworkPolicyListener mPolicyListener;
12221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private TrustedTime mTime;
12321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private IConnectivityManager mConnManager;
1242ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkey    private INotificationManager mNotifManager;
1259599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1269599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private NetworkPolicyManagerService mService;
1279599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private IProcessObserver mProcessObserver;
12841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private INetworkManagementEventObserver mNetworkObserver;
1299599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1309599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private Binder mStubBinder = new Binder();
1319599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1328e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private long mStartTime;
1338e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private long mElapsedRealtime;
1348e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
135cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int USER_ID = 0;
136cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int USER_ID_GUEST = 1;
137cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey
138cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 800;
139cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 801;
140cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey
141cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int UID_A = UserId.getUid(USER_ID, APP_ID_A);
142cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int UID_B = UserId.getUid(USER_ID, APP_ID_B);
143cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int UID_A_GUEST = UserId.getUid(USER_ID_GUEST, APP_ID_A);
144cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int UID_B_GUEST = UserId.getUid(USER_ID_GUEST, APP_ID_B);
1459599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1469599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private static final int PID_1 = 400;
1479599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private static final int PID_2 = 401;
1489599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private static final int PID_3 = 402;
1499599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1509599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    @Override
1519599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    public void setUp() throws Exception {
1529599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        super.setUp();
1539599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1548e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        setCurrentTimeMillis(TEST_START);
1558e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
1569599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // intercept various broadcasts, and pretend that uids have packages
1579599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mServiceContext = new BroadcastInterceptingContext(getContext()) {
1589599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey            @Override
1599599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey            public PackageManager getPackageManager() {
1609599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey                return new MockPackageManager() {
1619599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey                    @Override
1629599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey                    public String[] getPackagesForUid(int uid) {
1639599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey                        return new String[] { "com.example" };
1649599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey                    }
1654414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
1664414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                    @Override
1674414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                    public PackageInfo getPackageInfo(String packageName, int flags) {
1684414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                        final PackageInfo info = new PackageInfo();
1694414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                        final Signature signature;
1704414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                        if ("android".equals(packageName)) {
1714414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                            signature = new Signature("F00D");
1724414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                        } else {
1734414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                            signature = new Signature("DEAD");
1744414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                        }
1754414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                        info.signatures = new Signature[] { signature };
1764414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                        return info;
1774414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                    }
178cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey
179cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey                    @Override
180cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey                    public List<UserInfo> getUsers() {
181cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey                        final ArrayList<UserInfo> users = new ArrayList<UserInfo>();
182cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey                        users.add(new UserInfo(USER_ID, "Primary", UserInfo.FLAG_PRIMARY));
183cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey                        users.add(new UserInfo(USER_ID_GUEST, "Guest", 0));
184cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey                        return users;
185cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey                    }
1869599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey                };
1879599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey            }
18841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
18941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            @Override
19041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            public void startActivity(Intent intent) {
19141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                // ignored
19241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            }
1939599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        };
1949599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
19521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mPolicyDir = getContext().getFilesDir();
1968e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        if (mPolicyDir.exists()) {
1978e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            IoUtils.deleteContents(mPolicyDir);
1984414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        }
19921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
2009599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mActivityManager = createMock(IActivityManager.class);
2019599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mPowerManager = createMock(IPowerManager.class);
20275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mStatsService = createMock(INetworkStatsService.class);
20341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkManager = createMock(INetworkManagementService.class);
2049599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mPolicyListener = createMock(INetworkPolicyListener.class);
20521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mTime = createMock(TrustedTime.class);
20621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mConnManager = createMock(IConnectivityManager.class);
2072ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkey        mNotifManager = createMock(INotificationManager.class);
2089599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2098e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mPowerManager,
2108e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                mStatsService, mNetworkManager, mTime, mPolicyDir, true);
21121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mService.bindConnectivityManager(mConnManager);
2122ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkey        mService.bindNotificationManager(mNotifManager);
2139599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2149599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // RemoteCallbackList needs a binder to use as key
2159599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        expect(mPolicyListener.asBinder()).andReturn(mStubBinder).atLeastOnce();
2169599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
2179599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mService.registerListener(mPolicyListener);
2189599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
2199599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
22041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // catch IProcessObserver during systemReady()
2219599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        final Capture<IProcessObserver> processObserver = new Capture<IProcessObserver>();
2229599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mActivityManager.registerProcessObserver(capture(processObserver));
2239599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        expectLastCall().atLeastOnce();
2249599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
22541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // catch INetworkManagementEventObserver during systemReady()
22641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
22741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                INetworkManagementEventObserver>();
22841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkManager.registerObserver(capture(networkObserver));
22941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        expectLastCall().atLeastOnce();
23041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
2319599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // expect to answer screen status during systemReady()
2329599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
2330cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey        expect(mNetworkManager.isBandwidthControlEnabled()).andReturn(true).atLeastOnce();
2348e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        expectCurrentTime();
2359599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2369599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
2379599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mService.systemReady();
2389599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
2399599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2409599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver = processObserver.getValue();
24141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkObserver = networkObserver.getValue();
2429599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2439599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
2449599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2459599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    @Override
2469599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    public void tearDown() throws Exception {
24721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        for (File file : mPolicyDir.listFiles()) {
24821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey            file.delete();
24921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        }
25021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
2519599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mServiceContext = null;
25221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mPolicyDir = null;
2539599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2549599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mActivityManager = null;
2559599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mPowerManager = null;
25675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mStatsService = null;
2579599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mPolicyListener = null;
25821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mTime = null;
2599599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2609599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mService = null;
2619599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver = null;
2629599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2639599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        super.tearDown();
2649599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
2659599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2669599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    @Suppress
2679599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    public void testPolicyChangeTriggersBroadcast() throws Exception {
268cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_NONE);
2699599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2709599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // change background policy and expect broadcast
2719599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        final Future<Intent> backgroundChanged = mServiceContext.nextBroadcastIntent(
2729599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey                ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
2739599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
274cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
2759599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2769599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        backgroundChanged.get();
2779599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
2789599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2799599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    public void testPidForegroundCombined() throws Exception {
2800e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        IdleFuture idle;
2810e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey
2829599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // push all uid into background
2830e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle = expectIdle();
2849599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
2859599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
2869599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, false);
2870e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle.get();
2889599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_A));
2899599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_B));
2909599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2919599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // push one of the shared pids into foreground
2920e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle = expectIdle();
2939599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
2940e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle.get();
2959599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertTrue(mService.isUidForeground(UID_A));
2969599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_B));
2979599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
2989599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // and swap another uid into foreground
2990e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle = expectIdle();
3009599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
3019599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, true);
3020e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle.get();
3039599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_A));
3049599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertTrue(mService.isUidForeground(UID_B));
3059599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3069599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // push both pid into foreground
3070e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle = expectIdle();
3089599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
3099599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
3100e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle.get();
3119599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertTrue(mService.isUidForeground(UID_A));
3129599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3139599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // pull one out, should still be foreground
3140e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle = expectIdle();
3159599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
3160e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle.get();
3179599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertTrue(mService.isUidForeground(UID_A));
3189599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3199599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // pull final pid out, should now be background
3200e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle = expectIdle();
3219599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
3220e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        idle.get();
3239599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_A));
3249599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
3259599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3269599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    public void testScreenChangesRules() throws Exception {
3274414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        Future<Void> future;
328cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        Future<Void> futureGuest;
3294414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
330b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
331b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, true);
3324414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
3339599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
3349599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
3354414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
3364414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        verifyAndReset();
3374414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
3384414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        // push strict policy for foreground uid, verify ALLOW rule
339b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
340b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, true);
341cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidNetworkRules(UID_A_GUEST, true);
342cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidForeground(UID_A_GUEST, false);
3434414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
344cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_REJECT_METERED);
3454414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        replay();
346cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
3474414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
348cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest.get();
3499599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
3509599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3519599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // now turn screen off and verify REJECT rule
3529599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        expect(mPowerManager.isScreenOn()).andReturn(false).atLeastOnce();
353b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, true);
354b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
3554414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
3569599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
3579599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF));
3584414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
3599599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
3609599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3619599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // and turn screen back on, verify ALLOW rule restored
3629599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
363b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
364b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, true);
3654414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
3669599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
3679599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON));
3684414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
3699599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
3709599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
3719599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3729599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    public void testPolicyNone() throws Exception {
3734414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        Future<Void> future;
374cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        Future<Void> futureGuest;
3754414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
376b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
377b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, true);
3784414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
3794414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        replay();
3804414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
3814414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
3824414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        verifyAndReset();
3834414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
3849599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // POLICY_NONE should RULE_ALLOW in foreground
385b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
386b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, true);
387cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidNetworkRules(UID_A_GUEST, false);
388cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidForeground(UID_A_GUEST, false);
3894414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
390cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_ALLOW_ALL);
3919599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
392cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_NONE);
3934414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
394cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest.get();
3959599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
3969599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3979599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // POLICY_NONE should RULE_ALLOW in background
398b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
399b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
4004414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
4019599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
4029599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
4034414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
4049599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
4059599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
4069599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
4079599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    public void testPolicyReject() throws Exception {
4084414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        Future<Void> future;
409cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        Future<Void> futureGuest;
4104414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
4119599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // POLICY_REJECT should RULE_ALLOW in background
412b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, true);
413b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
414cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidNetworkRules(UID_A_GUEST, true);
415cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidForeground(UID_A_GUEST, false);
4164414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
417cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_REJECT_METERED);
4189599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
419cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
4204414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
421cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest.get();
4229599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
4239599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
4249599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // POLICY_REJECT should RULE_ALLOW in foreground
425b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
426b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, true);
4274414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
4289599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
4299599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
4304414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
4319599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
4329599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
4339599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // POLICY_REJECT should RULE_REJECT in background
434b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, true);
435b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
4364414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
4379599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
4389599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
4394414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
4409599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
4419599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
4429599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
4439599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    public void testPolicyRejectAddRemove() throws Exception {
4444414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        Future<Void> future;
445cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        Future<Void> futureGuest;
4464414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
4479599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // POLICY_NONE should have RULE_ALLOW in background
448b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
449b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
450cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidNetworkRules(UID_A_GUEST, false);
451cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidForeground(UID_A_GUEST, false);
4524414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
453cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_ALLOW_ALL);
4549599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
4559599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
456cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_NONE);
4574414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
458cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest.get();
4599599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
4609599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
4619599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // adding POLICY_REJECT should cause RULE_REJECT
462b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, true);
463b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
464cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidNetworkRules(UID_A_GUEST, true);
465cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidForeground(UID_A_GUEST, false);
4664414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
467cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_REJECT_METERED);
4689599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
469cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
4704414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
471cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest.get();
4729599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
4739599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
4749599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // removing POLICY_REJECT should return us to RULE_ALLOW
475b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
476b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
477cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidNetworkRules(UID_A_GUEST, false);
478cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidForeground(UID_A_GUEST, false);
4794414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
480cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_ALLOW_ALL);
4819599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        replay();
482cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_NONE);
4834414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
484cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest.get();
4859599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        verifyAndReset();
4869599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
4879599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
48821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testLastCycleBoundaryThisMonth() throws Exception {
48921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // assume cycle day of "5th", which should be in same month
49021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
49121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
49221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
49341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
4949bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false);
49521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
496af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        assertTimeEquals(expectedCycle, actualCycle);
49721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
49821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
49921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testLastCycleBoundaryLastMonth() throws Exception {
50021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // assume cycle day of "20th", which should be in last month
50121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
50221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
50321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
50441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
5059bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false);
50621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
507af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        assertTimeEquals(expectedCycle, actualCycle);
50821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
50921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
51021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testLastCycleBoundaryThisMonthFebruary() throws Exception {
51121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // assume cycle day of "30th" in february; should go to january
51221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long currentTime = parseTime("2007-02-14T00:00:00.000Z");
51321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
51421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
51541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
5169bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
51721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
518af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        assertTimeEquals(expectedCycle, actualCycle);
51921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
52021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
52121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testLastCycleBoundaryLastMonthFebruary() throws Exception {
52221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // assume cycle day of "30th" in february, which should clamp
52321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long currentTime = parseTime("2007-03-14T00:00:00.000Z");
524af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z");
52521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
52641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
5279bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
52821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
529af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        assertTimeEquals(expectedCycle, actualCycle);
530af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
531af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
5329bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    public void testCycleBoundaryLeapYear() throws Exception {
5339bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
5349bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
5359bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
5369bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"),
5379bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy));
5389bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
5399bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy));
5409bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
5419bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
5429bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"),
5439bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
5449bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
5459bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"),
5469bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy));
5479bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"),
5489bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy));
5499bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"),
5509bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
5519bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"),
5529bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
5539bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    }
5549bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
5559bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    public void testNextCycleTimezoneAfterUtc() throws Exception {
5569bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        // US/Central is UTC-6
5579bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
5589bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 10, "US/Central", 1024L, 1024L, false);
5599bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"),
5609bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
5619bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    }
5629bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
5639bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    public void testNextCycleTimezoneBeforeUtc() throws Exception {
5649bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        // Israel is UTC+2
5659bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
5669bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 10, "Israel", 1024L, 1024L, false);
5679bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"),
5689bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
5699bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    }
5709bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
571af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    public void testNextCycleSane() throws Exception {
572af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
5739bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
574af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
575af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
576af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        // walk forwards, ensuring that cycle boundaries don't get stuck
577af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        long currentCycle = computeNextCycleBoundary(parseTime("2011-08-01T00:00:00.000Z"), policy);
578af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        for (int i = 0; i < 128; i++) {
579af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            long nextCycle = computeNextCycleBoundary(currentCycle, policy);
580af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            assertEqualsFuzzy(DAY_IN_MILLIS * 30, nextCycle - currentCycle, DAY_IN_MILLIS * 3);
581af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            assertUnique(seen, nextCycle);
582af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            currentCycle = nextCycle;
583af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        }
584af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
585af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
586af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    public void testLastCycleSane() throws Exception {
587af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
5889bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
589af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
590af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
591af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        // walk backwards, ensuring that cycle boundaries look sane
592af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        long currentCycle = computeLastCycleBoundary(parseTime("2011-08-04T00:00:00.000Z"), policy);
593af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        for (int i = 0; i < 128; i++) {
594af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            long lastCycle = computeLastCycleBoundary(currentCycle, policy);
595af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            assertEqualsFuzzy(DAY_IN_MILLIS * 30, currentCycle - lastCycle, DAY_IN_MILLIS * 3);
596af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            assertUnique(seen, lastCycle);
597af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            currentCycle = lastCycle;
598af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        }
59921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
60021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
60121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
60221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        NetworkState[] state = null;
60321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        NetworkStats stats = null;
6044414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        Future<Void> future;
60521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
60621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long TIME_FEB_15 = 1171497600000L;
60721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long TIME_MAR_10 = 1173484800000L;
60821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final int CYCLE_DAY = 15;
60921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
6108e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        setCurrentTimeMillis(TIME_MAR_10);
6118e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
61221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // first, pretend that wifi network comes online. no policy active,
61321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // which means we shouldn't push limit to interface.
61421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        state = new NetworkState[] { buildWifi() };
61521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
6168e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        expectCurrentTime();
61741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        expectClearNotifications();
6180cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey        expectAdvisePersistThreshold();
6194414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectMeteredIfacesChanged();
62021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
62121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        replay();
622961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
6234414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
62421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        verifyAndReset();
62521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
62621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // now change cycle to be on 15th, and test in early march, to verify we
62721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // pick cycle day in previous month.
62821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
6298e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        expectCurrentTime();
63021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
63121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // pretend that 512 bytes total have happened
6328e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        stats = new NetworkStats(getElapsedRealtime(), 1)
633b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
634b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, TIME_MAR_10))
635b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                .andReturn(stats.getTotalBytes()).atLeastOnce();
6367ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        expectPolicyDataEnable(TYPE_WIFI, true);
63721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
638b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        // TODO: consider making strongly ordered mock
639b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectRemoveInterfaceQuota(TEST_IFACE);
640163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        expectSetInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512);
64121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
6422ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkey        expectClearNotifications();
6430cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey        expectAdvisePersistThreshold();
6444414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectMeteredIfacesChanged(TEST_IFACE);
6452ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkey
64621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        replay();
647163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        setNetworkPolicies(new NetworkPolicy(
6489bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
6494414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
65021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        verifyAndReset();
65121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
65221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
653b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    public void testUidRemovedPolicyCleared() throws Exception {
6544414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        Future<Void> future;
655cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        Future<Void> futureGuest;
6564414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
657b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        // POLICY_REJECT should RULE_REJECT in background
658b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, true);
659b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
660cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidNetworkRules(UID_A_GUEST, true);
661cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidForeground(UID_A_GUEST, false);
6624414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
663cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_REJECT_METERED);
664b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        replay();
665cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
6664414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
667cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest.get();
668b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        verifyAndReset();
669b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey
670b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        // uninstall should clear RULE_REJECT
671b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectSetUidNetworkRules(UID_A, false);
672b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectSetUidForeground(UID_A, false);
673cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidNetworkRules(UID_A_GUEST, false);
674cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        expectSetUidForeground(UID_A_GUEST, false);
6754414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
676cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_ALLOW_ALL);
677b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        replay();
678b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        final Intent intent = new Intent(ACTION_UID_REMOVED);
679b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        intent.putExtra(EXTRA_UID, UID_A);
680b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mServiceContext.sendBroadcast(intent);
6814414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        future.get();
682cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey        futureGuest.get();
683b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        verifyAndReset();
684b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    }
685b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey
68641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    public void testOverWarningLimitNotification() throws Exception {
68741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        NetworkState[] state = null;
68841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        NetworkStats stats = null;
68941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        Future<Void> future;
6907ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        Future<String> tagFuture;
69141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
69241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final long TIME_FEB_15 = 1171497600000L;
69341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final long TIME_MAR_10 = 1173484800000L;
69441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final int CYCLE_DAY = 15;
69541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
6968e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        setCurrentTimeMillis(TIME_MAR_10);
6978e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
69841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // assign wifi policy
69941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        state = new NetworkState[] {};
7008e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        stats = new NetworkStats(getElapsedRealtime(), 1)
7018e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
70241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
70341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
7048e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            expectCurrentTime();
70541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
706b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
707b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    .andReturn(stats.getTotalBytes()).atLeastOnce();
7087ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            expectPolicyDataEnable(TYPE_WIFI, true);
70941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
71041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expectClearNotifications();
7110cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey            expectAdvisePersistThreshold();
71241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            future = expectMeteredIfacesChanged();
71341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
71441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            replay();
7159bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey            setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1
7169bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                    * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
71741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            future.get();
71841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            verifyAndReset();
71941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
72041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
72141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // bring up wifi network
7228e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        incrementCurrentTime(MINUTE_IN_MILLIS);
72341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        state = new NetworkState[] { buildWifi() };
7248e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        stats = new NetworkStats(getElapsedRealtime(), 1)
7258e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
72641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
72741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
7288e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            expectCurrentTime();
72941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
730b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
731b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    .andReturn(stats.getTotalBytes()).atLeastOnce();
7327ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            expectPolicyDataEnable(TYPE_WIFI, true);
73341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
73441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expectRemoveInterfaceQuota(TEST_IFACE);
735163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey            expectSetInterfaceQuota(TEST_IFACE, 2 * MB_IN_BYTES);
73641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
73741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expectClearNotifications();
7380cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey            expectAdvisePersistThreshold();
73941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            future = expectMeteredIfacesChanged(TEST_IFACE);
74041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
74141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            replay();
742961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey            mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
74341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            future.get();
74441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            verifyAndReset();
74541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
74641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
74741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // go over warning, which should kick notification
7488e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        incrementCurrentTime(MINUTE_IN_MILLIS);
7498e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        stats = new NetworkStats(getElapsedRealtime(), 1)
750163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey                .addIfaceValues(TEST_IFACE, 1536 * KB_IN_BYTES, 15L, 0L, 0L);
75141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
75241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
7538e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            expectCurrentTime();
754b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
755b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    .andReturn(stats.getTotalBytes()).atLeastOnce();
7567ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            expectPolicyDataEnable(TYPE_WIFI, true);
75741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
75841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expectForceUpdate();
75941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expectClearNotifications();
7607ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            tagFuture = expectEnqueueNotification();
76141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
76241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            replay();
76341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            mNetworkObserver.limitReached(null, TEST_IFACE);
7647ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            assertNotificationType(TYPE_WARNING, tagFuture.get());
76541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            verifyAndReset();
76641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
76741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
76841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // go over limit, which should kick notification and dialog
7698e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        incrementCurrentTime(MINUTE_IN_MILLIS);
7708e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        stats = new NetworkStats(getElapsedRealtime(), 1)
771163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey                .addIfaceValues(TEST_IFACE, 5 * MB_IN_BYTES, 512L, 0L, 0L);
77241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
77341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
7748e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            expectCurrentTime();
775b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
776b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    .andReturn(stats.getTotalBytes()).atLeastOnce();
7777ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            expectPolicyDataEnable(TYPE_WIFI, false);
77841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
77941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expectForceUpdate();
78041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expectClearNotifications();
7817ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            tagFuture = expectEnqueueNotification();
78241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
78341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            replay();
78441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            mNetworkObserver.limitReached(null, TEST_IFACE);
7857ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            assertNotificationType(TYPE_LIMIT, tagFuture.get());
78641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            verifyAndReset();
78741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
78841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
78941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // now snooze policy, which should remove quota
7908e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        incrementCurrentTime(MINUTE_IN_MILLIS);
79141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
79241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
7938e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            expectCurrentTime();
79441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
795b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
796b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    .andReturn(stats.getTotalBytes()).atLeastOnce();
7977ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            expectPolicyDataEnable(TYPE_WIFI, true);
79841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
7998e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            // snoozed interface still has high quota so background data is
8008e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            // still restricted.
80141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            expectRemoveInterfaceQuota(TEST_IFACE);
8028e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
8030cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey            expectAdvisePersistThreshold();
8047ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            expectMeteredIfacesChanged(TEST_IFACE);
80541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
806c506ff615080082515b1f634ad49b19fd2111669Jeff Sharkey            future = expectClearNotifications();
8077ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            tagFuture = expectEnqueueNotification();
80841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
80941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            replay();
8100e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey            mService.snoozeLimit(sTemplateWifi);
8117ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get());
812c506ff615080082515b1f634ad49b19fd2111669Jeff Sharkey            future.get();
81341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            verifyAndReset();
81441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
81541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
81641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
817f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey    public void testMeteredNetworkWithoutLimit() throws Exception {
818f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        NetworkState[] state = null;
819f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        NetworkStats stats = null;
820f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        Future<Void> future;
821f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        Future<String> tagFuture;
822f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
823f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        final long TIME_FEB_15 = 1171497600000L;
824f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        final long TIME_MAR_10 = 1173484800000L;
825f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        final int CYCLE_DAY = 15;
826f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
827f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        setCurrentTimeMillis(TIME_MAR_10);
828f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
829f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        // bring up wifi network with metered policy
830f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        state = new NetworkState[] { buildWifi() };
831f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        stats = new NetworkStats(getElapsedRealtime(), 1)
832f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey                .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
833f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
834f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        {
835f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            expectCurrentTime();
836f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
837b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
838b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    .andReturn(stats.getTotalBytes()).atLeastOnce();
839f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            expectPolicyDataEnable(TYPE_WIFI, true);
840f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
841f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            expectRemoveInterfaceQuota(TEST_IFACE);
842f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
843f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
844f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            expectClearNotifications();
8450cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey            expectAdvisePersistThreshold();
846f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            future = expectMeteredIfacesChanged(TEST_IFACE);
847f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
848f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            replay();
8499bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey            setNetworkPolicies(new NetworkPolicy(
8509bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                    sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
8519bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                    true));
852f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            future.get();
853f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey            verifyAndReset();
854f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        }
855f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey    }
856f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
85721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static long parseTime(String time) {
85821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final Time result = new Time();
85921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        result.parse3339(time);
86021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        return result.toMillis(true);
86121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
86221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
863af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey    private void setNetworkPolicies(NetworkPolicy... policies) {
864af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey        mService.setNetworkPolicies(policies);
865af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey    }
866af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey
86721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static NetworkState buildWifi() {
86821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
86921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        info.setDetailedState(DetailedState.CONNECTED, null, null);
87021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final LinkProperties prop = new LinkProperties();
87121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        prop.setInterfaceName(TEST_IFACE);
872e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        return new NetworkState(info, prop, null, null, TEST_SSID);
87321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
87421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
8758e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private void expectCurrentTime() throws Exception {
87621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        expect(mTime.forceRefresh()).andReturn(false).anyTimes();
87721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        expect(mTime.hasCache()).andReturn(true).anyTimes();
8788e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
87921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
88021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
88121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
88221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
88341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private void expectForceUpdate() throws Exception {
88441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mStatsService.forceUpdate();
88541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        expectLastCall().atLeastOnce();
88641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
88741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
888c506ff615080082515b1f634ad49b19fd2111669Jeff Sharkey    private Future<Void> expectClearNotifications() throws Exception {
889c506ff615080082515b1f634ad49b19fd2111669Jeff Sharkey        final FutureAnswer future = new FutureAnswer();
8902ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkey        mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt());
891c506ff615080082515b1f634ad49b19fd2111669Jeff Sharkey        expectLastCall().andAnswer(future).anyTimes();
892c506ff615080082515b1f634ad49b19fd2111669Jeff Sharkey        return future;
8932ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkey    }
8942ef2aeb18d9d1ca7e25ad705c4da559f3682805aJeff Sharkey
8957ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    private Future<String> expectEnqueueNotification() throws Exception {
8967ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        final FutureCapture<String> tag = new FutureCapture<String>();
8977ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        mNotifManager.enqueueNotificationWithTag(isA(String.class), capture(tag.capture), anyInt(),
89841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                isA(Notification.class), isA(int[].class));
89941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        return tag;
90041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
90141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
90241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private void expectSetInterfaceQuota(String iface, long quotaBytes) throws Exception {
90341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkManager.setInterfaceQuota(iface, quotaBytes);
904b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectLastCall().atLeastOnce();
905b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    }
906b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
907b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    private void expectRemoveInterfaceQuota(String iface) throws Exception {
90841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkManager.removeInterfaceQuota(iface);
90941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        expectLastCall().atLeastOnce();
91041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
91141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
91241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private void expectSetInterfaceAlert(String iface, long alertBytes) throws Exception {
91341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkManager.setInterfaceAlert(iface, alertBytes);
91441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        expectLastCall().atLeastOnce();
91541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
91641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
91741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private void expectRemoveInterfaceAlert(String iface) throws Exception {
91841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkManager.removeInterfaceAlert(iface);
919b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectLastCall().atLeastOnce();
920b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    }
921b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
922b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    private void expectSetUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces)
923b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            throws Exception {
92441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
925b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        expectLastCall().atLeastOnce();
926b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    }
927b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
928b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    private void expectSetUidForeground(int uid, boolean uidForeground) throws Exception {
929b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        mStatsService.setUidForeground(uid, uidForeground);
930b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        expectLastCall().atLeastOnce();
931b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    }
932b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
9334414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey    private Future<Void> expectRulesChanged(int uid, int policy) throws Exception {
9344414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        final FutureAnswer future = new FutureAnswer();
935fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        mPolicyListener.onUidRulesChanged(eq(uid), eq(policy));
9364414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        expectLastCall().andAnswer(future);
9374414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        return future;
938fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    }
939fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
9404414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey    private Future<Void> expectMeteredIfacesChanged(String... ifaces) throws Exception {
9414414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        final FutureAnswer future = new FutureAnswer();
942fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        mPolicyListener.onMeteredIfacesChanged(aryEq(ifaces));
9434414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        expectLastCall().andAnswer(future);
9444414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        return future;
9454414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey    }
9464414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
9477ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    private Future<Void> expectPolicyDataEnable(int type, boolean enabled) throws Exception {
9487ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        final FutureAnswer future = new FutureAnswer();
9498e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mConnManager.setPolicyDataEnable(type, enabled);
9507ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        expectLastCall().andAnswer(future);
9517ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        return future;
9528e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
9538e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
9540cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey    private void expectAdvisePersistThreshold() throws Exception {
9550cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey        mStatsService.advisePersistThreshold(anyLong());
9560cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey        expectLastCall().anyTimes();
9570cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey    }
9580cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey
9597ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    private static class TestAbstractFuture<T> extends AbstractFuture<T> {
9604414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        @Override
9617ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        public T get() throws InterruptedException, ExecutionException {
9624414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey            try {
9634414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                return get(5, TimeUnit.SECONDS);
9644414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey            } catch (TimeoutException e) {
9654414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                throw new RuntimeException(e);
9664414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey            }
9674414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        }
9687ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    }
9694414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
9707ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    private static class FutureAnswer extends TestAbstractFuture<Void> implements IAnswer<Void> {
9714414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        @Override
9724414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        public Void answer() {
9734414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey            set(null);
9744414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey            return null;
9754414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        }
9769599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
9779599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
9787ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    private static class FutureCapture<T> extends TestAbstractFuture<T> {
9797ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        public Capture<T> capture = new Capture<T>() {
9807ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            @Override
9817ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            public void setValue(T value) {
9827ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey                super.setValue(value);
9837ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey                set(value);
9847ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey            }
9857ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        };
9867ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    }
9877ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey
988163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    private static class IdleFuture extends AbstractFuture<Void> implements IdleHandler {
989163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        @Override
990163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        public Void get() throws InterruptedException, ExecutionException {
991163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey            try {
992163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey                return get(5, TimeUnit.SECONDS);
993163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey            } catch (TimeoutException e) {
994163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey                throw new RuntimeException(e);
995163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey            }
996163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        }
997163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
998bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
999163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        public boolean queueIdle() {
1000163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey            set(null);
1001163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey            return false;
1002163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        }
1003163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    }
1004163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
1005163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    /**
1006163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey     * Wait until {@link #mService} internal {@link Handler} is idle.
1007163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey     */
10080e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey    private IdleFuture expectIdle() {
1009163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        final IdleFuture future = new IdleFuture();
1010163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        mService.addIdleHandler(future);
10110e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey        return future;
1012163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    }
1013163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
1014af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    private static void assertTimeEquals(long expected, long actual) {
1015af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        if (expected != actual) {
1016af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual));
1017af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        }
1018af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
1019af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
1020af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    private static String formatTime(long millis) {
1021af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final Time time = new Time(Time.TIMEZONE_UTC);
1022af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        time.set(millis);
1023af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        return time.format3339(false);
1024af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
1025af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
1026af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) {
1027af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final long low = expected - fuzzy;
1028af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final long high = expected + fuzzy;
1029af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        if (actual < low || actual > high) {
1030af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            fail("value " + actual + " is outside [" + low + "," + high + "]");
1031af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        }
1032af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
1033af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
1034af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    private static void assertUnique(LinkedHashSet<Long> seen, Long value) {
1035af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        if (!seen.add(value)) {
1036af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            fail("found duplicate time " + value + " in series " + seen.toString());
1037af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        }
1038af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
1039af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
104041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private static void assertNotificationType(int expected, String actualTag) {
104141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        assertEquals(
104241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
104341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
104441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
10458e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private long getElapsedRealtime() {
10468e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        return mElapsedRealtime;
10478e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
10488e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
10498e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private void setCurrentTimeMillis(long currentTimeMillis) {
10508e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mStartTime = currentTimeMillis;
10518e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mElapsedRealtime = 0L;
10528e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
10538e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
10548e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private long currentTimeMillis() {
10558e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        return mStartTime + mElapsedRealtime;
10568e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
10578e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
10588e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private void incrementCurrentTime(long duration) {
10598e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mElapsedRealtime += duration;
10608e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
10618e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
10629599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private void replay() {
106350fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma        EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
106441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                mNetworkManager, mTime, mConnManager, mNotifManager);
10659599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
10669599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
10679599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private void verifyAndReset() {
106850fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma        EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
106941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                mNetworkManager, mTime, mConnManager, mNotifManager);
107050fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma        EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
107141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                mNetworkManager, mTime, mConnManager, mNotifManager);
10729599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
10739599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey}
1074