diff --git a/src/com/android/settings/core/LiveDataController.java b/src/com/android/settings/core/LiveDataController.java new file mode 100644 index 00000000000..2bca5b629f5 --- /dev/null +++ b/src/com/android/settings/core/LiveDataController.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.core; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.MutableLiveData; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settingslib.utils.ThreadUtils; + +/** + * This controller is targeted at the time consuming-bound controller. + */ +public abstract class LiveDataController extends BasePreferenceController { + @VisibleForTesting + protected CharSequence mSummary; + + private Preference mPreference; + private MutableLiveData mData; + + + public LiveDataController(Context context, String preferenceKey) { + super(context, preferenceKey); + mData = new MutableLiveData<>(); + mSummary = context.getText(R.string.summary_placeholder); + } + + /** + * Initialize controller as live data controller and + * execute the background task for retrieving the summary text right away. + * @param fragment the owner of the live data observer. + */ + public void initLifeCycleOwner(@NonNull Fragment fragment) { + mData.observe(fragment, str -> { + mSummary = str; + refreshSummary(mPreference); + }); + ThreadUtils.postOnBackgroundThread(() -> { + mData.postValue(getSummaryTextInBackground()); + }); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public CharSequence getSummary() { + return mSummary; + } + + /** + * Execute the time consuming work. + */ + @WorkerThread + protected abstract CharSequence getSummaryTextInBackground(); +} diff --git a/tests/robotests/src/com/android/settings/core/LiveDataControllerTest.java b/tests/robotests/src/com/android/settings/core/LiveDataControllerTest.java new file mode 100644 index 00000000000..2fe541623d9 --- /dev/null +++ b/tests/robotests/src/com/android/settings/core/LiveDataControllerTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settings.core; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.annotation.RealObject; + +@RunWith(RobolectricTestRunner.class) +public class LiveDataControllerTest { + private static final String KEY = "test_key"; + private static final CharSequence TEST_DATA = "test_data"; + + private Context mContext; + private TestPreferenceController mTestController; + private TestFragment mFragment; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mFragment = new TestFragment(); + mTestController = new TestPreferenceController(mContext, KEY); + } + + @Test + public void newController_returnPlaceHolderSummary() { + assertThat(mTestController.getSummary()).isEqualTo( + mContext.getText(R.string.summary_placeholder)); + } + + @Test + @Config(shadows = ShadowLiveDataController.class) + public void initLifeCycleOwner_returnTestData() { + mTestController.initLifeCycleOwner(mFragment); + assertThat(mTestController.getSummary()).isEqualTo(TEST_DATA); + } + + static class TestPreferenceController extends LiveDataController { + TestPreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public CharSequence getSummaryTextInBackground() { + return TEST_DATA; + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + } + + static class TestFragment extends SettingsPreferenceFragment { + @Override + public int getMetricsCategory() { + return 0; + } + } + + @Implements(LiveDataController.class) + public static class ShadowLiveDataController { + @RealObject LiveDataController mRealController; + + @Implementation + protected void initLifeCycleOwner(@NonNull Fragment fragment) { + mRealController.mSummary = TEST_DATA; + } + } +}