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 17 package com.android.server.timezone; 18 19 import com.android.internal.R; 20 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageInfo; 24 import android.content.pm.PackageManager; 25 import android.content.pm.ProviderInfo; 26 import android.content.pm.ResolveInfo; 27 import android.content.res.Resources; 28 import android.os.SystemClock; 29 import android.util.Slog; 30 31 import java.util.List; 32 33 /** 34 * A single class that implements multiple helper interfaces for use by {@link PackageTracker}. 35 */ 36 final class PackageTrackerHelperImpl implements ClockHelper, ConfigHelper, PackageManagerHelper { 37 38 private static final String TAG = "PackageTrackerHelperImpl"; 39 40 private final Context mContext; 41 private final PackageManager mPackageManager; 42 43 PackageTrackerHelperImpl(Context context) { 44 mContext = context; 45 mPackageManager = context.getPackageManager(); 46 } 47 48 @Override 49 public boolean isTrackingEnabled() { 50 return mContext.getResources().getBoolean(R.bool.config_timeZoneRulesUpdateTrackingEnabled); 51 } 52 53 @Override 54 public String getUpdateAppPackageName() { 55 return mContext.getResources().getString(R.string.config_timeZoneRulesUpdaterPackage); 56 } 57 58 @Override 59 public String getDataAppPackageName() { 60 Resources resources = mContext.getResources(); 61 return resources.getString(R.string.config_timeZoneRulesDataPackage); 62 } 63 64 @Override 65 public int getCheckTimeAllowedMillis() { 66 return mContext.getResources().getInteger( 67 R.integer.config_timeZoneRulesCheckTimeMillisAllowed); 68 } 69 70 @Override 71 public int getFailedCheckRetryCount() { 72 return mContext.getResources().getInteger(R.integer.config_timeZoneRulesCheckRetryCount); 73 } 74 75 @Override 76 public long currentTimestamp() { 77 // Use of elapsedRealtime() because this is in-memory state and elapsedRealtime() shouldn't 78 // change if the system clock changes. 79 return SystemClock.elapsedRealtime(); 80 } 81 82 @Override 83 public int getInstalledPackageVersion(String packageName) 84 throws PackageManager.NameNotFoundException { 85 int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; 86 PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags); 87 return packageInfo.versionCode; 88 } 89 90 @Override 91 public boolean isPrivilegedApp(String packageName) throws PackageManager.NameNotFoundException { 92 int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; 93 PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags); 94 return packageInfo.applicationInfo.isPrivilegedApp(); 95 } 96 97 @Override 98 public boolean usesPermission(String packageName, String requiredPermissionName) 99 throws PackageManager.NameNotFoundException { 100 int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS 101 | PackageManager.GET_PERMISSIONS; 102 PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags); 103 if (packageInfo.requestedPermissions == null) { 104 return false; 105 } 106 for (String requestedPermission : packageInfo.requestedPermissions) { 107 if (requiredPermissionName.equals(requestedPermission)) { 108 return true; 109 } 110 } 111 return false; 112 } 113 114 @Override 115 public boolean contentProviderRegistered(String authority, String requiredPackageName) { 116 int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; 117 ProviderInfo providerInfo = 118 mPackageManager.resolveContentProvider(authority, flags); 119 if (providerInfo == null) { 120 Slog.i(TAG, "contentProviderRegistered: No content provider registered with authority=" 121 + authority); 122 return false; 123 } 124 boolean packageMatches = 125 requiredPackageName.equals(providerInfo.applicationInfo.packageName); 126 if (!packageMatches) { 127 Slog.i(TAG, "contentProviderRegistered: App with packageName=" + requiredPackageName 128 + " does not expose the a content provider with authority=" + authority); 129 return false; 130 } 131 return true; 132 } 133 134 @Override 135 public boolean receiverRegistered(Intent intent, String requiredPermissionName) 136 throws PackageManager.NameNotFoundException { 137 138 int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; 139 List<ResolveInfo> resolveInfo = mPackageManager.queryBroadcastReceivers(intent, flags); 140 if (resolveInfo.size() != 1) { 141 Slog.i(TAG, "receiverRegistered: Zero or multiple broadcast receiver registered for" 142 + " intent=" + intent + ", found=" + resolveInfo); 143 return false; 144 } 145 146 ResolveInfo matched = resolveInfo.get(0); 147 boolean requiresPermission = requiredPermissionName.equals(matched.activityInfo.permission); 148 if (!requiresPermission) { 149 Slog.i(TAG, "receiverRegistered: Broadcast receiver registered for intent=" 150 + intent + " must require permission " + requiredPermissionName); 151 } 152 return requiresPermission; 153 } 154 } 155