1 /* 2 * Copyright (C) 2019 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 com.android.settings.panel; 18 19 import android.net.Uri; 20 21 import androidx.slice.Slice; 22 23 import java.util.HashSet; 24 import java.util.Set; 25 import java.util.concurrent.CountDownLatch; 26 27 /** 28 * Helper class to isolate the work tracking all of the {@link Slice Slices} being loaded. 29 * <p> 30 * Uses a {@link CountDownLatch} and a {@link Set} of Slices to track how many 31 * Slices have been loaded. A Slice can only be counted as being loaded a single time, even 32 * when they get updated later. 33 * <p> 34 * To use the class, pass the number of expected Slices to load into the constructor. For 35 * every Slice that loads, call {@link #markSliceLoaded(Uri)} with the corresponding 36 * {@link Uri}. Then check if all of the Slices have loaded with 37 * {@link #isPanelReadyToLoad()}, which will return {@code true} the first time after all 38 * Slices have loaded. 39 */ 40 public class PanelSlicesLoaderCountdownLatch { 41 private final Set<Uri> mLoadedSlices; 42 private final CountDownLatch mCountDownLatch; 43 private boolean slicesReadyToLoad = false; 44 PanelSlicesLoaderCountdownLatch(int countdownSize)45 public PanelSlicesLoaderCountdownLatch(int countdownSize) { 46 mLoadedSlices = new HashSet<>(); 47 mCountDownLatch = new CountDownLatch(countdownSize); 48 } 49 50 /** 51 * Checks if the {@param sliceUri} has been loaded: if not, then decrement the countdown 52 * latch, and if so, then do nothing. 53 */ markSliceLoaded(Uri sliceUri)54 public void markSliceLoaded(Uri sliceUri) { 55 if (mLoadedSlices.contains(sliceUri)) { 56 return; 57 } 58 mLoadedSlices.add(sliceUri); 59 mCountDownLatch.countDown(); 60 } 61 62 /** 63 * @return {@code true} if the Slice has already been loaded. 64 */ isSliceLoaded(Uri uri)65 public boolean isSliceLoaded(Uri uri) { 66 return mLoadedSlices.contains(uri); 67 } 68 69 /** 70 * @return {@code true} when all Slices have loaded, and the Panel has not yet been loaded. 71 */ isPanelReadyToLoad()72 public boolean isPanelReadyToLoad() { 73 /** 74 * Use {@link slicesReadyToLoad} to track whether or not the Panel has been loaded. We 75 * only want to animate the Panel a single time. 76 */ 77 if ((mCountDownLatch.getCount() == 0) && !slicesReadyToLoad) { 78 slicesReadyToLoad = true; 79 return true; 80 } 81 return false; 82 } 83 }