blob: e17b87057030b6ff6d2d0e7976f7b7b62a972c7f [file] [log] [blame]
/*
* Copyright (C) 2018 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.gestures;
import static android.os.UserHandle.USER_CURRENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.om.IOverlayManager;
import android.graphics.drawable.Drawable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.SearchIndexableResource;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.RadioButtonPickerFragment;
import com.android.settings.widget.RadioButtonPreference;
import com.android.settings.widget.VideoPreference;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.CandidateInfo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SearchIndexable
public class SystemNavigationGestureSettings extends RadioButtonPickerFragment {
private static final String TAG = "SystemNavigationGesture";
@VisibleForTesting
static final String KEY_SYSTEM_NAV_3BUTTONS = "system_nav_3buttons";
@VisibleForTesting
static final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons";
@VisibleForTesting
static final String KEY_SYSTEM_NAV_GESTURAL = "system_nav_gestural";
public static final String PREF_KEY_SUGGESTION_COMPLETE =
"pref_system_navigation_suggestion_complete";
private IOverlayManager mOverlayManager;
private VideoPreference mVideoPreference;
@Override
public void onAttach(Context context) {
super.onAttach(context);
SuggestionFeatureProvider suggestionFeatureProvider = FeatureFactory.getFactory(context)
.getSuggestionFeatureProvider(context);
SharedPreferences prefs = suggestionFeatureProvider.getSharedPrefs(context);
prefs.edit().putBoolean(PREF_KEY_SUGGESTION_COMPLETE, true).apply();
mOverlayManager = IOverlayManager.Stub.asInterface(
ServiceManager.getService(Context.OVERLAY_SERVICE));
mVideoPreference = new VideoPreference(context);
setIllustrationVideo(mVideoPreference, getDefaultKey());
}
@Override
public int getMetricsCategory() {
return SettingsEnums.SETTINGS_GESTURE_SWIPE_UP;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.system_navigation_gesture_settings;
}
@Override
protected void addStaticPreferences(PreferenceScreen screen) {
screen.addPreference(mVideoPreference);
}
@Override
protected List<? extends CandidateInfo> getCandidates() {
final Context c = getContext();
List<NavModeCandidateInfo> candidates = new ArrayList<>();
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_GESTURAL_OVERLAY)) {
candidates.add(new NavModeCandidateInfo(
c.getText(R.string.edge_to_edge_navigation_title),
c.getText(R.string.edge_to_edge_navigation_summary),
KEY_SYSTEM_NAV_GESTURAL, true /* enabled */));
}
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_2BUTTON_OVERLAY)) {
candidates.add(new NavModeCandidateInfo(
c.getText(R.string.swipe_up_to_switch_apps_title),
c.getText(R.string.swipe_up_to_switch_apps_summary),
KEY_SYSTEM_NAV_2BUTTONS, true /* enabled */));
}
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_3BUTTON_OVERLAY)) {
candidates.add(new NavModeCandidateInfo(
c.getText(R.string.legacy_navigation_title),
c.getText(R.string.legacy_navigation_summary),
KEY_SYSTEM_NAV_3BUTTONS, true /* enabled */));
}
return candidates;
}
@Override
protected String getDefaultKey() {
return getCurrentSystemNavigationMode(getContext());
}
@Override
protected boolean setDefaultKey(String key) {
setCurrentSystemNavigationMode(mOverlayManager, key);
setIllustrationVideo(mVideoPreference, key);
return true;
}
@VisibleForTesting
static String getCurrentSystemNavigationMode(Context context) {
if (SystemNavigationPreferenceController.isEdgeToEdgeEnabled(context)) {
return KEY_SYSTEM_NAV_GESTURAL;
} else if (SystemNavigationPreferenceController.isSwipeUpEnabled(context)) {
return KEY_SYSTEM_NAV_2BUTTONS;
} else {
return KEY_SYSTEM_NAV_3BUTTONS;
}
}
@VisibleForTesting
static void setCurrentSystemNavigationMode(IOverlayManager overlayManager, String key) {
switch (key) {
case KEY_SYSTEM_NAV_GESTURAL:
setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_GESTURAL_OVERLAY);
break;
case KEY_SYSTEM_NAV_2BUTTONS:
setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY);
break;
case KEY_SYSTEM_NAV_3BUTTONS:
setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_3BUTTON_OVERLAY);
break;
}
}
/**
* Enables the specified overlay package.
*/
static void setNavBarInteractionMode(IOverlayManager overlayManager, String overlayPackage) {
try {
overlayManager.setEnabledExclusiveInCategory(overlayPackage, USER_CURRENT);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
static void setIllustrationVideo(VideoPreference videoPref, String systemNavKey) {
videoPref.setVideo(0, 0);
switch (systemNavKey) {
case KEY_SYSTEM_NAV_GESTURAL:
videoPref.setVideo(R.raw.system_nav_fully_gestural,
R.drawable.system_nav_fully_gestural);
break;
case KEY_SYSTEM_NAV_2BUTTONS:
videoPref.setVideo(R.raw.system_nav_2_button, R.drawable.system_nav_2_button);
break;
case KEY_SYSTEM_NAV_3BUTTONS:
videoPref.setVideo(R.raw.system_nav_3_button, R.drawable.system_nav_3_button);
break;
}
}
@Override
public void bindPreferenceExtra(RadioButtonPreference pref,
String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
if (info instanceof NavModeCandidateInfo) {
pref.setSummary(((NavModeCandidateInfo) info).loadSummary());
pref.setAppendixVisibility(View.GONE);
}
}
static class NavModeCandidateInfo extends CandidateInfo {
private final CharSequence mLabel;
private final CharSequence mSummary;
private final String mKey;
NavModeCandidateInfo(CharSequence label, CharSequence summary, String key,
boolean enabled) {
super(enabled);
mLabel = label;
mSummary = summary;
mKey = key;
}
@Override
public CharSequence loadLabel() {
return mLabel;
}
public CharSequence loadSummary() {
return mSummary;
}
@Override
public Drawable loadIcon() {
return null;
}
@Override
public String getKey() {
return mKey;
}
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.system_navigation_gesture_settings;
return Arrays.asList(sir);
}
@Override
protected boolean isPageSearchEnabled(Context context) {
return SystemNavigationPreferenceController.isGestureAvailable(context);
}
};
}