/**
   * Constructor.
   *
   * @param context the caller's context
   */
  public SecurePreferencesOld(Context context) {
    // Proxy design pattern
    if (SecurePreferencesOld.sFile == null) {
      SecurePreferencesOld.sFile = PreferenceManager.getDefaultSharedPreferences(context);
    }
    // Initialize encryption/decryption key
    try {
      final String key = SecurePreferencesOld.generateAesKeyName(context);
      String value = SecurePreferencesOld.sFile.getString(key, null);
      if (value == null) {
        value = SecurePreferencesOld.generateAesKeyValue();
        SecurePreferencesOld.sFile.edit().putString(key, value).commit();
      }
      SecurePreferencesOld.sKey = SecurePreferencesOld.decode(value);

    } catch (Exception e) {
      if (sLoggingEnabled) {
        Log.e(TAG, "Error init:" + e.getMessage());
      }
      throw new IllegalStateException(e);
    }
    // initialize OnSecurePreferencesChangeListener HashMap
    sOnSharedPreferenceChangeListeners =
        new HashMap<OnSharedPreferenceChangeListener, OnSharedPreferenceChangeListener>(10);
  }
 @Override
 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
 public SharedPreferences.Editor putStringSet(String key, Set<String> values) {
   final Set<String> encryptedValues = new HashSet<String>(values.size());
   for (String value : values) {
     encryptedValues.add(SecurePreferencesOld.encrypt(value));
   }
   mEditor.putStringSet(SecurePreferencesOld.encrypt(key), encryptedValues);
   return this;
 }
 @Override
 public boolean getBoolean(String key, boolean defaultValue) {
   final String encryptedValue =
       SecurePreferencesOld.sFile.getString(SecurePreferencesOld.encrypt(key), null);
   if (encryptedValue == null) {
     return defaultValue;
   }
   try {
     return Boolean.parseBoolean(SecurePreferencesOld.decrypt(encryptedValue));
   } catch (NumberFormatException e) {
     throw new ClassCastException(e.getMessage());
   }
 }
 @Override
 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
 public Set<String> getStringSet(String key, Set<String> defaultValues) {
   final Set<String> encryptedSet =
       SecurePreferencesOld.sFile.getStringSet(SecurePreferencesOld.encrypt(key), null);
   if (encryptedSet == null) {
     return defaultValues;
   }
   final Set<String> decryptedSet = new HashSet<String>(encryptedSet.size());
   for (String encryptedValue : encryptedSet) {
     decryptedSet.add(SecurePreferencesOld.decrypt(encryptedValue));
   }
   return decryptedSet;
 }
 @Override
 public Map<String, String> getAll() {
   final Map<String, ?> encryptedMap = SecurePreferencesOld.sFile.getAll();
   final Map<String, String> decryptedMap = new HashMap<String, String>(encryptedMap.size());
   for (Entry<String, ?> entry : encryptedMap.entrySet()) {
     try {
       decryptedMap.put(
           SecurePreferencesOld.decrypt(entry.getKey()),
           SecurePreferencesOld.decrypt(entry.getValue().toString()));
     } catch (Exception e) {
       // Ignore unencrypted key/value pairs
     }
   }
   return decryptedMap;
 }
  private static String generateAesKeyName(Context context)
      throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException {
    final char[] password = context.getPackageName().toCharArray();

    final byte[] salt = getDeviceSerialNumber(context).getBytes();

    SecretKey key;
    try {
      // TODO: what if there's an OS upgrade and now supports the primary
      // PBE
      key =
          SecurePreferencesOld.generatePBEKey(
              password, salt, PRIMARY_PBE_KEY_ALG, ITERATIONS, KEY_SIZE);
    } catch (NoSuchAlgorithmException e) {
      // older devices may not support the have the implementation try
      // with a weaker
      // algorthm
      key =
          SecurePreferencesOld.generatePBEKey(
              password, salt, BACKUP_PBE_KEY_ALG, ITERATIONS, KEY_SIZE);
    }
    return SecurePreferencesOld.encode(key.getEncoded());
  }
 @Deprecated
 private static String decrypt(String ciphertext) {
   if (ciphertext == null || ciphertext.length() == 0) {
     return ciphertext;
   }
   try {
     final Cipher cipher = Cipher.getInstance(AES_KEY_ALG, PROVIDER);
     cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(SecurePreferencesOld.sKey, AES_KEY_ALG));
     return new String(cipher.doFinal(SecurePreferencesOld.decode(ciphertext)), "UTF-8");
   } catch (Exception e) {
     if (sLoggingEnabled) {
       Log.w(TAG, "decrypt", e);
     }
     return null;
   }
 }
  @Deprecated
  private static String generateAesKeyValue() throws NoSuchAlgorithmException {
    // Do *not* seed secureRandom! Automatically seeded from system entropy
    final SecureRandom random = new SecureRandom();

    // Use the largest AES key length which is supported by the OS
    final KeyGenerator generator = KeyGenerator.getInstance("AES");
    try {
      generator.init(KEY_SIZE, random);
    } catch (Exception e) {
      try {
        generator.init(192, random);
      } catch (Exception e1) {
        generator.init(128, random);
      }
    }
    return SecurePreferencesOld.encode(generator.generateKey().getEncoded());
  }
 @Override
 public boolean contains(String key) {
   return SecurePreferencesOld.sFile.contains(SecurePreferencesOld.encrypt(key));
 }
 @Override
 public SharedPreferences.Editor remove(String key) {
   mEditor.remove(SecurePreferencesOld.encrypt(key));
   return this;
 }
 @Override
 public SharedPreferences.Editor putBoolean(String key, boolean value) {
   mEditor.putString(
       SecurePreferencesOld.encrypt(key), SecurePreferencesOld.encrypt(Boolean.toString(value)));
   return this;
 }
 @Override
 public SharedPreferences.Editor putFloat(String key, float value) {
   mEditor.putString(
       SecurePreferencesOld.encrypt(key), SecurePreferencesOld.encrypt(Float.toString(value)));
   return this;
 }
 @Override
 public SharedPreferences.Editor putLong(String key, long value) {
   mEditor.putString(
       SecurePreferencesOld.encrypt(key), SecurePreferencesOld.encrypt(Long.toString(value)));
   return this;
 }
 @Override
 public SharedPreferences.Editor putInt(String key, int value) {
   mEditor.putString(
       SecurePreferencesOld.encrypt(key), SecurePreferencesOld.encrypt(Integer.toString(value)));
   return this;
 }
 /**
  * This is useful for storing values that have be encrypted by something else
  *
  * @param key - encrypted as usual
  * @param value will not be encrypted
  * @return
  */
 public SharedPreferences.Editor putStringNoEncrypted(String key, String value) {
   mEditor.putString(SecurePreferencesOld.encrypt(key), value);
   return this;
 }
 @Override
 public String getString(String key, String defaultValue) {
   final String encryptedValue =
       SecurePreferencesOld.sFile.getString(SecurePreferencesOld.encrypt(key), null);
   return (encryptedValue != null) ? SecurePreferencesOld.decrypt(encryptedValue) : defaultValue;
 }
 /**
  * Added to get a values as as it can be useful to store values that are already encrypted and
  * encoded
  *
  * @param key
  * @param defaultValue
  * @return Unencrypted value of the key or the defaultValue if
  */
 public String getStringUnencrypted(String key, String defaultValue) {
   final String nonEncryptedValue =
       SecurePreferencesOld.sFile.getString(SecurePreferencesOld.encrypt(key), null);
   return (nonEncryptedValue != null) ? nonEncryptedValue : defaultValue;
 }