1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server.cts.device.batterystats; 17 18 import android.accounts.Account; 19 import android.content.AbstractThreadedSyncAdapter; 20 import android.content.ContentProviderClient; 21 import android.content.ContentResolver; 22 import android.content.Context; 23 import android.content.SyncResult; 24 import android.os.Bundle; 25 import android.os.SystemClock; 26 import android.util.Log; 27 28 import org.junit.Assert; 29 30 import javax.annotation.concurrent.GuardedBy; 31 32 /** 33 * Sync adapter for the sync test. 34 */ 35 public class BatteryStatsSyncAdapter extends AbstractThreadedSyncAdapter { 36 private static final String TAG = "BatteryStatsSyncAdapter"; 37 38 private static final int TIMEOUT_SECONDS = 60 * 2; 39 40 private static final Object sLock = new Object(); 41 42 /** 43 * # of total syncs happened; used to wait until a request sync finishes. 44 */ 45 @GuardedBy("sLock") 46 private static int sSyncCount; 47 48 public BatteryStatsSyncAdapter(Context context) { 49 // No need for auto-initialization because we set isSyncable in the test anyway. 50 super(context, /* autoInitialize= */ false); 51 } 52 53 @Override 54 public void onPerformSync(Account account, Bundle extras, String authority, 55 ContentProviderClient provider, SyncResult syncResult) { 56 try { 57 Thread.sleep(1000); 58 } catch (InterruptedException e) { 59 } 60 synchronized (sLock) { 61 sSyncCount++; 62 Log.i(TAG, "onPerformSync: count -> " + sSyncCount); 63 sLock.notifyAll(); 64 } 65 } 66 67 /** 68 * Returns the current sync count. 69 */ 70 private static int getSyncCount() { 71 synchronized (sLock) { 72 return sSyncCount; 73 } 74 } 75 76 /** 77 * Wait until the sync count reaches the given value. 78 */ 79 private static void waitUntilSyncCount(int expectCount) throws Exception { 80 final long timeout = SystemClock.elapsedRealtime() + (TIMEOUT_SECONDS * 1000); 81 82 synchronized (sLock) { 83 for (;;) { 84 Log.i(TAG, "waitUntilSyncCount: current count=" + sSyncCount); 85 if (sSyncCount >= expectCount) { 86 return; 87 } 88 final long sleep = timeout - SystemClock.elapsedRealtime(); 89 if (sleep <= 0) { 90 break; 91 } 92 sLock.wait(sleep); 93 } 94 } 95 Assert.fail("Sync didn't happen."); 96 } 97 98 /** 99 * Request a sync on the given account, and wait for it. 100 */ 101 public static void requestSync(Account account) throws Exception { 102 final int startCount = BatteryStatsSyncAdapter.getSyncCount(); 103 104 final Bundle extras = new Bundle(); 105 extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); 106 extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true); 107 extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true); 108 109 ContentResolver.requestSync(account, BatteryStatsProvider.AUTHORITY, extras); 110 111 waitUntilSyncCount(startCount + 1); 112 } 113 114 /** 115 * Cancel all pending sync requests on the given account. 116 */ 117 public static void cancelPendingSyncs(Account account) throws Exception { 118 final long timeout = SystemClock.elapsedRealtime() + (TIMEOUT_SECONDS * 1000); 119 120 ContentResolver.cancelSync(account, BatteryStatsProvider.AUTHORITY); 121 122 for (;;) { 123 if (!ContentResolver.isSyncPending(account, BatteryStatsProvider.AUTHORITY) 124 && !ContentResolver.isSyncActive(account, BatteryStatsProvider.AUTHORITY)) { 125 return; 126 } 127 final long sleep = timeout - SystemClock.elapsedRealtime(); 128 if (sleep <= 0) { 129 break; 130 } 131 Thread.sleep(sleep); 132 } 133 Assert.fail("Couldn't cancel pending sync."); 134 } 135 } 136