blob: 66ecd6e67e5640527064b124bad6d8403afa1dd5 [file] [log] [blame]
/*
* Copyright (C) 2021 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.pm;
import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
import static com.android.server.pm.PackageManagerService.TAG;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManagerNative;
import android.content.pm.IStagedApexObserver;
import android.content.pm.PackageInfo;
import android.content.pm.StagedApexInfo;
import android.os.Binder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Slog;
import java.util.Arrays;
final class PackageManagerNative extends IPackageManagerNative.Stub {
private final PackageManagerService mPm;
PackageManagerNative(PackageManagerService pm) {
mPm = pm;
}
@Override
public String[] getNamesForUids(int[] uids) throws RemoteException {
String[] names = null;
String[] results = null;
try {
if (uids == null || uids.length == 0) {
return null;
}
names = mPm.snapshotComputer().getNamesForUids(uids);
results = (names != null) ? names : new String[uids.length];
// massage results so they can be parsed by the native binder
for (int i = results.length - 1; i >= 0; --i) {
if (results[i] == null) {
results[i] = "";
}
}
return results;
} catch (Throwable t) {
// STOPSHIP(186558987): revert addition of try/catch/log
Slog.e(TAG, "uids: " + Arrays.toString(uids));
Slog.e(TAG, "names: " + Arrays.toString(names));
Slog.e(TAG, "results: " + Arrays.toString(results));
Slog.e(TAG, "throwing exception", t);
throw t;
}
}
@Override
public int getPackageUid(String packageName, long flags, int userId) throws RemoteException {
return mPm.snapshotComputer().getPackageUid(packageName, flags, userId);
}
// NB: this differentiates between preloads and sideloads
@Override
public String getInstallerForPackage(String packageName) throws RemoteException {
final Computer snapshot = mPm.snapshotComputer();
final int callingUser = UserHandle.getUserId(Binder.getCallingUid());
final String installerName = snapshot.getInstallerPackageName(packageName, callingUser);
if (!TextUtils.isEmpty(installerName)) {
return installerName;
}
// differentiate between preload and sideload
ApplicationInfo appInfo = snapshot.getApplicationInfo(packageName,
/*flags*/ 0,
/*userId*/ callingUser);
if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
return "preload";
}
return "";
}
@Override
public long getVersionCodeForPackage(String packageName) throws RemoteException {
try {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
PackageInfo pInfo = mPm.snapshotComputer()
.getPackageInfo(packageName, 0, callingUser);
if (pInfo != null) {
return pInfo.getLongVersionCode();
}
} catch (Exception e) {
}
return 0;
}
@Override
public int getTargetSdkVersionForPackage(String packageName) throws RemoteException {
int targetSdk = mPm.snapshotComputer().getTargetSdkVersion(packageName);
if (targetSdk != -1) {
return targetSdk;
}
throw new RemoteException("Couldn't get targetSdkVersion for package " + packageName);
}
@Override
public boolean isPackageDebuggable(String packageName) throws RemoteException {
int callingUser = UserHandle.getCallingUserId();
ApplicationInfo appInfo = mPm.snapshotComputer()
.getApplicationInfo(packageName, 0, callingUser);
if (appInfo != null) {
return (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
}
throw new RemoteException("Couldn't get debug flag for package " + packageName);
}
@Override
public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
throws RemoteException {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
final Computer snapshot = mPm.snapshotComputer();
boolean[] results = new boolean[packageNames.length];
for (int i = results.length - 1; i >= 0; --i) {
ApplicationInfo appInfo = snapshot.getApplicationInfo(packageNames[i], 0, callingUser);
results[i] = appInfo != null && appInfo.isAudioPlaybackCaptureAllowed();
}
return results;
}
@Override
public int getLocationFlags(String packageName) throws RemoteException {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
ApplicationInfo appInfo = mPm.snapshotComputer().getApplicationInfo(packageName,
/*flags*/ 0,
/*userId*/ callingUser);
if (appInfo == null) {
throw new RemoteException(
"Couldn't get ApplicationInfo for package " + packageName);
}
return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
| (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
| (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
}
@Override
public String getModuleMetadataPackageName() throws RemoteException {
return mPm.getModuleMetadataPackageName();
}
@Override
public boolean hasSha256SigningCertificate(String packageName, byte[] certificate)
throws RemoteException {
return mPm.snapshotComputer()
.hasSigningCertificate(packageName, certificate, CERT_INPUT_SHA256);
}
@Override
public boolean hasSystemFeature(String featureName, int version) {
return mPm.hasSystemFeature(featureName, version);
}
@Override
public void registerStagedApexObserver(IStagedApexObserver observer) {
mPm.mInstallerService.getStagingManager().registerStagedApexObserver(observer);
}
@Override
public void unregisterStagedApexObserver(IStagedApexObserver observer) {
mPm.mInstallerService.getStagingManager().unregisterStagedApexObserver(observer);
}
@Override
public String[] getStagedApexModuleNames() {
return mPm.mInstallerService.getStagingManager()
.getStagedApexModuleNames().toArray(new String[0]);
}
@Override
@Nullable
public StagedApexInfo getStagedApexInfo(String moduleName) {
return mPm.mInstallerService.getStagingManager().getStagedApexInfo(moduleName);
}
}