<commit_before>package jp.takke.cpustats

import android.app.KeyguardManager
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import java.lang.ref.WeakReference

internal class NotificationPresenter/*package*/(service: Service, private val mConfig: MyConfig) {

    private val mServiceRef: WeakReference<Service> = WeakReference(service)

    // 通知時刻[ms]
    private var mNotificationTime: Long = 0

    // 通知時刻の非更新時刻(この時間になるまで更新しない。スリープ復帰時にはすぐに更新するとステータスバーの順序がずれてうざいので)[ms]
    var mNotificationTimeKeep: Long = 0

    /**
     * ステータスバー通知の設定
     */
    fun updateNotifications(cpuUsages: IntArray?, currentCpuClock: Int, minFreq: Int, maxFreq: Int, requestForeground: Boolean) {

        val service = mServiceRef.get() ?: return

        // N分おきに通知時刻を更新する
        val now = System.currentTimeMillis()
        if (now > mNotificationTime + 3 * 60 * 1000 && now > mNotificationTimeKeep) {
            mNotificationTime = now
        }

        val nm = service.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // 通知ウインドウをクリックした際に起動するインテント
        val intent = Intent(service, PreviewActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(service, 0, intent,
                PendingIntent.FLAG_CANCEL_CURRENT)

        //--------------------------------------------------
        // CPU使用率通知
        //--------------------------------------------------
        if (cpuUsages != null && mConfig.showUsageNotification) {

            // cpuUsagesを各通知アイコンのデータに振り分ける
            val data = CpuNotificationDataDistributor.distributeNotificationData(cpuUsages, mConfig.coreDistributionMode)

            if (MyLog.debugMode) {
                dumpCpuUsagesForDebug(cpuUsages, data)
            }

            // Android O (8.0) 以降では通知チャンネルが必要
            createNotificationChannel(service, CHANNEL_ID_CPU_USAGE, "CPU Usage")

            // Notification(icon1)
            if (data.isNotEmpty()) {
                doNotify(MY_USAGE_NOTIFICATION_ID1, makeUsageNotification(data[0], pendingIntent).build(), service, nm, requestForeground)
            } else {
                nm.cancel(MY_USAGE_NOTIFICATION_ID1)
            }
            // Notification(icon2)
            if (data.size >= 2) {
                doNotify(MY_USAGE_NOTIFICATION_ID2, makeUsageNotification(data[1], pendingIntent).build(), service, nm, requestForeground)
            } else {
                nm.cancel(MY_USAGE_NOTIFICATION_ID2)
            }
        }

        //--------------------------------------------------
        // 周波数通知
        //--------------------------------------------------
        if (currentCpuClock > 0 && mConfig.showFrequencyNotification) {

            // Android O (8.0) 以降では通知チャンネルが必要
            createNotificationChannel(service, CHANNEL_ID_CPU_FREQUENCY, "CPU Frequency")

            doNotify(MY_FREQ_NOTIFICATION_ID, makeFrequencyNotification(minFreq, maxFreq, currentCpuClock, pendingIntent).build(),
                    service, nm, requestForeground)
        }
    }/*package*/

    private fun doNotify(notificationId: Int, notification: Notification,
                         service: Service, nm: NotificationManager, requestForeground: Boolean) {
        if (requestForeground) {
            service.startForeground(notificationId, notification)
        } else {
            nm.notify(notificationId, notification)
        }
    }

    private fun createNotificationChannel(context: Context, channelId: String, channelName: String) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            if (manager.getNotificationChannel(channelId) == null) {
                createNotificationChannel(manager, channelId, channelName)
            }
        }
    }

    /*package*/   fun cancelNotifications() {

        val context = mServiceRef.get() ?: return

        val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (!mConfig.showUsageNotification) {
            nm.cancel(MY_USAGE_NOTIFICATION_ID1)
            nm.cancel(MY_USAGE_NOTIFICATION_ID2)
        }
        if (!mConfig.showFrequencyNotification) {
            nm.cancel(MY_FREQ_NOTIFICATION_ID)
        }
    }

    private fun makeUsageNotification(data: CpuNotificationData, pendingIntent: PendingIntent): NotificationCompat.Builder {

        val notificationTitle0 = "CPU Usage"

        val cpuUsages = data.cpuUsages
        val totalUsage = if (cpuUsages == null) 0 else cpuUsages[0]
        val iconId = ResourceUtil.getIconIdForCpuUsage(cpuUsages)
        val context = mServiceRef.get()
        val builder = NotificationCompat.Builder(context!!, CHANNEL_ID_CPU_USAGE)

        builder.setSmallIcon(iconId)
        builder.color = ResourceUtil.getNotificationIconColorFromUsage(totalUsage)
        builder.setTicker(notificationTitle0)
        builder.setWhen(mNotificationTime)

        // 消えないようにする
        builder.setOngoing(true)<commit_msg>remove invalid comment<commit_after>package jp.takke.cpustats

import android.app.KeyguardManager
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import java.lang.ref.WeakReference

internal class NotificationPresenter(service: Service, private val mConfig: MyConfig) {

    private val mServiceRef: WeakReference<Service> = WeakReference(service)

    // 通知時刻[ms]
    private var mNotificationTime: Long = 0

    // 通知時刻の非更新時刻(この時間になるまで更新しない。スリープ復帰時にはすぐに更新するとステータスバーの順序がずれてうざいので)[ms]
    var mNotificationTimeKeep: Long = 0

    /**
     * ステータスバー通知の設定
     */
    fun updateNotifications(cpuUsages: IntArray?, currentCpuClock: Int, minFreq: Int, maxFreq: Int, requestForeground: Boolean) {

        val service = mServiceRef.get() ?: return

        // N分おきに通知時刻を更新する
        val now = System.currentTimeMillis()
        if (now > mNotificationTime + 3 * 60 * 1000 && now > mNotificationTimeKeep) {
            mNotificationTime = now
        }

        val nm = service.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // 通知ウインドウをクリックした際に起動するインテント
        val intent = Intent(service, PreviewActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(service, 0, intent,
                PendingIntent.FLAG_CANCEL_CURRENT)

        //--------------------------------------------------
        // CPU使用率通知
        //--------------------------------------------------
        if (cpuUsages != null && mConfig.showUsageNotification) {

            // cpuUsagesを各通知アイコンのデータに振り分ける
            val data = CpuNotificationDataDistributor.distributeNotificationData(cpuUsages, mConfig.coreDistributionMode)

            if (MyLog.debugMode) {
                dumpCpuUsagesForDebug(cpuUsages, data)
            }

            // Android O (8.0) 以降では通知チャンネルが必要
            createNotificationChannel(service, CHANNEL_ID_CPU_USAGE, "CPU Usage")

            // Notification(icon1)
            if (data.isNotEmpty()) {
                doNotify(MY_USAGE_NOTIFICATION_ID1, makeUsageNotification(data[0], pendingIntent).build(), service, nm, requestForeground)
            } else {
                nm.cancel(MY_USAGE_NOTIFICATION_ID1)
            }
            // Notification(icon2)
            if (data.size >= 2) {
                doNotify(MY_USAGE_NOTIFICATION_ID2, makeUsageNotification(data[1], pendingIntent).build(), service, nm, requestForeground)
            } else {
                nm.cancel(MY_USAGE_NOTIFICATION_ID2)
            }
        }

        //--------------------------------------------------
        // 周波数通知
        //--------------------------------------------------
        if (currentCpuClock > 0 && mConfig.showFrequencyNotification) {

            // Android O (8.0) 以降では通知チャンネルが必要
            createNotificationChannel(service, CHANNEL_ID_CPU_FREQUENCY, "CPU Frequency")

            doNotify(MY_FREQ_NOTIFICATION_ID, makeFrequencyNotification(minFreq, maxFreq, currentCpuClock, pendingIntent).build(),
                    service, nm, requestForeground)
        }
    }

    private fun doNotify(notificationId: Int, notification: Notification,
                         service: Service, nm: NotificationManager, requestForeground: Boolean) {
        if (requestForeground) {
            service.startForeground(notificationId, notification)
        } else {
            nm.notify(notificationId, notification)
        }
    }

    private fun createNotificationChannel(context: Context, channelId: String, channelName: String) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            if (manager.getNotificationChannel(channelId) == null) {
                createNotificationChannel(manager, channelId, channelName)
            }
        }
    }

    fun cancelNotifications() {

        val context = mServiceRef.get() ?: return

        val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (!mConfig.showUsageNotification) {
            nm.cancel(MY_USAGE_NOTIFICATION_ID1)
            nm.cancel(MY_USAGE_NOTIFICATION_ID2)
        }
        if (!mConfig.showFrequencyNotification) {
            nm.cancel(MY_FREQ_NOTIFICATION_ID)
        }
    }

    private fun makeUsageNotification(data: CpuNotificationData, pendingIntent: PendingIntent): NotificationCompat.Builder {

        val notificationTitle0 = "CPU Usage"

        val cpuUsages = data.cpuUsages
        val totalUsage = if (cpuUsages == null) 0 else cpuUsages[0]
        val iconId = ResourceUtil.getIconIdForCpuUsage(cpuUsages)
        val context = mServiceRef.get()
        val builder = NotificationCompat.Builder(context!!, CHANNEL_ID_CPU_USAGE)

        builder.setSmallIcon(iconId)
        builder.color = ResourceUtil.getNotificationIconColorFromUsage(totalUsage)
        builder.setTicker(notificationTitle0)
        builder.setWhen(mNotificationTime)

        // 消えないようにする
        builder.setOngoing(true)
{'fraction_non_alphanumeric': 0.117470162578705, 'fraction_numerical': 0.00563856780377784, 'mean_word_length': 2.380559085133418, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1460865', 'n_tokens_mistral': 3185, 'n_tokens_neox': 3013, 'n_words': 523}