<commit_before>/*
 *     Copyright (C) 2017 <NAME>
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License along
 *     with this program; if not, write to the Free Software Foundation, Inc.,
 *     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package com.pyamsoft.padlock

import android.app.Application
import android.support.annotation.CheckResult
import android.support.v4.app.Fragment
import com.pyamsoft.padlock.base.PadLockProvider
import com.pyamsoft.padlock.lock.LockScreenActivity
import com.pyamsoft.padlock.main.MainActivity
import com.pyamsoft.padlock.service.RecheckService
import com.pyamsoft.padlock.settings.SettingsPreferenceFragment
import com.pyamsoft.padlock.uicommon.CanaryDialog
import com.pyamsoft.padlock.uicommon.CanaryFragment
import com.pyamsoft.pydroid.PYDroidModule
import com.pyamsoft.pydroid.about.Licenses
import com.pyamsoft.pydroid.loader.LoaderModule
import com.pyamsoft.pydroid.ui.PYDroid
import com.squareup.leakcanary.LeakCanary
import com.squareup.leakcanary.RefWatcher

class PadLock : Application() {

  private lateinit var refWatcher: RefWatcher
  private var component: PadLockComponent? = null
  private lateinit var pydroidModule: PYDroidModule
  private lateinit var loaderModule: LoaderModule

  override fun onCreate() {
    super.onCreate()
    if (LeakCanary.isInAnalyzerProcess(this)) {
      return
    }

    refWatcher = if (BuildConfig.DEBUG) {
      LeakCanary.install(this)
    } else {
      RefWatcher.DISABLED
    }

    pydroidModule = PYDroidModule(this, BuildConfig.DEBUG)
    loaderModule = LoaderModule(this)
    PYDroid.init(pydroidModule, loaderModule)
    Licenses.create("SQLBrite", "https://github.com/square/sqlbrite", "licenses/sqlbrite")
    Licenses.create("SQLDelight", "https://github.com/square/sqldelight", "licenses/sqldelight")
    Licenses.create("Dagger", "https://github.com/google/dagger", "licenses/dagger2")
    Licenses.create("FastAdapter", "https://github.com/mikepenz/fastadapter",
        "licenses/fastadapter")
    Licenses.create("Firebase", "https://firebase.google.com", "licenses/firebase")
    Licenses.create("PatternLockView", "https://github.com/aritraroy/PatternLockView",
        "licenses/patternlock")

    val dagger = Injector.obtain<PadLockComponent>(applicationContext)
    val receiver = dagger.provideApplicationInstallReceiver()
    val preferences = dagger.provideInstallListenerPreferences()
    if (preferences.isInstallListenerEnabled()) {
      receiver.register()
    } else {
      receiver.unregister()
    }
  }

  private fun buildDagger(): PadLockComponent {
    val provider = PadLockProvider(pydroidModule, loaderModule, MainActivity::class.java,
        LockScreenActivity::class.java,
        RecheckService::class.java)
    return DaggerPadLockComponent.builder().padLockProvider(provider).build()
  }

  override fun getSystemService(name: String?): Any {
    return if (Injector.name == name) {
      val graph: PadLockComponent
      val dagger = component
      if (dagger == null) {
        graph = buildDagger()
        component = graph
      } else {
        graph = dagger
      }

      // Return
      graph
    } else {
      // Return
      super.getSystemService(name)
    }
  }

  companion object {

    @JvmStatic
    @CheckResult
    fun getRefWatcher(fragment: CanaryFragment): RefWatcher = getRefWatcherInternal(fragment)

    @CheckResult
    @JvmStatic
    fun getRefWatcher(fragment: CanaryDialog): RefWatcher = getRefWatcherInternal(fragment)

    @JvmStatic
    @CheckResult
    fun getRefWatcher(preferenceFragment: SettingsPreferenceFragment): RefWatcher = getRefWatcherInternal(
        preferenceFragment)

    @JvmStatic
    @CheckResult<commit_msg>Watch app ops manager state<commit_after>/*
 *     Copyright (C) 2017 <NAME>
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License along
 *     with this program; if not, write to the Free Software Foundation, Inc.,
 *     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package com.pyamsoft.padlock

import android.app.AppOpsManager
import android.app.AppOpsManager.OnOpChangedListener
import android.app.Application
import android.content.Context
import android.support.annotation.CheckResult
import android.support.v4.app.Fragment
import com.pyamsoft.padlock.base.PadLockProvider
import com.pyamsoft.padlock.lock.LockScreenActivity
import com.pyamsoft.padlock.main.MainActivity
import com.pyamsoft.padlock.service.PadLockService
import com.pyamsoft.padlock.service.RecheckService
import com.pyamsoft.padlock.service.UsagePermissionChecker
import com.pyamsoft.padlock.settings.SettingsPreferenceFragment
import com.pyamsoft.padlock.uicommon.CanaryDialog
import com.pyamsoft.padlock.uicommon.CanaryFragment
import com.pyamsoft.pydroid.PYDroidModule
import com.pyamsoft.pydroid.about.Licenses
import com.pyamsoft.pydroid.loader.LoaderModule
import com.pyamsoft.pydroid.ui.PYDroid
import com.squareup.leakcanary.LeakCanary
import com.squareup.leakcanary.RefWatcher
import timber.log.Timber

class PadLock : Application() {

  private lateinit var refWatcher: RefWatcher
  private var component: PadLockComponent? = null
  private lateinit var pydroidModule: PYDroidModule
  private lateinit var loaderModule: LoaderModule

  override fun onCreate() {
    super.onCreate()
    if (LeakCanary.isInAnalyzerProcess(this)) {
      return
    }

    refWatcher = if (BuildConfig.DEBUG) {
      LeakCanary.install(this)
    } else {
      RefWatcher.DISABLED
    }

    pydroidModule = PYDroidModule(this, BuildConfig.DEBUG)
    loaderModule = LoaderModule(this)
    PYDroid.init(pydroidModule, loaderModule)
    Licenses.create("SQLBrite", "https://github.com/square/sqlbrite", "licenses/sqlbrite")
    Licenses.create("SQLDelight", "https://github.com/square/sqldelight", "licenses/sqldelight")
    Licenses.create("Dagger", "https://github.com/google/dagger", "licenses/dagger2")
    Licenses.create("FastAdapter", "https://github.com/mikepenz/fastadapter",
        "licenses/fastadapter")
    Licenses.create("Firebase", "https://firebase.google.com", "licenses/firebase")
    Licenses.create("PatternLockView", "https://github.com/aritraroy/PatternLockView",
        "licenses/patternlock")

    val dagger = Injector.obtain<PadLockComponent>(applicationContext)
    val receiver = dagger.provideApplicationInstallReceiver()
    val preferences = dagger.provideInstallListenerPreferences()
    if (preferences.isInstallListenerEnabled()) {
      receiver.register()
    } else {
      receiver.unregister()
    }

    listenForAppOps()
  }

  private fun listenForAppOps() {
    val listener = OnOpChangedListener { op, packageName ->
      Timber.d("Op: $op changed for package name: $packageName")
      if (UsagePermissionChecker.missingUsageStatsPermission(applicationContext)) {
        Timber.d("Ops permission lost, stop service")
        PadLockService.stop(applicationContext)
      } else {
        Timber.d("Ops permission gained, start service")
        PadLockService.start(applicationContext)
      }
    }

    val appOpsManager: AppOpsManager = applicationContext.getSystemService(
        Context.APP_OPS_SERVICE) as AppOpsManager

    // Listen for as long as the application is alive
    Timber.d("Start watching app ops: ${AppOpsManager.OPSTR_GET_USAGE_STATS}")
    appOpsManager.startWatchingMode(AppOpsManager.OPSTR_GET_USAGE_STATS,
        applicationContext.packageName, listener)
  }

  private fun buildDagger(): PadLockComponent {
    val provider = PadLockProvider(pydroidModule, loaderModule, MainActivity::class.java,
        LockScreenActivity::class.java,
        RecheckService::class.java)
    return DaggerPadLockComponent.builder().padLockProvider(provider).build()
  }

  override fun getSystemService(name: String?): Any {
    return if (Injector.name == name) {
      val graph: PadLockComponent
      val dagger = component
      if (dagger == null) {
        graph = buildDagger()
        component = graph
      } else {
        graph = dagger
      }

      // Return
      graph
    } else {
      // Return
      super.getSystemService(name)
    }
  }

  companion object {

    @JvmStatic
    @CheckResult
    fun getRefWatcher(fragment: CanaryFragment): RefWatcher = getRefWatcherInternal(fragment)

    @CheckResult
    @JvmStatic
    fun getRefWatcher(fragment: CanaryDialog): RefWatcher = getRefWatcherInternal(fragment)

    @JvmStatic
    @CheckResult
    fun getRefWatcher(
        preferenceFragment: SettingsPreferenceFragment): RefWatcher = getRefWatcherInternal(
        preferenceFragment)

    @JvmStatic
    @CheckResult
{'fraction_non_alphanumeric': 0.08914450035945364, 'fraction_numerical': 0.003697237342097155, 'mean_word_length': 3.830357142857143, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 12, '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': '131791', 'n_tokens_mistral': 2835, 'n_tokens_neox': 2791, 'n_words': 663}