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 17 package com.android.settings.slices; 18 19 import android.content.Context; 20 import android.net.Uri; 21 import android.util.Log; 22 23 import androidx.annotation.Nullable; 24 import androidx.annotation.VisibleForTesting; 25 import androidx.lifecycle.LiveData; 26 import androidx.lifecycle.Observer; 27 import androidx.preference.PreferenceScreen; 28 import androidx.slice.Slice; 29 import androidx.slice.widget.SliceLiveData; 30 import androidx.slice.widget.SliceView; 31 32 import com.android.settings.core.BasePreferenceController; 33 import com.android.settingslib.core.lifecycle.LifecycleObserver; 34 import com.android.settingslib.core.lifecycle.events.OnStart; 35 import com.android.settingslib.core.lifecycle.events.OnStop; 36 37 /** 38 * Default {@link BasePreferenceController} for {@link SliceView}. It will take {@link Uri} for 39 * Slice and display what's inside this {@link Uri} 40 */ 41 public class SlicePreferenceController extends BasePreferenceController implements 42 LifecycleObserver, OnStart, OnStop, Observer<Slice> { 43 private static final String TAG = "SlicePreferenceController"; 44 @VisibleForTesting 45 LiveData<Slice> mLiveData; 46 @VisibleForTesting 47 SlicePreference mSlicePreference; 48 private Uri mUri; 49 SlicePreferenceController(Context context, String preferenceKey)50 public SlicePreferenceController(Context context, String preferenceKey) { 51 super(context, preferenceKey); 52 } 53 54 @Override displayPreference(PreferenceScreen screen)55 public void displayPreference(PreferenceScreen screen) { 56 super.displayPreference(screen); 57 mSlicePreference = screen.findPreference(getPreferenceKey()); 58 } 59 60 @Override getAvailabilityStatus()61 public int getAvailabilityStatus() { 62 return mUri != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE; 63 } 64 65 /** Sets Slice uri for the preference. */ setSliceUri(@ullable Uri uri)66 public void setSliceUri(@Nullable Uri uri) { 67 mUri = uri; 68 mLiveData = SliceLiveData.fromUri(mContext, mUri, (int type, Throwable source) -> { 69 Log.w(TAG, "Slice may be null. uri = " + uri + ", error = " + type); 70 }); 71 72 //TODO(b/120803703): figure out why we need to remove observer first 73 removeLiveDataObserver(); 74 } 75 76 @Override onStart()77 public void onStart() { 78 if (mLiveData == null) { 79 return; 80 } 81 82 try { 83 mLiveData.observeForever(this); 84 } catch (SecurityException e) { 85 Log.w(TAG, "observeForever - no permission"); 86 } 87 } 88 89 @Override onStop()90 public void onStop() { 91 removeLiveDataObserver(); 92 } 93 94 @Override onChanged(Slice slice)95 public void onChanged(Slice slice) { 96 mSlicePreference.onSliceUpdated(slice); 97 Log.w(TAG, "Slice UI updated, uri: " + mUri + ", slice content: " + slice); 98 } 99 removeLiveDataObserver()100 private void removeLiveDataObserver() { 101 if (mLiveData == null) { 102 return; 103 } 104 105 try { 106 mLiveData.removeObserver(this); 107 } catch (SecurityException e) { 108 Log.w(TAG, "removeLiveDataObserver - no permission"); 109 } 110 } 111 } 112