Home | History | Annotate | Download | only in common
      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 
     17 package android.autofillservice.cts.common;
     18 
     19 import static android.autofillservice.cts.common.SettingsHelper.NAMESPACE_GLOBAL;
     20 import static android.autofillservice.cts.common.SettingsHelper.NAMESPACE_SECURE;
     21 
     22 import android.content.ContentResolver;
     23 import android.content.Context;
     24 import android.database.ContentObserver;
     25 import android.net.Uri;
     26 import android.os.Handler;
     27 import android.os.Looper;
     28 import android.provider.Settings;
     29 
     30 import java.util.concurrent.CountDownLatch;
     31 import java.util.concurrent.TimeUnit;
     32 
     33 /**
     34  * Helper used to block tests until a secure settings value has been updated.
     35  */
     36 public final class OneTimeSettingsListener extends ContentObserver {
     37     private final CountDownLatch mLatch = new CountDownLatch(1);
     38     private final ContentResolver mResolver;
     39     private final String mKey;
     40 
     41     public OneTimeSettingsListener(Context context, String key) {
     42         this(context, NAMESPACE_SECURE, key);
     43     }
     44 
     45     public OneTimeSettingsListener(Context context, String namespace, String key) {
     46         super(new Handler(Looper.getMainLooper()));
     47         mKey = key;
     48         mResolver = context.getContentResolver();
     49         final Uri uri;
     50         switch (namespace) {
     51             case NAMESPACE_SECURE:
     52                 uri = Settings.Secure.getUriFor(key);
     53                 break;
     54             case NAMESPACE_GLOBAL:
     55                 uri = Settings.Global.getUriFor(key);
     56                 break;
     57             default:
     58                 throw new IllegalArgumentException("invalid namespace: " + namespace);
     59         }
     60         mResolver.registerContentObserver(uri, false, this);
     61     }
     62 
     63     @Override
     64     public void onChange(boolean selfChange, Uri uri) {
     65         mResolver.unregisterContentObserver(this);
     66         mLatch.countDown();
     67     }
     68 
     69     /**
     70      * Blocks for a few seconds until it's called.
     71      *
     72      * @throws IllegalStateException if it's not called.
     73      */
     74     public void assertCalled() {
     75         try {
     76             final boolean updated = mLatch.await(5, TimeUnit.SECONDS);
     77             if (!updated) {
     78                 throw new IllegalStateException("Settings " + mKey + " not called in 5s");
     79             }
     80         } catch (InterruptedException e) {
     81             Thread.currentThread().interrupt();
     82             throw new IllegalStateException("Interrupted", e);
     83         }
     84     }
     85 }
     86