| /* | |
| * Copyright (C) 2017 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| package com.android.server.timezone; | |
| import com.android.internal.R; | |
| import android.content.Context; | |
| import android.content.Intent; | |
| import android.content.pm.PackageInfo; | |
| import android.content.pm.PackageManager; | |
| import android.content.pm.ProviderInfo; | |
| import android.content.pm.ResolveInfo; | |
| import android.content.res.Resources; | |
| import android.os.SystemClock; | |
| import android.os.UserHandle; | |
| import android.util.Slog; | |
| import java.util.List; | |
| /** | |
| * A single class that implements multiple helper interfaces for use by {@link PackageTracker}. | |
| */ | |
| final class PackageTrackerHelperImpl implements ClockHelper, ConfigHelper, PackageManagerHelper { | |
| private static final String TAG = "PackageTrackerHelperImpl"; | |
| private final Context mContext; | |
| private final PackageManager mPackageManager; | |
| PackageTrackerHelperImpl(Context context) { | |
| mContext = context; | |
| mPackageManager = context.getPackageManager(); | |
| } | |
| @Override | |
| public boolean isTrackingEnabled() { | |
| return mContext.getResources().getBoolean(R.bool.config_timeZoneRulesUpdateTrackingEnabled); | |
| } | |
| @Override | |
| public String getUpdateAppPackageName() { | |
| return mContext.getResources().getString(R.string.config_timeZoneRulesUpdaterPackage); | |
| } | |
| @Override | |
| public String getDataAppPackageName() { | |
| Resources resources = mContext.getResources(); | |
| return resources.getString(R.string.config_timeZoneRulesDataPackage); | |
| } | |
| @Override | |
| public int getCheckTimeAllowedMillis() { | |
| return mContext.getResources().getInteger( | |
| R.integer.config_timeZoneRulesCheckTimeMillisAllowed); | |
| } | |
| @Override | |
| public int getFailedCheckRetryCount() { | |
| return mContext.getResources().getInteger(R.integer.config_timeZoneRulesCheckRetryCount); | |
| } | |
| @Override | |
| public long currentTimestamp() { | |
| // Use of elapsedRealtime() because this is in-memory state and elapsedRealtime() shouldn't | |
| // change if the system clock changes. | |
| return SystemClock.elapsedRealtime(); | |
| } | |
| @Override | |
| public int getInstalledPackageVersion(String packageName) | |
| throws PackageManager.NameNotFoundException { | |
| int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; | |
| PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags); | |
| return packageInfo.versionCode; | |
| } | |
| @Override | |
| public boolean isPrivilegedApp(String packageName) throws PackageManager.NameNotFoundException { | |
| int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; | |
| PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags); | |
| return packageInfo.applicationInfo.isPrivilegedApp(); | |
| } | |
| @Override | |
| public boolean usesPermission(String packageName, String requiredPermissionName) | |
| throws PackageManager.NameNotFoundException { | |
| int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS | |
| | PackageManager.GET_PERMISSIONS; | |
| PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags); | |
| if (packageInfo.requestedPermissions == null) { | |
| return false; | |
| } | |
| for (String requestedPermission : packageInfo.requestedPermissions) { | |
| if (requiredPermissionName.equals(requestedPermission)) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| @Override | |
| public boolean contentProviderRegistered(String authority, String requiredPackageName) { | |
| int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; | |
| ProviderInfo providerInfo = mPackageManager.resolveContentProviderAsUser( | |
| authority, flags, UserHandle.SYSTEM.getIdentifier()); | |
| if (providerInfo == null) { | |
| Slog.i(TAG, "contentProviderRegistered: No content provider registered with authority=" | |
| + authority); | |
| return false; | |
| } | |
| boolean packageMatches = | |
| requiredPackageName.equals(providerInfo.applicationInfo.packageName); | |
| if (!packageMatches) { | |
| Slog.i(TAG, "contentProviderRegistered: App with packageName=" + requiredPackageName | |
| + " does not expose the a content provider with authority=" + authority); | |
| return false; | |
| } | |
| return true; | |
| } | |
| @Override | |
| public boolean receiverRegistered(Intent intent, String requiredPermissionName) | |
| throws PackageManager.NameNotFoundException { | |
| int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; | |
| List<ResolveInfo> resolveInfo = mPackageManager.queryBroadcastReceiversAsUser( | |
| intent, flags, UserHandle.SYSTEM); | |
| if (resolveInfo.size() != 1) { | |
| Slog.i(TAG, "receiverRegistered: Zero or multiple broadcast receiver registered for" | |
| + " intent=" + intent + ", found=" + resolveInfo); | |
| return false; | |
| } | |
| ResolveInfo matched = resolveInfo.get(0); | |
| boolean requiresPermission = requiredPermissionName.equals(matched.activityInfo.permission); | |
| if (!requiresPermission) { | |
| Slog.i(TAG, "receiverRegistered: Broadcast receiver registered for intent=" | |
| + intent + " must require permission " + requiredPermissionName); | |
| } | |
| return requiresPermission; | |
| } | |
| } |