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 com.android.tv.settings;
18 
19 import static androidx.lifecycle.Lifecycle.Event.ON_CREATE;
20 import static androidx.lifecycle.Lifecycle.Event.ON_DESTROY;
21 import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
22 import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
23 import static androidx.lifecycle.Lifecycle.Event.ON_START;
24 import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
25 
26 import android.annotation.CallSuper;
27 import android.content.Context;
28 import android.os.Bundle;
29 import android.view.Menu;
30 import android.view.MenuInflater;
31 import android.view.MenuItem;
32 
33 import androidx.annotation.NonNull;
34 import androidx.leanback.preference.LeanbackPreferenceFragment;
35 import androidx.lifecycle.LifecycleOwner;
36 import androidx.preference.PreferenceScreen;
37 
38 import com.android.settingslib.core.instrumentation.Instrumentable;
39 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
40 import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
41 import com.android.settingslib.core.lifecycle.Lifecycle;
42 
43 /**
44  * A {@link LeanbackPreferenceFragment} that has hooks to observe fragment lifecycle events
45  * and allow for instrumentation.
46  */
47 public abstract class SettingsPreferenceFragment extends LeanbackPreferenceFragment
48         implements LifecycleOwner, Instrumentable {
49     private final Lifecycle mLifecycle = new Lifecycle(this);
50     private final VisibilityLoggerMixin mVisibilityLoggerMixin;
51     protected MetricsFeatureProvider mMetricsFeatureProvider;
52 
53     @NonNull
getLifecycle()54     public Lifecycle getLifecycle() {
55         return mLifecycle;
56     }
57 
SettingsPreferenceFragment()58     public SettingsPreferenceFragment() {
59         mMetricsFeatureProvider = new MetricsFeatureProvider();
60         // Mixin that logs visibility change for activity.
61         mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
62                 mMetricsFeatureProvider);
63         getLifecycle().addObserver(mVisibilityLoggerMixin);
64     }
65 
66     @CallSuper
67     @Override
onAttach(Context context)68     public void onAttach(Context context) {
69         super.onAttach(context);
70         mLifecycle.onAttach(context);
71     }
72 
73     @CallSuper
74     @Override
onCreate(Bundle savedInstanceState)75     public void onCreate(Bundle savedInstanceState) {
76         mLifecycle.onCreate(savedInstanceState);
77         mLifecycle.handleLifecycleEvent(ON_CREATE);
78         super.onCreate(savedInstanceState);
79     }
80 
81     @Override
setPreferenceScreen(PreferenceScreen preferenceScreen)82     public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
83         mLifecycle.setPreferenceScreen(preferenceScreen);
84         super.setPreferenceScreen(preferenceScreen);
85     }
86 
87     @CallSuper
88     @Override
onSaveInstanceState(Bundle outState)89     public void onSaveInstanceState(Bundle outState) {
90         super.onSaveInstanceState(outState);
91         mLifecycle.onSaveInstanceState(outState);
92     }
93 
94     @CallSuper
95     @Override
onStart()96     public void onStart() {
97         mLifecycle.handleLifecycleEvent(ON_START);
98         super.onStart();
99     }
100 
101     @CallSuper
102     @Override
onResume()103     public void onResume() {
104         mVisibilityLoggerMixin.setSourceMetricsCategory(getActivity());
105         mLifecycle.handleLifecycleEvent(ON_RESUME);
106         super.onResume();
107     }
108 
109     @CallSuper
110     @Override
onPause()111     public void onPause() {
112         mLifecycle.handleLifecycleEvent(ON_PAUSE);
113         super.onPause();
114     }
115 
116     @CallSuper
117     @Override
onStop()118     public void onStop() {
119         mLifecycle.handleLifecycleEvent(ON_STOP);
120         super.onStop();
121     }
122 
123     @CallSuper
124     @Override
onDestroy()125     public void onDestroy() {
126         mLifecycle.handleLifecycleEvent(ON_DESTROY);
127         super.onDestroy();
128     }
129 
130     @CallSuper
131     @Override
onCreateOptionsMenu(final Menu menu, final MenuInflater inflater)132     public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
133         mLifecycle.onCreateOptionsMenu(menu, inflater);
134         super.onCreateOptionsMenu(menu, inflater);
135     }
136 
137     @CallSuper
138     @Override
onPrepareOptionsMenu(final Menu menu)139     public void onPrepareOptionsMenu(final Menu menu) {
140         mLifecycle.onPrepareOptionsMenu(menu);
141         super.onPrepareOptionsMenu(menu);
142     }
143 
144     @CallSuper
145     @Override
onOptionsItemSelected(final MenuItem menuItem)146     public boolean onOptionsItemSelected(final MenuItem menuItem) {
147         boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
148         if (!lifecycleHandled) {
149             return super.onOptionsItemSelected(menuItem);
150         }
151         return lifecycleHandled;
152     }
153 }
154