Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright 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 androidx.slice.widget;
     17 
     18 import static androidx.annotation.RestrictTo.Scope.LIBRARY;
     19 
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.net.Uri;
     23 import android.os.AsyncTask;
     24 
     25 import androidx.annotation.NonNull;
     26 import androidx.annotation.RestrictTo;
     27 import androidx.collection.ArraySet;
     28 import androidx.lifecycle.LiveData;
     29 import androidx.slice.Slice;
     30 import androidx.slice.SliceManager;
     31 import androidx.slice.SliceSpec;
     32 import androidx.slice.SliceSpecs;
     33 
     34 import java.util.Arrays;
     35 import java.util.Set;
     36 
     37 /**
     38  * Class with factory methods for creating LiveData that observes slices.
     39  *
     40  * @see #fromUri(Context, Uri)
     41  * @see LiveData
     42  */
     43 public final class SliceLiveData {
     44 
     45     /**
     46      * @hide
     47      */
     48     @RestrictTo(LIBRARY)
     49     public static final SliceSpec OLD_BASIC = new SliceSpec("androidx.app.slice.BASIC", 1);
     50 
     51     /**
     52      * @hide
     53      */
     54     @RestrictTo(LIBRARY)
     55     public static final SliceSpec OLD_LIST = new SliceSpec("androidx.app.slice.LIST", 1);
     56 
     57     /**
     58      * @hide
     59      */
     60     @RestrictTo(LIBRARY)
     61     public static final Set<SliceSpec> SUPPORTED_SPECS = new ArraySet<>(
     62             Arrays.asList(SliceSpecs.BASIC, SliceSpecs.LIST, OLD_BASIC, OLD_LIST));
     63 
     64     /**
     65      * Produces an {@link LiveData} that tracks a Slice for a given Uri. To use
     66      * this method your app must have the permission to the slice Uri.
     67      */
     68     public static LiveData<Slice> fromUri(Context context, Uri uri) {
     69         return new SliceLiveDataImpl(context.getApplicationContext(), uri);
     70     }
     71 
     72     /**
     73      * Produces an {@link LiveData} that tracks a Slice for a given Intent. To use
     74      * this method your app must have the permission to the slice Uri.
     75      */
     76     public static LiveData<Slice> fromIntent(@NonNull Context context, @NonNull Intent intent) {
     77         return new SliceLiveDataImpl(context.getApplicationContext(), intent);
     78     }
     79 
     80     private static class SliceLiveDataImpl extends LiveData<Slice> {
     81         private final Intent mIntent;
     82         private final SliceManager mSliceManager;
     83         private Uri mUri;
     84 
     85         private SliceLiveDataImpl(Context context, Uri uri) {
     86             super();
     87             mSliceManager = SliceManager.getInstance(context);
     88             mUri = uri;
     89             mIntent = null;
     90             // TODO: Check if uri points at a Slice?
     91         }
     92 
     93         private SliceLiveDataImpl(Context context, Intent intent) {
     94             super();
     95             mSliceManager = SliceManager.getInstance(context);
     96             mUri = null;
     97             mIntent = intent;
     98         }
     99 
    100         @Override
    101         protected void onActive() {
    102             AsyncTask.execute(mUpdateSlice);
    103             if (mUri != null) {
    104                 mSliceManager.registerSliceCallback(mUri, mSliceCallback);
    105             }
    106         }
    107 
    108         @Override
    109         protected void onInactive() {
    110             if (mUri != null) {
    111                 mSliceManager.unregisterSliceCallback(mUri, mSliceCallback);
    112             }
    113         }
    114 
    115         private final Runnable mUpdateSlice = new Runnable() {
    116             @Override
    117             public void run() {
    118                 Slice s = mUri != null ? mSliceManager.bindSlice(mUri)
    119                         : mSliceManager.bindSlice(mIntent);
    120                 if (mUri == null && s != null) {
    121                     mUri = s.getUri();
    122                     mSliceManager.registerSliceCallback(mUri, mSliceCallback);
    123                 }
    124                 postValue(s);
    125             }
    126         };
    127 
    128         private final SliceManager.SliceCallback mSliceCallback = new SliceManager.SliceCallback() {
    129             @Override
    130             public void onSliceUpdated(@NonNull Slice s) {
    131                 postValue(s);
    132             }
    133         };
    134     }
    135 
    136     private SliceLiveData() {
    137     }
    138 }
    139