gt:         if (isDebug) {
context: /*
   *  Copyright (C) 2013 - 2016 Alexander "Evisceration" Martinz
   *
   * 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 3 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, see <http://www.gnu.org/licenses/>.
   *
   */
  package org.namelessrom.devicecontrol;
  
  import android.annotation.SuppressLint;
  import android.content.Context;
  import android.os.AsyncTask;
  import android.os.Handler;
  import android.os.Looper;
  import android.os.PowerManager;
  import android.os.Vibrator;
  import android.support.annotation.WorkerThread;
  import android.support.v7.app.AppCompatDelegate;
  import android.util.Log;
  
  import org.namelessrom.devicecontrol.models.DeviceConfig;
  import org.namelessrom.devicecontrol.utils.CustomTabsHelper;
  
  import java.io.File;
  import java.util.Arrays;
  import java.util.HashSet;
  
  import at.amartinz.execution.ShellManager;
  import at.amartinz.universaldebug.UniversalDebug;
  import at.amartinz.universaldebug.fabric.FabricConfig;
  import at.amartinz.universaldebug.fabric.trees.CrashlyticsComponent;
  import at.amartinz.universaldebug.trees.BaseTree;
  import at.amartinz.universaldebug.trees.LogComponent;
  import at.amartinz.universaldebug.trees.VibrationComponent;
  import at.amartinz.universaldebug.trees.WriterComponent;
  import io.paperdb.Paper;
  import timber.log.Timber;
  
  // XXX: DO NOT USE ROOT HERE! NEVER!
  public class App extends android.app.Application {
      public static final Handler HANDLER = new Handler(Looper.getMainLooper());
  
      private static final int APP_VERSION = 1;
  
      private static App sInstance;
      private static boolean enableDebug = BuildConfig.DEBUG;
  
      private CustomTabsHelper customTabsHelper;
  
      private PowerManager powerManager;
      private Vibrator vibrator;
  
      public static App get() {
          return App.sInstance;
      }
  
      public static App get(Context context) {
          return ((App) context.getApplicationContext());
      }
  
      public CustomTabsHelper getCustomTabsHelper() {
          if (customTabsHelper == null) {
              customTabsHelper = new CustomTabsHelper(this);
          }
          return customTabsHelper;
      }
  
      public PowerManager getPowerManager() {
          if (powerManager == null) {
              powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
          }
          return powerManager;
      }
  
      public Vibrator getVibrator() {
          if (vibrator == null) {
              vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
          }
          return vibrator;
      }
  
      @Override public void onCreate() {
          super.onCreate();
          if (App.sInstance != null) {
              return;
          }
          App.sInstance = this;
  
          final UniversalDebug universalDebug = new UniversalDebug(this)
                  .withDebug(BuildConfig.DEBUG)
                  .withTimber(true)
                  .withDebugTree(buildDebugTree())
                  .withProductionTree(buildProductionTree());
  
          if (!enableDebug) {
              final FabricConfig fabricConfig = new FabricConfig(universalDebug)
                      .withAnswers()
                      .withCrashlytics();
              universalDebug.withExtension(fabricConfig);
          }
  
          universalDebug.install();
          ShellManager.enableDebug(App.enableDebug);
  
          Paper.init(this);
          setupThemeMode();
  
          AsyncTask.execute(new Runnable() {
              @Override public void run() {
                  setupEverythingAsync();
              }
          });
      }
  
      public static void setupThemeMode() {
          final DeviceConfig deviceConfig = DeviceConfig.get();
          switch (deviceConfig.themeMode) {
              case DeviceConfig.THEME_AUTO: {
                  AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
                  break;
              }
              case DeviceConfig.THEME_DAY: {
                  AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                  break;
              }
              default:
              case DeviceConfig.THEME_NIGHT: {
                  AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                  break;
              }
          }
      }
  
      @WorkerThread private void setupEverythingAsync() {
          Timber.d("Enable debug: %s", App.enableDebug);
  
          final String basePath = getFilesDirectory();
          final String[] dirList = new String[]{ basePath + DeviceConstants.DC_LOG_DIR };
          for (final String s : dirList) {
              final File dir = new File(s);
              if (!dir.exists()) {
                  Timber.v("setupDirectories: creating %s -> %s", s, dir.mkdirs());
              }
          }
  
          handleAppUpgrades();
  
          if (App.enableDebug) {
              final int gmsVersion = getResources().getInteger(R.integer.google_play_services_version);
              Timber.v("Google Play Services -> %s", gmsVersion);
          }
      }
  
      private void handleAppUpgrades() {
          boolean needsUpgrade = false;
  
          final DeviceConfig deviceConfig = DeviceConfig.get();
          if (deviceConfig.appVersion < 1) {
              needsUpgrade = true;
  
              final File externalCache = new File(getExternalCacheDir(), "bitmapCache");
              clearDirectory(externalCache);
  
              final File internalCacheOld = new File(getFilesDir(), "bitmapCache");
              clearDirectory(internalCacheOld);
  
              final File internalCache = new File(getCacheDir(), "bitmapCache");
              clearDirectory(internalCache);
          }
  
          if (needsUpgrade) {
              deviceConfig.appVersion = APP_VERSION;
              deviceConfig.save();
          }
      }
  
      @SuppressWarnings("ResultOfMethodCallIgnored") private void clearDirectory(File directory) {
          if (directory.exists()) {
              final File[] cacheFiles = directory.listFiles();
              if (cacheFiles != null) {
                  for (final File cacheFile : cacheFiles) {
                      cacheFile.delete();
                  }
              }
              directory.delete();
          }
      }
  
      @SuppressLint("SdCardPath") public String getFilesDirectory() {
          final File tmp = getFilesDir();
          if (tmp != null && tmp.isDirectory()) {
              return tmp.getPath();
          } else {
              return "/data/data/" + getPackageName();
          }
      }
  
      public String[] getStringArray(final int resId) {
          return getResources().getStringArray(resId);
      }
  
      private BaseTree buildDebugTree() {
          return buildTree(true);
      }
  
      private BaseTree buildProductionTree() {
          return buildTree(false);
      }
  
      private BaseTree buildTree(boolean isDebug) {
          final HashSet<Integer> priorityFilter = new HashSet<>();
          // if we are in release mode, remove all log calls except ERROR and WARN
          if (!isDebug) {
              priorityFilter.addAll(Arrays.asList(Log.ASSERT, Log.DEBUG, Log.INFO, Log.VERBOSE));
          }
          final BaseTree baseTree = new BaseTree(this, priorityFilter);
  
          final LogComponent logComponent = new LogComponent(baseTree);
          baseTree.addComponent(logComponent);
  
  