1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.example.android.autofill.service.data.source.local; 17 18 import android.content.Context; 19 import android.content.SharedPreferences; 20 import android.content.pm.PackageInfo; 21 import android.content.pm.PackageManager; 22 23 import com.example.android.autofill.service.data.source.PackageVerificationDataSource; 24 import com.example.android.autofill.service.util.SecurityHelper; 25 26 import static com.example.android.autofill.service.util.Util.logd; 27 import static com.example.android.autofill.service.util.Util.logw; 28 29 public class SharedPrefsPackageVerificationRepository implements PackageVerificationDataSource { 30 31 private static final String SHARED_PREF_KEY = "com.example.android.autofill.service" 32 + ".datasource.PackageVerificationDataSource"; 33 private static PackageVerificationDataSource sInstance; 34 35 private final SharedPreferences mSharedPrefs; 36 private final Context mContext; 37 38 private SharedPrefsPackageVerificationRepository(Context context) { 39 mSharedPrefs = context.getApplicationContext() 40 .getSharedPreferences(SHARED_PREF_KEY, Context.MODE_PRIVATE); 41 mContext = context.getApplicationContext(); 42 } 43 44 public static PackageVerificationDataSource getInstance(Context context) { 45 if (sInstance == null) { 46 sInstance = new SharedPrefsPackageVerificationRepository( 47 context.getApplicationContext()); 48 } 49 return sInstance; 50 } 51 52 @Override 53 public void clear() { 54 mSharedPrefs.edit().clear().apply(); 55 } 56 57 @Override 58 public boolean putPackageSignatures(String packageName) { 59 String hash; 60 try { 61 PackageManager pm = mContext.getPackageManager(); 62 PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); 63 hash = SecurityHelper.getFingerprint(packageInfo, packageName); 64 logd("Hash for %s: %s", packageName, hash); 65 } catch (Exception e) { 66 logw(e, "Error getting hash for %s.", packageName); 67 return false; 68 } 69 70 if (!containsSignatureForPackage(packageName)) { 71 // Storage does not yet contain signature for this package name. 72 mSharedPrefs.edit().putString(packageName, hash).apply(); 73 return true; 74 } 75 return containsMatchingSignatureForPackage(packageName, hash); 76 } 77 78 private boolean containsSignatureForPackage(String packageName) { 79 return mSharedPrefs.contains(packageName); 80 } 81 82 private boolean containsMatchingSignatureForPackage(String packageName, 83 String hash) { 84 return hash.equals(mSharedPrefs.getString(packageName, null)); 85 } 86 } 87