<commit_before>/*
 * Copyright (C) 2013 <NAME> for GravityBox Project (C3C076@xda)
 * 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.ceco.kitkat.gravitybox;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.PowerManager;
import android.os.Vibrator;
import android.os.PowerManager.WakeLock;
import android.view.View;
import android.widget.ImageView;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;

public class ModDialer {
    private static final String TAG = "GB:ModDialer";
    public static final List<String> PACKAGE_NAMES = new ArrayList<String>(Arrays.asList(
        "com.google.android.dialer", "com.android.dialer"));

    private static final String CLASS_GLOWPAD_WRAPPER = "com.android.incallui.GlowPadWrapper";
    private static final String CLASS_CALL_CARD_FRAGMENT = "com.android.incallui.CallCardFragment";
    private static final String CLASS_DIALTACTS_ACTIVITY = "com.android.dialer.DialtactsActivity";
    private static final String CLASS_DIALTACTS_ACTIVITY_GOOGLE = 
            "com.google.android.dialer.extensions.GoogleDialtactsActivity";
    private static final String CLASS_IN_CALL_PRESENTER = "com.android.incallui.InCallPresenter";
    private static final String ENUM_IN_CALL_STATE = "com.android.incallui.InCallPresenter$InCallState";
    private static final String CLASS_CALL_LIST = "com.android.incallui.CallList";
    private static final String CLASS_CALL_CMD_CLIENT = "com.android.incallui.CallCommandClient";
    private static final boolean DEBUG = false;

    private static final int CALL_STATE_ACTIVE = 2;
    private static final int CALL_STATE_INCOMING = 3;
    private static final int CALL_STATE_WAITING = 4;

    private static XSharedPreferences mPrefsPhone;
    private static int mFlipAction = GravityBoxSettings.PHONE_FLIP_ACTION_NONE;
    private static Set<String> mCallVibrations;
    private static Context mContext;
    private static SensorManager mSensorManager;
    private static boolean mSensorListenerAttached = false;
    private static Object mIncomingCall;
    private static Class<?> mClassCallCmdClient;
    private static Object mPreviousCallState;
    private static Vibrator mVibrator;
    private static Handler mHandler;
    private static WakeLock mWakeLock;

    private static void log(String message) {
        XposedBridge.log(TAG + ": " + message);
    }

    private static PhoneSensorEventListener mPhoneSensorEventListener = 
            new PhoneSensorEventListener(new PhoneSensorEventListener.ActionHandler() {
        @Override
        public void onFaceUp() {
            if (DEBUG) log("PhoneSensorEventListener.onFaceUp");
            // do nothing
        }

        @Override
        public void onFaceDown() {
            if (DEBUG) log("PhoneSensorEventListener.onFaceDown");

            try {
                switch (mFlipAction) {
                    case GravityBoxSettings.PHONE_FLIP_ACTION_MUTE:
                        if (DEBUG) log("Muting call");
                        silenceRinger();
                        break;
                    case GravityBoxSettings.PHONE_FLIP_ACTION_DISMISS:
                        if (DEBUG) log("Rejecting call");
                        rejectCall(mIncomingCall);
                        break;
                    case GravityBoxSettings.PHONE_FLIP_ACTION_NONE:
                    default:
                        // do nothing
                }
            } catch (Throwable t) {
                XposedBridge.log(t);
            }
        }
    });

    private static void attachSensorListener() {
        if (mSensorManager == null || 
                mSensorListenerAttached ||
                mFlipAction == GravityBoxSettings.PHONE_FLIP_ACTION_NONE) return;

        mPhoneSensorEventListener.reset();
        mSensorManager.registerListener(mPhoneSensorEventListener, 
                mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
                SensorManager.SENSOR_DELAY_NORMAL);
        mSensorListenerAttached = true;

        if (DEBUG) log("Sensor listener attached");
    }

    private static void detachSensorListener() {
        if (mSensorManager == null || !mSensorListenerAttached) return;

        mSensorManager.unregisterListener(mPhoneSensorEventListener);
        mSensorListenerAttached = false;

        if (DEBUG) log("Sensor listener detached");
    }

    private static void silenceRinger() {
        try {
            final Class<?> classSm = XposedHelpers.findClass("android.os.ServiceManager", null);
            final Class<?> classITelephony = XposedHelpers.findClass(
                    "com.android.internal.telephony.ITelephony.Stub", null);
            final Object ts = XposedHelpers.callStaticMethod(classSm, "checkService", Context.TELEPHONY_SERVICE);            
            final Object its = XposedHelpers.callStaticMethod(classITelephony, "asInterface", ts);
            XposedHelpers.callMethod(its, "silenceRinger");
        } catch(Throwable t) {
            XposedBridge.log(t);
        }
    }

    private static void rejectCall(Object call) {
        if (call == null || 
                mClassCallCmdClient == null) return;

        try {
            final Object callCmdClient = 
                    XposedHelpers.callStaticMethod(mClassCallCmdClient, "getInstance");
            if (callCmdClient != null) {
                Class<?>[] pArgs = new Class<?>[] { call.getClass(), boolean.class, String.class };
                XposedHelpers.callMethod(callCmdClient, "rejectCall", pArgs,
                        call, false, null);
                if (DEBUG) log("Call rejected");
            }
        } catch (Throwable t) {
            XposedBridge.log(t);
        }
    }

    private static void vibrate(int v1, int p1, int v2) {
        if (mVibrator == null) return;

        long[] pattern = new long[] { 0, v1, p1, v2 };
        mVibrator.vibrate(pattern, -1);
    }

    private static Runnable mPeriodicVibrator = new Runnable() {
        @Override
        public void run() {
            if (mWakeLock != null) {
                if (mWakeLock.isHeld()) {
                    mWakeLock.release();
                }
                mWakeLock.acquire(61000);
                if (DEBUG) log("Partial Wake Lock timeout extended");
            }
            vibrate(70, 0, 0);
            mHandler.postDelayed(this, 60000);
        }
    };<commit_msg>Dialer: more gentle periodic vibrator (some babes would love this)<commit_after>/*
 * Copyright (C) 2013 <NAME> for GravityBox Project (C3C076@xda)
 * 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.ceco.kitkat.gravitybox;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.PowerManager;
import android.os.Vibrator;
import android.os.PowerManager.WakeLock;
import android.view.View;
import android.widget.ImageView;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;

public class ModDialer {
    private static final String TAG = "GB:ModDialer";
    public static final List<String> PACKAGE_NAMES = new ArrayList<String>(Arrays.asList(
        "com.google.android.dialer", "com.android.dialer"));

    private static final String CLASS_GLOWPAD_WRAPPER = "com.android.incallui.GlowPadWrapper";
    private static final String CLASS_CALL_CARD_FRAGMENT = "com.android.incallui.CallCardFragment";
    private static final String CLASS_DIALTACTS_ACTIVITY = "com.android.dialer.DialtactsActivity";
    private static final String CLASS_DIALTACTS_ACTIVITY_GOOGLE = 
            "com.google.android.dialer.extensions.GoogleDialtactsActivity";
    private static final String CLASS_IN_CALL_PRESENTER = "com.android.incallui.InCallPresenter";
    private static final String ENUM_IN_CALL_STATE = "com.android.incallui.InCallPresenter$InCallState";
    private static final String CLASS_CALL_LIST = "com.android.incallui.CallList";
    private static final String CLASS_CALL_CMD_CLIENT = "com.android.incallui.CallCommandClient";
    private static final boolean DEBUG = false;

    private static final int CALL_STATE_ACTIVE = 2;
    private static final int CALL_STATE_INCOMING = 3;
    private static final int CALL_STATE_WAITING = 4;

    private static XSharedPreferences mPrefsPhone;
    private static int mFlipAction = GravityBoxSettings.PHONE_FLIP_ACTION_NONE;
    private static Set<String> mCallVibrations;
    private static Context mContext;
    private static SensorManager mSensorManager;
    private static boolean mSensorListenerAttached = false;
    private static Object mIncomingCall;
    private static Class<?> mClassCallCmdClient;
    private static Object mPreviousCallState;
    private static Vibrator mVibrator;
    private static Handler mHandler;
    private static WakeLock mWakeLock;

    private static void log(String message) {
        XposedBridge.log(TAG + ": " + message);
    }

    private static PhoneSensorEventListener mPhoneSensorEventListener = 
            new PhoneSensorEventListener(new PhoneSensorEventListener.ActionHandler() {
        @Override
        public void onFaceUp() {
            if (DEBUG) log("PhoneSensorEventListener.onFaceUp");
            // do nothing
        }

        @Override
        public void onFaceDown() {
            if (DEBUG) log("PhoneSensorEventListener.onFaceDown");

            try {
                switch (mFlipAction) {
                    case GravityBoxSettings.PHONE_FLIP_ACTION_MUTE:
                        if (DEBUG) log("Muting call");
                        silenceRinger();
                        break;
                    case GravityBoxSettings.PHONE_FLIP_ACTION_DISMISS:
                        if (DEBUG) log("Rejecting call");
                        rejectCall(mIncomingCall);
                        break;
                    case GravityBoxSettings.PHONE_FLIP_ACTION_NONE:
                    default:
                        // do nothing
                }
            } catch (Throwable t) {
                XposedBridge.log(t);
            }
        }
    });

    private static void attachSensorListener() {
        if (mSensorManager == null || 
                mSensorListenerAttached ||
                mFlipAction == GravityBoxSettings.PHONE_FLIP_ACTION_NONE) return;

        mPhoneSensorEventListener.reset();
        mSensorManager.registerListener(mPhoneSensorEventListener, 
                mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
                SensorManager.SENSOR_DELAY_NORMAL);
        mSensorListenerAttached = true;

        if (DEBUG) log("Sensor listener attached");
    }

    private static void detachSensorListener() {
        if (mSensorManager == null || !mSensorListenerAttached) return;

        mSensorManager.unregisterListener(mPhoneSensorEventListener);
        mSensorListenerAttached = false;

        if (DEBUG) log("Sensor listener detached");
    }

    private static void silenceRinger() {
        try {
            final Class<?> classSm = XposedHelpers.findClass("android.os.ServiceManager", null);
            final Class<?> classITelephony = XposedHelpers.findClass(
                    "com.android.internal.telephony.ITelephony.Stub", null);
            final Object ts = XposedHelpers.callStaticMethod(classSm, "checkService", Context.TELEPHONY_SERVICE);            
            final Object its = XposedHelpers.callStaticMethod(classITelephony, "asInterface", ts);
            XposedHelpers.callMethod(its, "silenceRinger");
        } catch(Throwable t) {
            XposedBridge.log(t);
        }
    }

    private static void rejectCall(Object call) {
        if (call == null || 
                mClassCallCmdClient == null) return;

        try {
            final Object callCmdClient = 
                    XposedHelpers.callStaticMethod(mClassCallCmdClient, "getInstance");
            if (callCmdClient != null) {
                Class<?>[] pArgs = new Class<?>[] { call.getClass(), boolean.class, String.class };
                XposedHelpers.callMethod(callCmdClient, "rejectCall", pArgs,
                        call, false, null);
                if (DEBUG) log("Call rejected");
            }
        } catch (Throwable t) {
            XposedBridge.log(t);
        }
    }

    private static void vibrate(int v1, int p1, int v2) {
        if (mVibrator == null) return;

        long[] pattern = new long[] { 0, v1, p1, v2 };
        mVibrator.vibrate(pattern, -1);
    }

    private static Runnable mPeriodicVibrator = new Runnable() {
        @Override
        public void run() {
            if (mWakeLock != null) {
                if (mWakeLock.isHeld()) {
                    mWakeLock.release();
                }
                mWakeLock.acquire(61000);
                if (DEBUG) log("Partial Wake Lock timeout extended");
            }
            vibrate(50, 0, 0);
            mHandler.postDelayed(this, 60000);
        }
    };
{'fraction_non_alphanumeric': 0.08483932443977131, 'fraction_numerical': 0.004862982190970625, 'mean_word_length': 2.656415185007208, 'pattern_counts': {'":': 2, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3425150', 'n_tokens_mistral': 4247, 'n_tokens_neox': 4121, 'n_words': 1021}