1 /* 2 * Copyright (C) 2018 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 android.content.syncmanager.cts.app; 17 18 import static org.mockito.Mockito.mock; 19 20 import android.accounts.Account; 21 import android.content.AbstractThreadedSyncAdapter; 22 import android.content.ContentProviderClient; 23 import android.content.ContentResolver; 24 import android.content.Context; 25 import android.content.SyncResult; 26 import android.content.syncmanager.cts.SyncManagerCtsProto.Payload.Request.SetResult; 27 import android.content.syncmanager.cts.SyncManagerCtsProto.Payload.Request.SetResult.Result; 28 import android.content.syncmanager.cts.SyncManagerCtsProto.Payload.SyncInvocation; 29 import android.os.Bundle; 30 import android.os.SystemClock; 31 import android.util.Log; 32 33 import com.android.compatibility.common.util.ParcelUtils; 34 35 import com.google.protobuf.ByteString; 36 37 import java.util.ArrayList; 38 import java.util.List; 39 40 /** 41 * Sync adapter for the sync test. 42 */ 43 public class SyncManagerCtsSyncAdapter extends AbstractThreadedSyncAdapter { 44 private static final String TAG = "SyncManagerCtsSyncAdapter"; 45 SyncManagerCtsSyncAdapter(Context context)46 public SyncManagerCtsSyncAdapter(Context context) { 47 super(context, /* autoInitialize= */ false); 48 } 49 50 private static final Object sLock = new Object(); 51 52 private static List<SyncInvocation> sSyncInvocations = new ArrayList<>(); 53 54 private static SetResult sResult; 55 56 public interface SyncInterceptor { onPerformSync(Account account, Bundle extras, String authority, SyncResult syncResult)57 SyncResult onPerformSync(Account account, Bundle extras, String authority, 58 SyncResult syncResult); 59 } 60 61 public static final SyncInterceptor sSyncInterceptor = mock(SyncInterceptor.class); 62 63 @Override onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)64 public void onPerformSync(Account account, Bundle extras, String authority, 65 ContentProviderClient provider, SyncResult syncResult) { 66 try { 67 extras.size(); // Force unparcel extras. 68 Log.i(TAG, "onPerformSync: account=" + account + " authority=" + authority 69 + " extras=" + extras); 70 71 synchronized (sSyncInvocations) { 72 sSyncInvocations.add(SyncInvocation.newBuilder() 73 .setTime(SystemClock.elapsedRealtime()) 74 .setAccountName(account.name) 75 .setAccountType(account.type) 76 .setAuthority(authority) 77 .setExtras(ByteString.copyFrom(ParcelUtils.toBytes(extras))).build()); 78 } 79 80 if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE)) { 81 getContext().getContentResolver().setIsSyncable(account, authority, 1); 82 } 83 84 sSyncInterceptor.onPerformSync(account, extras, authority, syncResult); 85 86 synchronized (sLock) { 87 if ((sResult == null) || sResult.getResult() == Result.OK) { 88 syncResult.stats.numInserts++; 89 90 } else if (sResult.getResult() == Result.SOFT_ERROR) { 91 syncResult.stats.numIoExceptions++; 92 93 } else if (sResult.getResult() == Result.HARD_ERROR) { 94 syncResult.stats.numAuthExceptions++; 95 } 96 } 97 98 } catch (Throwable th) { 99 Log.e(TAG, "Exception in onPerformSync", th); 100 } 101 Log.i(TAG, "onPerformSyncFinishing: account=" + account + " authority=" + authority 102 + " extras=" + extras + " result=" + syncResult); 103 } 104 getSyncInvocations()105 public static List<SyncInvocation> getSyncInvocations() { 106 synchronized (sLock) { 107 return new ArrayList<>(sSyncInvocations); 108 } 109 } 110 clearSyncInvocations()111 public static void clearSyncInvocations() { 112 synchronized (sLock) { 113 sSyncInvocations.clear(); 114 } 115 } 116 setResult(SetResult result)117 public static void setResult(SetResult result) { 118 synchronized (sLock) { 119 sResult = result; 120 } 121 } 122 } 123