1 /*
2  * Copyright (C) 2021 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.homepage;
18 
19 import android.content.DialogInterface;
20 import android.os.Bundle;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.text.TextUtils;
24 import android.util.Log;
25 
26 import androidx.fragment.app.FragmentActivity;
27 import androidx.preference.PreferenceScreen;
28 import androidx.recyclerview.widget.RecyclerView;
29 
30 import com.android.settings.SettingsActivity;
31 import com.android.settings.widget.HighlightableTopLevelPreferenceAdapter;
32 
33 /** A highlight mixin for the top level settings fragment. */
34 public class TopLevelHighlightMixin implements Parcelable, DialogInterface.OnShowListener,
35         DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
36 
37     private static final String TAG = "TopLevelHighlightMixin";
38 
39     private String mCurrentKey;
40     // Stores the previous key for the profile select dialog cancel event
41     private String mPreviousKey;
42     // Stores the key hidden for the search page presence
43     private String mHiddenKey;
44     private DialogInterface mDialog;
45     private HighlightableTopLevelPreferenceAdapter mTopLevelAdapter;
46 
TopLevelHighlightMixin()47     public TopLevelHighlightMixin() {
48     }
49 
TopLevelHighlightMixin(Parcel source)50     public TopLevelHighlightMixin(Parcel source) {
51         mCurrentKey = source.readString();
52         mPreviousKey = source.readString();
53         mHiddenKey = source.readString();
54     }
55 
56     @Override
writeToParcel(Parcel dest, int flags)57     public void writeToParcel(Parcel dest, int flags) {
58         dest.writeString(mCurrentKey);
59         dest.writeString(mPreviousKey);
60         dest.writeString(mHiddenKey);
61     }
62 
63     @Override
describeContents()64     public int describeContents() {
65         return 0;
66     }
67 
68     public static final Creator<TopLevelHighlightMixin> CREATOR = new Creator<>() {
69         @Override
70         public TopLevelHighlightMixin createFromParcel(Parcel source) {
71             return new TopLevelHighlightMixin(source);
72         }
73 
74         @Override
75         public TopLevelHighlightMixin[] newArray(int size) {
76             return new TopLevelHighlightMixin[size];
77         }
78     };
79 
80     @Override
onShow(DialogInterface dialog)81     public void onShow(DialogInterface dialog) {
82         mDialog = dialog;
83     }
84 
85     @Override
onDismiss(DialogInterface dialog)86     public void onDismiss(DialogInterface dialog) {
87         mDialog = null;
88     }
89 
90     @Override
onCancel(DialogInterface dialog)91     public void onCancel(DialogInterface dialog) {
92         if (mTopLevelAdapter != null) {
93             mCurrentKey = mPreviousKey;
94             mPreviousKey = null;
95             mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ false);
96         }
97     }
98 
onCreateAdapter(TopLevelSettings topLevelSettings, PreferenceScreen preferenceScreen)99     RecyclerView.Adapter onCreateAdapter(TopLevelSettings topLevelSettings,
100             PreferenceScreen preferenceScreen) {
101         if (TextUtils.isEmpty(mCurrentKey)) {
102             mCurrentKey = getHighlightPrefKeyFromArguments(topLevelSettings.getArguments());
103         }
104 
105         Log.d(TAG, "onCreateAdapter, pref key: " + mCurrentKey);
106         mTopLevelAdapter = new HighlightableTopLevelPreferenceAdapter(
107                 (SettingsHomepageActivity) topLevelSettings.getActivity(), preferenceScreen,
108                 topLevelSettings.getListView(), mCurrentKey);
109         return mTopLevelAdapter;
110     }
111 
reloadHighlightMenuKey(Bundle arguments)112     void reloadHighlightMenuKey(Bundle arguments) {
113         if (mTopLevelAdapter == null) {
114             return;
115         }
116         ensureDialogDismissed();
117 
118         mCurrentKey = getHighlightPrefKeyFromArguments(arguments);
119         Log.d(TAG, "reloadHighlightMenuKey, pref key: " + mCurrentKey);
120         mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ true);
121     }
122 
setHighlightPreferenceKey(String prefKey)123     void setHighlightPreferenceKey(String prefKey) {
124         if (mTopLevelAdapter != null) {
125             ensureDialogDismissed();
126             mPreviousKey = mCurrentKey;
127             mCurrentKey = prefKey;
128             mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ false);
129         }
130     }
131 
highlightPreferenceIfNeeded(FragmentActivity activity)132     void highlightPreferenceIfNeeded(FragmentActivity activity) {
133         if (mTopLevelAdapter != null) {
134             mTopLevelAdapter.requestHighlight();
135         }
136     }
137 
setMenuHighlightShowed(boolean show)138     void setMenuHighlightShowed(boolean show) {
139         if (mTopLevelAdapter == null) {
140             return;
141         }
142         ensureDialogDismissed();
143 
144         if (show) {
145             mCurrentKey = mHiddenKey;
146             mHiddenKey = null;
147         } else {
148             if (mHiddenKey == null) {
149                 mHiddenKey = mCurrentKey;
150             }
151             mCurrentKey = null;
152         }
153         mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ show);
154     }
155 
setHighlightMenuKey(String menuKey, boolean scrollNeeded)156     void setHighlightMenuKey(String menuKey, boolean scrollNeeded) {
157         if (mTopLevelAdapter == null) {
158             return;
159         }
160         ensureDialogDismissed();
161 
162         final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
163         if (TextUtils.isEmpty(prefKey)) {
164             Log.e(TAG, "Invalid highlight menu key: " + menuKey);
165         } else {
166             Log.d(TAG, "Menu key: " + menuKey);
167             mCurrentKey = prefKey;
168             mTopLevelAdapter.highlightPreference(prefKey, scrollNeeded);
169         }
170     }
171 
getHighlightPrefKeyFromArguments(Bundle arguments)172     private static String getHighlightPrefKeyFromArguments(Bundle arguments) {
173         final String menuKey = arguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
174         final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
175         if (TextUtils.isEmpty(prefKey)) {
176             Log.e(TAG, "Invalid highlight menu key: " + menuKey);
177         } else {
178             Log.d(TAG, "Menu key: " + menuKey);
179         }
180         return prefKey;
181     }
182 
ensureDialogDismissed()183     private void ensureDialogDismissed() {
184         if (mDialog != null) {
185             onCancel(mDialog);
186             mDialog.dismiss();
187         }
188     }
189 }
190