Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35d25465 authored by LuK1337's avatar LuK1337 Committed by Zhao Wei Liew
Browse files

Settings: Add CMHW vibrator intensity preference

Port the related changes from the following cm-13.0 commits:
a284b34f settings: Squashed commit of CMHW features
d4ebf3a5 Settings: Cleanup display settings code
ba4c43f7 Settings: Change to CmHardwareService
d2d9f452 settings: Move CMHW to CMSDK
bd3fe676 Add isSupported() method to VibratorIntensity class
9c353384 Settings : Add multiuser support for CMHardware
bac46048 Settings: Fix one-time vibration intensity restore
a3a64ce7 Settings: Rework vibration intensity slider
76997a78 Settings: Save vibration intensity on close
a44bfb5a Settings: Move vibrator value restore to onActivityStop
9176a64e Settings: Improve vibrator intensity dialog layout

Change-Id: Iece36085f8f07a171affefd9a1027fb11fed5d93
parent 4e559c6d
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2013-2016 The CyanogenMod 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.
-->
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:paddingTop="24dp"
    android:paddingBottom="24dp"
    android:paddingEnd="24dp">

    <TextView
        android:id="@+id/value"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_marginStart="4dp"
        android:gravity="center_horizontal"
        android:minEms="2" />

    <SeekBar
        android:id="@*android:id/seekbar"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_alignParentStart="true"
        android:layout_marginStart="8dp"
        android:layout_toStartOf="@id/value" />

    <TextView
        android:id="@+id/warning_text"
        android:layout_below="@*android:id/seekbar"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp" />

</RelativeLayout>
+5 −0
Original line number Diff line number Diff line
@@ -238,6 +238,11 @@
    <!-- Volume settings - Volume adjustment sound -->
    <string name="volume_adjust_sounds_title">Volume adjustment sounds</string>

    <!-- Vibrator intensity -->
    <string name="vibrator_intensity_title">Vibrator intensity</string>
    <string name="vibrator_intensity_dialog_warning">Values greater than %1$d%% are not recommended</string>
    <string name="vibrator_intensity_dialog_reset">Reset</string>

    <!-- Sizes for pattern lockscreen -->
    <string name="lock_pattern_size_3">3x3</string>
    <string name="lock_pattern_size_4">4x4</string>
+7 −0
Original line number Diff line number Diff line
@@ -55,6 +55,13 @@
            android:key="vibrate_on_touch"
            android:title="@string/vibrate_on_touch_title" />

    <!-- Vibrator intensity -->
    <com.android.settings.hardware.VibratorIntensity
            android:key="vibrator_intensity"
            android:title="@string/vibrator_intensity_title"
            android:dialogTitle="@string/vibrator_intensity_title"
            android:persistent="false" />

    <!-- Dock speaker plays -->
    <DropDownPreference
            android:key="dock_audio_media"
+43 −0
Original line number Diff line number Diff line
@@ -71,6 +71,10 @@ public class CustomDialogPreference extends DialogPreference {
        mFragment = fragment;
    }

    protected boolean onDismissDialog(final DialogInterface dialog, final int which) {
        return true;
    }

    public static class CustomPreferenceDialogFragment extends PreferenceDialogFragment {

        public static CustomPreferenceDialogFragment newInstance(String key) {
@@ -85,6 +89,45 @@ public class CustomDialogPreference extends DialogPreference {
            return (CustomDialogPreference) getPreference();
        }

        private class OnDismissListener implements View.OnClickListener {
            private final int mWhich;
            private final DialogInterface mDialog;

            public OnDismissListener(final DialogInterface dialog, final int which) {
                mWhich = which;
                mDialog = dialog;
            }

            @Override
            public void onClick(final View view) {
                CustomPreferenceDialogFragment.this.onClick(mDialog, mWhich);
                if (getCustomizablePreference().onDismissDialog(mDialog, mWhich)) {
                    mDialog.dismiss();
                }
            }
        }

        @Override
        public void onStart() {
            super.onStart();

            if (getDialog() instanceof AlertDialog) {
                final AlertDialog dialog = (AlertDialog) getDialog();
                if (dialog.getButton(Dialog.BUTTON_NEUTRAL) != null) {
                    dialog.getButton(Dialog.BUTTON_NEUTRAL).setOnClickListener(
                            new OnDismissListener(dialog, Dialog.BUTTON_NEUTRAL));
                }
                if (dialog.getButton(Dialog.BUTTON_POSITIVE) != null) {
                    dialog.getButton(Dialog.BUTTON_POSITIVE).setOnClickListener(
                            new OnDismissListener(dialog, Dialog.BUTTON_POSITIVE));
                }
                if (dialog.getButton(Dialog.BUTTON_NEGATIVE) != null) {
                    dialog.getButton(Dialog.BUTTON_NEGATIVE).setOnClickListener(
                            new OnDismissListener(dialog, Dialog.BUTTON_NEGATIVE));
                }
            }
        }

        @Override
        protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
            super.onPrepareDialogBuilder(builder);
+206 −0
Original line number Diff line number Diff line
/**
 * Copyright (C) 2013-2016 The CyanogenMod 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.hardware;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Button;

import com.android.settings.CustomDialogPreference;
import com.android.settings.R;

import cyanogenmod.hardware.CMHardwareManager;
import cyanogenmod.providers.CMSettings;

public class VibratorIntensity extends CustomDialogPreference
        implements SeekBar.OnSeekBarChangeListener {

    private int mOriginalValue;
    private int mMinValue;
    private int mMaxValue;
    private int mDefaultValue;
    private int mWarningValue;

    private SeekBar mSeekBar;
    private TextView mValueText;
    private TextView mWarningText;

    private Drawable mProgressDrawable;
    private Drawable mProgressThumb;
    private LightingColorFilter mRedFilter;

    public VibratorIntensity(final Context context, final AttributeSet attrs) {
        super(context, attrs);

        setDialogLayoutResource(R.layout.vibrator_intensity);
    }

    @Override
    protected void onPrepareDialogBuilder(final AlertDialog.Builder builder,
            final DialogInterface.OnClickListener listener) {
        builder.setNeutralButton(R.string.vibrator_intensity_dialog_reset, null);
    }

    @Override
    protected void onBindDialogView(final View view) {
        super.onBindDialogView(view);

        mSeekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
        mValueText = (TextView) view.findViewById(R.id.value);
        mWarningText = (TextView) view.findViewById(R.id.warning_text);

        // Read the current value in case user wants to dismiss his changes
        final CMHardwareManager hardware = CMHardwareManager.getInstance(getContext());
        mOriginalValue = hardware.getVibratorIntensity();
        mWarningValue = hardware.getVibratorWarningIntensity();
        mMinValue = hardware.getVibratorMinIntensity();
        mMaxValue = hardware.getVibratorMaxIntensity();
        mDefaultValue = hardware.getVibratorDefaultIntensity();

        final String message = getContext().getResources().getString(
                R.string.vibrator_intensity_dialog_warning,
                intensityToPercent(mMinValue, mMaxValue, mWarningValue));
        mWarningText.setText(message);
        if (mWarningValue <= 0) {
            mWarningText.setVisibility(View.GONE);
        }

        final Drawable progressDrawable = mSeekBar.getProgressDrawable();
        if (progressDrawable instanceof LayerDrawable) {
            LayerDrawable ld = (LayerDrawable) progressDrawable;
            mProgressDrawable = ld.findDrawableByLayerId(android.R.id.progress);
        }
        mProgressThumb = mSeekBar.getThumb();
        mRedFilter = new LightingColorFilter(Color.BLACK,
                getContext().getResources().getColor(android.R.color.holo_red_light));

        mSeekBar.setOnSeekBarChangeListener(this);
        mSeekBar.setMax(mMaxValue - mMinValue);
        mSeekBar.setProgress(mOriginalValue - mMinValue);
    }

    @Override
    protected boolean onDismissDialog(final DialogInterface dialog, final int which) {
        // Can't use onPrepareDialogBuilder for this as we want the dialog
        // to be kept open on click
        if (which == DialogInterface.BUTTON_NEUTRAL) {
            mSeekBar.setProgress(mDefaultValue - mMinValue);
            setVibratorIntensity(mDefaultValue);
            testVibration();
            return false;
        }
        return true;
    }

    @Override
    protected void onDialogClosed(final boolean positiveResult) {
        super.onDialogClosed(positiveResult);

        if (positiveResult) {
            // Store percent value in SharedPreferences object
            final SharedPreferences prefs = PreferenceManager
                    .getDefaultSharedPreferences(getContext());
            final int intensity = mSeekBar.getProgress() + mMinValue;
            final int percent = intensityToPercent(mMinValue, mMaxValue, intensity);
            prefs.edit().putInt(CMSettings.Secure.VIBRATOR_INTENSITY, percent).commit();
            CMSettings.Secure.putInt(getContext().getContentResolver(),
                    CMSettings.Secure.VIBRATOR_INTENSITY, intensity);
        } else {
            setVibratorIntensity(mOriginalValue);
            CMSettings.Secure.putInt(getContext().getContentResolver(),
                    CMSettings.Secure.VIBRATOR_INTENSITY, mOriginalValue);
        }
    }

    @Override
    public void onProgressChanged(
                final SeekBar seekBar, final int progress, final boolean fromUser) {
        final int intensity = progress + mMinValue;
        final boolean shouldWarn = mWarningValue > 0 && intensity >= mWarningValue;

        if (mProgressDrawable != null) {
            mProgressDrawable.setColorFilter(shouldWarn ? mRedFilter : null);
        }
        if (mProgressThumb != null) {
            mProgressThumb.setColorFilter(shouldWarn ? mRedFilter : null);
        }

        mValueText.setText(
                String.format("%d%%", intensityToPercent(mMinValue, mMaxValue, intensity)));
    }

    @Override
    public void onStartTrackingTouch(final SeekBar seekBar) {
        // Do nothing
    }

    @Override
    public void onStopTrackingTouch(final SeekBar seekBar) {
        setVibratorIntensity(seekBar.getProgress() + mMinValue);
        testVibration();
    }

    private void setVibratorIntensity(final int intensity) {
        final CMHardwareManager hardware = CMHardwareManager.getInstance(getContext());
        hardware.setVibratorIntensity(intensity);
    }

    private void testVibration() {
        final Vibrator vib = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
        vib.vibrate(200);
    }

    private static int intensityToPercent(final int min, final int max, final int value) {
        int percent = Math.round((value - min) * (100.f / (max - min)));

        if (percent > 100) {
            percent = 100;
        } else if (percent < 0) {
            percent = 0;
        }

        return percent;
    }

    private static int percentToIntensity(final int min, final int max, final int percent) {
        int value = Math.round((((max - min) * percent) / 100.f) + min);

        if (value > max) {
            value = max;
        } else if (value < min) {
            value = min;
        }

        return value;
    }
}
Loading