/* * Copyright (C) 2013 The CyanogenMod Project * Copyright (C) 2017 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 com.cyanogenmod.setupwizard.setup; import android.app.Fragment; import android.app.FragmentManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ThemeConfig; import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.preference.PreferenceManager; import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.util.Log; import android.view.IWindowManager; import android.view.View; import android.view.WindowManagerGlobal; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; import com.cyanogenmod.setupwizard.R; import com.cyanogenmod.setupwizard.SetupWizardApp; import com.cyanogenmod.setupwizard.cmstats.SetupStats; import com.cyanogenmod.setupwizard.ui.SetupPageFragment; import com.cyanogenmod.setupwizard.util.SetupWizardUtils; import cyanogenmod.hardware.CMHardwareManager; import cyanogenmod.providers.CMSettings; import cyanogenmod.themes.ThemeManager; public class CyanogenSettingsPage extends SetupPage { public static final String TAG = "CyanogenSettingsPage"; public static final String KEY_SEND_METRICS = "send_metrics"; public static final String DISABLE_NAV_KEYS = "disable_nav_keys"; public static final String KEY_APPLY_DEFAULT_THEME = "apply_default_theme"; public static final String KEY_BUTTON_BACKLIGHT = "pre_navbar_button_backlight"; public static final String KEY_PRIVACY_GUARD = "privacy_guard_default"; public static final String PRIVACY_POLICY_URI = "http://lineageos.org/legal"; public CyanogenSettingsPage(Context context, SetupDataCallbacks callbacks) { super(context, callbacks); } @Override public Fragment getFragment(FragmentManager fragmentManager, int action) { Fragment fragment = fragmentManager.findFragmentByTag(getKey()); if (fragment == null) { Bundle args = new Bundle(); args.putString(Page.KEY_PAGE_ARGUMENT, getKey()); args.putInt(Page.KEY_PAGE_ACTION, action); fragment = new CyanogenSettingsFragment(); fragment.setArguments(args); } return fragment; } @Override public String getKey() { return TAG; } @Override public int getTitleResId() { return R.string.setup_services; } @Override public int getIconResId() { return R.drawable.ic_features; } private static void writeDisableNavkeysOption(Context context, boolean enabled) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); CMSettings.Global.putInt(context.getContentResolver(), CMSettings.Global.DEV_FORCE_SHOW_NAVBAR, enabled ? 1 : 0); CMHardwareManager hardware = CMHardwareManager.getInstance(context); hardware.set(CMHardwareManager.FEATURE_KEY_DISABLE, enabled); /* Save/restore button timeouts to disable them in softkey mode */ if (enabled) { CMSettings.Secure.putInt(context.getContentResolver(), CMSettings.Secure.BUTTON_BRIGHTNESS, 0); } else { int currentBrightness = CMSettings.Secure.getInt(context.getContentResolver(), CMSettings.Secure.BUTTON_BRIGHTNESS, 100); int oldBright = prefs.getInt(KEY_BUTTON_BACKLIGHT, currentBrightness); CMSettings.Secure.putInt(context.getContentResolver(), CMSettings.Secure.BUTTON_BRIGHTNESS, oldBright); } } @Override public void onFinishSetup() { getCallbacks().addFinishRunnable(new Runnable() { @Override public void run() { if (getData().containsKey(DISABLE_NAV_KEYS)) { SetupStats.addEvent(SetupStats.Categories.SETTING_CHANGED, SetupStats.Action.ENABLE_NAV_KEYS, SetupStats.Label.CHECKED, String.valueOf(getData().getBoolean(DISABLE_NAV_KEYS))); writeDisableNavkeysOption(mContext, getData().getBoolean(DISABLE_NAV_KEYS)); } } }); handleEnableMetrics(); handleDefaultThemeSetup(); handlePrivacyGuard(); } private void handleEnableMetrics() { Bundle privacyData = getData(); if (privacyData != null && privacyData.containsKey(KEY_SEND_METRICS)) { CMSettings.Secure.putInt(mContext.getContentResolver(), CMSettings.Secure.STATS_COLLECTION, privacyData.getBoolean(KEY_SEND_METRICS) ? 1 : 0); } } private void handleDefaultThemeSetup() { Bundle privacyData = getData(); if (!SetupWizardUtils.getDefaultThemePackageName(mContext).equals( ThemeConfig.SYSTEM_DEFAULT) && privacyData != null && privacyData.getBoolean(KEY_APPLY_DEFAULT_THEME)) { SetupStats.addEvent(SetupStats.Categories.SETTING_CHANGED, SetupStats.Action.APPLY_CUSTOM_THEME, SetupStats.Label.CHECKED, String.valueOf(privacyData.getBoolean(KEY_APPLY_DEFAULT_THEME))); Log.i(TAG, "Applying default theme"); final ThemeManager tm = ThemeManager.getInstance(mContext); tm.applyDefaultTheme(); } else { getCallbacks().finishSetup(); } } private void handlePrivacyGuard() { Bundle mPrivacyData = getData(); if (mPrivacyData != null && mPrivacyData.containsKey(KEY_PRIVACY_GUARD)) { CMSettings.Secure.putInt(mContext.getContentResolver(), CMSettings.Secure.PRIVACY_GUARD_DEFAULT, mPrivacyData.getBoolean(KEY_PRIVACY_GUARD) ? 1 : 0); } } private static boolean hideKeyDisabler(Context ctx) { final CMHardwareManager hardware = CMHardwareManager.getInstance(ctx); return !hardware.isSupported(CMHardwareManager.FEATURE_KEY_DISABLE); } private static boolean isKeyDisablerActive(Context ctx) { final CMHardwareManager hardware = CMHardwareManager.getInstance(ctx); return hardware.get(CMHardwareManager.FEATURE_KEY_DISABLE); } private static boolean hideThemeSwitch(Context context) { return SetupWizardUtils.getDefaultThemePackageName(context) .equals(ThemeConfig.SYSTEM_DEFAULT); } public static class CyanogenSettingsFragment extends SetupPageFragment { private View mKillSwitchView; private TextView mKillSwitchTitle; private ImageView mKillSwitchStatus; private View mMetricsRow; private View mDefaultThemeRow; private View mNavKeysRow; private View mPrivacyGuardRow; private CheckBox mMetrics; private CheckBox mDefaultTheme; private CheckBox mNavKeys; private CheckBox mPrivacyGuard; private boolean mHideNavKeysRow = false; private boolean mHideThemeRow = false; private View.OnClickListener mMetricsClickListener = new View.OnClickListener() { @Override public void onClick(View view) { boolean checked = !mMetrics.isChecked(); mMetrics.setChecked(checked); mPage.getData().putBoolean(KEY_SEND_METRICS, checked); } }; private View.OnClickListener mDefaultThemeClickListener = new View.OnClickListener() { @Override public void onClick(View view) { boolean checked = !mDefaultTheme.isChecked(); mDefaultTheme.setChecked(checked); mPage.getData().putBoolean(KEY_APPLY_DEFAULT_THEME, checked); } }; private View.OnClickListener mNavKeysClickListener = new View.OnClickListener() { @Override public void onClick(View view) { boolean checked = !mNavKeys.isChecked(); mNavKeys.setChecked(checked); mPage.getData().putBoolean(DISABLE_NAV_KEYS, checked); } }; private View.OnClickListener mPrivacyGuardClickListener = new View.OnClickListener() { @Override public void onClick(View view) { boolean checked = !mPrivacyGuard.isChecked(); mPrivacyGuard.setChecked(checked); mPage.getData().putBoolean(KEY_PRIVACY_GUARD, checked); } }; @Override protected void initializePage() { String privacy_policy = getString(R.string.services_privacy_policy); String policySummary = getString(R.string.services_explanation, privacy_policy); SpannableString ss = new SpannableString(policySummary); ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(View textView) { // At this point of the setup, the device has already been unlocked (if frp // had been enabled), so there should be no issues regarding security final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(PRIVACY_POLICY_URI)); try { getActivity().startActivity(intent); } catch (Exception e) { Log.e(TAG, "Unable to start activity " + intent.toString(), e); } } }; ss.setSpan(clickableSpan, policySummary.length() - privacy_policy.length() - 1, policySummary.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); TextView privacyPolicy = (TextView) mRootView.findViewById(R.id.privacy_policy); privacyPolicy.setMovementMethod(LinkMovementMethod.getInstance()); privacyPolicy.setText(ss); mKillSwitchView = mRootView.findViewById(R.id.killswitch); mKillSwitchTitle = (TextView)mRootView.findViewById(R.id.killswitch_title); mKillSwitchStatus = (ImageView)mRootView.findViewById(R.id.killswitch_check); if (hideKillSwitch()) { mKillSwitchView.setVisibility(View.GONE); } else { if (SetupWizardUtils.isDeviceLocked()) { mKillSwitchTitle.setEnabled(true); mKillSwitchStatus.setImageResource(R.drawable.tick); } else { mKillSwitchTitle.setEnabled(false); mKillSwitchStatus.setImageResource(R.drawable.cross); } } mMetricsRow = mRootView.findViewById(R.id.metrics); mMetricsRow.setOnClickListener(mMetricsClickListener); String metricsHelpImproveCM = getString(R.string.services_help_improve_cm, getString(R.string.os_name)); String metricsSummary = getString(R.string.services_metrics_label, metricsHelpImproveCM, getString(R.string.os_name)); final SpannableStringBuilder metricsSpan = new SpannableStringBuilder(metricsSummary); metricsSpan.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), 0, metricsHelpImproveCM.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); TextView metrics = (TextView) mRootView.findViewById(R.id.enable_metrics_summary); metrics.setText(metricsSpan); mMetrics = (CheckBox) mRootView.findViewById(R.id.enable_metrics_checkbox); mDefaultThemeRow = mRootView.findViewById(R.id.theme); mHideThemeRow = hideThemeSwitch(getActivity()); if (mHideThemeRow) { mDefaultThemeRow.setVisibility(View.GONE); } else { mDefaultThemeRow.setOnClickListener(mDefaultThemeClickListener); String defaultTheme = getString(R.string.services_apply_theme, getString(R.string.default_theme_name)); String defaultThemeSummary = getString(R.string.services_apply_theme_label, defaultTheme); final SpannableStringBuilder themeSpan = new SpannableStringBuilder(defaultThemeSummary); themeSpan.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), 0, defaultTheme.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); TextView theme = (TextView) mRootView.findViewById(R.id.enable_theme_summary); theme.setText(themeSpan); mDefaultTheme = (CheckBox) mRootView.findViewById(R.id.enable_theme_checkbox); } mNavKeysRow = mRootView.findViewById(R.id.nav_keys); mNavKeysRow.setOnClickListener(mNavKeysClickListener); mNavKeys = (CheckBox) mRootView.findViewById(R.id.nav_keys_checkbox); boolean needsNavBar = true; try { IWindowManager windowManager = WindowManagerGlobal.getWindowManagerService(); needsNavBar = windowManager.needsNavigationBar(); } catch (RemoteException e) { } mHideNavKeysRow = hideKeyDisabler(getActivity()); if (mHideNavKeysRow || needsNavBar) { mNavKeysRow.setVisibility(View.GONE); } else { boolean navKeysDisabled = isKeyDisablerActive(getActivity()); mNavKeys.setChecked(navKeysDisabled); } mPrivacyGuardRow = mRootView.findViewById(R.id.privacy_guard); mPrivacyGuardRow.setOnClickListener(mPrivacyGuardClickListener); mPrivacyGuard = (CheckBox) mRootView.findViewById(R.id.privacy_guard_checkbox); mPrivacyGuard.setChecked(CMSettings.Secure.getInt(getActivity().getContentResolver(), CMSettings.Secure.PRIVACY_GUARD_DEFAULT, 0) == 1); } @Override protected int getLayoutResource() { return R.layout.setup_cyanogen_services; } @Override public void onResume() { super.onResume(); updateDisableNavkeysOption(); updateMetricsOption(); updateThemeOption(); } private void updateMetricsOption() { final Bundle myPageBundle = mPage.getData(); boolean metricsChecked = !myPageBundle.containsKey(KEY_SEND_METRICS) || myPageBundle .getBoolean(KEY_SEND_METRICS); mMetrics.setChecked(metricsChecked); myPageBundle.putBoolean(KEY_SEND_METRICS, metricsChecked); } private void updateThemeOption() { if (!mHideThemeRow) { final Bundle myPageBundle = mPage.getData(); boolean themesChecked; if (myPageBundle.containsKey(KEY_APPLY_DEFAULT_THEME)) { themesChecked = myPageBundle.getBoolean(KEY_APPLY_DEFAULT_THEME); } else { themesChecked = getActivity().getResources().getBoolean( R.bool.check_custom_theme_by_default); } mDefaultTheme.setChecked(themesChecked); myPageBundle.putBoolean(KEY_APPLY_DEFAULT_THEME, themesChecked); } } private void updateDisableNavkeysOption() { if (!mHideNavKeysRow) { final Bundle myPageBundle = mPage.getData(); boolean enabled = CMSettings.Secure.getInt(getActivity().getContentResolver(), CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR, 0) != 0; boolean checked = myPageBundle.containsKey(DISABLE_NAV_KEYS) ? myPageBundle.getBoolean(DISABLE_NAV_KEYS) : enabled; mNavKeys.setChecked(checked); myPageBundle.putBoolean(DISABLE_NAV_KEYS, checked); } } private static boolean hideKillSwitch() { return !SetupWizardUtils.hasKillSwitch(); } } }