SUW: add page for navigation mode

Skip the page if device has HW-keys and does not enable software keys.

Change-Id: I9efb49ddb1c2a101e6395c9034eacbeb0cfec6b6
This commit is contained in:
Timi Rautamäki
2022-03-16 13:21:30 +00:00
committed by Michael W
parent 563a38c121
commit e83f9e12a1
12 changed files with 366 additions and 5 deletions

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 The CyanogenMod Project
Copyright (C) 2017-2021 The LineageOS Project
Copyright (C) 2017-2022 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -240,6 +240,19 @@
</intent-filter>
</activity>
<activity android:name=".NavigationSettingsActivity"
android:label="@string/activity_label_empty"
android:excludeFromRecents="true"
android:configChanges="mcc|mnc"
android:immersive="true"
android:exported="true"
android:windowSoftInputMode="stateAlwaysHidden">
<intent-filter>
<action android:name="org.lineageos.setupwizard.NAVIGATION_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".BiometricActivity"
android:label="@string/activity_label_empty"
android:excludeFromRecents="true"

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/black"
android:pathData="M4.59,6.89C5.29,6.18 6,5.54 6.3,5.67C6.8,5.87 6.3,6.7 6,7.19C5.75,7.61 3.14,11.08 3.14,13.5C3.14,14.78 3.62,15.84 4.5,16.5C5.23,17.04 6.22,17.21 7.12,16.94C8.19,16.63 9.07,15.54 10.18,14.17C11.39,12.68 13,10.73 14.26,10.73C15.89,10.73 15.91,11.74 16,12.5C12.24,13.16 10.64,16.19 10.64,17.89C10.64,19.59 12.08,21 13.85,21C15.5,21 18.14,19.65 18.54,14.88H21V12.38H18.53C18.38,10.73 17.44,8.18 14.5,8.18C12.25,8.18 10.32,10.09 9.56,11C9,11.75 7.5,13.5 7.27,13.74C7,14.04 6.59,14.58 6.16,14.58C5.71,14.58 5.44,13.75 5.8,12.66C6.15,11.57 7.2,9.8 7.65,9.14C8.43,8 8.95,7.22 8.95,5.86C8.95,3.69 7.31,3 6.44,3C5.12,3 3.97,4 3.72,4.25C3.36,4.61 3.06,4.91 2.84,5.18L4.59,6.89M13.88,18.55C13.57,18.55 13.14,18.29 13.14,17.83C13.14,17.23 13.87,15.63 16,15.07C15.71,17.76 14.58,18.55 13.88,18.55Z" />
</vector>

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2022 The LineageOS 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.
-->
<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@style/SudContentFrame"
android:layout_marginTop="@dimen/base_margin_top">
<FrameLayout
android:id="@+id/page"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/navigation_illustration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:lottie_rawRes="@raw/lottie_system_nav_fully_gestural"
app:lottie_autoPlay="true"
app:lottie_loop="true" />
<RadioGroup
android:id="@+id/navigation_radio_group"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/radio_gesture"
android:text="@string/gesture_navigation"
android:checked="true"
style="@style/SudRadioButton" />
<RadioButton
android:id="@+id/radio_two_button"
android:text="@string/two_button_navigation"
style="@style/SudRadioButton" />
<RadioButton
android:id="@+id/radio_sw_keys"
android:text="@string/navbar_navigation"
style="@style/SudRadioButton" />
</RadioGroup>
<CheckBox
android:id="@+id/hide_navigation_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hide_gesture_hint"
android:layout_marginTop="0dp"
android:layout_marginBottom="6dp"
android:layout_marginLeft="-6dp"
android:paddingLeft="18dp"
style="@style/SudCheckBox" />
</LinearLayout>
</ScrollView>
</FrameLayout>
<org.lineageos.setupwizard.NavigationLayout
android:id="@+id/navigation_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</com.google.android.setupdesign.GlifLayout>

View File

@@ -2,7 +2,7 @@
<!--
Copyright (C) 2016 The CyanogenMod Project
Copyright (C) 2017-2021 The LineageOS Project
Copyright (C) 2017-2022 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -56,6 +56,10 @@
</WizardAction>
<WizardAction wizard:uri="intent:#Intent;action=org.lineageos.setupwizard.LINEAGE_SETTINGS;end" id="lineage_settings">
<result wizard:action="navigation_settings" />
</WizardAction>
<WizardAction wizard:uri="intent:#Intent;action=org.lineageos.setupwizard.NAVIGATION_SETTINGS;end" id="navigation_settings">
<result wizard:action="biometric_settings" />
</WizardAction>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -115,6 +115,9 @@
<result wizard:action="lineage_settings" />
</WizardAction>
<WizardAction wizard:uri="intent:#Intent;action=org.lineageos.setupwizard.LINEAGE_SETTINGS;end" id="lineage_settings">
<result wizard:action="navigation_settings" />
</WizardAction>
<WizardAction wizard:uri="intent:#Intent;action=org.lineageos.setupwizard.NAVIGATION_SETTINGS;end" id="navigation_settings">
<result wizard:action="restore" />
</WizardAction>
<WizardAction wizard:uri="intent:#Intent;action=org.lineageos.setupwizard.LINEAGE_RESTORE_BACKUP;end" id="restore">

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013-2015 The CyanogenMod Project
Copyright (C) 2017-2020 The LineageOS Project
Copyright (C) 2017-2020, 2022 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -105,4 +105,12 @@
<string name="update_recovery_warning">Recovery will be updated as soon as you finish the setup. If you wish to keep it intact, disable this feature.</string>
<string name="update_recovery_setting">Update Lineage Recovery alongside the OS</string>
<string name="update_recovery_full_description"><xliff:g id="recovery_update_description">%1$s</xliff:g>\n<xliff:g id="recovery_update_warning">%2$s</xliff:g></string>
<!-- Navigation settings -->
<string name="setup_navigation">Navigation</string>
<string name="navigation_summary">Choose preferred navigation method</string>
<string name="gesture_navigation">Gesture navigation</string>
<string name="two_button_navigation">2-button navigation</string>
<string name="navbar_navigation">3-button navigation</string>
<string name="hide_gesture_hint">Hide gestural navigation hint</string>
</resources>

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2016 The CyanogenMod Project
* Copyright (C) 2017-2020 The LineageOS Project
* Copyright (C) 2017-2020, 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,9 @@
package org.lineageos.setupwizard;
import static android.os.Binder.getCallingUserHandle;
import static android.os.UserHandle.USER_CURRENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
import static org.lineageos.setupwizard.Manifest.permission.FINISH_SETUP;
import static org.lineageos.setupwizard.SetupWizardApp.ACTION_SETUP_COMPLETE;
@@ -25,6 +28,7 @@ import static org.lineageos.setupwizard.SetupWizardApp.DISABLE_NAV_KEYS;
import static org.lineageos.setupwizard.SetupWizardApp.ENABLE_RECOVERY_UPDATE;
import static org.lineageos.setupwizard.SetupWizardApp.KEY_SEND_METRICS;
import static org.lineageos.setupwizard.SetupWizardApp.LOGV;
import static org.lineageos.setupwizard.SetupWizardApp.NAVIGATION_OPTION_KEY;
import static org.lineageos.setupwizard.SetupWizardApp.UPDATE_RECOVERY_PROP;
import android.animation.Animator;
@@ -33,11 +37,13 @@ import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.om.IOverlayManager;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.preference.PreferenceManager;
@@ -172,6 +178,7 @@ public class FinishActivity extends BaseSetupWizardActivity {
handleEnableMetrics(mSetupWizardApp);
handleNavKeys(mSetupWizardApp);
handleRecoveryUpdate(mSetupWizardApp);
handleNavigationOption(mSetupWizardApp);
final WallpaperManager wallpaperManager =
WallpaperManager.getInstance(mSetupWizardApp);
wallpaperManager.forgetLoadedWallpaper();
@@ -209,6 +216,19 @@ public class FinishActivity extends BaseSetupWizardActivity {
}
}
private void handleNavigationOption(Context context) {
Bundle settingsBundle = mSetupWizardApp.getSettingsBundle();
if (settingsBundle.containsKey(NAVIGATION_OPTION_KEY)) {
IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
ServiceManager.getService(Context.OVERLAY_SERVICE));
String selectedNavMode = settingsBundle.getString(NAVIGATION_OPTION_KEY);
try {
overlayManager.setEnabledExclusiveInCategory(selectedNavMode, USER_CURRENT);
} catch (Exception e) {}
}
}
private static void writeDisableNavkeysOption(Context context, boolean enabled) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

View File

@@ -0,0 +1,197 @@
/*
* Copyright (C) 2022 The LineageOS 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 org.lineageos.setupwizard;
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 static org.lineageos.internal.util.DeviceKeysConstants.KEY_MASK_APP_SWITCH;
import static org.lineageos.setupwizard.SetupWizardApp.DISABLE_NAV_KEYS;
import static org.lineageos.setupwizard.SetupWizardApp.NAVIGATION_OPTION_KEY;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.content.Context;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import com.airbnb.lottie.LottieAnimationView;
import com.google.android.setupcompat.util.WizardManagerHelper;
import lineageos.providers.LineageSettings;
import org.lineageos.setupwizard.util.SetupWizardUtils;
public class NavigationSettingsActivity extends BaseSetupWizardActivity {
public static final String TAG = NavigationSettingsActivity.class.getSimpleName();
private SetupWizardApp mSetupWizardApp;
private String mSelection = NAV_BAR_MODE_GESTURAL_OVERLAY;
private CheckBox mHideGesturalHint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSetupWizardApp = (SetupWizardApp) getApplication();
boolean navBarEnabled = false;
if (mSetupWizardApp.getSettingsBundle().containsKey(DISABLE_NAV_KEYS)) {
navBarEnabled = mSetupWizardApp.getSettingsBundle().getBoolean(DISABLE_NAV_KEYS);
}
int deviceKeys = getResources().getInteger(
org.lineageos.platform.internal.R.integer.config_deviceHardwareKeys);
boolean hasHomeKey = (deviceKeys & KEY_MASK_APP_SWITCH) != 0;
getGlifLayout().setDescriptionText(getString(R.string.navigation_summary));
setNextText(R.string.next);
int available = 3;
// Hide unavailable navigation modes
if (!isOverlayPackageAvailable(this, NAV_BAR_MODE_GESTURAL_OVERLAY)) {
findViewById(R.id.radio_gesture).setVisibility(View.GONE);
((RadioButton) findViewById(R.id.radio_sw_keys)).setChecked(true);
available--;
}
if (!isOverlayPackageAvailable(this, NAV_BAR_MODE_2BUTTON_OVERLAY)) {
findViewById(R.id.radio_two_button).setVisibility(View.GONE);
available--;
}
if (!isOverlayPackageAvailable(this, NAV_BAR_MODE_3BUTTON_OVERLAY)) {
findViewById(R.id.radio_sw_keys).setVisibility(View.GONE);
available--;
}
// Hide this page if the device has hardware keys but didn't enable navbar
// or if there's <= 1 available navigation modes
if (!navBarEnabled && hasHomeKey || available <= 1) {
mSetupWizardApp.getSettingsBundle().putString(NAVIGATION_OPTION_KEY,
NAV_BAR_MODE_3BUTTON_OVERLAY);
Intent intent = WizardManagerHelper.getNextIntent(getIntent(), Activity.RESULT_OK);
finishAction(RESULT_OK, intent);
}
final LottieAnimationView navigationIllustration =
findViewById(R.id.navigation_illustration);
final RadioGroup radioGroup = findViewById(R.id.navigation_radio_group);
mHideGesturalHint = findViewById(R.id.hide_navigation_hint);
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.radio_gesture:
mSelection = NAV_BAR_MODE_GESTURAL_OVERLAY;
navigationIllustration
.setAnimation(R.raw.lottie_system_nav_fully_gestural);
revealHintCheckbox();
break;
case R.id.radio_two_button:
mSelection = NAV_BAR_MODE_2BUTTON_OVERLAY;
navigationIllustration.setAnimation(R.raw.lottie_system_nav_2_button);
hideHintCheckBox();
break;
case R.id.radio_sw_keys:
mSelection = NAV_BAR_MODE_3BUTTON_OVERLAY;
navigationIllustration.setAnimation(R.raw.lottie_system_nav_3_button);
hideHintCheckBox();
break;
}
navigationIllustration.playAnimation();
}
});
}
private void revealHintCheckbox() {
if (mHideGesturalHint.getVisibility() == View.VISIBLE) {
return;
}
mHideGesturalHint.setVisibility(View.VISIBLE);
mHideGesturalHint.setAlpha(0.0f);
mHideGesturalHint.animate()
.translationY(0)
.alpha(1.0f)
.setListener(null);
}
private void hideHintCheckBox() {
if (mHideGesturalHint.getVisibility() == View.INVISIBLE) {
return;
}
mHideGesturalHint.animate()
.translationY(-mHideGesturalHint.getHeight())
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mHideGesturalHint.setVisibility(View.INVISIBLE);
}
});
}
@Override
protected void onNextPressed() {
mSetupWizardApp.getSettingsBundle().putString(NAVIGATION_OPTION_KEY, mSelection);
boolean hideHint = mHideGesturalHint.isChecked();
LineageSettings.System.putIntForUser(getContentResolver(),
LineageSettings.System.NAVIGATION_BAR_HINT, hideHint ? 0 : 1,
UserHandle.USER_CURRENT);
Intent intent = WizardManagerHelper.getNextIntent(getIntent(), Activity.RESULT_OK);
nextAction(NEXT_REQUEST, intent);
}
@Override
protected int getLayoutResId() {
return R.layout.setup_navigation;
}
@Override
protected int getTitleResId() {
return R.string.setup_navigation;
}
@Override
protected int getIconResId() {
return R.drawable.ic_navigation;
}
private static boolean isOverlayPackageAvailable(Context context, String overlayPackage) {
try {
return context.getPackageManager().getPackageInfo(overlayPackage, 0) != null;
} catch (Exception e) {
// Not found, just return unavailable
return false;
}
}
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2013 The CyanogenMod Project
* Copyright (C) 2017-2021 The LineageOS Project
* Copyright (C) 2017-2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -65,6 +65,8 @@ public class SetupWizardApp extends Application {
public static final String ENABLE_RECOVERY_UPDATE = "enable_recovery_update";
public static final String UPDATE_RECOVERY_PROP = "persist.vendor.recovery_update";
public static final String NAVIGATION_OPTION_KEY = "navigation_option";
public static final int REQUEST_CODE_SETUP_NETWORK = 0;
public static final int REQUEST_CODE_SETUP_CAPTIVE_PORTAL = 4;
public static final int REQUEST_CODE_SETUP_BLUETOOTH = 5;